Merge branch 'v2features' into 'develop'

V2features
This commit is contained in:
momo5502 2017-05-31 12:09:19 +02:00
commit c0575fdc50
74 changed files with 646 additions and 302 deletions

View File

@ -64,6 +64,7 @@ namespace Components
Loader::Register(new Monitor()); Loader::Register(new Monitor());
Loader::Register(new Network()); Loader::Register(new Network());
Loader::Register(new Theatre()); Loader::Register(new Theatre());
Loader::Register(new Clantags());
Loader::Register(new Download()); Loader::Register(new Download());
Loader::Register(new Playlist()); Loader::Register(new Playlist());
Loader::Register(new RawFiles()); Loader::Register(new RawFiles());
@ -81,6 +82,7 @@ namespace Components
Loader::Register(new Gametypes()); Loader::Register(new Gametypes());
Loader::Register(new Materials()); Loader::Register(new Materials());
Loader::Register(new Threading()); Loader::Register(new Threading());
Loader::Register(new CardTitles());
Loader::Register(new FileSystem()); Loader::Register(new FileSystem());
Loader::Register(new ModelSurfs()); Loader::Register(new ModelSurfs());
Loader::Register(new PlayerName()); Loader::Register(new PlayerName());
@ -94,6 +96,7 @@ namespace Components
Loader::Register(new AssetHandler()); Loader::Register(new AssetHandler());
Loader::Register(new Localization()); Loader::Register(new Localization());
Loader::Register(new MusicalTalent()); Loader::Register(new MusicalTalent());
Loader::Register(new ServerCommands());
Loader::Register(new StructuredData()); Loader::Register(new StructuredData());
Loader::Register(new ConnectProtocol()); Loader::Register(new ConnectProtocol());
Loader::Register(new StartupMessages()); Loader::Register(new StartupMessages());
@ -111,7 +114,7 @@ namespace Components
#ifdef DEBUG #ifdef DEBUG
if(!Loader::PerformingUnitTests()) if(!Loader::PerformingUnitTests())
{ {
Logger::Print("Unregistering component: %s\n", component->getName()); Logger::Print("Unregistering component: %s\n", component->getName().data());
} }
#endif #endif
delete component; delete component;
@ -164,7 +167,7 @@ namespace Components
for (auto component : Loader::Components) for (auto component : Loader::Components)
{ {
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) #if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
Logger::Print("Testing '%s'...\n", component->getName()); Logger::Print("Testing '%s'...\n", component->getName().data());
#endif #endif
auto startTime = std::chrono::high_resolution_clock::now(); auto startTime = std::chrono::high_resolution_clock::now();
bool testRes = component->unitTest(); bool testRes = component->unitTest();
@ -192,7 +195,7 @@ namespace Components
#ifdef DEBUG #ifdef DEBUG
if(!Loader::PerformingUnitTests()) if(!Loader::PerformingUnitTests())
{ {
Logger::Print("Component registered: %s\n", component->getName()); Logger::Print("Component registered: %s\n", component->getName().data());
} }
#endif #endif
Loader::Components.push_back(component); Loader::Components.push_back(component);

View File

@ -9,7 +9,12 @@ namespace Components
virtual ~Component() {}; virtual ~Component() {};
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) #if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
virtual const char* getName() { return "Unknown"; }; virtual std::string getName()
{
std::string name = typeid(*this).name();
Utils::String::Replace(name, "class Components::", "");
return name;
};
#endif #endif
// It's illegal to spawn threads in DLLMain, and apparently it causes problems if they are destroyed there as well. // It's illegal to spawn threads in DLLMain, and apparently it causes problems if they are destroyed there as well.
@ -34,6 +39,20 @@ namespace Components
static bool IsPostgame(); static bool IsPostgame();
static bool IsComInitialized(); static bool IsComInitialized();
template <typename T>
static T* GetInstance()
{
for (auto& component : Loader::Components)
{
if (typeid(*component) == typeid(T))
{
return reinterpret_cast<T*>(component);
}
}
return nullptr;
}
static Utils::Memory::Allocator* GetAlloctor(); static Utils::Memory::Allocator* GetAlloctor();
private: private:
@ -75,6 +94,7 @@ namespace Components
#include "Modules/Logger.hpp" #include "Modules/Logger.hpp"
#include "Modules/Friends.hpp" #include "Modules/Friends.hpp"
#include "Modules/IPCPipe.hpp" #include "Modules/IPCPipe.hpp"
#include "Modules/Clantags.hpp"
#include "Modules/Download.hpp" #include "Modules/Download.hpp"
#include "Modules/Playlist.hpp" #include "Modules/Playlist.hpp"
#include "Modules/RawFiles.hpp" #include "Modules/RawFiles.hpp"
@ -91,6 +111,7 @@ namespace Components
#include "Modules/Materials.hpp" #include "Modules/Materials.hpp"
#include "Modules/Singleton.hpp" #include "Modules/Singleton.hpp"
#include "Modules/Threading.hpp" #include "Modules/Threading.hpp"
#include "Modules/CardTitles.hpp"
#include "Modules/FileSystem.hpp" #include "Modules/FileSystem.hpp"
#include "Modules/ModelSurfs.hpp" #include "Modules/ModelSurfs.hpp"
#include "Modules/PlayerName.hpp" #include "Modules/PlayerName.hpp"
@ -103,6 +124,7 @@ namespace Components
#include "Modules/AssetHandler.hpp" #include "Modules/AssetHandler.hpp"
#include "Modules/Localization.hpp" #include "Modules/Localization.hpp"
#include "Modules/MusicalTalent.hpp" #include "Modules/MusicalTalent.hpp"
#include "Modules/ServerCommands.hpp"
#include "Modules/StructuredData.hpp" #include "Modules/StructuredData.hpp"
#include "Modules/ConnectProtocol.hpp" #include "Modules/ConnectProtocol.hpp"
#include "Modules/StartupMessages.hpp" #include "Modules/StartupMessages.hpp"

View File

@ -16,10 +16,6 @@ namespace Components
AntiCheat(); AntiCheat();
~AntiCheat(); ~AntiCheat();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "AntiCheat"; };
#endif
static void CrashClient(); static void CrashClient();
static void InitLoadLibHook(); static void InitLoadLibHook();

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
ArenaLength(); ArenaLength();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "ArenaLength"; };
#endif
static Game::newMapArena_t NewArenas[128]; static Game::newMapArena_t NewArenas[128];
private: private:

View File

@ -22,10 +22,6 @@ namespace Components
AssetHandler(); AssetHandler();
~AssetHandler(); ~AssetHandler();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "AssetHandler"; };
#endif
static void OnFind(Game::XAssetType type, Utils::Slot<Callback> callback); static void OnFind(Game::XAssetType type, Utils::Slot<Callback> callback);
static void OnLoad(Utils::Slot<RestrictCallback> callback); static void OnLoad(Utils::Slot<RestrictCallback> callback);

View File

@ -8,10 +8,6 @@ namespace Components
Auth(); Auth();
~Auth(); ~Auth();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Auth"; };
#endif
void preDestroy() override; void preDestroy() override;
bool unitTest() override; bool unitTest() override;

View File

@ -10,10 +10,6 @@ namespace Components
Bans(); Bans();
~Bans(); ~Bans();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Bans"; };
#endif
static void BanClientNum(int num, std::string reason); static void BanClientNum(int num, std::string reason);
static bool IsBanned(Entry entry); static bool IsBanned(Entry entry);

View File

@ -8,10 +8,6 @@ namespace Components
Bots(); Bots();
~Bots(); ~Bots();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Bots"; };
#endif
private: private:
static std::vector<std::string> BotNames; static std::vector<std::string> BotNames;

View File

@ -0,0 +1,230 @@
#include "STDInclude.hpp"
namespace Components
{
std::string CardTitles::CustomTitles[18];
Dvar::Var CardTitles::CustomTitleDvar;
CClient* CardTitles::GetClientByIndex(std::uint32_t index)
{
return &reinterpret_cast<CClient*>(0x8E77B0)[index];
}
std::int32_t CardTitles::GetPlayerCardClientInfo(std::int32_t lookupResult, playercarddata_s* data)
{
std::int32_t returnResult = lookupResult;
std::string username = Dvar::Var("name").get<std::string>();
if (data->name == username)
{
returnResult += 0xFE000000;
}
else
{
for (auto clientNum = 0; clientNum < 18; clientNum++)
{
CClient* c = GetClientByIndex(clientNum);
if (c != nullptr)
{
if (!strcmp(data->name, c->Name))
{
// Since a 4 byte integer is overkill for a row num: We can use it to store the customprefix + clientNum and use a 2 byte integer for the row number
returnResult += 0xFF000000;
returnResult += clientNum * 0x10000;
break;
}
}
}
}
return returnResult;
}
void __declspec(naked) CardTitles::GetPlayerCardClientInfoStub()
{
__asm
{
push eax
pushad
push esi
push eax
call GetPlayerCardClientInfo
add esp, 8
mov [esp + 20h], eax
popad
pop eax
pop esi
pop ebp
mov[ebx + 4], eax
pop ebx
push 62EB2Ch
retn
}
}
const char* CardTitles::TableLookupByRowHook(Game::Operand* operand, tablelookuprequest_s* request)
{
std::uint8_t prefix = (request->tableRow >> (8 * 3)) & 0xFF;
std::uint8_t data = (request->tableRow >> (8 * 2)) & 0xFF;
if (request->tablename == "mp/cardTitleTable.csv"s)
{
if (prefix != 0x00)
{
// Column 1 = CardTitle
if (request->tableColumn == 1)
{
if (prefix == 0xFE)
{
if (!CustomTitleDvar.get<std::string>().empty())
{
// 0xFF in front of the title to skip localization. Or else it will wait for a couple of seconds for the asset of type localize
const char* title = Utils::String::VA("\x15%s", CustomTitleDvar.get<const char*>());
// prepare return value
operand->internals.stringVal.string = title;
operand->dataType = Game::VAL_STRING;
return title;
}
}
else if (prefix == 0xFF)
{
if (!CustomTitles[data].empty())
{
const char* title = Utils::String::VA("\x15%s", CustomTitles[data].data());
// prepare return value
operand->internals.stringVal.string = title;
operand->dataType = Game::VAL_STRING;
return title;
}
}
}
// If the title was changed it already returned at this point so...
// Remove prefix and data to make being readable to the normal lookuprequest
request->tableRow = static_cast<std::int32_t>(*(reinterpret_cast<WORD*>(&request->tableRow)));
}
}
return nullptr;
}
__declspec(naked) void CardTitles::TableLookupByRowHookStub()
{
__asm
{
push eax
pushad
push esi
push ebx
call TableLookupByRowHook
add esp, 8
mov [esp + 20h], eax
popad
pop eax
cmp eax, 0
jz OriginalTitle
pop ecx
mov ecx, DWORD ptr[esi + 4]
retn
OriginalTitle:
mov eax, [esi + 50h]
cmp eax, 3
push 62DCC7h
retn
}
}
void CardTitles::SendCustomTitlesToClients()
{
std::string list;
for (int i = 0; i < 18; i++)
{
char playerTitle[18];
if (Game::svs_clients[i].state >= 3)
{
strncpy_s(playerTitle, Game::Info_ValueForKey(Game::svs_clients[i].connectInfoString, "customTitle"), 17);
}
else
{
memset(playerTitle, 0, 18);
}
list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).c_str(), playerTitle));
}
std::string command = Utils::String::VA("%c customTitles \"%s\"", 21, list.data());
Game::SV_GameSendServerCommand(-1, 0, command.data());
}
void CardTitles::ParseCustomTitles(const char* msg)
{
for (int i = 0; i < 18; ++i)
{
const char* playerTitle = Game::Info_ValueForKey(msg, std::to_string(i).c_str());
if (playerTitle) CardTitles::CustomTitles[i] = playerTitle;
else CardTitles::CustomTitles[i].clear();
}
}
CardTitles::CardTitles()
{
Dvar::OnInit([]()
{
CardTitles::CustomTitleDvar = Dvar::Register<const char*>("customtitle", "", Game::dvar_flag::DVAR_FLAG_USERINFO | Game::dvar_flag::DVAR_FLAG_SAVED, "Custom card title");
});
ServerCommands::OnCommand(21, [](Command::Params* params)
{
if (params->get(1) == "customTitles"s && !Dedicated::IsEnabled())
{
if (params->length() == 3)
{
CardTitles::ParseCustomTitles(params->get(2));
return true;
}
}
return false;
});
for(int i = 0; i < ARRAYSIZE(CardTitles::CustomTitles); ++i)
{
CardTitles::CustomTitles[i].clear();
}
Utils::Hook(0x62EB26, CardTitles::GetPlayerCardClientInfoStub).install()->quick();
// Table lookup stuff
Utils::Hook(0x62DCC1, CardTitles::TableLookupByRowHookStub).install()->quick();
Utils::Hook::Nop(0x62DCC6, 1);
}
CardTitles::~CardTitles()
{
for (int i = 0; i < ARRAYSIZE(CardTitles::CustomTitles); ++i)
{
CardTitles::CustomTitles[i].clear();
}
}
}

View File

@ -0,0 +1,74 @@
#pragma once
namespace Components
{
struct tablelookuprequest_s
{
std::uint8_t padding[4];
char* tablename;
std::uint8_t padding2[4];
std::int32_t tableRow;
std::uint8_t padding3[4];
std::int32_t tableColumn;
};
struct playercarddata_s
{
std::uint32_t padding;
std::uint32_t playercardNumber;
std::uint32_t unknown;
std::uint32_t unknown2;
std::uint32_t level; //Level is counted from 0 -> Value 69 is Level 70
std::uint32_t prestige;
std::uint32_t padding2;
char name[40];
};
struct CClient
{
std::uint32_t IsValid; // 0x0000
std::uint32_t IsValid2; // 0x0004
std::uint32_t ClientNumber; // 0x0008
char Name[16]; // 0x000C
std::uint32_t Team; // 0x001C
std::uint32_t Team2; // 0x0020
std::uint32_t Rank; // 0x0024 (rank - 1)
std::uint32_t Prestige; // 0x0028
std::uint32_t Perks; // 0x002C
std::uint32_t Kills; // 0x0030
std::uint32_t Score; // 0x0034
std::uint8_t _0x0038[968];
std::uint32_t ViewAngles; // 0x0400
std::uint8_t _0x040C[136];
std::uint32_t IsShooting; // 0x0494
std::uint8_t _0x0498[4];
std::uint32_t IsZoomed; // 0x049C
std::uint8_t _0x04A0[68];
std::uint32_t weaponID; // 0x04E4
std::uint8_t _0x04E8[24];
std::uint32_t weaponID2; // 0x0500
std::uint8_t _0x0504[40];
std::uint8_t _padding[8];
};
class CardTitles : public Component
{
public:
static Dvar::Var CustomTitleDvar;
static std::string CustomTitles[18];
static void SendCustomTitlesToClients();
static void ParseCustomTitles(const char * msg);
CardTitles();
~CardTitles();
private:
static CClient * GetClientByIndex(std::uint32_t index);
static std::int32_t GetPlayerCardClientInfo(std::int32_t lookupResult, playercarddata_s * data);
static void GetPlayerCardClientInfoStub();
static const char* TableLookupByRowHook(Game::Operand * operand, tablelookuprequest_s * request);
static void TableLookupByRowHookStub();
};
}

View File

@ -8,10 +8,6 @@ namespace Components
Changelog(); Changelog();
~Changelog(); ~Changelog();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Changelog"; };
#endif
static void LoadChangelog(); static void LoadChangelog();
private: private:

View File

@ -0,0 +1,107 @@
#include "STDInclude.hpp"
namespace Components
{
std::string Clantags::Tags[18];
void Clantags::ParseClantags(const char* infoString)
{
for (int i = 0; i < 18; i++)
{
const char* clantag = Game::Info_ValueForKey(infoString, std::to_string(i).data());
if (clantag) Clantags::Tags[i] = clantag;
else Clantags::Tags[i].clear();
}
}
void Clantags::SendClantagsToClients()
{
std::string list;
for (int i = 0; i < 18; ++i)
{
char clantag[5] = { 0 };
if (Game::svs_clients[i].state >= 3)
{
strncpy_s(clantag, Game::Info_ValueForKey(Game::svs_clients[i].connectInfoString, "iw4x_clantag"), 4);
}
list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).data(), clantag));
}
std::string command = Utils::String::VA("%c clantags \"%s\"", 22, list.data());
Game::SV_GameSendServerCommand(-1, 0, command.data());
}
const char* Clantags::GetUserClantag(std::uint32_t clientnum, const char* playername)
{
if (Clantags::Tags[clientnum].empty()) return playername;
return Utils::String::VA("[%s] %s", Clantags::Tags[clientnum].data(), playername);
}
__declspec(naked) void Clantags::DrawPlayerNameOnScoreboard()
{
__asm
{
push eax
pushad
push edi
push [ebp]
call Clantags::GetUserClantag
add esp, 8
mov [esp + 20h], eax
popad
pop edi
push 591247h // Return address
push 5909E0h // Draw string func
retn
}
}
Clantags::Clantags()
{
// Create clantag dvar
Dvar::OnInit([]()
{
Dvar::Register<const char*>("iw4x_clantag", "", Game::dvar_flag::DVAR_FLAG_USERINFO | Game::dvar_flag::DVAR_FLAG_SAVED, "If set, your clantag will be shown on the scoreboard.");
});
// Servercommand hook
ServerCommands::OnCommand(22, [](Command::Params* params)
{
if (params->get(1) == "clantags"s && !Dedicated::IsEnabled())
{
if (params->length() == 3)
{
Clantags::ParseClantags(params->get(2));
return true;
}
}
return false;
});
for (int i = 0; i < ARRAYSIZE(Clantags::Tags); ++i)
{
Clantags::Tags[i].clear();
}
// Draw clantag before playername
Utils::Hook(0x591242, Clantags::DrawPlayerNameOnScoreboard).install()->quick();
}
Clantags::~Clantags()
{
for (int i = 0; i < ARRAYSIZE(Clantags::Tags); ++i)
{
Clantags::Tags[i].clear();
}
}
}

View File

@ -0,0 +1,21 @@
#pragma once
namespace Components
{
class Clantags : public Component
{
public:
static void ParseClantags(const char * infoString);
static void SendClantagsToClients();
Clantags();
~Clantags();
private:
static std::string Clantags::Tags[18];
static const char* GetUserClantag(std::uint32_t clientnum, const char * playername);
static void DrawPlayerNameOnScoreboard();
};
}

View File

@ -8,10 +8,6 @@ namespace Components
Colors(); Colors();
~Colors(); ~Colors();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Colors"; };
#endif
static void Strip(const char* in, char* out, int max); static void Strip(const char* in, char* out, int max);
static std::string Strip(std::string in); static std::string Strip(std::string in);

View File

@ -50,10 +50,6 @@ namespace Components
Command(); Command();
~Command(); ~Command();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Command"; };
#endif
static Game::cmd_function_t* Allocate(); static Game::cmd_function_t* Allocate();
static void Add(const char* name, Utils::Slot<Callback> callback); static void Add(const char* name, Utils::Slot<Callback> callback);

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
ConnectProtocol(); ConnectProtocol();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "ConnectProtocol"; };
#endif
static bool IsEvaluated(); static bool IsEvaluated();
static bool Used(); static bool Used();

View File

@ -11,10 +11,6 @@ namespace Components
Console(); Console();
~Console(); ~Console();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Console"; };
#endif
static void SetSkipShutdown(); static void SetSkipShutdown();
static void FreeNativeConsole(); static void FreeNativeConsole();

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
D3D9Ex(); D3D9Ex();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "D3D9Ex"; };
#endif
private: private:
class D3D9Device : public IDirect3DDevice9 class D3D9Device : public IDirect3DDevice9

View File

@ -185,56 +185,6 @@ namespace Components
Game::Com_Error(code, message); Game::Com_Error(code, message);
} }
__declspec(naked) void Dedicated::OnServerCommandStub()
{
__asm
{
push eax
pushad
call Dedicated::OnServerCommand
mov [esp + 20h], eax
popad
pop eax
test al, al
jnz returnSafe
push 5944AEh
retn
returnSafe:
push 594536h
retn
}
}
int Dedicated::OnServerCommand()
{
Command::ClientParams params;
ZeroMemory(Dedicated::PlayerGuids, sizeof(Dedicated::PlayerGuids));
if (params.length() >= (18 * 2 + 1) && params.get(0)[0] == 20)
{
for (int client = 0; client < 18; client++)
{
Dedicated::PlayerGuids[client][0].bits = strtoull(params.get(2 * client + 1), nullptr, 16);
Dedicated::PlayerGuids[client][1].bits = strtoull(params.get(2 * client + 2), nullptr, 16);
if(Steam::Proxy::SteamFriends && Dedicated::PlayerGuids[client][1].bits != 0)
{
Steam::Proxy::SteamFriends->SetPlayedWith(Dedicated::PlayerGuids[client][1]);
}
}
return 1;
}
return 0;
}
void Dedicated::MapRotate() void Dedicated::MapRotate()
{ {
if (!Dedicated::IsEnabled() && Dvar::Var("sv_dontrotate").get<bool>()) if (!Dedicated::IsEnabled() && Dvar::Var("sv_dontrotate").get<bool>())
@ -452,6 +402,20 @@ namespace Components
// Post initialization point // Post initialization point
Utils::Hook(0x60BFBF, Dedicated::PostInitializationStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x60BFBF, Dedicated::PostInitializationStub, HOOK_JUMP).install()->quick();
// Transmit custom data
Dedicated::OnFrame([]()
{
static std::uint64_t LastUpdate = 0;
if ((GetTickCount64() - LastUpdate) > 10000)
{
CardTitles::SendCustomTitlesToClients();
Clantags::SendClantagsToClients();
LastUpdate = GetTickCount64();
}
});
#ifdef USE_LEGACY_SERVER_LIST #ifdef USE_LEGACY_SERVER_LIST
// Heartbeats // Heartbeats
@ -565,7 +529,21 @@ namespace Components
} }
// Intercept server commands // Intercept server commands
Utils::Hook(0x59449F, Dedicated::OnServerCommandStub, HOOK_JUMP).install()->quick(); ServerCommands::OnCommand(20, [](Command::Params* params)
{
for (int client = 0; client < 18; client++)
{
Dedicated::PlayerGuids[client][0].bits = strtoull(params->get(2 * client + 1), nullptr, 16);
Dedicated::PlayerGuids[client][1].bits = strtoull(params->get(2 * client + 2), nullptr, 16);
if (Steam::Proxy::SteamFriends && Dedicated::PlayerGuids[client][1].bits != 0)
{
Steam::Proxy::SteamFriends->SetPlayedWith(Dedicated::PlayerGuids[client][1]);
}
}
return true;
});
} }
QuickPatch::OnFrame([]() QuickPatch::OnFrame([]()

View File

@ -10,10 +10,6 @@ namespace Components
Dedicated(); Dedicated();
~Dedicated(); ~Dedicated();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Dedicated"; };
#endif
static SteamID PlayerGuids[18][2]; static SteamID PlayerGuids[18][2];
static bool IsEnabled(); static bool IsEnabled();
@ -29,9 +25,6 @@ namespace Components
static bool SendChat; static bool SendChat;
static void OnServerCommandStub();
static int OnServerCommand();
static void MapRotate(); static void MapRotate();
static void FrameHandler(); static void FrameHandler();
static void FrameStub(); static void FrameStub();

View File

@ -8,10 +8,6 @@ namespace Components
Discovery(); Discovery();
~Discovery(); ~Discovery();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Discovery"; };
#endif
void preDestroy() override; void preDestroy() override;
static void Perform(); static void Perform();

View File

@ -9,10 +9,6 @@ namespace Components
Download(); Download();
~Download(); ~Download();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Download"; };
#endif
void preDestroy() override; void preDestroy() override;
static void InitiateClientDownload(std::string mod, bool map = false); static void InitiateClientDownload(std::string mod, bool map = false);

View File

@ -44,10 +44,6 @@ namespace Components
Dvar(); Dvar();
~Dvar(); ~Dvar();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Dvar"; };
#endif
static void OnInit(Utils::Slot<Callback> callback); static void OnInit(Utils::Slot<Callback> callback);
// Only strings and bools use this type of declaration // Only strings and bools use this type of declaration

View File

@ -8,9 +8,6 @@ namespace Components
Exception(); Exception();
~Exception(); ~Exception();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Exception"; };
#endif
static LPTOP_LEVEL_EXCEPTION_FILTER Hook(); static LPTOP_LEVEL_EXCEPTION_FILTER Hook();
static void SetMiniDumpType(bool codeseg, bool dataseg); static void SetMiniDumpType(bool codeseg, bool dataseg);

View File

@ -8,10 +8,6 @@ namespace Components
FastFiles(); FastFiles();
~FastFiles(); ~FastFiles();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "FastFiles"; };
#endif
static void AddZonePath(std::string path); static void AddZonePath(std::string path);
static std::string Current(); static std::string Current();
static bool Ready(); static bool Ready();

View File

@ -88,10 +88,6 @@ namespace Components
FileSystem(); FileSystem();
~FileSystem(); ~FileSystem();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "FileSystem"; };
#endif
static std::vector<std::string> GetFileList(std::string path, std::string extension); static std::vector<std::string> GetFileList(std::string path, std::string extension);
static std::vector<std::string> GetSysFileList(std::string path, std::string extension, bool folders = false); static std::vector<std::string> GetSysFileList(std::string path, std::string extension, bool folders = false);
static void DeleteFile(std::string folder, std::string file); static void DeleteFile(std::string folder, std::string file);

View File

@ -8,10 +8,6 @@ namespace Components
Flags(); Flags();
~Flags(); ~Flags();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Flags"; };
#endif
static bool HasFlag(std::string flag); static bool HasFlag(std::string flag);
private: private:

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
FrameTime(); FrameTime();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "FrameTime"; };
#endif
private: private:
static void SVFrameWaitStub(); static void SVFrameWaitStub();
static void SVFrameWaitFunc(); static void SVFrameWaitFunc();

View File

@ -8,10 +8,6 @@ namespace Components
Friends(); Friends();
~Friends(); ~Friends();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Friends"; };
#endif
static void UpdateFriends(); static void UpdateFriends();
static void UpdateRank(); static void UpdateRank();
static void UpdateServer(Network::Address server, std::string hostname, std::string mapname); static void UpdateServer(Network::Address server, std::string hostname, std::string mapname);

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
Gametypes(); Gametypes();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Gametypes"; };
#endif
private: private:
static unsigned int GetGametypeCount(); static unsigned int GetGametypeCount();
static const char* GetGametypeText(unsigned int index, int column); static const char* GetGametypeText(unsigned int index, int column);

View File

@ -65,10 +65,6 @@ namespace Components
public: public:
IPCPipe(); IPCPipe();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "IPCPipe"; };
#endif
void preDestroy() override; void preDestroy() override;
static bool Write(std::string command, std::string data); static bool Write(std::string command, std::string data);

View File

@ -10,10 +10,6 @@ namespace Components
public: public:
Lean(); Lean();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Lean"; };
#endif
private: private:
static Game::kbutton_t in_leanleft; static Game::kbutton_t in_leanleft;
static Game::kbutton_t in_leanright; static Game::kbutton_t in_leanright;

View File

@ -8,10 +8,6 @@ namespace Components
Localization(); Localization();
~Localization(); ~Localization();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Localization"; };
#endif
static void Set(std::string key, std::string value); static void Set(std::string key, std::string value);
static const char* Get(const char* key); static const char* Get(const char* key);

View File

@ -8,10 +8,6 @@ namespace Components
Logger(); Logger();
~Logger(); ~Logger();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Logger"; };
#endif
static void MessagePrint(int channel, std::string message); static void MessagePrint(int channel, std::string message);
static void Print(int channel, const char* message, ...); static void Print(int channel, const char* message, ...);
static void Print(const char* message, ...); static void Print(const char* message, ...);

View File

@ -49,10 +49,6 @@ namespace Components
Maps(); Maps();
~Maps(); ~Maps();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Maps"; };
#endif
static void HandleAsSPMap(); static void HandleAsSPMap();
static void AddDependency(std::string expression, std::string zone); static void AddDependency(std::string expression, std::string zone);

View File

@ -8,10 +8,6 @@ namespace Components
Materials(); Materials();
~Materials(); ~Materials();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Materials"; };
#endif
static int FormatImagePath(char* buffer, size_t size, int, int, const char* image); static int FormatImagePath(char* buffer, size_t size, int, int, const char* image);
private: private:

View File

@ -11,10 +11,6 @@ namespace Components
Menus(); Menus();
~Menus(); ~Menus();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Menus"; };
#endif
static void FreeEverything(); static void FreeEverything();
static void Add(std::string menu); static void Add(std::string menu);

View File

@ -8,10 +8,6 @@ namespace Components
ModList(); ModList();
~ModList(); ~ModList();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "ModList"; };
#endif
static void RunMod(std::string mod); static void RunMod(std::string mod);
private: private:

View File

@ -8,10 +8,6 @@ namespace Components
ModelSurfs(); ModelSurfs();
~ModelSurfs(); ~ModelSurfs();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "ModelSurfs"; };
#endif
private: private:
static std::unordered_map<void*, IUnknown*> BufferMap; static std::unordered_map<void*, IUnknown*> BufferMap;
static std::unordered_map<std::string, Game::CModelAllocData*> AllocMap; static std::unordered_map<std::string, Game::CModelAllocData*> AllocMap;

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
Monitor(); Monitor();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Monitor"; };
#endif
static bool IsEnabled(); static bool IsEnabled();
private: private:

View File

@ -8,10 +8,6 @@ namespace Components
MusicalTalent(); MusicalTalent();
~MusicalTalent(); ~MusicalTalent();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "MusicalTalent"; };
#endif
static void Replace(std::string sound, const char* file); static void Replace(std::string sound, const char* file);
private: private:

View File

@ -58,10 +58,6 @@ namespace Components
Network(); Network();
~Network(); ~Network();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Network"; };
#endif
static void Handle(std::string packet, Utils::Slot<Callback> callback); static void Handle(std::string packet, Utils::Slot<Callback> callback);
static void OnStart(Utils::Slot<CallbackRaw> callback); static void OnStart(Utils::Slot<CallbackRaw> callback);

View File

@ -8,10 +8,6 @@ namespace Components
News(); News();
~News(); ~News();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "News"; };
#endif
void preDestroy() override; void preDestroy() override;
bool unitTest() override; bool unitTest() override;

View File

@ -21,10 +21,6 @@ namespace Components
Node(); Node();
~Node(); ~Node();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Node"; };
#endif
bool unitTest() override; bool unitTest() override;
static void SyncNodeList(); static void SyncNodeList();

View File

@ -8,10 +8,6 @@ namespace Components
Party(); Party();
~Party(); ~Party();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Party"; };
#endif
static Network::Address Target(); static Network::Address Target();
static void Connect(Network::Address target); static void Connect(Network::Address target);
static const char* GetLobbyInfo(SteamID lobby, std::string key); static const char* GetLobbyInfo(SteamID lobby, std::string key);

View File

@ -8,10 +8,6 @@ namespace Components
PlayerName(); PlayerName();
~PlayerName(); ~PlayerName();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "PlayerName"; };
#endif
private: private:
static std::string PlayerNames[18]; static std::string PlayerNames[18];

View File

@ -10,10 +10,6 @@ namespace Components
Playlist(); Playlist();
~Playlist(); ~Playlist();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Playlist"; };
#endif
static void LoadPlaylist(); static void LoadPlaylist();
static std::string ReceivedPlaylistBuffer; static std::string ReceivedPlaylistBuffer;

View File

@ -10,10 +10,6 @@ namespace Components
QuickPatch(); QuickPatch();
~QuickPatch(); ~QuickPatch();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "QuickPatch"; };
#endif
bool unitTest() override; bool unitTest() override;
static void UnlockStats(); static void UnlockStats();

View File

@ -8,10 +8,6 @@ namespace Components
RCon(); RCon();
~RCon(); ~RCon();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "RCon"; };
#endif
private: private:
class Container class Container
{ {

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
RawFiles(); RawFiles();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "RawFiles"; };
#endif
static void* RawFiles::LoadModdableRawfileFunc(const char* filename); static void* RawFiles::LoadModdableRawfileFunc(const char* filename);
}; };
} }

View File

@ -11,10 +11,6 @@ namespace Components
Renderer(); Renderer();
~Renderer(); ~Renderer();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Renderer"; };
#endif
static int Width(); static int Width();
static int Height(); static int Height();

View File

@ -26,10 +26,6 @@ namespace Components
Script(); Script();
~Script(); ~Script();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Script"; };
#endif
static int LoadScriptAndLabel(std::string script, std::string label); static int LoadScriptAndLabel(std::string script, std::string label);
static void AddFunction(std::string name, Game::scr_function_t function, bool isDev = false); static void AddFunction(std::string name, Game::scr_function_t function, bool isDev = false);

View File

@ -0,0 +1,106 @@
#include "STDInclude.hpp"
namespace Components
{
std::unordered_map<std::int32_t, std::function<bool(Command::Params*)>> ServerCommands::Commands;
std::uint32_t ServerCommands::LastServerCommand;
void ServerCommands::OnCommand(std::int32_t cmd, std::function<bool(Command::Params*)> cb)
{
ServerCommands::Commands[cmd] = cb;
}
bool ServerCommands::OnServerCommand()
{
Command::ClientParams params(*Game::cmd_id);
for (auto &serverCommandCB : ServerCommands::Commands)
{
if (params.length() >= 1)
{
if (params.get(0)[0] == serverCommandCB.first)
{
return serverCommandCB.second(&params);
}
}
}
return false;
}
__declspec(naked) void ServerCommands::OnServerCommandStub()
{
__asm
{
push eax
pushad
call ServerCommands::OnServerCommand
mov [esp + 20h], eax
popad
pop eax
test al, al
jnz jumpback
push 5944AEh
retn
jumpback:
push 594536h
retn
}
}
__declspec(naked) void ServerCommands::OnServerCommandPreFailStub()
{
__asm
{
mov ServerCommands::LastServerCommand, ecx
cmp ecx, 79h
jl above
push 59449Fh
retn
above:
push 593C28h
retn
}
}
void ServerCommands::OnServerCommandFailPrint(int type, const char *, ...)
{
Command::ClientParams params(*Game::cmd_id);
Game::Com_Printf(type, "Unknown client game command: %i %s\n", LastServerCommand, params.join(1));
}
__declspec(naked) void ServerCommands::OnServerCommandFailPrintStub()
{
__asm
{
pushad
call ServerCommands::OnServerCommandFailPrint
popad
push 5944C0h
retn
}
}
ServerCommands::ServerCommands()
{
// Server command receive hook
Utils::Hook(0x59449F, ServerCommands::OnServerCommandStub).install()->quick();
// Server command fail hooks
Utils::Hook(0x593C1F, ServerCommands::OnServerCommandPreFailStub).install()->quick();
Utils::Hook(0x5944BB, ServerCommands::OnServerCommandFailPrintStub).install()->quick();
Utils::Hook::Set<std::uint8_t>(0x5944D3, 0xEB);
}
ServerCommands::~ServerCommands()
{
ServerCommands::Commands.clear();
}
}

View File

@ -0,0 +1,23 @@
#pragma once
namespace Components
{
class ServerCommands : public Component
{
public:
ServerCommands();
~ServerCommands();
static void OnCommand(std::int32_t cmd, std::function<bool(Command::Params*)> cb);
private:
static std::unordered_map<std::int32_t, std::function<bool(Command::Params*)>> Commands;
static std::uint32_t LastServerCommand;
static bool OnServerCommand();
static void OnServerCommandStub();
static void OnServerCommandPreFailStub();
static void OnServerCommandFailPrint(int type, const char * trash, ...);
static void OnServerCommandFailPrintStub();
};
}

View File

@ -8,10 +8,6 @@ namespace Components
ServerInfo(); ServerInfo();
~ServerInfo(); ~ServerInfo();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "ServerInfo"; };
#endif
static Utils::InfoString GetInfo(); static Utils::InfoString GetInfo();
private: private:

View File

@ -32,10 +32,6 @@ namespace Components
ServerList(); ServerList();
~ServerList(); ~ServerList();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "ServerList"; };
#endif
static void Refresh(UIScript::Token); static void Refresh(UIScript::Token);
static void RefreshVisibleList(UIScript::Token); static void RefreshVisibleList(UIScript::Token);
static void UpdateVisibleList(UIScript::Token); static void UpdateVisibleList(UIScript::Token);

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
Singleton(); Singleton();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Singleton"; };
#endif
static bool IsFirstInstance(); static bool IsFirstInstance();
private: private:

View File

@ -10,10 +10,6 @@ namespace Components
public: public:
SlowMotion(); SlowMotion();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "SlowMotion"; };
#endif
private: private:
static int Delay; static int Delay;

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
StartupMessages(); StartupMessages();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "StartupMessages"; };
#endif
static void AddMessage(std::string message); static void AddMessage(std::string message);
private: private:

View File

@ -8,10 +8,6 @@ namespace Components
Stats(); Stats();
~Stats(); ~Stats();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Stats"; };
#endif
static bool IsMaxLevel(); static bool IsMaxLevel();
private: private:

View File

@ -8,10 +8,6 @@ namespace Components
StringTable(); StringTable();
~StringTable(); ~StringTable();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "StringTable"; };
#endif
private: private:
static std::unordered_map<std::string, Game::StringTable*> StringTableMap; static std::unordered_map<std::string, Game::StringTable*> StringTableMap;

View File

@ -26,10 +26,6 @@ namespace Components
StructuredData(); StructuredData();
~StructuredData(); ~StructuredData();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "StructuredData"; };
#endif
private: private:
static bool UpdateVersionOffsets(Game::StructuredDataDefSet *set, Game::StructuredDataBuffer *buffer, Game::StructuredDataDef *oldDef); static bool UpdateVersionOffsets(Game::StructuredDataDefSet *set, Game::StructuredDataBuffer *buffer, Game::StructuredDataDef *oldDef);

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
Theatre(); Theatre();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Theatre"; };
#endif
static void StopRecording(); static void StopRecording();
private: private:

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
Threading(); Threading();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Threading"; };
#endif
private: private:
static void FrameEpilogueStub(); static void FrameEpilogueStub();
static void PacketEventStub(); static void PacketEventStub();

View File

@ -11,10 +11,6 @@ namespace Components
typedef WinToastLib::WinToastTemplate Template; typedef WinToastLib::WinToastTemplate Template;
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Toast"; };
#endif
static void Show(std::string image, std::string title, std::string description, int length); static void Show(std::string image, std::string title, std::string description, int length);
static bool ShowNative(const WinToastLib::WinToastTemplate& toast); static bool ShowNative(const WinToastLib::WinToastTemplate& toast);

View File

@ -19,10 +19,6 @@ namespace Components
UIFeeder(); UIFeeder();
~UIFeeder(); ~UIFeeder();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "UIFeeder"; };
#endif
static void Add(float feeder, GetItemCount_t itemCountCb, GetItemText_t itemTextCb, Select_t selectCb); static void Add(float feeder, GetItemCount_t itemCountCb, GetItemText_t itemTextCb, Select_t selectCb);
private: private:

View File

@ -8,10 +8,6 @@ namespace Components
UIScript(); UIScript();
~UIScript(); ~UIScript();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "UIScript"; };
#endif
class Token class Token
{ {
public: public:

View File

@ -420,6 +420,22 @@ namespace Components
Utils::Hook::Set<DWORD>(0x4F7630, 0x12DC + (sizeof(bg_sharedAmmoCaps) - (1200 * 4))); Utils::Hook::Set<DWORD>(0x4F7630, 0x12DC + (sizeof(bg_sharedAmmoCaps) - (1200 * 4)));
} }
void* Weapon::LoadNoneWeaponHook()
{
// load anim scripts now, rather than a bit later on
Utils::Hook::Call<void()>(0x4E46A0)();
return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_WEAPON, "none").data;
}
void __declspec(naked) Weapon::LoadNoneWeaponHookStub()
{
__asm
{
jmp LoadNoneWeaponHook
}
}
Weapon::Weapon() Weapon::Weapon()
{ {
Weapon::PatchLimit(); Weapon::PatchLimit();
@ -436,6 +452,10 @@ namespace Components
// Skip double loading for fs_game // Skip double loading for fs_game
Utils::Hook::Set<BYTE>(0x4081FD, 0xEB); Utils::Hook::Set<BYTE>(0x4081FD, 0xEB);
// Weapon swap fix
Utils::Hook::Nop(0x4B3670, 5);
Utils::Hook(0x57B4F0, LoadNoneWeaponHookStub).install()->quick();
// Don't load bounce sounds for now, it causes crashes // Don't load bounce sounds for now, it causes crashes
// TODO: Actually check the weaponfiles and/or reset the soundtable correctly! // TODO: Actually check the weaponfiles and/or reset the soundtable correctly!
//Utils::Hook::Nop(0x57A360, 5); //Utils::Hook::Nop(0x57A360, 5);

View File

@ -12,13 +12,11 @@ namespace Components
public: public:
Weapon(); Weapon();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Weapon"; };
#endif
private: private:
static Game::XAssetHeader WeaponFileLoad(Game::XAssetType type, std::string filename); static Game::XAssetHeader WeaponFileLoad(Game::XAssetType type, std::string filename);
static void PatchLimit(); static void PatchLimit();
static void* LoadNoneWeaponHook();
static void LoadNoneWeaponHookStub();
static void PatchConfigStrings(); static void PatchConfigStrings();
static const char* GetWeaponConfigString(int index); static const char* GetWeaponConfigString(int index);

View File

@ -7,10 +7,6 @@ namespace Components
public: public:
Window(); Window();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Window"; };
#endif
static int Width(); static int Width();
static int Height(); static int Height();
static int Width(HWND window); static int Width(HWND window);

View File

@ -95,7 +95,6 @@ namespace Components
~ZoneBuilder(); ~ZoneBuilder();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) #if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "ZoneBuilder"; };
bool unitTest() override; bool unitTest() override;
#endif #endif

View File

@ -12,10 +12,6 @@ namespace Components
Zones(); Zones();
~Zones(); ~Zones();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() override { return "Zones"; };
#endif
static void SetVersion(int version); static void SetVersion(int version);
static int Version() { return Zones::ZoneVersion; }; static int Version() { return Zones::ZoneVersion; };

View File

@ -121,6 +121,8 @@ namespace Game
Image_LoadFromFileWithReader_t Image_LoadFromFileWithReader = Image_LoadFromFileWithReader_t(0x53ABF0); Image_LoadFromFileWithReader_t Image_LoadFromFileWithReader = Image_LoadFromFileWithReader_t(0x53ABF0);
Image_Release_t Image_Release = Image_Release_t(0x51F010); Image_Release_t Image_Release = Image_Release_t(0x51F010);
Info_ValueForKey_t Info_ValueForKey = Info_ValueForKey_t(0x47C820);
Key_SetCatcher_t Key_SetCatcher = Key_SetCatcher_t(0x43BD00); Key_SetCatcher_t Key_SetCatcher = Key_SetCatcher_t(0x43BD00);
LargeLocalInit_t LargeLocalInit = LargeLocalInit_t(0x4A62A0); LargeLocalInit_t LargeLocalInit = LargeLocalInit_t(0x4A62A0);

View File

@ -304,6 +304,9 @@ namespace Game
typedef void(__cdecl * Image_Release_t)(GfxImage* image); typedef void(__cdecl * Image_Release_t)(GfxImage* image);
extern Image_Release_t Image_Release; extern Image_Release_t Image_Release;
typedef char*(__cdecl * Info_ValueForKey_t)(const char* infoString, const char* key);
extern Info_ValueForKey_t Info_ValueForKey;
typedef void(__cdecl * Key_SetCatcher_t)(int localClientNum, int catcher); typedef void(__cdecl * Key_SetCatcher_t)(int localClientNum, int catcher);
extern Key_SetCatcher_t Key_SetCatcher; extern Key_SetCatcher_t Key_SetCatcher;