1.1 --- a/core/GameDataFetcher.cpp Sat Dec 27 19:50:13 2008 -0500
1.2 +++ b/core/GameDataFetcher.cpp Sun Dec 28 01:02:05 2008 -0500
1.3 @@ -1,33 +1,33 @@
1.4 /**
1.5 -* vim: set ts=4 :
1.6 -* =============================================================================
1.7 -* SourceMod
1.8 -* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 -* =============================================================================
1.10 -*
1.11 -* This program is free software; you can redistribute it and/or modify it under
1.12 -* the terms of the GNU General Public License, version 3.0, as published by the
1.13 -* Free Software Foundation.
1.14 -*
1.15 -* This program is distributed in the hope that it will be useful, but WITHOUT
1.16 -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 -* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 -* details.
1.19 -*
1.20 -* You should have received a copy of the GNU General Public License along with
1.21 -* this program. If not, see <http://www.gnu.org/licenses/>.
1.22 -*
1.23 -* As a special exception, AlliedModders LLC gives you permission to link the
1.24 -* code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 -* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 -* by the Valve Corporation. You must obey the GNU General Public License in
1.27 -* all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 -* this exception to all derivative works. AlliedModders LLC defines further
1.29 -* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 -* or <http://www.sourcemod.net/license.php>.
1.31 -*
1.32 -* Version: $Id$
1.33 -*/
1.34 + * vim: set ts=4 :
1.35 + * =============================================================================
1.36 + * SourceMod
1.37 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.38 + * =============================================================================
1.39 + *
1.40 + * This program is free software; you can redistribute it and/or modify it under
1.41 + * the terms of the GNU General Public License, version 3.0, as published by the
1.42 + * Free Software Foundation.
1.43 + *
1.44 + * This program is distributed in the hope that it will be useful, but WITHOUT
1.45 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.46 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.47 + * details.
1.48 + *
1.49 + * You should have received a copy of the GNU General Public License along with
1.50 + * this program. If not, see <http://www.gnu.org/licenses/>.
1.51 + *
1.52 + * As a special exception, AlliedModders LLC gives you permission to link the
1.53 + * code of this program (as well as its derivative works) to "Half-Life 2," the
1.54 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.55 + * by the Valve Corporation. You must obey the GNU General Public License in
1.56 + * all respects for all other code used. Additionally, AlliedModders LLC grants
1.57 + * this exception to all derivative works. AlliedModders LLC defines further
1.58 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.59 + * or <http://www.sourcemod.net/license.php>.
1.60 + *
1.61 + * Version: $Id$
1.62 + */
1.63
1.64 #include "GameDataFetcher.h"
1.65 #include "bitbuf.h"
1.66 @@ -63,19 +63,49 @@
1.67 #include "compat_wrappers.h"
1.68 #include "sm_stringutil.h"
1.69 #include "md5.h"
1.70 +#include "frame_hooks.h"
1.71
1.72 #define QUERY_MAX_LENGTH 1024
1.73
1.74 -BuildMD5ableBuffer g_MD5Builder;
1.75 -FetcherThread g_FetchThread;
1.76 +static BuildMD5ableBuffer g_MD5Builder;
1.77 +static FetcherThread g_FetchThread;
1.78
1.79 -FILE *logfile = NULL;
1.80 +static FILE *logfile = NULL;
1.81
1.82 bool g_disableGameDataUpdate = false;
1.83 +
1.84 +/**
1.85 + * Note on this. If we issue a reload and changelevel, my srcds.exe will emit
1.86 + * Assertion Failed: !m_bServiceStarted
1.87 + * on quit. This seems like a non-issue, because before we just terminated the
1.88 + * server anyway. If anyone notices and files a bug, we can look into it further.
1.89 + */
1.90 bool g_restartAfterUpdate = false;
1.91
1.92 -int g_serverPort = 6500;
1.93 -char g_serverAddress[100] = "smupdate.alliedmods.net";
1.94 +static bool was_level_started = false;
1.95 +static int g_serverPort = 6500;
1.96 +static char g_serverAddress[100] = "smupdate.alliedmods.net";
1.97 +
1.98 +static void _ForceRestart(void *data)
1.99 +{
1.100 + char cmd[300];
1.101 + g_Logger.LogMessage("Automatically restarting SourceMod after a successful gamedata update.");
1.102 + UTIL_Format(cmd, sizeof(cmd), "meta unload %d\n", g_PLID);
1.103 + engine->ServerCommand(cmd);
1.104 + UTIL_Format(cmd, sizeof(cmd), "changelevel \"%s\"\n", STRING(gpGlobals->mapname));
1.105 + engine->ServerCommand(cmd);
1.106 + UTIL_Format(cmd, sizeof(cmd), "echo SourceMod restarted after gamedata update.\n");
1.107 + engine->ServerCommand(cmd);
1.108 +}
1.109 +
1.110 +static void ForceRestart()
1.111 +{
1.112 + FrameAction action;
1.113 +
1.114 + action.action = _ForceRestart;
1.115 + action.data = NULL;
1.116 + AddFrameAction(action);
1.117 +}
1.118
1.119 void FetcherThread::RunThread(IThreadHandle *pHandle)
1.120 {
1.121 @@ -173,6 +203,11 @@
1.122 {
1.123 g_blockGameDataLoad = false;
1.124
1.125 + if (cancel)
1.126 + {
1.127 + return;
1.128 + }
1.129 +
1.130 if (wasSuccess)
1.131 {
1.132 HandleUpdateStatus(updateStatus, build);
1.133 @@ -181,8 +216,10 @@
1.134 {
1.135 if (g_restartAfterUpdate)
1.136 {
1.137 - g_Logger.LogMessage("Automatically restarting server after a successful gamedata update!");
1.138 - engine->ServerCommand("quit\n");
1.139 + if (was_level_started)
1.140 + {
1.141 + ForceRestart();
1.142 + }
1.143 }
1.144 else
1.145 {
1.146 @@ -642,6 +679,7 @@
1.147 }
1.148
1.149 bool g_blockGameDataLoad = false;
1.150 +static IThreadHandle *fetch_thread_hndl;
1.151
1.152 class InitFetch : public SMGlobalClass
1.153 {
1.154 @@ -660,7 +698,30 @@
1.155
1.156 ThreadParams fetchThreadParams = ThreadParams();
1.157 fetchThreadParams.prio = ThreadPrio_Low;
1.158 - g_pThreader->MakeThread(&g_FetchThread, &fetchThreadParams);
1.159 + fetch_thread_hndl = g_pThreader->MakeThread(&g_FetchThread, &fetchThreadParams);
1.160 + }
1.161 +
1.162 + void OnSourceModShutdown()
1.163 + {
1.164 + fetch_thread_hndl->WaitForThread();
1.165 + fetch_thread_hndl->DestroyThis();
1.166 + }
1.167 +
1.168 + void OnSourceModLevelActivated()
1.169 + {
1.170 + was_level_started = true;
1.171 +
1.172 + if (g_restartAfterUpdate &&
1.173 + g_FetchThread.wasSuccess &&
1.174 + g_FetchThread.needsRestart)
1.175 + {
1.176 + ForceRestart();
1.177 + }
1.178 + }
1.179 +
1.180 + void OnSourceModLevelEnd()
1.181 + {
1.182 + was_level_started = false;
1.183 }
1.184
1.185 ConfigResult OnSourceModConfigChanged(const char *key,
1.186 @@ -820,7 +881,6 @@
1.187
1.188 FetcherThread::~FetcherThread()
1.189 {
1.190 - //delete filenames;
1.191 SourceHook::CVector<FileData *>::iterator iter = filenames.begin();
1.192
1.193 FileData *curData;
1.194 @@ -838,5 +898,6 @@
1.195 {
1.196 memtable = new BaseMemTable(4096);
1.197 wasSuccess = false;
1.198 + needsRestart = false;
1.199 }
1.200