[Theatre]: Cleanup (#624)

This commit is contained in:
Edo 2022-12-05 18:45:14 +00:00 committed by GitHub
parent c6cbd7d5c8
commit 210873499c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 216 additions and 111 deletions

View File

@ -58,6 +58,7 @@ namespace Components
Loader::Register(new MapDump());
Loader::Register(new ModList());
Loader::Register(new Network());
Loader::Register(new NetworkDebug());
Loader::Register(new Session());
Loader::Register(new Theatre());
Loader::Register(new ClanTags());

View File

@ -81,6 +81,7 @@ namespace Components
#include "Modules/UIScript.hpp"
#include "Modules/ModList.hpp"
#include "Modules/Network.hpp"
#include "Modules/NetworkDebug.hpp"
#include "Modules/Theatre.hpp"
#include "Modules/QuickPatch.hpp"
#include "Modules/Security.hpp"

View File

@ -94,7 +94,7 @@ namespace Components
++(*Game::com_errorPrintsCount);
MessagePrint(channel, msg);
if (*Game::cls_uiStarted != 0 && (*Game::com_fixedConsolePosition == 0))
if (Game::cls->uiStarted != 0 && (*Game::com_fixedConsolePosition == 0))
{
Game::CL_ConsoleFixPosition();
}

View File

@ -263,7 +263,7 @@ namespace Components
{
if (client->reliableAcknowledge < 0)
{
Logger::Print(Game::conChannel_t::CON_CHANNEL_NETWORK, "Negative reliableAcknowledge from {} - cl->reliableSequence is {}, reliableAcknowledge is {}\n",
Logger::Print(Game::CON_CHANNEL_NETWORK, "Negative reliableAcknowledge from {} - cl->reliableSequence is {}, reliableAcknowledge is {}\n",
client->name, client->reliableSequence, client->reliableAcknowledge);
client->reliableAcknowledge = client->reliableSequence;
SendCommand(Game::NS_SERVER, client->header.netchan.remoteAddress, "error", "EXE_LOSTRELIABLECOMMANDS");

View File

@ -0,0 +1,47 @@
#include <STDInclude.hpp>
namespace Components
{
void NetworkDebug::CL_ParseServerMessage_Hk(Game::msg_t* msg)
{
auto file = Game::FS_FOpenFileWrite("badpacket.dat");
if (file)
{
Game::FS_Write(msg->data, msg->cursize, file);
Game::FS_FCloseFile(file);
}
Game::MSG_Discard(msg);
}
void NetworkDebug::CL_ParseBadPacket_f()
{
Game::msg_t msg;
unsigned char* file;
auto fileSize = Game::FS_ReadFile("badpacket.dat", reinterpret_cast<char**>(&file));
if (fileSize < 0)
{
return;
}
ZeroMemory(&msg, sizeof(msg));
msg.cursize = fileSize;
msg.data = file;
Game::MSG_ReadLong(&msg);
Game::MSG_ReadLong(&msg);
assert(0 && "Time to debug this packet, baby!");
Game::CL_ParseServerMessage(0, &msg);
Game::FS_FreeFile(file);
}
NetworkDebug::NetworkDebug()
{
#ifdef _DEBUG
Utils::Hook(0x4AA06A, CL_ParseServerMessage_Hk, HOOK_CALL).install()->quick();
Command::Add("parseBadPacket", CL_ParseBadPacket_f);
#endif
// Backport updates from IW5
Utils::Hook::Set<const char*>(0x45D112, "CL_PacketEvent - ignoring illegible message\n");
}
}

View File

@ -0,0 +1,15 @@
#pragma once
namespace Components
{
class NetworkDebug : public Component
{
public:
NetworkDebug();
private:
static void CL_ParseServerMessage_Hk(Game::msg_t* msg);
static void CL_ParseBadPacket_f();
};
}

View File

@ -2,9 +2,9 @@
namespace Components
{
int Security::MsgReadBitsCompressCheckSV(const char* from, char* to, int size)
int Security::MsgReadBitsCompressCheckSV(const unsigned char* from, unsigned char* to, int size)
{
static char buffer[0x8000];
static unsigned char buffer[0x8000];
if (size > 0x800) return 0;
size = Game::MSG_ReadBitsCompress(from, buffer, size);
@ -15,9 +15,9 @@ namespace Components
return size;
}
int Security::MsgReadBitsCompressCheckCL(const char* from, char* to, int size)
int Security::MsgReadBitsCompressCheckCL(const unsigned char* from, unsigned char* to, int size)
{
static char buffer[0x100000];
static unsigned char buffer[0x100000];
if (size > 0x20000) return 0;
size = Game::MSG_ReadBitsCompress(from, buffer, size);

View File

@ -7,10 +7,10 @@ namespace Components
public:
Security();
private:
static int MsgReadBitsCompressCheckSV(const char* from, char* to, int size);
static int MsgReadBitsCompressCheckCL(const char* from, char* to, int size);
static int MsgReadBitsCompressCheckSV(const unsigned char* from, unsigned char* to, int size);
static int MsgReadBitsCompressCheckCL(const unsigned char* from, unsigned char* to, int size);
private:
static int SVCanReplaceServerCommand(Game::client_t* client, const char* cmd);
static long AtolAdjustPlayerLimit(const char* string);

View File

@ -25,11 +25,11 @@ namespace Components
void Theatre::StoreBaseline(PBYTE snapshotMsg)
{
// Store offset and length
Theatre::BaselineSnapshotMsgLen = *reinterpret_cast<int*>(snapshotMsg + 20);
Theatre::BaselineSnapshotMsgOff = *reinterpret_cast<int*>(snapshotMsg + 28) - 7;
BaselineSnapshotMsgLen = *reinterpret_cast<int*>(snapshotMsg + 20);
BaselineSnapshotMsgOff = *reinterpret_cast<int*>(snapshotMsg + 28) - 7;
// Copy to our snapshot buffer
std::memcpy(Theatre::BaselineSnapshot, *reinterpret_cast<DWORD**>(snapshotMsg + 8), *reinterpret_cast<DWORD*>(snapshotMsg + 20));
std::memcpy(BaselineSnapshot, *reinterpret_cast<DWORD**>(snapshotMsg + 8), *reinterpret_cast<DWORD*>(snapshotMsg + 20));
}
__declspec(naked) void Theatre::BaselineStoreStub()
@ -37,7 +37,7 @@ namespace Components
_asm
{
push edi
call Theatre::StoreBaseline
call StoreBaseline
pop edi
mov edx, 5ABEF5h
@ -48,15 +48,15 @@ namespace Components
void Theatre::WriteBaseline()
{
static unsigned char bufData[131072];
static char cmpData[131072];
static unsigned char cmpData[131072];
Game::msg_t buf;
Game::MSG_Init(&buf, bufData, 131072);
Game::MSG_WriteData(&buf, &Theatre::BaselineSnapshot[Theatre::BaselineSnapshotMsgOff], Theatre::BaselineSnapshotMsgLen - Theatre::BaselineSnapshotMsgOff);
Game::MSG_WriteData(&buf, &BaselineSnapshot[BaselineSnapshotMsgOff], BaselineSnapshotMsgLen - BaselineSnapshotMsgOff);
Game::MSG_WriteByte(&buf, 6);
const auto compressedSize = Game::MSG_WriteBitsCompress(false, reinterpret_cast<char*>(buf.data), cmpData, buf.cursize);
const auto compressedSize = Game::MSG_WriteBitsCompress(false, buf.data, cmpData, buf.cursize);
const auto fileCompressedSize = compressedSize + 4;
int byte8 = 8;
@ -86,7 +86,7 @@ namespace Components
__asm
{
pushad
call Theatre::WriteBaseline
call WriteBaseline
popad
// Restore overwritten operation
@ -161,12 +161,12 @@ namespace Components
{
Game::Com_Printf(channel, message, file);
Theatre::CurrentInfo.name = file;
Theatre::CurrentInfo.mapname = (*Game::sv_mapname)->current.string;
Theatre::CurrentInfo.gametype = (*Game::sv_gametype)->current.string;
Theatre::CurrentInfo.author = Steam::SteamFriends()->GetPersonaName();
Theatre::CurrentInfo.length = Game::Sys_Milliseconds();
std::time(&Theatre::CurrentInfo.timeStamp);
CurrentInfo.name = file;
CurrentInfo.mapname = (*Game::sv_mapname)->current.string;
CurrentInfo.gametype = (*Game::sv_gametype)->current.string;
CurrentInfo.author = Steam::SteamFriends()->GetPersonaName();
CurrentInfo.length = Game::Sys_Milliseconds();
std::time(&CurrentInfo.timeStamp);
}
void Theatre::StopRecordStub(int channel, char* message)
@ -174,17 +174,17 @@ namespace Components
Game::Com_Printf(channel, message);
// Store correct length
Theatre::CurrentInfo.length = Game::Sys_Milliseconds() - Theatre::CurrentInfo.length;
CurrentInfo.length = Game::Sys_Milliseconds() - CurrentInfo.length;
// Write metadata
FileSystem::FileWriter meta(Utils::String::VA("%s.json", Theatre::CurrentInfo.name.data()));
meta.write(nlohmann::json(Theatre::CurrentInfo.to_json()).dump());
FileSystem::FileWriter meta(std::format("{}.json", CurrentInfo.name));
meta.write(nlohmann::json(CurrentInfo.to_json()).dump());
}
void Theatre::LoadDemos([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
{
Theatre::CurrentSelection = 0;
Theatre::Demos.clear();
CurrentSelection = 0;
Demos.clear();
const auto demos = FileSystem::GetFileList("demos/", "dm_13");
@ -198,35 +198,34 @@ namespace Components
try
{
metaObject = nlohmann::json::parse(meta.getBuffer());
DemoInfo demoInfo;
demoInfo.name = demo.substr(0, demo.find_last_of("."));
demoInfo.author = metaObject["author"].get<std::string>();
demoInfo.gametype = metaObject["gametype"].get<std::string>();
demoInfo.mapname = metaObject["mapname"].get<std::string>();
demoInfo.length = metaObject["length"].get<int>();
auto timestamp = metaObject["timestamp"].get<std::string>();
demoInfo.timeStamp = _atoi64(timestamp.data());
Demos.push_back(demoInfo);
}
catch (const nlohmann::json::parse_error& ex)
{
Logger::PrintError(Game::CON_CHANNEL_ERROR, "Json Parse Error: {}\n", ex.what());
continue;
}
Theatre::DemoInfo demoInfo;
demoInfo.name = demo.substr(0, demo.find_last_of("."));
demoInfo.author = metaObject["author"].get<std::string>();
demoInfo.gametype = metaObject["gametype"].get<std::string>();
demoInfo.mapname = metaObject["mapname"].get<std::string>();
demoInfo.length = metaObject["length"].get<int>();
auto timestamp = metaObject["timestamp"].get<std::string>();
demoInfo.timeStamp = _atoi64(timestamp.data());
Theatre::Demos.push_back(demoInfo);
}
}
// Reverse, latest demo first!
std::ranges::reverse(Theatre::Demos);
std::ranges::reverse(Demos);
}
void Theatre::DeleteDemo([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
{
if (Theatre::CurrentSelection < Theatre::Demos.size())
if (CurrentSelection < Demos.size())
{
Theatre::DemoInfo demoInfo = Theatre::Demos[Theatre::CurrentSelection];
auto demoInfo = Demos.at(CurrentSelection);
Logger::Print("Deleting demo {}...\n", demoInfo.name);
@ -242,31 +241,30 @@ namespace Components
Dvar::Var("ui_demo_date").set("");
// Reload demos
Theatre::LoadDemos(UIScript::Token(), info);
LoadDemos(UIScript::Token(), info);
}
}
void Theatre::PlayDemo([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
{
if (Theatre::CurrentSelection < Theatre::Demos.size())
if (CurrentSelection < Demos.size())
{
Command::Execute(Utils::String::VA("demo %s", Theatre::Demos[Theatre::CurrentSelection].name.data()), true);
Command::Execute(std::format("demo {}", Demos[CurrentSelection].name), true);
Command::Execute("demoback", false);
}
}
unsigned int Theatre::GetDemoCount()
{
return Theatre::Demos.size();
return Demos.size();
}
// Omit column here
const char* Theatre::GetDemoText(unsigned int item, int /*column*/)
{
if (item < Theatre::Demos.size())
if (item < Demos.size())
{
Theatre::DemoInfo info = Theatre::Demos[item];
auto info = Demos.at(item);
return Utils::String::VA("%s on %s", Game::UI_LocalizeGameType(info.gametype.data()), Game::UI_LocalizeMapName(info.mapname.data()));
}
@ -275,13 +273,13 @@ namespace Components
void Theatre::SelectDemo(unsigned int index)
{
if (index < Theatre::Demos.size())
if (index < Demos.size())
{
Theatre::CurrentSelection = index;
Theatre::DemoInfo info = Theatre::Demos[index];
CurrentSelection = index;
auto info = Demos.at(index);
tm time;
char buffer[1000] = { 0 };
char buffer[1000] = {0};
localtime_s(&time, &info.timeStamp);
asctime_s(buffer, sizeof buffer, &time);
@ -299,7 +297,7 @@ namespace Components
if (Dvar::Var("cl_autoRecord").get<bool>() && !*Game::demoPlaying)
{
std::vector<std::string> files;
std::vector<std::string> demos = FileSystem::GetFileList("demos/", "dm_13");
auto demos = FileSystem::GetFileList("demos/", "dm_13");
for (auto demo : demos)
{
@ -309,9 +307,9 @@ namespace Components
}
}
int numDel = files.size() - Dvar::Var("cl_demosKeep").get<int>();
auto numDel = static_cast<int>(files.size()) - Dvar::Var("cl_demosKeep").get<int>();
for (int i = 0; i < numDel; ++i)
for (auto i = 0; i < numDel; ++i)
{
Logger::Print("Deleting old demo {}\n", files[i]);
FileSystem::_DeleteFile("demos", files[i].data());
@ -326,17 +324,10 @@ namespace Components
void Theatre::MapChangeStub()
{
Theatre::StopRecording();
StopRecording();
Utils::Hook::Call<void()>(0x464A60)();
}
// DANGEROUS, DON'T USE THIS ONE!
void Theatre::MapChangeSVStub(char* a1, char* a2)
{
Theatre::StopRecording();
Utils::Hook::Call<void(char*, char*)>(0x487C50)(a1, a2);
}
void Theatre::StopRecording()
{
if (*Game::demoRecording)
@ -350,30 +341,29 @@ namespace Components
Dvar::Register<bool>("cl_autoRecord", true, Game::DVAR_ARCHIVE, "Automatically record games.");
Dvar::Register<int>("cl_demosKeep", 30, 1, 999, Game::DVAR_ARCHIVE, "How many demos to keep with autorecord.");
Utils::Hook(0x5A8370, Theatre::GamestateWriteStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5A85D2, Theatre::RecordGamestateStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5ABE36, Theatre::BaselineStoreStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x5A8630, Theatre::BaselineToFileStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x4CB3EF, Theatre::UISetActiveMenuStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x50320E, Theatre::AdjustTimeDeltaStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5A8E03, Theatre::ServerTimedOutStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x5A8370, GamestateWriteStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5A85D2, RecordGamestateStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5ABE36, BaselineStoreStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x5A8630, BaselineToFileStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x4CB3EF, UISetActiveMenuStub, HOOK_JUMP).install()->quick();
Utils::Hook(0x50320E, AdjustTimeDeltaStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5A8E03, ServerTimedOutStub, HOOK_JUMP).install()->quick();
// Hook commands to enforce metadata generation
Utils::Hook(0x5A82AE, Theatre::RecordStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5A8156, Theatre::StopRecordStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5A82AE, RecordStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5A8156, StopRecordStub, HOOK_CALL).install()->quick();
// Autorecording
Utils::Hook(0x5A1D6A, Theatre::InitCGameStub, HOOK_CALL).install()->quick();
Utils::Hook(0x4A712A, Theatre::MapChangeStub, HOOK_CALL).install()->quick();
//Utils::Hook(0x5AA91C, Theatre::MapChangeSVStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5A1D6A, InitCGameStub, HOOK_CALL).install()->quick();
Utils::Hook(0x4A712A, MapChangeStub, HOOK_CALL).install()->quick();
// UIScripts
UIScript::Add("loadDemos", Theatre::LoadDemos);
UIScript::Add("launchDemo", Theatre::PlayDemo);
UIScript::Add("deleteDemo", Theatre::DeleteDemo);
UIScript::Add("loadDemos", LoadDemos);
UIScript::Add("launchDemo", PlayDemo);
UIScript::Add("deleteDemo", DeleteDemo);
// Feeder
UIFeeder::Add(10.0f, Theatre::GetDemoCount, Theatre::GetDemoText, Theatre::SelectDemo);
UIFeeder::Add(10.0f, GetDemoCount, GetDemoText, SelectDemo);
// set the configstrings stuff to load the default (empty) string table; this should allow demo recording on all gametypes/maps
if (!Dedicated::IsEnabled()) Utils::Hook::Set<const char*>(0x47440B, "mp/defaultStringTable.csv");
@ -381,11 +371,5 @@ namespace Components
// Change font size
Utils::Hook::Set<BYTE>(0x5AC854, 2);
Utils::Hook::Set<BYTE>(0x5AC85A, 2);
// Command::Add("democycle", [] (Command::Params params)
// {
// // Cmd_FollowCycle_f
// Utils::Hook::Call<void(Game::gentity_t*, int)>(0x458ED0)(Game::g_entities, -1);
// });
}
}

View File

@ -62,7 +62,6 @@ namespace Components
static uint32_t InitCGameStub();
static void MapChangeStub();
static void MapChangeSVStub(char* a1, char* a2);
static void RecordStub(int channel, char* message, char* file);
static void StopRecordStub(int channel, char* message);

View File

@ -8,6 +8,10 @@ namespace Game
CL_DownloadsComplete_t CL_DownloadsComplete = CL_DownloadsComplete_t(0x42CE90);
CL_DrawStretchPicPhysical_t CL_DrawStretchPicPhysical = CL_DrawStretchPicPhysical_t(0x4FC120);
CL_GetConfigString_t CL_GetConfigString = CL_GetConfigString_t(0x44ADB0);
CL_AddReliableCommand_t CL_AddReliableCommand = CL_AddReliableCommand_t(0x454F40);
CL_ParseGamestate_t CL_ParseGamestate = CL_ParseGamestate_t(0x5AC250);
CL_ParseSnapshot_t CL_ParseSnapshot = CL_ParseSnapshot_t(0x5ABD40);
CL_ParseServerMessage_t CL_ParseServerMessage = CL_ParseServerMessage_t(0x4A9E90);
CL_GetMaxRank_t CL_GetMaxRank = CL_GetMaxRank_t(0x44BA30);
CL_GetRankForXP_t CL_GetRankForXP = CL_GetRankForXP_t(0x4FF8A0);
CL_GetRankIcon_t CL_GetRankIcon = CL_GetRankIcon_t(0x4A7B30);
@ -19,6 +23,8 @@ namespace Game
CL_GetLocalClientActiveCount_t CL_GetLocalClientActiveCount = CL_GetLocalClientActiveCount_t(0x5BAD90);
CL_ControllerIndexFromClientNum_t CL_ControllerIndexFromClientNum = CL_ControllerIndexFromClientNum_t(0x449E30);
CL_MouseEvent_t CL_MouseEvent = CL_MouseEvent_t(0x4D7C50);
CL_WriteDemoClientArchive_t CL_WriteDemoClientArchive = CL_WriteDemoClientArchive_t(0x5A8020);
CL_WriteDemoMessage_t CL_WriteDemoMessage = CL_WriteDemoMessage_t(0x4707C0);
float* cl_angles = reinterpret_cast<float*>(0xB2F8D0);
@ -28,13 +34,15 @@ namespace Game
clientUIActive_t* clientUIActives = reinterpret_cast<clientUIActive_t*>(0xB2BB88);
clientActive_t* clients = reinterpret_cast<clientActive_t*>(0xB2C698);
voiceCommunication_t* cl_voiceCommunication = reinterpret_cast<voiceCommunication_t*>(0x1079DA0);
int CL_GetMaxXP()
{
StringTable* rankTable = DB_FindXAssetHeader(ASSET_TYPE_STRINGTABLE, "mp/rankTable.csv").stringTable;
const char* maxrank = StringTable_Lookup(rankTable, 0, "maxrank", 1);
return atoi(StringTable_Lookup(rankTable, 0, maxrank, 7));
return std::atoi(StringTable_Lookup(rankTable, 0, maxrank, 7));
}
clientConnection_t* CL_GetLocalClientConnection(const int localClientNum)
@ -64,4 +72,11 @@ namespace Game
AssertIn(localClientNum, MAX_LOCAL_CLIENTS);
return &clientUIActives[localClientNum];
}
clientActive_t* CL_GetLocalClientGlobals(const int localClientNum)
{
AssertIn(localClientNum, MAX_LOCAL_CLIENTS);
assert(clients[localClientNum].alwaysFalse == false);
return &clients[localClientNum];
}
}

View File

@ -20,6 +20,18 @@ namespace Game
typedef const char* (*CL_GetConfigString_t)(int index);
extern CL_GetConfigString_t CL_GetConfigString;
typedef void(*CL_AddReliableCommand_t)(int localClientNum, const char* cmd);
extern CL_AddReliableCommand_t CL_AddReliableCommand;
typedef void(*CL_ParseGamestate_t)(int localClientNum, msg_t* msg);
extern CL_ParseGamestate_t CL_ParseGamestate;
typedef void(*CL_ParseSnapshot_t)(int localClientNum, msg_t* msg);
extern CL_ParseSnapshot_t CL_ParseSnapshot;
typedef void(*CL_ParseServerMessage_t)(int localClientNum, msg_t* msg);
extern CL_ParseServerMessage_t CL_ParseServerMessage;
typedef int(*CL_GetMaxRank_t)();
extern CL_GetMaxRank_t CL_GetMaxRank;
@ -53,6 +65,12 @@ namespace Game
typedef int(*CL_MouseEvent_t)(int x, int y, int dx, int dy);
extern CL_MouseEvent_t CL_MouseEvent;
typedef void(*CL_WriteDemoClientArchive_t)(void (*write)(const void*, int, int), const playerState_s* ps, const float* viewangles, const float* selectedLocation, float selectedLocationAngle, int localClientNum, int index);
extern CL_WriteDemoClientArchive_t CL_WriteDemoClientArchive;
typedef void(*CL_WriteDemoMessage_t)(void (*write)(const void*, int, int), int serverMessageSequence, unsigned char* data, int len, int localClientNum);
extern CL_WriteDemoMessage_t CL_WriteDemoMessage;
extern float* cl_angles;
extern clientConnection_t* clientConnections;
@ -61,6 +79,8 @@ namespace Game
extern clientUIActive_t* clientUIActives;
extern clientActive_t* clients;
extern voiceCommunication_t* cl_voiceCommunication;
extern int CL_GetMaxXP();
@ -68,4 +88,5 @@ namespace Game
extern connstate_t CL_GetLocalClientConnectionState(int localClientNum);
extern voiceCommunication_t* CL_GetLocalClientVoiceCommunication(int localClientNum);
extern clientUIActive_t* CL_GetLocalClientUIGlobals(int localClientNum);
extern clientActive_t* CL_GetLocalClientGlobals(int localClientNum);
}

View File

@ -45,6 +45,7 @@ namespace Game
const dvar_t** cl_showSend = reinterpret_cast<const dvar_t**>(0xA1E870);
const dvar_t** cl_voice = reinterpret_cast<const dvar_t**>(0xB2BB44);
const dvar_t** cl_ingame = reinterpret_cast<const dvar_t**>(0xB2BB80);
const dvar_t** cl_shownet = reinterpret_cast<const dvar_t**>(0x1059008);
const dvar_t** g_cheats = reinterpret_cast<const dvar_t**>(0x1A45D54);
const dvar_t** g_deadChat = reinterpret_cast<const dvar_t**>(0x19BD5DC);

View File

@ -101,6 +101,7 @@ namespace Game
extern const dvar_t** cl_showSend;
extern const dvar_t** cl_voice;
extern const dvar_t** cl_ingame;
extern const dvar_t** cl_shownet;
extern const dvar_t** g_cheats;
extern const dvar_t** g_deadChat;

View File

@ -99,10 +99,11 @@ namespace Game
MSG_WriteLong_t MSG_WriteLong = MSG_WriteLong_t(0x41CA20);
MSG_WriteShort_t MSG_WriteShort = MSG_WriteShort_t(0x503B90);
MSG_WriteString_t MSG_WriteString = MSG_WriteString_t(0x463820);
MSG_ReadDeltaUsercmdKey_t MSG_ReadDeltaUsercmdKey = MSG_ReadDeltaUsercmdKey_t(0x491F00);
MSG_WriteBitsCompress_t MSG_WriteBitsCompress = MSG_WriteBitsCompress_t(0x4319D0);
MSG_Discard_t MSG_Discard = MSG_Discard_t(0x4F56D0);
MSG_ReadByte_t MSG_ReadByte = MSG_ReadByte_t(0x4C1C20);
MSG_ReadDeltaUsercmdKey_t MSG_ReadDeltaUsercmdKey = MSG_ReadDeltaUsercmdKey_t(0x491F00);
MSG_ReadBitsCompress_t MSG_ReadBitsCompress = MSG_ReadBitsCompress_t(0x4DCC30);
MSG_WriteBitsCompress_t MSG_WriteBitsCompress = MSG_WriteBitsCompress_t(0x4319D0);
NetadrToSockadr_t NetadrToSockadr = NetadrToSockadr_t(0x4B4B40);
@ -262,6 +263,7 @@ namespace Game
LargeLocalBegin_t LargeLocalBegin = LargeLocalBegin_t(0x4127A0);
LargeLocalBeginRight_t LargeLocalBeginRight = LargeLocalBeginRight_t(0x644140);
LargeLocalReset_t LargeLocalReset = LargeLocalReset_t(0x430630);
CmdArgs* cmd_args = reinterpret_cast<CmdArgs*>(0x1AAC5D0);
CmdArgs* sv_cmd_args = reinterpret_cast<CmdArgs*>(0x1ACF8A0);
@ -343,8 +345,6 @@ namespace Game
ScreenPlacement* scrPlaceFull = reinterpret_cast<ScreenPlacement*>(0x10843F0);
ScreenPlacement* scrPlaceFullUnsafe = reinterpret_cast<ScreenPlacement*>(0x1084460);
ScreenPlacement* scrPlaceView = reinterpret_cast<ScreenPlacement*>(0x1084378);
clientActive_t* clients = reinterpret_cast<clientActive_t*>(0xB2C698);
cg_s* cgArray = reinterpret_cast<cg_s*>(0x7F0F78);
cgs_t* cgsArray = reinterpret_cast<cgs_t*>(0x7ED3B8);
@ -381,8 +381,6 @@ namespace Game
unsigned long* _tls_index = reinterpret_cast<unsigned long*>(0x66D94A8);
int* cls_uiStarted = reinterpret_cast<int*>(0xA7FFA0);
unsigned int* playerCardUIStringIndex = reinterpret_cast<unsigned int*>(0x62CD7A8);
char (*playerCardUIStringBuf)[PLAYER_CARD_UI_STRING_COUNT][38] = reinterpret_cast<char(*)[PLAYER_CARD_UI_STRING_COUNT][38]>(0x62CB4F8);

View File

@ -224,18 +224,12 @@ namespace Game
typedef __int64(*MSG_ReadInt64_t)(msg_t* msg);
extern MSG_ReadInt64_t MSG_ReadInt64;
typedef char* (*MSG_ReadString_t)(msg_t* msg);
typedef char*(*MSG_ReadString_t)(msg_t* msg, char* string, unsigned int maxChars);
extern MSG_ReadString_t MSG_ReadString;
typedef char* (*MSG_ReadStringLine_t)(msg_t *msg, char *string, unsigned int maxChars);
typedef char*(*MSG_ReadStringLine_t)(msg_t *msg, char *string, unsigned int maxChars);
extern MSG_ReadStringLine_t MSG_ReadStringLine;
typedef int(*MSG_ReadByte_t)(msg_t* msg);
extern MSG_ReadByte_t MSG_ReadByte;
typedef int(*MSG_ReadBitsCompress_t)(const char *from, char *to, int size);
extern MSG_ReadBitsCompress_t MSG_ReadBitsCompress;
typedef void(*MSG_WriteByte_t)(msg_t* msg, int c);
extern MSG_WriteByte_t MSG_WriteByte;
@ -251,10 +245,19 @@ namespace Game
typedef void(*MSG_WriteString_t)(msg_t* msg, const char *str);
extern MSG_WriteString_t MSG_WriteString;
typedef void(*MSG_Discard_t)(msg_t* msg);
extern MSG_Discard_t MSG_Discard;
typedef int(*MSG_ReadByte_t)(msg_t* msg);
extern MSG_ReadByte_t MSG_ReadByte;
typedef bool(*MSG_ReadDeltaUsercmdKey_t)(msg_t* msg, int key, const usercmd_s* from, usercmd_s* to);
extern MSG_ReadDeltaUsercmdKey_t MSG_ReadDeltaUsercmdKey;
typedef int(*MSG_WriteBitsCompress_t)(bool trainHuffman, const char *from, char *to, int size);
typedef int(*MSG_ReadBitsCompress_t)(const unsigned char* from, unsigned char* to, int size);
extern MSG_ReadBitsCompress_t MSG_ReadBitsCompress;
typedef int(*MSG_WriteBitsCompress_t)(bool trainHuffman, const unsigned char* from, unsigned char* to, int size);
extern MSG_WriteBitsCompress_t MSG_WriteBitsCompress;
typedef void(*NetadrToSockadr_t)(netadr_t *a, sockaddr *s);
@ -578,6 +581,9 @@ namespace Game
typedef int(*LargeLocalBeginRight_t)(int size);
extern LargeLocalBeginRight_t LargeLocalBeginRight;
typedef void(*LargeLocalReset_t)();
extern LargeLocalReset_t LargeLocalReset;
constexpr std::size_t STATIC_MAX_LOCAL_CLIENTS = 1;
constexpr std::size_t MAX_LOCAL_CLIENTS = 1;
constexpr std::size_t MAX_CLIENTS = 18;
@ -662,8 +668,6 @@ namespace Game
extern ScreenPlacement* scrPlaceFull;
extern ScreenPlacement* scrPlaceFullUnsafe;
extern ScreenPlacement* scrPlaceView;
extern clientActive_t* clients;
extern cg_s* cgArray;
extern cgs_t* cgsArray;
@ -704,8 +708,6 @@ namespace Game
extern unsigned long* _tls_index;
extern int* cls_uiStarted;
constexpr std::size_t PLAYER_CARD_UI_STRING_COUNT = 18;
extern unsigned int* playerCardUIStringIndex;
extern char (*playerCardUIStringBuf)[PLAYER_CARD_UI_STRING_COUNT][38];
@ -724,6 +726,8 @@ namespace Game
extern int* ui_numArenas;
extern int* ui_arenaBufPos;
constexpr auto MAX_MSGLEN = 0x20000;
ScreenPlacement* ScrPlace_GetFullPlacement();
ScreenPlacement* ScrPlace_GetUnsafeFullPlacement();

View File

@ -19,6 +19,7 @@ namespace Game
SV_GetPlayerByName_t SV_GetPlayerByName = SV_GetPlayerByName_t(0x6242B0);
SV_GetPlayerByNum_t SV_GetPlayerByNum = SV_GetPlayerByNum_t(0x624390);
SV_FindClientByAddress_t SV_FindClientByAddress = SV_FindClientByAddress_t(0x44F450);
SV_WaitServer_t SV_WaitServer = SV_WaitServer_t(0x4256F0);
int* svs_time = reinterpret_cast<int*>(0x31D9384);
int* sv_timeResidual = reinterpret_cast<int*>(0x2089E14);

View File

@ -44,15 +44,18 @@ namespace Game
typedef void(*SV_DropClient_t)(client_t* drop, const char* reason, bool tellThem);
extern SV_DropClient_t SV_DropClient;
typedef client_t* (*SV_GetPlayerByName_t)();
typedef client_t*(*SV_GetPlayerByName_t)();
extern SV_GetPlayerByName_t SV_GetPlayerByName;
typedef client_t* (*SV_GetPlayerByNum_t)();
typedef client_t*(*SV_GetPlayerByNum_t)();
extern SV_GetPlayerByNum_t SV_GetPlayerByNum;
typedef client_t* (*SV_FindClientByAddress_t)(netadr_t from, int qport, int remoteClientIndex);
typedef client_t*(*SV_FindClientByAddress_t)(netadr_t from, int qport, int remoteClientIndex);
extern SV_FindClientByAddress_t SV_FindClientByAddress;
typedef void(*SV_WaitServer_t)();
extern SV_WaitServer_t SV_WaitServer;
constexpr auto MAX_STATPACKETS = 7;
extern int* svs_time;

View File

@ -1603,6 +1603,8 @@ namespace Game
int serverCommandNum;
};
static_assert(sizeof(clSnapshot_t) == 0x314C);
enum StanceState
{
CL_STANCE_STAND = 0x0,
@ -5962,6 +5964,17 @@ namespace Game
FS_LIST_ALL = 0x1,
};
enum svc_ops_e
{
svc_nop = 0x0,
svc_gamestate = 0x1,
svc_configstring = 0x2,
svc_serverCommand = 0x3,
svc_matchdata = 0x4,
svc_snapshot = 0x5,
svc_EOF = 0x6,
};
enum netsrc_t
{
NS_CLIENT1 = 0x0,

View File

@ -45,6 +45,7 @@
#include <source_location>
#include <sstream>
#include <thread>
#include <type_traits>
#include <unordered_map>
#pragma warning(pop)