core/GameDataFetcher.cpp
changeset 2476 c21fd6e89ff5
parent 2475 297d0a773483
child 2479 44e8e76d4e53
child 2484 2c3479db5956
     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