2023-10-28 16:00:36 +00:00
|
|
|
|
|
|
|
#include "main.h"
|
2024-04-23 14:44:38 +00:00
|
|
|
#include "../raknet/SocketDataEncryptor.h"
|
2023-10-28 16:00:36 +00:00
|
|
|
|
2024-04-22 15:01:00 +00:00
|
|
|
int CanFileBeOpenedForReading(char * filename);
|
|
|
|
|
2024-01-25 14:16:28 +00:00
|
|
|
char szGameModeFile[256];
|
|
|
|
|
2024-05-11 14:43:01 +00:00
|
|
|
//----------------------------------------------------
|
|
|
|
|
|
|
|
// This is from RakNet sources.
|
|
|
|
BYTE GetPacketID(Packet *p)
|
|
|
|
{
|
|
|
|
if (p==0) return 255;
|
|
|
|
|
|
|
|
if ((unsigned char)p->data[0] == ID_TIMESTAMP) {
|
|
|
|
assert(p->length > sizeof(unsigned char) + sizeof(unsigned long));
|
|
|
|
return (unsigned char) p->data[sizeof(unsigned char) + sizeof(unsigned long)];
|
|
|
|
}
|
|
|
|
else return (unsigned char) p->data[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
|
2024-05-11 14:43:29 +00:00
|
|
|
bool HasTimestamps(Packet *p)
|
|
|
|
{
|
|
|
|
if (p==0) return 0;
|
|
|
|
|
|
|
|
if ((unsigned char)p->data[0] == ID_TIMESTAMP)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
|
2023-10-28 16:00:36 +00:00
|
|
|
CNetGame::CNetGame()
|
|
|
|
{
|
2023-11-17 15:54:20 +00:00
|
|
|
m_bAllowWeapons = FALSE;
|
|
|
|
m_byteWorldTime = 12;
|
|
|
|
m_byteWeather = 1;
|
|
|
|
m_bStuntBonus = true;
|
|
|
|
m_fGravity = 0.008f;
|
|
|
|
m_iDeathDropMoney = 0;
|
|
|
|
field_6A = false;
|
|
|
|
m_bVehicleFriendlyFire = FALSE;
|
|
|
|
|
|
|
|
// Init member variables
|
|
|
|
m_pPlayerPool = NULL;
|
|
|
|
m_pVehiclePool = NULL;
|
|
|
|
m_pGameMode = NULL;
|
|
|
|
m_pPickupPool = NULL;
|
|
|
|
m_pObjectPool = NULL;
|
|
|
|
m_pMenuPool = NULL;
|
|
|
|
m_pTextPool = NULL;
|
|
|
|
m_bNameTagLOS = true;
|
|
|
|
m_pGangZonePool = NULL;
|
|
|
|
m_pLabelPool = NULL;
|
|
|
|
m_pActorPool = NULL;
|
|
|
|
m_bLanMode = FALSE;
|
|
|
|
field_6B = 1;
|
|
|
|
|
|
|
|
m_bLimitGlobalChatRadius = FALSE;
|
|
|
|
m_fGlobalChatRadius = 10000.0f;
|
|
|
|
m_bLimitPlayerMarkerRadius = FALSE;
|
|
|
|
m_fPlayerMarkerRadius = 10000.0f;
|
|
|
|
m_fNameTagDrawDistance = 70.0f;
|
|
|
|
m_bDisableEnterExits = false;
|
|
|
|
field_5C = 0;
|
|
|
|
|
|
|
|
m_iCurrentGameModeIndex = 0;
|
|
|
|
m_iCurrentGameModeRepeat = 0;
|
|
|
|
m_bFirstGameModeLoaded = FALSE;
|
|
|
|
|
|
|
|
m_pScriptTimers = new CScriptTimers;
|
|
|
|
m_pScriptHttps = new CScriptHttps;
|
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
m_dElapsedTime = 0.0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if(pConsole->GetIntVariable("maxplayers") > MAX_PLAYERS) {
|
|
|
|
pConsole->SetIntVariable("maxplayers", MAX_PLAYERS);
|
|
|
|
}
|
|
|
|
|
|
|
|
CHAR *szBindAddress = pConsole->GetStringVariable("bind");
|
|
|
|
if (szBindAddress && szBindAddress[0] == 0)
|
|
|
|
szBindAddress = NULL;
|
|
|
|
|
|
|
|
DWORD dwPort = pConsole->GetIntVariable("port");
|
|
|
|
DWORD dwMaxPlayers = pConsole->GetIntVariable("maxplayers");
|
|
|
|
BOOL bLanMode = pConsole->GetBoolVariable("lanmode");
|
|
|
|
|
|
|
|
// Setup RakNet
|
|
|
|
m_pRak = RakNetworkFactory::GetRakServerInterface();
|
|
|
|
|
2024-04-23 14:44:38 +00:00
|
|
|
SocketDataEncryptor::SetKey(dwPort);
|
2023-11-17 15:54:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2023-10-28 16:00:36 +00:00
|
|
|
// TODO: CNetGame::CNetGame W: 0048EEE0 L: 080AF360
|
|
|
|
|
2023-11-17 15:54:20 +00:00
|
|
|
/*
|
2023-10-28 16:00:36 +00:00
|
|
|
sub_496D10(v9);
|
|
|
|
dword_515CFC = sub_44E9D0();
|
|
|
|
_this->field_44 = sub_48DBD0(_this);
|
|
|
|
_this->field_48 = 0;
|
|
|
|
_this->field_4C = 0;
|
|
|
|
sub_46A7B0(v8);
|
|
|
|
if ( (unsigned __int8)(*(int (__stdcall **)(int, _DWORD, int, int, char *))(*(_DWORD *)_this->field_40 + 4))(
|
|
|
|
v19,
|
|
|
|
0,
|
|
|
|
iSleep,
|
|
|
|
v8,
|
|
|
|
v7) )
|
|
|
|
{
|
|
|
|
sub_48EAE0(_this);
|
|
|
|
if ( !sub_48DD50(0) )
|
|
|
|
{
|
|
|
|
logprintf("I couldn't load any gamemode scripts. Please verify your server.cfg");
|
|
|
|
logprintf("It needs a gamemode0 line at the very least.");
|
|
|
|
_fcloseall();
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
(*(void (**)(void))(*(_DWORD *)_this->field_40 + 84))();
|
|
|
|
v10 = CConsole::GetStringVariable(pConsole, "password");
|
|
|
|
if ( v10 && *v10 )
|
|
|
|
(*(void (__stdcall **)(char *))(*(_DWORD *)_this->field_40 + 16))(v10);
|
|
|
|
sprintf(&pInitStr, "%02d:%02d", _this->field_59, 0);
|
|
|
|
CConsole::AddStringVariable(pConsole, "worldtime", 4u, &pInitStr, 0);
|
|
|
|
if ( v20 )
|
|
|
|
_this->field_50 = 1;
|
|
|
|
GetCurrentDirectoryA(0x200u, &Value);
|
|
|
|
v11 = strlen(&Value);
|
|
|
|
if ( *((_BYTE *)&v22 + v11 + 3) != 92 )
|
|
|
|
{
|
|
|
|
*(&Value + v11) = 92;
|
|
|
|
v24[v11] = 0;
|
|
|
|
}
|
|
|
|
v12 = (char *)&v22 + 3;
|
|
|
|
do
|
|
|
|
v13 = (v12++)[1];
|
|
|
|
while ( v13 );
|
|
|
|
*(_DWORD *)v12 = 1769104243;
|
|
|
|
*((_DWORD *)v12 + 1) = 1768322160;
|
|
|
|
*((_DWORD *)v12 + 2) = 1551066476;
|
|
|
|
v12[12] = 0;
|
|
|
|
SetEnvironmentVariableA("AMXFILE", &Value);
|
|
|
|
v14 = operator new(0x1034u);
|
|
|
|
v22 = v14;
|
|
|
|
v26 = 2;
|
|
|
|
if ( v14 )
|
|
|
|
v15 = sub_46A7C0(v14);
|
|
|
|
else
|
|
|
|
v15 = 0;
|
|
|
|
_this->field_4 = v15;
|
|
|
|
if ( v21 )
|
|
|
|
{
|
|
|
|
v16 = (int (__stdcall **)(int, int, int))"ON";
|
|
|
|
if ( !v20 )
|
|
|
|
v16 = &off_4B9C04;
|
|
|
|
printf(
|
|
|
|
"\nStarted server on %s:%d, with maxplayers: %d lanmode is %s.\n\n",
|
|
|
|
v21,
|
|
|
|
(unsigned __int16)v8,
|
|
|
|
(unsigned __int16)v19,
|
|
|
|
v16);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
v17 = (int (__stdcall **)(int, int, int))"ON";
|
|
|
|
if ( !v20 )
|
|
|
|
v17 = &off_4B9C04;
|
|
|
|
printf(
|
|
|
|
"\nStarted server on port: %d, with maxplayers: %d lanmode is %s.\n\n",
|
|
|
|
(unsigned __int16)v8,
|
|
|
|
(unsigned __int16)v19,
|
|
|
|
v17);
|
|
|
|
}
|
|
|
|
_this->field_5E = 0;
|
|
|
|
}
|
|
|
|
else if ( v7 )
|
|
|
|
{
|
|
|
|
logprintf("Unable to start server on %s:%d. Port in use?", v7, (unsigned __int16)v8);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
logprintf("Unable to start server on port: %d. Port in use?", (unsigned __int16)v8);
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
2024-01-06 15:31:55 +00:00
|
|
|
//----------------------------------------------------
|
|
|
|
|
2023-10-28 16:00:36 +00:00
|
|
|
CNetGame::~CNetGame()
|
|
|
|
{
|
2024-01-06 15:31:55 +00:00
|
|
|
logprintf("--- Server Shutting Down.");
|
2023-10-28 16:00:36 +00:00
|
|
|
|
2024-01-06 15:31:55 +00:00
|
|
|
SAFE_DELETE(m_pGameMode);
|
|
|
|
SAFE_DELETE(m_pFilterScripts);
|
|
|
|
SAFE_DELETE(m_pScriptTimers);
|
|
|
|
SAFE_DELETE(m_pScriptHttps);
|
|
|
|
SAFE_DELETE(m_pLabelPool);
|
|
|
|
SAFE_DELETE(m_pVehiclePool);
|
|
|
|
SAFE_DELETE(m_pPlayerPool);
|
|
|
|
SAFE_DELETE(m_pObjectPool);
|
|
|
|
SAFE_DELETE(m_pPickupPool);
|
|
|
|
SAFE_DELETE(m_pMenuPool);
|
|
|
|
SAFE_DELETE(m_pTextPool);
|
|
|
|
SAFE_DELETE(m_pGangZonePool);
|
|
|
|
SAFE_DELETE(m_pActorPool);
|
|
|
|
|
2024-01-25 14:09:18 +00:00
|
|
|
m_pRak->Disconnect(100);
|
2024-01-06 15:31:55 +00:00
|
|
|
UnRegisterRPCs(m_pRak);
|
|
|
|
|
|
|
|
RakNetworkFactory::DestroyRakServerInterface(m_pRak);
|
2023-10-28 16:00:36 +00:00
|
|
|
}
|
|
|
|
|
2024-01-25 14:14:31 +00:00
|
|
|
//----------------------------------------------------
|
|
|
|
// Loads filterscripts after pools initialisation
|
|
|
|
|
|
|
|
void CNetGame::LoadAllFilterscripts()
|
|
|
|
{
|
|
|
|
logprintf("");
|
|
|
|
logprintf("Filterscripts");
|
|
|
|
logprintf("---------------");
|
|
|
|
int iScriptCount = 0;
|
|
|
|
char* szFilterScript = strtok(pConsole->GetStringVariable("filterscripts"), " ");
|
|
|
|
while (szFilterScript)
|
|
|
|
{
|
|
|
|
logprintf(" Loading filterscript '%s.amx'...", szFilterScript);
|
|
|
|
if (m_pFilterScripts->LoadFilterScript(szFilterScript))
|
|
|
|
{
|
|
|
|
iScriptCount++;
|
|
|
|
} else {
|
|
|
|
logprintf(" Unable to load filterscript '%s.amx'.", szFilterScript);
|
|
|
|
}
|
|
|
|
szFilterScript = strtok(NULL, " ");
|
|
|
|
}
|
|
|
|
logprintf(" Loaded %d filterscripts.\n", iScriptCount);
|
|
|
|
}
|
|
|
|
|
2024-04-22 14:57:50 +00:00
|
|
|
//----------------------------------------------------
|
|
|
|
// Handles rotation and setting of the current
|
|
|
|
// script file to be used. If szFile is NULL, it
|
|
|
|
// will attempt to rotate scripts as per configuration.
|
|
|
|
// returns FALSE if it was not able to set the script,
|
|
|
|
// true otherwise.
|
|
|
|
|
|
|
|
// Returns the name of the next gamemode
|
|
|
|
// Code taken from SetNextScriptFile but required by "gmx" (easiest way without major re-write)
|
|
|
|
char *CNetGame::GetNextScriptFile()
|
|
|
|
{
|
|
|
|
char *szTemp;
|
|
|
|
char szCurGameModeConsoleVar[64];
|
|
|
|
|
|
|
|
m_iCurrentGameModeIndex++;
|
|
|
|
|
|
|
|
sprintf(szCurGameModeConsoleVar,"gamemode%u",m_iCurrentGameModeIndex);
|
|
|
|
szTemp = strtok(pConsole->GetStringVariable(szCurGameModeConsoleVar), " ");
|
|
|
|
|
|
|
|
// if the var isn't there then cycle back to 0
|
|
|
|
if(!szTemp || !strlen(szTemp)) {
|
|
|
|
m_iCurrentGameModeIndex = 0;
|
|
|
|
sprintf(szCurGameModeConsoleVar,"gamemode%u",m_iCurrentGameModeIndex);
|
|
|
|
szTemp = strtok(pConsole->GetStringVariable(szCurGameModeConsoleVar), " ");
|
|
|
|
}
|
|
|
|
|
|
|
|
// if it's still NULL then we've got an error.
|
|
|
|
if(!szTemp || !strlen(szTemp)) return NULL;
|
|
|
|
return szTemp;
|
|
|
|
}
|
2024-01-25 14:14:31 +00:00
|
|
|
|
2024-04-22 15:01:00 +00:00
|
|
|
BOOL CNetGame::SetNextScriptFile(char *szFile)
|
|
|
|
{
|
|
|
|
char szConfigFileName[64];
|
|
|
|
char *szTemp;
|
|
|
|
int iConfigRepeatCount=0;
|
|
|
|
|
|
|
|
if(NULL == szFile) {
|
|
|
|
// rotate by config
|
|
|
|
|
|
|
|
if(m_iCurrentGameModeRepeat || !m_bFirstGameModeLoaded) {
|
|
|
|
// repeats of this script, cycle to the current
|
|
|
|
m_iCurrentGameModeIndex--;
|
|
|
|
}
|
|
|
|
|
|
|
|
szTemp = this->GetNextScriptFile();
|
|
|
|
if (szTemp == NULL) return false;
|
|
|
|
|
|
|
|
sscanf(szTemp,"%s%d",szConfigFileName,&iConfigRepeatCount);
|
|
|
|
|
|
|
|
// set it and verify the file is readable
|
|
|
|
sprintf(szGameModeFile,"gamemodes/%s.amx",szConfigFileName);
|
|
|
|
|
|
|
|
if(!CanFileBeOpenedForReading(szGameModeFile)) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!m_iCurrentGameModeRepeat) {
|
|
|
|
m_iCurrentGameModeRepeat = iConfigRepeatCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iCurrentGameModeRepeat--;
|
|
|
|
|
|
|
|
m_bFirstGameModeLoaded = TRUE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// set the script from szFile
|
2024-01-25 14:14:31 +00:00
|
|
|
|
2024-04-22 15:01:00 +00:00
|
|
|
// set it and verify the file is readable
|
|
|
|
sprintf(szGameModeFile,"gamemodes/%s.amx",szFile);
|
2024-01-25 14:14:31 +00:00
|
|
|
|
2024-04-22 15:01:00 +00:00
|
|
|
if(!CanFileBeOpenedForReading(szGameModeFile)) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iCurrentGameModeRepeat = 0;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2024-01-25 14:14:31 +00:00
|
|
|
|
2024-04-22 14:57:50 +00:00
|
|
|
//----------------------------------------------------
|
|
|
|
|
2023-10-28 16:00:36 +00:00
|
|
|
void CNetGame::Init(BOOL bFirst)
|
|
|
|
{
|
2024-01-25 14:16:28 +00:00
|
|
|
m_iSpawnsAvailable = 0;
|
2023-10-28 16:00:36 +00:00
|
|
|
|
2024-01-25 14:16:28 +00:00
|
|
|
// Setup player pool
|
|
|
|
if(!m_pPlayerPool) {
|
|
|
|
m_pPlayerPool = new CPlayerPool();
|
|
|
|
} else {
|
|
|
|
m_pPlayerPool->ResetPlayerScoresAndMoney();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup vehicle pool
|
|
|
|
if(!m_pVehiclePool) {
|
|
|
|
m_pVehiclePool = new CVehiclePool();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup pickup pool
|
|
|
|
if(!m_pPickupPool) {
|
|
|
|
m_pPickupPool = new CPickupPool();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup Object pool
|
|
|
|
if (!m_pObjectPool) {
|
|
|
|
m_pObjectPool = new CObjectPool();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup Menu pool
|
|
|
|
if (!m_pMenuPool) {
|
|
|
|
m_pMenuPool = new CMenuPool();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup Text pool
|
|
|
|
if (!m_pTextPool) {
|
|
|
|
m_pTextPool = new CTextDrawPool();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup Gang Zone pool
|
|
|
|
if (!m_pGangZonePool) {
|
|
|
|
m_pGangZonePool = new CGangZonePool();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup Label pool
|
|
|
|
if (!m_pLabelPool) {
|
|
|
|
m_pLabelPool = new CLabelPool();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup Actor pool
|
|
|
|
if (!m_pActorPool) {
|
|
|
|
m_pActorPool = new CActorPool();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup gamemode
|
|
|
|
if(!m_pGameMode) {
|
|
|
|
m_pGameMode = new CGameMode();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default tags/markers
|
|
|
|
m_bShowNameTags = TRUE;
|
|
|
|
m_iShowPlayerMarkers = 1;
|
|
|
|
m_bNameTagLOS = true;
|
|
|
|
m_bUseCJWalk = FALSE;
|
|
|
|
|
|
|
|
// Set the default world time for clients.
|
|
|
|
m_byteWorldTime = 12; // 12:00
|
|
|
|
|
|
|
|
// Set the default weather
|
|
|
|
m_byteWeather = 1;
|
|
|
|
|
|
|
|
m_bLimitGlobalChatRadius = FALSE;
|
|
|
|
m_bLimitPlayerMarkerRadius = FALSE;
|
|
|
|
m_fGlobalChatRadius = 10000.0f;
|
|
|
|
m_fPlayerMarkerRadius = 10000.0f;
|
|
|
|
m_fNameTagDrawDistance = 70.0f;
|
|
|
|
m_bDisableEnterExits = false;
|
|
|
|
m_bManualVehicleEngineAndLights = false;
|
|
|
|
|
|
|
|
if (bFirst) LoadAllFilterscripts();
|
|
|
|
// Has to be done here as it need to be AFTER the pools but BEFORE the gamemode
|
|
|
|
|
|
|
|
// Start the gamemode script.
|
|
|
|
m_pGameMode->Load(szGameModeFile);
|
|
|
|
|
|
|
|
logprintf("Number of vehicle models: %d", m_pVehiclePool->GetModelCount());
|
|
|
|
|
|
|
|
// Flag we're in a running state.
|
|
|
|
m_iGameState = GAMESTATE_RUNNING;
|
2023-10-28 16:00:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CNetGame::ShutdownForGameModeRestart()
|
|
|
|
{
|
|
|
|
// TODO: CNetGame::ShutdownForGameModeRestart W: 0048F430 L: 080ABBE0
|
|
|
|
|
|
|
|
/*
|
|
|
|
sub_804C8A0(&v8);
|
|
|
|
sub_80ABAD0(this, "(", &v8, -1, 2);
|
|
|
|
sub_80D1690(this->field_8);
|
|
|
|
v1 = (void *)this->field_0;
|
|
|
|
if ( this->field_0 )
|
|
|
|
{
|
|
|
|
sub_80A5060(this->field_0);
|
|
|
|
operator delete(v1);
|
|
|
|
this->field_0 = 0;
|
|
|
|
}
|
|
|
|
v2 = (void *)this->field_C;
|
|
|
|
if ( v2 )
|
|
|
|
{
|
|
|
|
sub_814CCA0(this->field_C);
|
|
|
|
operator delete(v2);
|
|
|
|
this->field_C = 0;
|
|
|
|
}
|
|
|
|
if ( this->field_10 )
|
|
|
|
{
|
|
|
|
operator delete((void *)this->field_10);
|
|
|
|
this->field_10 = 0;
|
|
|
|
}
|
|
|
|
v3 = (void *)this->field_14;
|
|
|
|
if ( v3 )
|
|
|
|
{
|
|
|
|
sub_80C8A20(this->field_14);
|
|
|
|
operator delete(v3);
|
|
|
|
this->field_14 = 0;
|
|
|
|
}
|
|
|
|
v4 = (void *)this->field_18;
|
|
|
|
if ( v4 )
|
|
|
|
{
|
|
|
|
sub_80AADA0(this->field_18);
|
|
|
|
operator delete(v4);
|
|
|
|
this->field_18 = 0;
|
|
|
|
}
|
|
|
|
v5 = (void *)this->field_1C;
|
|
|
|
if ( v5 )
|
|
|
|
{
|
|
|
|
sub_814A2D0(this->field_1C);
|
|
|
|
operator delete(v5);
|
|
|
|
this->field_1C = 0;
|
|
|
|
}
|
|
|
|
if ( this->field_24 )
|
|
|
|
{
|
|
|
|
operator delete((void *)this->field_24);
|
|
|
|
this->field_24 = 0;
|
|
|
|
}
|
|
|
|
v6 = (void *)this->field_20;
|
|
|
|
if ( v6 )
|
|
|
|
{
|
|
|
|
sub_804C1E0(this->field_20);
|
|
|
|
operator delete(v6);
|
|
|
|
this->field_20 = 0;
|
|
|
|
}
|
|
|
|
v7 = (void *)this->field_28;
|
|
|
|
if ( v7 )
|
|
|
|
{
|
|
|
|
sub_8094C00(this->field_28);
|
|
|
|
operator delete(v7);
|
|
|
|
this->field_28 = 0;
|
|
|
|
}
|
|
|
|
this->field_5A = 0;
|
|
|
|
dword_81CA600 = 0;
|
|
|
|
this->field_59 = 12;
|
|
|
|
this->field_5D = 1;
|
|
|
|
LODWORD(this->field_62) = 1006834287;
|
|
|
|
this->field_66 = 0;
|
|
|
|
this->field_6A = 0;
|
|
|
|
this->gap78[0] = 0;
|
|
|
|
this->field_5E = 2;
|
|
|
|
sub_804CCB0(&v8);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
2024-04-24 14:42:10 +00:00
|
|
|
//----------------------------------------------------
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
|
|
|
#pragma comment(lib, "winmm.lib")
|
|
|
|
float GetElapsedTime()
|
|
|
|
{
|
|
|
|
static BOOL bTimerInit = false;
|
|
|
|
static BOOL bUsingOPF = false;
|
|
|
|
static LONGLONG nTicksPerSec = 0;
|
|
|
|
|
|
|
|
if (!bTimerInit)
|
|
|
|
{
|
|
|
|
bTimerInit = true;
|
|
|
|
LARGE_INTEGER qwTicksPerSec;
|
|
|
|
bUsingOPF = QueryPerformanceFrequency(&qwTicksPerSec);
|
|
|
|
if (bUsingOPF) nTicksPerSec = qwTicksPerSec.QuadPart;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bUsingOPF)
|
|
|
|
{
|
|
|
|
LARGE_INTEGER qwTime;
|
|
|
|
QueryPerformanceCounter(&qwTime);
|
|
|
|
static LONGLONG llLastTime = qwTime.QuadPart;
|
|
|
|
double fElapsedTime = (double)(qwTime.QuadPart - llLastTime) / (double) nTicksPerSec;
|
|
|
|
llLastTime = qwTime.QuadPart;
|
|
|
|
return (float)fElapsedTime;
|
|
|
|
} else {
|
|
|
|
double fTime = timeGetTime() * 0.001;
|
|
|
|
static double fLastTime = fTime;
|
|
|
|
double fElapsedTime = (double)(fTime - fLastTime);
|
|
|
|
fLastTime = fTime;
|
|
|
|
return (float)fElapsedTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
float GetElapsedTime()
|
|
|
|
{
|
|
|
|
static timeval lasttv;
|
|
|
|
timeval tv;
|
|
|
|
float fRet;
|
|
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
|
|
|
if (!timerisset(&lasttv)) memcpy(&lasttv, &tv, sizeof(timeval));
|
|
|
|
|
|
|
|
fRet = (float)((tv.tv_sec - lasttv.tv_sec) * 1000000) + (tv.tv_usec - lasttv.tv_usec);
|
|
|
|
fRet /= 1000000.0f;
|
|
|
|
|
|
|
|
memcpy(&lasttv,&tv,sizeof(timeval));
|
|
|
|
|
|
|
|
return fRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // WIN32
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
2024-05-11 14:44:43 +00:00
|
|
|
|
|
|
|
void CNetGame::MasterServerAnnounce(float fElapsedTime)
|
|
|
|
{
|
|
|
|
static float fRemainingTime = 0.0f;
|
|
|
|
fRemainingTime -= fElapsedTime;
|
|
|
|
char szPort[32];
|
|
|
|
|
|
|
|
if(fRemainingTime <= 0.0f)
|
|
|
|
{
|
|
|
|
fRemainingTime = 300.0f; // 300secs = 5mins.
|
|
|
|
sprintf(szPort,"%d",pConsole->GetIntVariable("port"));
|
|
|
|
|
|
|
|
CHAR *szBindAddress = pConsole->GetStringVariable("bind");
|
|
|
|
if (szBindAddress && szBindAddress[0] == 0)
|
|
|
|
szBindAddress = NULL;
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
char szParams[256];
|
|
|
|
sprintf(szParams, "%s", szPort);
|
|
|
|
ShellExecute(0,"open","announce.exe",szParams,NULL,SW_HIDE);
|
|
|
|
#else
|
|
|
|
char szCurrentDir[256];
|
|
|
|
char szAnnounceCmd[256];
|
|
|
|
getcwd(szCurrentDir,256);
|
|
|
|
if(szBindAddress)
|
|
|
|
sprintf(szAnnounceCmd,"%s/announce %s %s &",szCurrentDir,szPort,szBindAddress);
|
|
|
|
else
|
|
|
|
sprintf(szAnnounceCmd,"%s/announce %s &",szCurrentDir,szPort);
|
|
|
|
//printf("Running announce. %s",szAnnounceCmd);
|
|
|
|
system(szAnnounceCmd);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
2024-04-24 14:42:10 +00:00
|
|
|
|
2023-10-28 16:00:36 +00:00
|
|
|
void CNetGame::Process()
|
|
|
|
{
|
2024-04-24 14:42:10 +00:00
|
|
|
float fElapsedTime = GetElapsedTime();
|
|
|
|
|
2024-06-25 14:26:45 +00:00
|
|
|
if(m_iGameState == GAMESTATE_RUNNING)
|
|
|
|
{
|
|
|
|
if(m_pGameMode) m_pGameMode->Frame(fElapsedTime);
|
2024-06-25 14:29:12 +00:00
|
|
|
if(m_pScriptTimers) m_pScriptTimers->Process((DWORD)(fElapsedTime * 1000.0f));
|
2024-06-25 14:26:45 +00:00
|
|
|
}
|
|
|
|
else if(m_iGameState == GAMESTATE_RESTARTING)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2024-04-24 14:42:10 +00:00
|
|
|
|
2023-10-28 16:00:36 +00:00
|
|
|
// TODO: CNetGame::Process W: 00491240 L: 080AEEE0
|
|
|
|
|
|
|
|
/*
|
|
|
|
sub_80ABF00(this);
|
|
|
|
sub_80AECE0((int)this);
|
|
|
|
v1 = this->field_5E;
|
|
|
|
if ( v1 == 1 )
|
|
|
|
{
|
|
|
|
if ( this->field_8 )
|
|
|
|
sub_80D0DF0(this->field_8, v4);
|
|
|
|
if ( this->field_C )
|
|
|
|
sub_814CD00(this->field_C, v4);
|
|
|
|
if ( this->field_14 )
|
|
|
|
sub_80C8760(this->field_14, v4);
|
|
|
|
if ( this->field_0 )
|
|
|
|
sub_80A5080(this->field_0, v4);
|
|
|
|
v2 = this->field_3C;
|
|
|
|
if ( v2 )
|
|
|
|
sub_80EBAF0(v2, (signed __int64)(v4 * 1000.0));
|
|
|
|
if ( this->field_38 )
|
|
|
|
sub_80EA2E0(this->field_38);
|
|
|
|
}
|
|
|
|
else if ( v1 == 2 )
|
|
|
|
{
|
|
|
|
v3 = v4 + *(float *)&dword_81CA600;
|
|
|
|
*(float *)&dword_81CA600 = v3;
|
|
|
|
if ( v3 > 12.0 )
|
|
|
|
sub_80AE530(this);
|
|
|
|
}
|
|
|
|
if ( CConsole::GetBoolVariable(pConsole, "announce") )
|
|
|
|
{
|
|
|
|
sub_80ABDE0((int)this, v4);
|
|
|
|
sub_80D1CA0(pPlugins);
|
|
|
|
this->field_82 = this->field_82 + v4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sub_80D1CA0(pPlugins);
|
|
|
|
this->field_82 = this->field_82 + v4;
|
|
|
|
}
|
|
|
|
*/
|
2024-01-25 14:16:28 +00:00
|
|
|
}
|
2023-12-02 14:26:47 +00:00
|
|
|
|
2024-10-27 14:39:37 +00:00
|
|
|
void CNetGame::BroadcastData(char *szUniqueID,
|
|
|
|
RakNet::BitStream *bitStream,
|
|
|
|
PLAYERID excludedPlayer,
|
|
|
|
char orderingStream)
|
|
|
|
{
|
|
|
|
// TODO: CNetGame::BroadcastData W: .text:0048E190 L: .text:080ABAD0
|
|
|
|
}
|
|
|
|
|
|
|
|
void CNetGame::SendToPlayer(char *szUniqueID,
|
|
|
|
RakNet::BitStream *bitStream,
|
|
|
|
PLAYERID playerId,
|
|
|
|
char orderingChannel)
|
|
|
|
{
|
|
|
|
// TODO: CNetGame::SendToPlayer W: .text:0048E440 L: .text:080AC1D0
|
|
|
|
}
|
|
|
|
|
2023-12-02 14:26:47 +00:00
|
|
|
void CNetGame::LoadBanList()
|
|
|
|
{
|
|
|
|
// TODO: CNetGame::LoadBanList W: 48EAE0 L: 80AF1A0
|
|
|
|
}
|
|
|
|
|
2024-04-24 14:45:44 +00:00
|
|
|
//----------------------------------------------------
|
|
|
|
|
2023-12-02 14:28:37 +00:00
|
|
|
DWORD CNetGame::GetTime()
|
|
|
|
{
|
|
|
|
return (DWORD)RakNet::GetTime();
|
|
|
|
}
|
2024-04-24 14:45:44 +00:00
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
|
|
|
|
const PCHAR CNetGame::GetWeaponName(int iWeaponID)
|
|
|
|
{
|
|
|
|
switch(iWeaponID) {
|
|
|
|
case WEAPON_BRASSKNUCKLE:
|
|
|
|
return "Brass Knuckles";
|
|
|
|
case WEAPON_GOLFCLUB:
|
|
|
|
return "Golf Club";
|
|
|
|
case WEAPON_NITESTICK:
|
|
|
|
return "Nite Stick";
|
|
|
|
case WEAPON_KNIFE:
|
|
|
|
return "Knife";
|
|
|
|
case WEAPON_BAT:
|
|
|
|
return "Baseball Bat";
|
|
|
|
case WEAPON_SHOVEL:
|
|
|
|
return "Shovel";
|
|
|
|
case WEAPON_POOLSTICK:
|
|
|
|
return "Pool Cue";
|
|
|
|
case WEAPON_KATANA:
|
|
|
|
return "Katana";
|
|
|
|
case WEAPON_CHAINSAW:
|
|
|
|
return "Chainsaw";
|
|
|
|
case WEAPON_DILDO:
|
|
|
|
return "Dildo";
|
|
|
|
case WEAPON_DILDO2:
|
|
|
|
return "Dildo";
|
|
|
|
case WEAPON_VIBRATOR:
|
|
|
|
return "Vibrator";
|
|
|
|
case WEAPON_VIBRATOR2:
|
|
|
|
return "Vibrator";
|
|
|
|
case WEAPON_FLOWER:
|
|
|
|
return "Flowers";
|
|
|
|
case WEAPON_CANE:
|
|
|
|
return "Cane";
|
|
|
|
case WEAPON_GRENADE:
|
|
|
|
return "Grenade";
|
|
|
|
case WEAPON_TEARGAS:
|
|
|
|
return "Teargas";
|
|
|
|
case WEAPON_MOLTOV:
|
|
|
|
return "Molotov Cocktail";
|
|
|
|
case WEAPON_COLT45:
|
|
|
|
return "Colt 45";
|
|
|
|
case WEAPON_SILENCED:
|
|
|
|
return "Silenced Pistol";
|
|
|
|
case WEAPON_DEAGLE:
|
|
|
|
return "Desert Eagle";
|
|
|
|
case WEAPON_SHOTGUN:
|
|
|
|
return "Shotgun";
|
|
|
|
case WEAPON_SAWEDOFF:
|
|
|
|
return "Sawn-off Shotgun";
|
|
|
|
case WEAPON_SHOTGSPA: // wtf?
|
|
|
|
return "Combat Shotgun";
|
|
|
|
case WEAPON_UZI:
|
|
|
|
return "UZI";
|
|
|
|
case WEAPON_MP5:
|
|
|
|
return "MP5";
|
|
|
|
case WEAPON_AK47:
|
|
|
|
return "AK47";
|
|
|
|
case WEAPON_M4:
|
|
|
|
return "M4";
|
|
|
|
case WEAPON_TEC9:
|
|
|
|
return "TEC9";
|
|
|
|
case WEAPON_RIFLE:
|
|
|
|
return "Rifle";
|
|
|
|
case WEAPON_SNIPER:
|
|
|
|
return "Sniper Rifle";
|
|
|
|
case WEAPON_ROCKETLAUNCHER:
|
|
|
|
return "Rocket Launcher";
|
|
|
|
case WEAPON_HEATSEEKER:
|
|
|
|
return "Heat Seaker";
|
|
|
|
case WEAPON_FLAMETHROWER:
|
|
|
|
return "Flamethrower";
|
|
|
|
case WEAPON_MINIGUN:
|
|
|
|
return "Minigun";
|
|
|
|
case WEAPON_SATCHEL:
|
|
|
|
return "Satchel Explosives";
|
|
|
|
case WEAPON_BOMB:
|
|
|
|
return "Bomb";
|
|
|
|
case WEAPON_SPRAYCAN:
|
|
|
|
return "Spray Can";
|
|
|
|
case WEAPON_FIREEXTINGUISHER:
|
|
|
|
return "Fire Extinguisher";
|
|
|
|
case WEAPON_CAMERA:
|
|
|
|
return "Camera";
|
|
|
|
case WEAPON_NIGHTVISION:
|
|
|
|
return "Night Vision";
|
|
|
|
case WEAPON_INFRARED:
|
|
|
|
return "Thermal Goggles";
|
|
|
|
case WEAPON_PARACHUTE:
|
|
|
|
return "Parachute";
|
|
|
|
case WEAPON_VEHICLE:
|
|
|
|
return "Vehicle";
|
|
|
|
case WEAPON_DROWN:
|
|
|
|
return "Drowned";
|
|
|
|
case WEAPON_COLLISION:
|
|
|
|
return "Splat";
|
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
// EOF
|