Another gamedata cleanup sponsored by an r=pred (bug 3351).
This commit is contained in:
parent
cb41fa6de4
commit
4daca3c5ba
@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#define INVALID_SOCKET -1
|
#define INVALID_SOCKET -1
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
|
#define WSAGetLastError() errno
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sh_vector.h"
|
#include "sh_vector.h"
|
||||||
@ -61,6 +62,7 @@
|
|||||||
#include "TimerSys.h"
|
#include "TimerSys.h"
|
||||||
#include "compat_wrappers.h"
|
#include "compat_wrappers.h"
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
#define QUERY_MAX_LENGTH 1024
|
#define QUERY_MAX_LENGTH 1024
|
||||||
|
|
||||||
@ -73,7 +75,7 @@ bool g_disableGameDataUpdate = false;
|
|||||||
bool g_restartAfterUpdate = false;
|
bool g_restartAfterUpdate = false;
|
||||||
|
|
||||||
int g_serverPort = 6500;
|
int g_serverPort = 6500;
|
||||||
char g_serverAddress[100] = "hayate.alliedmods.net";
|
char g_serverAddress[100] = "smupdate.alliedmods.net";
|
||||||
|
|
||||||
void FetcherThread::RunThread(IThreadHandle *pHandle)
|
void FetcherThread::RunThread(IThreadHandle *pHandle)
|
||||||
{
|
{
|
||||||
@ -127,9 +129,7 @@ void FetcherThread::RunThread( IThreadHandle *pHandle )
|
|||||||
|
|
||||||
if (g_disableGameDataUpdate)
|
if (g_disableGameDataUpdate)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
|
||||||
g_Logger.LogMessage("Skipping GameData Query due to DisableAutoUpdate being set to true");
|
g_Logger.LogMessage("Skipping GameData Query due to DisableAutoUpdate being set to true");
|
||||||
#endif
|
|
||||||
|
|
||||||
fclose(logfile);
|
fclose(logfile);
|
||||||
unlink(lock_path);
|
unlink(lock_path);
|
||||||
@ -148,13 +148,15 @@ void FetcherThread::RunThread( IThreadHandle *pHandle )
|
|||||||
|
|
||||||
int sent = SendData(socketDescriptor, query, len);
|
int sent = SendData(socketDescriptor, query, len);
|
||||||
|
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Sent Query!");
|
g_Logger.LogToOpenFile(logfile, "Sent gamedata query");
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
if (sent == 0)
|
if (sent == 0)
|
||||||
{
|
{
|
||||||
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Failed to send gamedata query data to remote host");
|
g_Logger.LogToOpenFile(logfile, "Failed to send gamedata query data to remote host");
|
||||||
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
closesocket(socketDescriptor);
|
closesocket(socketDescriptor);
|
||||||
fclose(logfile);
|
fclose(logfile);
|
||||||
@ -204,41 +206,39 @@ int FetcherThread::BuildGameDataQuery( char *buffer, int maxlen )
|
|||||||
{
|
{
|
||||||
const char *name = dir->GetEntryName();
|
const char *name = dir->GetEntryName();
|
||||||
size_t len = strlen(name);
|
size_t len = strlen(name);
|
||||||
if (len >= 4
|
if (len >= 4 && strcmp(&name[len-4], ".txt") == 0)
|
||||||
&& strcmp(&name[len-4], ".txt") == 0)
|
|
||||||
{
|
{
|
||||||
|
MD5 md5;
|
||||||
|
SMCError err;
|
||||||
|
SMCStates states;
|
||||||
|
unsigned char raw[16];
|
||||||
char file[PLATFORM_MAX_PATH];
|
char file[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
g_LibSys.PathFormat(file, sizeof(file), "%s/%s", gamedata_path, name);
|
g_LibSys.PathFormat(file, sizeof(file), "%s/%s", gamedata_path, name);
|
||||||
|
|
||||||
SMCStates states;
|
g_MD5Builder.checksum = &md5;
|
||||||
if (g_TextParser.ParseFile_SMC(file, &g_MD5Builder, &states) == SMCError_Okay)
|
if ((err = g_TextParser.ParseFile_SMC(file, &g_MD5Builder, &states)) == SMCError_Okay)
|
||||||
{
|
|
||||||
unsigned char *md5 = g_MD5Builder.GetMD5();
|
|
||||||
if (md5 != NULL)
|
|
||||||
{
|
{
|
||||||
|
md5.raw_digest(raw);
|
||||||
(uint8_t)buffer[10]++; //Increment the file counter
|
(uint8_t)buffer[10]++; //Increment the file counter
|
||||||
Writer.WriteBytes(md5, 16);
|
Writer.WriteBytes(raw, 16);
|
||||||
|
|
||||||
g_Logger.LogToOpenFile(logfile, "%s - \"%s\"", file, g_MD5Builder.GetMD5String());
|
|
||||||
|
|
||||||
FileData *data = new FileData();
|
FileData *data = new FileData();
|
||||||
data->filename = new SourceHook::String(file);
|
data->filename = new SourceHook::String(file);
|
||||||
memcpy(data->checksum, g_MD5Builder.GetMD5String(), 33);
|
md5.hex_digest(data->checksum);
|
||||||
filenames.push_back(data);
|
filenames.push_back(data);
|
||||||
|
|
||||||
|
IF_DEBUG_SPEW
|
||||||
|
g_Logger.LogToOpenFile(logfile, "Parsed file: %s as %s", file, data->checksum);
|
||||||
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "%s no md5?", file);
|
const char *error = g_TextParser.GetSMCErrorString(err);
|
||||||
#endif
|
g_Logger.LogToOpenFile(logfile, "Parsing of file %s failed: %s", file, error);
|
||||||
}
|
ENDIF_DEBUG_SPEW
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
g_Logger.LogToOpenFile(logfile, "%s failed!", file);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,17 +251,16 @@ int FetcherThread::BuildGameDataQuery( char *buffer, int maxlen )
|
|||||||
|
|
||||||
int FetcherThread::ConnectSocket()
|
int FetcherThread::ConnectSocket()
|
||||||
{
|
{
|
||||||
struct protoent *ptrp;
|
#if defined PLATFORM_WINDOWS
|
||||||
ptrp = getprotobyname("tcp");
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
WSAStartup(0x0101, &wsaData);
|
WSAStartup(0x0101, &wsaData);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ptrp == NULL)
|
struct protoent *ptrp;
|
||||||
|
|
||||||
|
if ((ptrp = getprotobyname("tcp")) == NULL)
|
||||||
{
|
{
|
||||||
g_Logger.LogToOpenFile(logfile, "Failed to find TCP");
|
g_Logger.LogToOpenFile(logfile, "Error: Failed to find TCP protocol");
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,12 +268,9 @@ int FetcherThread::ConnectSocket()
|
|||||||
|
|
||||||
if (socketDescriptor == INVALID_SOCKET)
|
if (socketDescriptor == INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
//bugger aye?
|
char error[255];
|
||||||
#ifdef WIN32
|
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
|
||||||
g_Logger.LogToOpenFile(logfile, "Failed to create a new socket - Error %i", WSAGetLastError());
|
g_Logger.LogToOpenFile(logfile, "Error: Failed to create socket: %s", error);
|
||||||
#else
|
|
||||||
g_Logger.LogToOpenFile(logfile, "Failed to create a new socket - Error %i", errno);
|
|
||||||
#endif
|
|
||||||
closesocket(socketDescriptor);
|
closesocket(socketDescriptor);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
@ -291,7 +287,7 @@ int FetcherThread::ConnectSocket()
|
|||||||
{
|
{
|
||||||
if ((local_addr.sin_addr.s_addr = inet_addr(g_serverAddress)) == INADDR_NONE)
|
if ((local_addr.sin_addr.s_addr = inet_addr(g_serverAddress)) == INADDR_NONE)
|
||||||
{
|
{
|
||||||
g_Logger.LogToOpenFile(logfile, "Couldn't locate address");
|
g_Logger.LogToOpenFile(logfile, "Couldn't locate address: %s", g_serverAddress);
|
||||||
closesocket(socketDescriptor);
|
closesocket(socketDescriptor);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
@ -303,11 +299,9 @@ int FetcherThread::ConnectSocket()
|
|||||||
|
|
||||||
if (connect(socketDescriptor, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0)
|
if (connect(socketDescriptor, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
char error[255];
|
||||||
g_Logger.LogToOpenFile(logfile, "Couldn't connect - Error %i", WSAGetLastError());
|
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
|
||||||
#else
|
g_Logger.LogToOpenFile(logfile, "Couldn't connect to %s: %s", g_serverAddress, error);
|
||||||
g_Logger.LogToOpenFile(logfile, "Couldn't connect - Error %i", errno);
|
|
||||||
#endif
|
|
||||||
closesocket(socketDescriptor);
|
closesocket(socketDescriptor);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
@ -318,35 +312,34 @@ int FetcherThread::ConnectSocket()
|
|||||||
void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
||||||
{
|
{
|
||||||
char buffer[50];
|
char buffer[50];
|
||||||
#ifdef DEBUG
|
|
||||||
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Waiting for reply!");
|
g_Logger.LogToOpenFile(logfile, "Waiting for reply!");
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
//Read in the header bytes
|
//Read in the header bytes
|
||||||
int returnLen = RecvData(socketDescriptor, buffer, 12);
|
int returnLen = RecvData(socketDescriptor, buffer, 12);
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
g_Logger.LogToOpenFile(logfile, "Recv Completed");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (returnLen == 0)
|
if (returnLen == 0)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
char error[255];
|
||||||
g_Logger.LogToOpenFile(logfile, ",but it failed.");
|
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
|
||||||
#endif
|
g_Logger.LogToOpenFile(logfile, "Did not receive reply: %s", error);
|
||||||
/* Timeout or fail? */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Received Header!");
|
g_Logger.LogToOpenFile(logfile, "Received Header!");
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
bf_read Reader = bf_read("GameDataQuery", buffer, 12);
|
bf_read Reader = bf_read("GameDataQuery", buffer, 12);
|
||||||
|
|
||||||
if (Reader.ReadByte() != 'A' || Reader.ReadByte() != 'G')
|
if (Reader.ReadByte() != 'A' || Reader.ReadByte() != 'G')
|
||||||
{
|
{
|
||||||
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Unknown Query Response");
|
g_Logger.LogToOpenFile(logfile, "Unknown Query Response");
|
||||||
|
ENDIF_DEBUG_SPEW
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,17 +352,23 @@ void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
|||||||
build[2] = Reader.ReadShort();
|
build[2] = Reader.ReadShort();
|
||||||
build[3] = Reader.ReadShort();
|
build[3] = Reader.ReadShort();
|
||||||
|
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Update Status: %i - Latest %i.%i.%i.%i", updateStatus, build[0], build[1], build[2], build[3]);
|
g_Logger.LogToOpenFile(logfile,
|
||||||
#endif
|
"Update Status: %i - Latest %i.%i.%i.%i",
|
||||||
|
updateStatus,
|
||||||
|
build[0],
|
||||||
|
build[1],
|
||||||
|
build[2],
|
||||||
|
build[3]);
|
||||||
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
HandleUpdateStatus(updateStatus, build);
|
HandleUpdateStatus(updateStatus, build);
|
||||||
|
|
||||||
int changedFiles = Reader.ReadByte();
|
int changedFiles = Reader.ReadByte();
|
||||||
|
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Files to download: %i", changedFiles);
|
g_Logger.LogToOpenFile(logfile, "Files to download: %i", changedFiles);
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
for (int i=0; i<changedFiles; i++)
|
for (int i=0; i<changedFiles; i++)
|
||||||
{
|
{
|
||||||
@ -387,9 +386,9 @@ void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
|||||||
int index = Reader.ReadByte();
|
int index = Reader.ReadByte();
|
||||||
int tempLen = Reader.ReadUBitLong(32);
|
int tempLen = Reader.ReadUBitLong(32);
|
||||||
|
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "File index %i and length %i", index, tempLen);
|
g_Logger.LogToOpenFile(logfile, "File index %i and length %i", index, tempLen);
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
void *memPtr;
|
void *memPtr;
|
||||||
memtable->CreateMem(tempLen+1, &memPtr);
|
memtable->CreateMem(tempLen+1, &memPtr);
|
||||||
@ -397,9 +396,9 @@ void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
|||||||
//Read the contents of our file into the memtable
|
//Read the contents of our file into the memtable
|
||||||
returnLen = RecvData(socketDescriptor, (char *)memPtr, tempLen);
|
returnLen = RecvData(socketDescriptor, (char *)memPtr, tempLen);
|
||||||
|
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Recieved %i bytes", returnLen);
|
g_Logger.LogToOpenFile(logfile, "Received %i bytes", returnLen);
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
if (returnLen == 0)
|
if (returnLen == 0)
|
||||||
{
|
{
|
||||||
@ -419,12 +418,12 @@ void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
|||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
fprintf(fp, (const char *)memPtr);
|
fprintf(fp, "%s", (const char *)memPtr);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_Logger.LogToOpenFile(logfile, "Failed to open file \"%s\"", filename);
|
g_Logger.LogToOpenFile(logfile, "Failed to open file \"%s\" for writing", filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -434,14 +433,13 @@ void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
|||||||
|
|
||||||
memtable->Reset();
|
memtable->Reset();
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
g_Logger.LogToOpenFile(logfile, "Updated File %s", filename);
|
g_Logger.LogToOpenFile(logfile, "Updated file: %s", filename);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "File Downloads Completed!");
|
g_Logger.LogToOpenFile(logfile, "File Downloads Completed!");
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
bool needsRestart = false;
|
bool needsRestart = false;
|
||||||
|
|
||||||
@ -456,8 +454,9 @@ void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
|||||||
|
|
||||||
if (returnLen == 0)
|
if (returnLen == 0)
|
||||||
{
|
{
|
||||||
/* Timeout or fail? */
|
char error[255];
|
||||||
g_Logger.LogToOpenFile(logfile, "Failed to receive unknown count");
|
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
|
||||||
|
g_Logger.LogToOpenFile(logfile, "Did not receive count reply: %s", error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,28 +464,27 @@ void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
|||||||
|
|
||||||
changedFiles = Reader.ReadByte();
|
changedFiles = Reader.ReadByte();
|
||||||
|
|
||||||
if (changedFiles == 0)
|
if (changedFiles < 1)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "No unknown files. We're all done");
|
g_Logger.LogToOpenFile(logfile, "No unknown files. We're all done");
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *changedFileIndexes = new char[changedFiles];
|
char *changedFileIndexes = new char[changedFiles];
|
||||||
|
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "%i Files were unknown", changedFiles);
|
g_Logger.LogToOpenFile(logfile, "%i Files were unknown", changedFiles);
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
|
|
||||||
returnLen = RecvData(socketDescriptor, changedFileIndexes, changedFiles);
|
returnLen = RecvData(socketDescriptor, changedFileIndexes, changedFiles);
|
||||||
|
|
||||||
if (returnLen == 0)
|
if (returnLen == 0)
|
||||||
{
|
{
|
||||||
/* Timeout or fail? */
|
char error[255];
|
||||||
#ifdef DEBUG
|
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
|
||||||
g_Logger.LogToOpenFile(logfile, "Failed to receive unknown list");
|
g_Logger.LogToOpenFile(logfile, "Did not receive list reply: %s", error);
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,15 +507,16 @@ void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_LibSys.GetFileFromPath(fileName, sizeof(fileName), pathname);
|
g_LibSys.GetFileFromPath(fileName, sizeof(fileName), pathname);
|
||||||
#ifdef DEBUG
|
IF_DEBUG_SPEW
|
||||||
g_Logger.LogToOpenFile(logfile, "Unknown File %i : %s", index, fileName);
|
g_Logger.LogToOpenFile(logfile, "Unknown File %i : %s", index, fileName);
|
||||||
#endif
|
ENDIF_DEBUG_SPEW
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] changedFileIndexes;
|
delete [] changedFileIndexes;
|
||||||
|
|
||||||
if (needsRestart && g_restartAfterUpdate)
|
if (needsRestart && g_restartAfterUpdate)
|
||||||
{
|
{
|
||||||
|
/* :TODO: none of this is thread safe. */
|
||||||
g_Logger.LogMessage("Automatically restarting server after a successful gamedata update!");
|
g_Logger.LogMessage("Automatically restarting server after a successful gamedata update!");
|
||||||
engine->ServerCommand("quit\n");
|
engine->ServerCommand("quit\n");
|
||||||
}
|
}
|
||||||
@ -609,14 +608,12 @@ void FetcherThread::HandleUpdateStatus( UpdateStatus status, short version[4] )
|
|||||||
|
|
||||||
case Update_NewBuild:
|
case Update_NewBuild:
|
||||||
{
|
{
|
||||||
g_Logger.LogMessage("SourceMod Update: A new Mercurial build is available from sourcemod.net");
|
|
||||||
g_Logger.LogMessage("Current Version: %i.%i.%i.%i Available: %i.%i.%i.%i", version[0], version[1], version[2], version[3], version[0], version[1], version[2], version[3]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Update_MinorAvailable:
|
case Update_MinorAvailable:
|
||||||
{
|
{
|
||||||
g_Logger.LogMessage("SourceMod Update: An incremental minor release of SourceMod is now available from sourcemod.net");
|
g_Logger.LogMessage("SourceMod Update: A new release of SourceMod is now available from sourcemod.net");
|
||||||
g_Logger.LogMessage("Current Version: %i.%i.%i Available: %i.%i.%i", version[0], version[1], version[2], version[0], version[1], version[2]);
|
g_Logger.LogMessage("Current Version: %i.%i.%i Available: %i.%i.%i", version[0], version[1], version[2], version[0], version[1], version[2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -630,8 +627,8 @@ void FetcherThread::HandleUpdateStatus( UpdateStatus status, short version[4] )
|
|||||||
|
|
||||||
case Update_CriticalAvailable:
|
case Update_CriticalAvailable:
|
||||||
{
|
{
|
||||||
g_Logger.LogError("SourceMod Update: A new critical release of SourceMod is now available from sourcemod.net. It is strongly recommended that you update");
|
g_Logger.LogError("SourceMod Update: A critical SourceMod release is available from sourcemod.net. It is strongly recommended that you update!");
|
||||||
g_Logger.LogMessage("Current Version: %i.%i.%i.%i Available: %i.%i.%i.%i", version[0], version[1], version[2], version[3], version[0], version[1], version[2], version[3]);
|
g_Logger.LogMessage("Current Version: %i.%i.%i Available: %i.%i.%i", version[0], version[1], version[2], version[0], version[1], version[2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -665,14 +662,14 @@ public:
|
|||||||
char *error,
|
char *error,
|
||||||
size_t maxlength)
|
size_t maxlength)
|
||||||
{
|
{
|
||||||
if (strcmp(key, "DisableAutoUpdate") == 0)
|
if (strcasecmp(key, "DisableAutoUpdate") == 0)
|
||||||
{
|
{
|
||||||
if (strcmp(value, "yes") == 0)
|
if (strcasecmp(value, "yes") == 0)
|
||||||
{
|
{
|
||||||
g_disableGameDataUpdate = true;
|
g_disableGameDataUpdate = true;
|
||||||
return ConfigResult_Accept;
|
return ConfigResult_Accept;
|
||||||
}
|
}
|
||||||
else if (strcmp(value, "no") == 0)
|
else if (strcasecmp(value, "no") == 0)
|
||||||
{
|
{
|
||||||
g_disableGameDataUpdate = false;
|
g_disableGameDataUpdate = false;
|
||||||
return ConfigResult_Accept;
|
return ConfigResult_Accept;
|
||||||
@ -681,14 +678,14 @@ public:
|
|||||||
return ConfigResult_Reject;
|
return ConfigResult_Reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(key, "ForceRestartAfterUpdate") == 0)
|
if (strcasecmp(key, "ForceRestartAfterUpdate") == 0)
|
||||||
{
|
{
|
||||||
if (strcmp(value, "yes") == 0)
|
if (strcasecmp(value, "yes") == 0)
|
||||||
{
|
{
|
||||||
g_restartAfterUpdate = true;
|
g_restartAfterUpdate = true;
|
||||||
return ConfigResult_Accept;
|
return ConfigResult_Accept;
|
||||||
}
|
}
|
||||||
else if (strcmp(value, "no") == 0)
|
else if (strcasecmp(value, "no") == 0)
|
||||||
{
|
{
|
||||||
g_restartAfterUpdate = false;
|
g_restartAfterUpdate = false;
|
||||||
return ConfigResult_Accept;
|
return ConfigResult_Accept;
|
||||||
@ -697,14 +694,14 @@ public:
|
|||||||
return ConfigResult_Reject;
|
return ConfigResult_Reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(key, "AutoUpdateServer") == 0)
|
if (strcasecmp(key, "AutoUpdateServer") == 0)
|
||||||
{
|
{
|
||||||
UTIL_Format(g_serverAddress, sizeof(g_serverAddress), "%s", value);
|
UTIL_Format(g_serverAddress, sizeof(g_serverAddress), "%s", value);
|
||||||
|
|
||||||
return ConfigResult_Accept;
|
return ConfigResult_Accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(key, "AutoUpdatePort") == 0)
|
if (strcasecmp(key, "AutoUpdatePort") == 0)
|
||||||
{
|
{
|
||||||
int port = atoi(value);
|
int port = atoi(value);
|
||||||
|
|
||||||
@ -722,6 +719,55 @@ public:
|
|||||||
}
|
}
|
||||||
} g_InitFetch;
|
} g_InitFetch;
|
||||||
|
|
||||||
|
BuildMD5ableBuffer::BuildMD5ableBuffer()
|
||||||
|
{
|
||||||
|
stringTable = new BaseStringTable(2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildMD5ableBuffer::~BuildMD5ableBuffer()
|
||||||
|
{
|
||||||
|
delete stringTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildMD5ableBuffer::ReadSMC_ParseStart()
|
||||||
|
{
|
||||||
|
stringTable->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
SMCResult BuildMD5ableBuffer::ReadSMC_KeyValue(const SMCStates *states,
|
||||||
|
const char *key,
|
||||||
|
const char *value)
|
||||||
|
{
|
||||||
|
stringTable->AddString(key);
|
||||||
|
stringTable->AddString(value);
|
||||||
|
|
||||||
|
return SMCResult_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMCResult BuildMD5ableBuffer::ReadSMC_NewSection(const SMCStates *states, const char *name)
|
||||||
|
{
|
||||||
|
stringTable->AddString(name);
|
||||||
|
|
||||||
|
return SMCResult_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildMD5ableBuffer::ReadSMC_ParseEnd(bool halted, bool failed)
|
||||||
|
{
|
||||||
|
if (halted || failed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *data = stringTable->GetMemTable()->GetAddress(0);
|
||||||
|
|
||||||
|
if (data != NULL)
|
||||||
|
{
|
||||||
|
checksum->update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum->finalize();
|
||||||
|
}
|
||||||
|
|
||||||
CON_COMMAND(sm_gamedata_md5, "Checks the MD5 sum for a given gamedata file")
|
CON_COMMAND(sm_gamedata_md5, "Checks the MD5 sum for a given gamedata file")
|
||||||
{
|
{
|
||||||
#if !defined ORANGEBOX_BUILD
|
#if !defined ORANGEBOX_BUILD
|
||||||
@ -764,3 +810,25 @@ CON_COMMAND(sm_gamedata_md5, "Checks the MD5 sum for a given gamedata file")
|
|||||||
|
|
||||||
g_SMAPI->ConPrint("File not found!\n");
|
g_SMAPI->ConPrint("File not found!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FetcherThread::~FetcherThread()
|
||||||
|
{
|
||||||
|
//delete filenames;
|
||||||
|
SourceHook::CVector<FileData *>::iterator iter = filenames.begin();
|
||||||
|
|
||||||
|
FileData *curData;
|
||||||
|
|
||||||
|
while (iter != filenames.end())
|
||||||
|
{
|
||||||
|
curData = (*iter);
|
||||||
|
delete curData->filename;
|
||||||
|
delete curData;
|
||||||
|
iter = filenames.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FetcherThread::FetcherThread()
|
||||||
|
{
|
||||||
|
memtable = new BaseMemTable(4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "LibrarySys.h"
|
#include "LibrarySys.h"
|
||||||
#include "ThreadSupport.h"
|
#include "ThreadSupport.h"
|
||||||
#include "md5.h"
|
|
||||||
#include "sm_memtable.h"
|
#include "sm_memtable.h"
|
||||||
|
|
||||||
enum UpdateStatus
|
enum UpdateStatus
|
||||||
@ -51,127 +50,44 @@ enum UpdateStatus
|
|||||||
Update_CriticalAvailable = 5, /* A critical update has been released (security fixes etc) */
|
Update_CriticalAvailable = 5, /* A critical update has been released (security fixes etc) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MD5;
|
||||||
|
|
||||||
class BuildMD5ableBuffer : public ITextListener_SMC
|
class BuildMD5ableBuffer : public ITextListener_SMC
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
BuildMD5ableBuffer();
|
||||||
BuildMD5ableBuffer()
|
~BuildMD5ableBuffer();
|
||||||
{
|
void ReadSMC_ParseStart();
|
||||||
stringTable = new BaseStringTable(2048);
|
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
|
||||||
md5[0] = 0;
|
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
|
||||||
md5String[0] = 0;
|
void ReadSMC_ParseEnd(bool halted, bool failed);
|
||||||
}
|
public:
|
||||||
|
MD5 *checksum;
|
||||||
~BuildMD5ableBuffer()
|
|
||||||
{
|
|
||||||
delete stringTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadSMC_ParseStart()
|
|
||||||
{
|
|
||||||
checksum = MD5();
|
|
||||||
}
|
|
||||||
|
|
||||||
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
|
|
||||||
{
|
|
||||||
stringTable->AddString(key);
|
|
||||||
stringTable->AddString(value);
|
|
||||||
|
|
||||||
return SMCResult_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
|
|
||||||
{
|
|
||||||
stringTable->AddString(name);
|
|
||||||
|
|
||||||
return SMCResult_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadSMC_ParseEnd(bool halted, bool failed)
|
|
||||||
{
|
|
||||||
if (halted || failed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *data = stringTable->GetMemTable()->GetAddress(0);
|
|
||||||
|
|
||||||
if (data != NULL)
|
|
||||||
{
|
|
||||||
checksum.update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
checksum.finalize();
|
|
||||||
|
|
||||||
checksum.hex_digest(md5String);
|
|
||||||
checksum.raw_digest(md5);
|
|
||||||
|
|
||||||
stringTable->Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char * GetMD5()
|
|
||||||
{
|
|
||||||
return md5;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char * GetMD5String()
|
|
||||||
{
|
|
||||||
return (unsigned char *)&md5String[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MD5 checksum;
|
|
||||||
unsigned char md5[16];
|
|
||||||
char md5String[33];
|
|
||||||
BaseStringTable *stringTable;
|
BaseStringTable *stringTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileData
|
struct FileData
|
||||||
{
|
{
|
||||||
SourceHook::String *filename;
|
SourceHook::String *filename;
|
||||||
unsigned char checksum[33];
|
char checksum[33];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class FetcherThread : public IThread
|
class FetcherThread : public IThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FetcherThread()
|
FetcherThread();
|
||||||
{
|
~FetcherThread();
|
||||||
//filenames = new BaseStringTable(200);
|
public:
|
||||||
memtable = new BaseMemTable(4096);
|
|
||||||
}
|
|
||||||
|
|
||||||
~FetcherThread()
|
|
||||||
{
|
|
||||||
//delete filenames;
|
|
||||||
SourceHook::CVector<FileData *>::iterator iter = filenames.begin();
|
|
||||||
|
|
||||||
FileData *curData;
|
|
||||||
|
|
||||||
while (iter != filenames.end())
|
|
||||||
{
|
|
||||||
curData = (*iter);
|
|
||||||
delete curData->filename;
|
|
||||||
delete curData;
|
|
||||||
iter = filenames.erase(iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunThread(IThreadHandle *pHandle);
|
void RunThread(IThreadHandle *pHandle);
|
||||||
void OnTerminate(IThreadHandle *pHandle, bool cancel);
|
void OnTerminate(IThreadHandle *pHandle, bool cancel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int BuildGameDataQuery(char *buffer, int maxlen);
|
int BuildGameDataQuery(char *buffer, int maxlen);
|
||||||
void ProcessGameDataQuery(int SocketDescriptor);
|
void ProcessGameDataQuery(int SocketDescriptor);
|
||||||
|
|
||||||
int RecvData(int socketDescriptor, char *buffer, int len);
|
int RecvData(int socketDescriptor, char *buffer, int len);
|
||||||
int SendData(int socketDescriptor, char *buffer, int len);
|
int SendData(int socketDescriptor, char *buffer, int len);
|
||||||
|
|
||||||
int ConnectSocket();
|
int ConnectSocket();
|
||||||
|
|
||||||
void HandleUpdateStatus(UpdateStatus status, short version[4]);
|
void HandleUpdateStatus(UpdateStatus status, short version[4]);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SourceHook::CVector<FileData *> filenames;
|
SourceHook::CVector<FileData *> filenames;
|
||||||
private:
|
private:
|
||||||
@ -182,3 +98,4 @@ extern BuildMD5ableBuffer g_MD5Builder;
|
|||||||
extern bool g_blockGameDataLoad;
|
extern bool g_blockGameDataLoad;
|
||||||
|
|
||||||
#endif // _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
|
#endif // _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
|
||||||
|
|
||||||
|
@ -272,21 +272,35 @@ IDirectory *LibrarySystem::OpenDirectory(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LibrarySystem::GetPlatformError(char *error, size_t maxlength)
|
void LibrarySystem::GetPlatformError(char *error, size_t maxlength)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
return GetPlatformErrorEx(GetLastError(), error, maxlength);
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
return GetPlatformErrorEx(errno, error, maxlength);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibrarySystem::GetPlatformErrorEx(int code, char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
if (error && maxlength)
|
if (error && maxlength)
|
||||||
{
|
{
|
||||||
#if defined PLATFORM_WINDOWS
|
#if defined PLATFORM_WINDOWS
|
||||||
DWORD dw = GetLastError();
|
|
||||||
FormatMessageA(
|
FormatMessageA(
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL,
|
NULL,
|
||||||
dw,
|
(DWORD)code,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
(LPSTR)error,
|
(LPSTR)error,
|
||||||
maxlength,
|
maxlength,
|
||||||
NULL);
|
NULL);
|
||||||
|
#elif defined PLATFORM_LINUX
|
||||||
|
const char *ae = strerror_r(code, error, maxlength);
|
||||||
|
if (ae != error)
|
||||||
|
{
|
||||||
|
UTIL_Format(error, maxlength, "%s", ae);
|
||||||
|
}
|
||||||
#elif defined PLATFORM_POSIX
|
#elif defined PLATFORM_POSIX
|
||||||
UTIL_Format(error, maxlength, "%s", strerror(errno));
|
strerror_r(code, error, maxlength);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ public:
|
|||||||
bool IsPathFile(const char *path);
|
bool IsPathFile(const char *path);
|
||||||
bool IsPathDirectory(const char *path);
|
bool IsPathDirectory(const char *path);
|
||||||
void GetPlatformError(char *error, size_t maxlength);
|
void GetPlatformError(char *error, size_t maxlength);
|
||||||
|
void GetPlatformErrorEx(int code, char *error, size_t maxlength);
|
||||||
size_t PathFormat(char *buffer, size_t len, const char *fmt, ...);
|
size_t PathFormat(char *buffer, size_t len, const char *fmt, ...);
|
||||||
const char *GetFileExtension(const char *filename);
|
const char *GetFileExtension(const char *filename);
|
||||||
bool CreateFolder(const char *path);
|
bool CreateFolder(const char *path);
|
||||||
|
@ -63,6 +63,7 @@ ISourcePawnEngine2 *g_pSourcePawn2 = NULL;
|
|||||||
IdentityToken_t *g_pCoreIdent = NULL;
|
IdentityToken_t *g_pCoreIdent = NULL;
|
||||||
IForward *g_pOnMapEnd = NULL;
|
IForward *g_pOnMapEnd = NULL;
|
||||||
bool g_Loaded = false;
|
bool g_Loaded = false;
|
||||||
|
bool sm_show_debug_spew = false;
|
||||||
|
|
||||||
typedef ISourcePawnEngine *(*GET_SP_V1)();
|
typedef ISourcePawnEngine *(*GET_SP_V1)();
|
||||||
typedef ISourcePawnEngine2 *(*GET_SP_V2)();
|
typedef ISourcePawnEngine2 *(*GET_SP_V2)();
|
||||||
@ -115,6 +116,12 @@ ConfigResult SourceModBase::OnSourceModConfigChanged(const char *key,
|
|||||||
|
|
||||||
return ConfigResult_Accept;
|
return ConfigResult_Accept;
|
||||||
}
|
}
|
||||||
|
else if (strcasecmp(key, "DebugSpew") == 0)
|
||||||
|
{
|
||||||
|
sm_show_debug_spew = (strcasecmp(value, "yes") == 0) ? true : false;
|
||||||
|
|
||||||
|
return ConfigResult_Accept;
|
||||||
|
}
|
||||||
|
|
||||||
return ConfigResult_Ignore;
|
return ConfigResult_Ignore;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,17 @@
|
|||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
|
|
||||||
|
#if defined _DEBUG
|
||||||
|
# define IF_DEBUG_SPEW
|
||||||
|
# define ENDIF_DEBUG_SPEW
|
||||||
|
#else
|
||||||
|
# define IF_DEBUG_SPEW \
|
||||||
|
if (sm_show_debug_spew) \
|
||||||
|
{
|
||||||
|
# define ENDIF_DEBUG_SPEW \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implements SourceMod's global overall management, API, and logic
|
* @brief Implements SourceMod's global overall management, API, and logic
|
||||||
*/
|
*/
|
||||||
@ -132,6 +143,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern bool g_Loaded;
|
extern bool g_Loaded;
|
||||||
|
extern bool sm_show_debug_spew;
|
||||||
extern SourceModBase g_SourceMod;
|
extern SourceModBase g_SourceMod;
|
||||||
extern HandleType_t g_WrBitBufType; //:TODO: find a better place for this
|
extern HandleType_t g_WrBitBufType; //:TODO: find a better place for this
|
||||||
extern HandleType_t g_RdBitBufType; //:TODO: find a better place for this
|
extern HandleType_t g_RdBitBufType; //:TODO: find a better place for this
|
||||||
|
Loading…
Reference in New Issue
Block a user