core/GameDataFetcher.h
author David Anderson <dvander@alliedmods.net>
Sun Nov 16 16:06:18 2008 -0800 (2008-11-16)
changeset 2411 8dfaa3d730b5
parent 2367 0a45bbad3bde
child 2474 1f4345fb0f75
permissions -rw-r--r--
Removed pointless "systems" folder from core.
pred@2142
     1
/**
pred@2142
     2
* vim: set ts=4 :
pred@2142
     3
* =============================================================================
pred@2142
     4
* SourceMod
pred@2142
     5
* Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
pred@2142
     6
* =============================================================================
pred@2142
     7
*
pred@2142
     8
* This program is free software; you can redistribute it and/or modify it under
pred@2142
     9
* the terms of the GNU General Public License, version 3.0, as published by the
pred@2142
    10
* Free Software Foundation.
pred@2142
    11
* 
pred@2142
    12
* This program is distributed in the hope that it will be useful, but WITHOUT
pred@2142
    13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
pred@2142
    14
* FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
pred@2142
    15
* details.
pred@2142
    16
*
pred@2142
    17
* You should have received a copy of the GNU General Public License along with
pred@2142
    18
* this program.  If not, see <http://www.gnu.org/licenses/>.
pred@2142
    19
*
pred@2142
    20
* As a special exception, AlliedModders LLC gives you permission to link the
pred@2142
    21
* code of this program (as well as its derivative works) to "Half-Life 2," the
pred@2142
    22
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
pred@2142
    23
* by the Valve Corporation.  You must obey the GNU General Public License in
pred@2142
    24
* all respects for all other code used.  Additionally, AlliedModders LLC grants
pred@2142
    25
* this exception to all derivative works.  AlliedModders LLC defines further
pred@2142
    26
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
pred@2142
    27
* or <http://www.sourcemod.net/license.php>.
pred@2142
    28
*
pred@2142
    29
* Version: $Id$
pred@2142
    30
*/
pred@2142
    31
pred@2142
    32
#ifndef _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
pred@2142
    33
#define _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
pred@2142
    34
pred@2142
    35
#include "sourcemod.h"
pred@2142
    36
#include "TextParsers.h"
pred@2142
    37
#include "IThreader.h"
pred@2142
    38
#include "Logger.h"
pred@2142
    39
#include "LibrarySys.h"
pred@2142
    40
#include "ThreadSupport.h"
pred@2142
    41
#include "md5.h"
pred@2142
    42
#include "sm_memtable.h"
pred@2142
    43
pred@2142
    44
enum UpdateStatus
pred@2142
    45
{ 
pred@2142
    46
	Update_Unknown = 0,				/* Version wasn't recognised or version querying is unsupported */
pred@2142
    47
	Update_Current = 1,				/* Server is running latest version */
pred@2142
    48
	Update_NewBuild = 2,			/* Server is on a svn release and a newer version is available */
pred@2142
    49
	Update_MinorAvailable = 3,		/* Server is on a release and a minor release has superceeded it */
pred@2142
    50
	Update_MajorAvailable = 4,		/* Server is on a release and a major release has superceeded it */
pred@2142
    51
	Update_CriticalAvailable = 5,	/* A critical update has been released (security fixes etc) */
pred@2142
    52
};
pred@2142
    53
pred@2142
    54
class BuildMD5ableBuffer : public ITextListener_SMC
pred@2142
    55
{
pred@2142
    56
public:
pred@2142
    57
pred@2142
    58
	BuildMD5ableBuffer()
pred@2142
    59
	{
pred@2142
    60
		stringTable = new BaseStringTable(2048);
pred@2142
    61
		md5[0] = 0;
pred@2142
    62
		md5String[0] = 0;
pred@2142
    63
	}
pred@2142
    64
pred@2142
    65
	~BuildMD5ableBuffer()
pred@2142
    66
	{
pred@2142
    67
		delete stringTable;
pred@2142
    68
	}
pred@2142
    69
pred@2142
    70
	void ReadSMC_ParseStart()
pred@2142
    71
	{
pred@2142
    72
		checksum = MD5();
pred@2142
    73
	}
pred@2142
    74
pred@2142
    75
	SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
pred@2142
    76
	{
pred@2142
    77
		stringTable->AddString(key);
pred@2142
    78
		stringTable->AddString(value);
pred@2142
    79
pred@2142
    80
		return SMCResult_Continue;
pred@2142
    81
	}
pred@2142
    82
pred@2142
    83
	SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
pred@2142
    84
	{
pred@2142
    85
		stringTable->AddString(name);
pred@2142
    86
pred@2142
    87
		return SMCResult_Continue;
pred@2142
    88
	}
pred@2142
    89
pred@2142
    90
	void ReadSMC_ParseEnd(bool halted, bool failed)
pred@2142
    91
	{
pred@2142
    92
		if (halted || failed)
pred@2142
    93
		{
pred@2142
    94
			return;
pred@2142
    95
		}
pred@2142
    96
pred@2142
    97
		void *data = stringTable->GetMemTable()->GetAddress(0);
pred@2142
    98
pred@2142
    99
		if (data != NULL)
pred@2142
   100
		{
pred@2142
   101
			checksum.update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
pred@2142
   102
		}
pred@2142
   103
pred@2142
   104
		checksum.finalize();
pred@2142
   105
pred@2142
   106
		checksum.hex_digest(md5String);
pred@2142
   107
		checksum.raw_digest(md5);
pred@2142
   108
pred@2142
   109
		stringTable->Reset();
pred@2142
   110
	}
pred@2142
   111
pred@2142
   112
	unsigned char * GetMD5()
pred@2142
   113
	{
pred@2142
   114
		return md5;
pred@2142
   115
	}
pred@2142
   116
pred@2142
   117
	unsigned char * GetMD5String()
pred@2142
   118
	{
pred@2142
   119
		return (unsigned char *)&md5String[0];
pred@2142
   120
	}
pred@2142
   121
pred@2142
   122
private:
pred@2142
   123
	MD5 checksum;
pred@2142
   124
	unsigned char md5[16];
pred@2142
   125
	char md5String[33];
pred@2142
   126
	BaseStringTable *stringTable;
pred@2142
   127
};
pred@2142
   128
pred@2142
   129
struct FileData
pred@2142
   130
{
pred@2142
   131
	SourceHook::String *filename;
pred@2142
   132
	unsigned char checksum[33];
pred@2142
   133
};
pred@2142
   134
pred@2142
   135
pred@2142
   136
class FetcherThread : public IThread
pred@2142
   137
{
pred@2142
   138
public:
pred@2142
   139
	FetcherThread() 
pred@2142
   140
	{
pred@2142
   141
		//filenames = new BaseStringTable(200);
pred@2142
   142
		memtable = new BaseMemTable(4096);
pred@2142
   143
	}
pred@2142
   144
pred@2142
   145
	~FetcherThread()
pred@2142
   146
	{
pred@2142
   147
		//delete filenames;
pred@2142
   148
		SourceHook::CVector<FileData *>::iterator iter = filenames.begin();
pred@2142
   149
pred@2142
   150
		FileData *curData;
pred@2142
   151
pred@2142
   152
		while (iter != filenames.end())
pred@2142
   153
		{
pred@2142
   154
			curData = (*iter);
pred@2142
   155
			delete curData->filename;
pred@2142
   156
			delete curData;
pred@2142
   157
			iter = filenames.erase(iter);
pred@2142
   158
		}
pred@2142
   159
	}
pred@2142
   160
pred@2142
   161
	void RunThread(IThreadHandle *pHandle);
pred@2142
   162
	void OnTerminate(IThreadHandle *pHandle, bool cancel);
pred@2142
   163
pred@2142
   164
private:
pred@2142
   165
	int BuildGameDataQuery(char *buffer, int maxlen);
pred@2142
   166
	void ProcessGameDataQuery(int SocketDescriptor);
pred@2142
   167
pred@2367
   168
	int RecvData(int socketDescriptor, char *buffer, int len);
pred@2367
   169
	int SendData(int socketDescriptor, char *buffer, int len);
pred@2142
   170
pred@2142
   171
	int ConnectSocket();
pred@2142
   172
pred@2142
   173
	void HandleUpdateStatus(UpdateStatus status, short version[4]);
pred@2142
   174
pred@2142
   175
public:
pred@2142
   176
	SourceHook::CVector<FileData *> filenames;
pred@2142
   177
private:
pred@2142
   178
	BaseMemTable *memtable;
pred@2142
   179
};
pred@2142
   180
pred@2142
   181
extern BuildMD5ableBuffer g_MD5Builder;
pred@2142
   182
extern bool g_blockGameDataLoad;
pred@2142
   183
pred@2142
   184
#endif // _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_