SourcePawn:AutoUpdater
From Devicenull's Code
This automatically installs and keeps plugins up to date
#pragma semicolon 1 #include <downloader> #include <sourcemod> #include <textparse> #include <keyvalues> #include <console> public Plugin:myinfo = { name = "AutoUpdater", author = "devicenull", description = "Automatically updates plugins", version = "0.1.0.1", url = "http://plugins.devicenull.org/" }; new Handle:cfgParser; new Handle:dw; #define MAX_PLUGINS 32 new String:PluginName[MAX_PLUGINS][256]; new PluginID[MAX_PLUGINS]; new PluginRev[MAX_PLUGINS]; new nextPlugin; new curPlugin; new String:recvBuffer[512]; new curState; #define STATE_CHECKING 0 #define STATE_DOWNLOADING 1 #define STATE_IDLE 3 #define CFG_PATH "configs/autoupdate.cfg" public OnPluginStart() { RegServerCmd("sm_addplugin",sm_addplugin,"<pluginid> <pluginname> - Adds this plugin to your server"); dw = CreateDownloader(); if (dw == 0) { PrintToServer("CreateHandle failed"); } SetCallback(dw,DownloadComplete); PrintToServer("OnPluginStart"); } public OnPluginEnd() { PrintToServer("OnPluginEnd "); if (!CloseHandle(dw)) { PrintToServer("Couldn't close handle!"); } } public OnServerLoad() { LogToGame("Starting update checks..."); //We only need to reload the config on mapchange decl String:path[128]; BuildPath(Path_SM,path,128,CFG_PATH); nextPlugin = curPlugin = 0; ParseConfig(path); --nextPlugin; DoUpdate(); } public DoUpdate() { curState = STATE_CHECKING; curPlugin = 0; //We need at least one plugin to continue if (nextPlugin > 0) { DoUpdateCheck(); } } public Action:sm_addplugin(args) { decl String:temp[64]; decl nextPos; decl String:arguments[256]; GetCmdArgString(arguments,256); nextPos = StrBreak(arguments,temp,64); if (nextPos == -1) { LogToGame("Usage: sm_addplugin <pluginid> <pluginname>"); return Plugin_Handled; } PluginID[nextPlugin] = StringToInt(temp); StrBreak(arguments[nextPos],PluginName[nextPlugin],256); ++nextPlugin; if (curState == STATE_IDLE) { DoUpdate(); } return Plugin_Handled; } DoUpdateCheck() { curState = STATE_CHECKING; ClearOutput(dw); SetOutputString(dw,recvBuffer,512); decl String:downloadurl[256]; Format(downloadurl,256,"http://plugins.devicenull.org/checkupdates.php?pluginid=%i&revision=%i",PluginID[curPlugin],PluginRev[curPlugin]); SetURL(dw,downloadurl); curState = STATE_CHECKING; Download(dw); } EndUpdateCheck() { curState = STATE_IDLE; decl String:temp[512]; BuildPath(Path_SM,temp,512,CFG_PATH); WriteConfig(temp); CloseHandle(dw); } DownloadPlugin(pluginID) { curState = STATE_DOWNLOADING; //Prepare to download the updated plugin ClearOutput(dw); decl String:temp[512]; BuildPath(Path_SM,temp,512,"plugins/"); Format(temp,512,"cstrike/%s%s.smx",temp,PluginName[pluginID]); SetOutputFile(dw,temp); Format(temp,512,"http://plugins.devicenull.org/getupdates.php?pluginid=%i",PluginID[pluginID]); SetURL(dw,temp); Download(dw); } public DownloadComplete(const sucess, const status, Handle:arg) { if (curState == STATE_CHECKING) { if (strcmp(recvBuffer,"ok",false) == 0) { PrintToServer("Plugin %s is up to date",PluginName[curPlugin]); if (++curPlugin < nextPlugin) { DoUpdateCheck(); } else { EndUpdateCheck(); } } else if (StrContains(recvBuffer,"upd",false) != -1) { PrintToServer("Plugin %s needs an update",PluginName[curPlugin]); //Get the new revision number PluginRev[curPlugin] = StringToInt(recvBuffer[4]); DownloadPlugin(curPlugin); } } else if (curState == STATE_DOWNLOADING) { curState = STATE_CHECKING; if (++curPlugin < nextPlugin) { DoUpdateCheck(); } else { EndUpdateCheck(); } } } WriteConfig(String:file[]) { new Handle:fl = OpenFile(file,"w"); WriteFileLine(fl,"Plugins"); WriteFileLine(fl,"{"); for (new i=0;i<nextPlugin;++i) { PrintToServer("I: %i next: %i",i,nextPlugin); WriteFileLine(fl,"\t\"%s\"",PluginName[i]); WriteFileLine(fl,"\t{"); WriteFileLine(fl,"\t\t\"id\"\t%i",PluginID[i]); WriteFileLine(fl,"\t\t\"rev\"\t%i",PluginRev[i]); WriteFileLine(fl,"\t}"); } WriteFileLine(fl,"}"); CloseHandle(fl); } public ParseConfig(String:cfgPath[]) { cfgParser = SMC_CreateParser(); SMC_SetReaders(cfgParser ,Config_NewSection ,Config_NewValue ,Config_EndSection); SMC_ParseFile(cfgParser,cfgPath); } public SMCResult:Config_NewSection(Handle:smc, const String:name[], bool:opt_quotes) { strcopy(PluginName[nextPlugin],256,name); return SMCParse_Continue; } public SMCResult:Config_NewValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes) { if (strcmp(key,"id",false)==0) { PluginID[nextPlugin] = StringToInt(value); } else if (strcmp(key,"rev",false)==0) { PluginRev[nextPlugin] = StringToInt(value); } return SMCParse_Continue; } public SMCResult:Config_EndSection(Handle:smc) { PrintToServer("Loaded plugin: %s - %i - %i",PluginName[nextPlugin],PluginID[nextPlugin],PluginRev[nextPlugin]); ++nextPlugin; return SMCParse_Continue; }