core/GameDataFetcher.h
author David Anderson <dvander@alliedmods.net>
Fri Jul 11 06:51:21 2008 +0000 (2008-07-11)
branchrefac-jit
changeset 2192 7602d7fb60d9
parent 2168 c24a6fa957db
child 2367 0a45bbad3bde
permissions -rw-r--r--
fixed a compat regression, forgot msvc does funky things with overloaded virtual calls
     1 /**
     2 * vim: set ts=4 :
     3 * =============================================================================
     4 * SourceMod
     5 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6 * =============================================================================
     7 *
     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.
    11 * 
    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
    15 * details.
    16 *
    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/>.
    19 *
    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>.
    28 *
    29 * Version: $Id$
    30 */
    31 
    32 #ifndef _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
    33 #define _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
    34 
    35 #include "sourcemod.h"
    36 #include "TextParsers.h"
    37 #include "IThreader.h"
    38 #include "Logger.h"
    39 #include "LibrarySys.h"
    40 #include "ThreadSupport.h"
    41 #include "md5.h"
    42 #include "sm_memtable.h"
    43 
    44 enum UpdateStatus
    45 { 
    46 	Update_Unknown = 0,				/* Version wasn't recognised or version querying is unsupported */
    47 	Update_Current = 1,				/* Server is running latest version */
    48 	Update_NewBuild = 2,			/* Server is on a svn release and a newer version is available */
    49 	Update_MinorAvailable = 3,		/* Server is on a release and a minor release has superceeded it */
    50 	Update_MajorAvailable = 4,		/* Server is on a release and a major release has superceeded it */
    51 	Update_CriticalAvailable = 5,	/* A critical update has been released (security fixes etc) */
    52 };
    53 
    54 class BuildMD5ableBuffer : public ITextListener_SMC
    55 {
    56 public:
    57 
    58 	BuildMD5ableBuffer()
    59 	{
    60 		stringTable = new BaseStringTable(2048);
    61 		md5[0] = 0;
    62 		md5String[0] = 0;
    63 	}
    64 
    65 	~BuildMD5ableBuffer()
    66 	{
    67 		delete stringTable;
    68 	}
    69 
    70 	void ReadSMC_ParseStart()
    71 	{
    72 		checksum = MD5();
    73 	}
    74 
    75 	SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
    76 	{
    77 		stringTable->AddString(key);
    78 		stringTable->AddString(value);
    79 
    80 		return SMCResult_Continue;
    81 	}
    82 
    83 	SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
    84 	{
    85 		stringTable->AddString(name);
    86 
    87 		return SMCResult_Continue;
    88 	}
    89 
    90 	void ReadSMC_ParseEnd(bool halted, bool failed)
    91 	{
    92 		if (halted || failed)
    93 		{
    94 			return;
    95 		}
    96 
    97 		void *data = stringTable->GetMemTable()->GetAddress(0);
    98 
    99 		if (data != NULL)
   100 		{
   101 			checksum.update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
   102 		}
   103 
   104 		checksum.finalize();
   105 
   106 		checksum.hex_digest(md5String);
   107 		checksum.raw_digest(md5);
   108 
   109 		stringTable->Reset();
   110 	}
   111 
   112 	unsigned char * GetMD5()
   113 	{
   114 		return md5;
   115 	}
   116 
   117 	unsigned char * GetMD5String()
   118 	{
   119 		return (unsigned char *)&md5String[0];
   120 	}
   121 
   122 private:
   123 	MD5 checksum;
   124 	unsigned char md5[16];
   125 	char md5String[33];
   126 	BaseStringTable *stringTable;
   127 };
   128 
   129 struct FileData
   130 {
   131 	SourceHook::String *filename;
   132 	unsigned char checksum[33];
   133 };
   134 
   135 
   136 class FetcherThread : public IThread
   137 {
   138 public:
   139 	FetcherThread() 
   140 	{
   141 		//filenames = new BaseStringTable(200);
   142 		memtable = new BaseMemTable(4096);
   143 	}
   144 
   145 	~FetcherThread()
   146 	{
   147 		//delete filenames;
   148 		SourceHook::CVector<FileData *>::iterator iter = filenames.begin();
   149 
   150 		FileData *curData;
   151 
   152 		while (iter != filenames.end())
   153 		{
   154 			curData = (*iter);
   155 			delete curData->filename;
   156 			delete curData;
   157 			iter = filenames.erase(iter);
   158 		}
   159 	}
   160 
   161 	void RunThread(IThreadHandle *pHandle);
   162 	void OnTerminate(IThreadHandle *pHandle, bool cancel);
   163 
   164 private:
   165 	int BuildGameDataQuery(char *buffer, int maxlen);
   166 	void ProcessGameDataQuery(int SocketDescriptor);
   167 
   168 	/* These names are a lie. It's really NoMoreBlockingThan10Seconds */
   169 	int NonBlockingRecv(int socketDescriptor, char *buffer, int len);
   170 	int NonBlockingSend(int socketDescriptor, char *buffer, int len);
   171 
   172 	int ConnectSocket();
   173 
   174 	void HandleUpdateStatus(UpdateStatus status, short version[4]);
   175 
   176 public:
   177 	SourceHook::CVector<FileData *> filenames;
   178 private:
   179 	BaseMemTable *memtable;
   180 };
   181 
   182 extern BuildMD5ableBuffer g_MD5Builder;
   183 extern bool g_blockGameDataLoad;
   184 
   185 #endif // _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_