One more dota build fix.
3 * =============================================================================
4 * SourceMod Updater Extension
5 * Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include <sourcemod_version.h>
37 #include "extension.h"
40 #include <sh_string.h>
42 #define DEFAULT_UPDATE_URL "http://www.sourcemod.net/update/"
44 using namespace SourceHook;
46 SmUpdater g_Updater; /**< Global singleton for extension's main interface */
47 SMEXT_LINK(&g_Updater);
49 IWebternet *webternet;
50 static List<String *> update_errors;
51 static IThreadHandle *update_thread;
52 static String update_url;
54 bool SmUpdater::SDK_OnLoad(char *error, size_t maxlength, bool late)
56 sharesys->AddDependency(myself, "webternet.ext", true, true);
58 SM_GET_IFACE(WEBTERNET, webternet);
60 const char *url = smutils->GetCoreConfigValue("AutoUpdateURL");
63 url = DEFAULT_UPDATE_URL;
65 update_url.assign(url);
68 params.flags = Thread_Default;
69 params.prio = ThreadPrio_Low;
70 update_thread = threader->MakeThread(this, ¶ms);
72 if (update_thread == NULL)
74 smutils->Format(error, maxlength, "Could not create thread");
81 void SmUpdater::SDK_OnUnload()
83 /* An interface drop might have killed this thread.
84 * But if the handle is still there, we have to wait.
86 if (update_thread != NULL)
88 update_thread->WaitForThread();
89 update_thread->DestroyThis();
92 /* Clear message tables */
93 List<String *>::iterator iter = update_errors.begin();
94 while (iter != update_errors.end())
96 iter = update_errors.erase(iter);
100 bool SmUpdater::QueryInterfaceDrop(SourceMod::SMInterface *pInterface)
102 if (pInterface == webternet)
110 void SmUpdater::NotifyInterfaceDrop(SMInterface *pInterface)
112 if (pInterface == webternet)
114 /* Can't be in the thread if we're losing this extension. */
115 update_thread->WaitForThread();
116 update_thread->DestroyThis();
117 update_thread = NULL;
121 static void PumpUpdate(void *data)
124 bool new_files = false;
125 List<String *>::iterator iter;
127 char path[PLATFORM_MAX_PATH];
129 UpdatePart *part = (UpdatePart*)data;
132 if (strstr(part->file, "..") != NULL)
134 /* Naughty naughty */
135 AddUpdateError("Detected invalid path escape (..): %s", part->file);
138 if (part->data == NULL)
140 smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", part->file);
141 if (libsys->IsPathDirectory(path))
145 if (!libsys->CreateFolder(path))
147 AddUpdateError("Could not create folder: %s", path);
151 smutils->LogMessage(myself, "Created folder \"%s\" from updater", path);
156 smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", part->file);
157 FILE *fp = fopen(path, "wb");
160 AddUpdateError("Could not open %s for writing", path);
163 if (fwrite(part->data, 1, part->length, fp) != part->length)
165 AddUpdateError("Could not write file %s", path);
169 smutils->LogMessage(myself,
170 "Successfully updated gamedata file \"%s\"",
184 if (update_errors.size())
186 smutils->LogError(myself, "--- BEGIN ERRORS FROM AUTOMATIC UPDATER ---");
188 for (iter = update_errors.begin();
189 iter != update_errors.end();
193 smutils->LogError(myself, "%s", str->c_str());
196 smutils->LogError(myself, "--- END ERRORS FROM AUTOMATIC UPDATER ---");
201 const char *force_restart = smutils->GetCoreConfigValue("ForceRestartAfterUpdate");
202 if (force_restart == NULL || strcasecmp(force_restart, "yes") != 0)
204 smutils->LogMessage(myself,
205 "SourceMod has been updated, please reload it or restart your server.");
210 smutils->Format(buffer,
213 smutils->GetPluginId());
214 gamehelpers->ServerCommand(buffer);
215 smutils->Format(buffer,
217 "changelevel \"%s\"\n",
218 gamehelpers->GetCurrentMap());
219 gamehelpers->ServerCommand(buffer);
220 gamehelpers->ServerCommand("echo SourceMod has been restarted from an automatic update.\n");
225 void SmUpdater::RunThread(IThreadHandle *pHandle)
229 ur.PerformUpdate(update_url.c_str());
231 smutils->AddFrameAction(PumpUpdate, ur.DetachParts());
234 void SmUpdater::OnTerminate(IThreadHandle *pHandle, bool cancel)
238 void AddUpdateError(const char *fmt, ...)
244 smutils->FormatArgs(buffer, sizeof(buffer), fmt, ap);
247 update_errors.push_back(new String(buffer));
250 const char *SmUpdater::GetExtensionVerString()
252 return SM_VERSION_STRING;
255 const char *SmUpdater::GetExtensionDateString()
257 return SM_BUILD_TIMESTAMP;