From 6fb6a1e977a29a54f10d130f9f1539c15e1fbebf Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Fri, 25 Dec 2015 21:42:35 +0100 Subject: [PATCH] Party and connect. --- iw4/Components/Command.cpp | 14 +++ iw4/Components/Command.hpp | 3 +- iw4/Components/Dvar.cpp | 4 +- iw4/Components/Dvar.hpp | 1 + iw4/Components/Loader.cpp | 1 + iw4/Components/Loader.hpp | 1 + iw4/Components/Menus.cpp | 69 ++++++--------- iw4/Components/Menus.hpp | 6 +- iw4/Components/Network.cpp | 45 +--------- iw4/Components/Network.hpp | 2 +- iw4/Components/Party.cpp | 133 +++++++++++++++++++++++++++++ iw4/Components/Party.hpp | 23 +++++ iw4/Components/QuickPatch.cpp | 16 ++++ iw4/Components/QuickPatch.hpp | 3 + iw4/Game/Functions.cpp | 21 +++++ iw4/Game/Functions.hpp | 55 ++++++++++++ iw4/STDInclude.hpp | 5 ++ iw4/Steam/Interfaces/SteamUser.cpp | 15 ++-- iw4/Utils/Utils.cpp | 27 +++--- iw4/Utils/Utils.hpp | 4 +- iw4/iw4.vcxproj | 2 + iw4/iw4.vcxproj.filters | 6 ++ 22 files changed, 345 insertions(+), 111 deletions(-) create mode 100644 iw4/Components/Party.cpp create mode 100644 iw4/Components/Party.hpp diff --git a/iw4/Components/Command.cpp b/iw4/Components/Command.cpp index 18e05658..74b12b43 100644 --- a/iw4/Components/Command.cpp +++ b/iw4/Components/Command.cpp @@ -36,6 +36,20 @@ namespace Components Game::Cmd_AddCommand(name, Command::MainCallback, Command::Allocate(), 0); } + void Command::Execute(std::string command, bool sync) + { + command.append("\n"); // Make sure it's terminated + + if (sync) + { + Game::Cmd_ExecuteSingleCommand(0, 0, command.data()); + } + else + { + Game::Cbuf_AddText(0, command.data()); + } + } + Game::cmd_function_t* Command::Allocate() { Game::cmd_function_t* cmd = new Game::cmd_function_t; diff --git a/iw4/Components/Command.hpp b/iw4/Components/Command.hpp index f1d7c625..1b293e7a 100644 --- a/iw4/Components/Command.hpp +++ b/iw4/Components/Command.hpp @@ -23,7 +23,8 @@ namespace Components const char* GetName() { return "Command"; }; static void Add(const char* name, Callback callback); - static int ArgCount(); + + static void Execute(std::string command, bool sync = true); private: static Game::cmd_function_t* Allocate(); diff --git a/iw4/Components/Dvar.cpp b/iw4/Components/Dvar.cpp index f9bc396d..7070d98a 100644 --- a/iw4/Components/Dvar.cpp +++ b/iw4/Components/Dvar.cpp @@ -8,7 +8,9 @@ namespace Components if (!this->dvar) { - // Register the dvar? + // Quick-register the dvar + Game::SetConsole(dvarName.data(), ""); + this->dvar = Game::Dvar_FindVar(dvarName.data()); } } diff --git a/iw4/Components/Dvar.hpp b/iw4/Components/Dvar.hpp index 65725015..c2c23b85 100644 --- a/iw4/Components/Dvar.hpp +++ b/iw4/Components/Dvar.hpp @@ -10,6 +10,7 @@ namespace Components Var(const Var &obj) { this->dvar = obj.dvar; }; Var(Game::dvar_t* _dvar) : dvar(_dvar) {}; Var(std::string dvarName); + Var(std::string dvarName, std::string value); template<typename T> T Get(); diff --git a/iw4/Components/Loader.cpp b/iw4/Components/Loader.cpp index a8e5a1c1..6e7a83af 100644 --- a/iw4/Components/Loader.cpp +++ b/iw4/Components/Loader.cpp @@ -8,6 +8,7 @@ namespace Components { Loader::Register(new Dvar()); Loader::Register(new Menus()); + Loader::Register(new Party()); Loader::Register(new Colors()); Loader::Register(new Logger()); Loader::Register(new Window()); diff --git a/iw4/Components/Loader.hpp b/iw4/Components/Loader.hpp index 8fda62a8..57220501 100644 --- a/iw4/Components/Loader.hpp +++ b/iw4/Components/Loader.hpp @@ -28,6 +28,7 @@ namespace Components #include "Command.hpp" #include "Console.hpp" #include "Network.hpp" +#include "Party.hpp" // Destroys the order, but requires network classes :D #include "RawFiles.hpp" #include "Renderer.hpp" #include "FastFiles.hpp" diff --git a/iw4/Components/Menus.cpp b/iw4/Components/Menus.cpp index 868e3ff4..274c85cb 100644 --- a/iw4/Components/Menus.cpp +++ b/iw4/Components/Menus.cpp @@ -116,7 +116,7 @@ namespace Components Game::pc_token_t token; Game::keywordHash_t *key; - if (!Menus::ReadToken(handle, &token) || token.string[0] != '{') + if (!Game::PC_ReadTokenHandle(handle, &token) || token.string[0] != '{') { return menu; } @@ -125,7 +125,7 @@ namespace Components { ZeroMemory(&token, sizeof(token)); - if (!Menus::ReadToken(handle, &token)) + if (!Game::PC_ReadTokenHandle(handle, &token)) { Game::PC_SourceError(handle, "end of file inside menu\n"); break; // Fail @@ -153,40 +153,11 @@ namespace Components } } + OutputDebugStringA(Utils::VA("%X %s", menu->window.name, menu->window.name)); + return menu; } - int Menus::ReadToken(int handle, Game::pc_token_t *pc_token) - { - Game::token_t token; - int ret; - - if (!Menus::IsValidSourceHandle(handle)) return 0; - - ret = Game::PC_ReadToken(Game::sourceFiles[handle], &token); - strcpy(pc_token->string, token.string); - pc_token->type = token.type; - pc_token->subtype = token.subtype; - pc_token->intvalue = token.intvalue; - pc_token->floatvalue = (float)token.floatvalue; - - if (pc_token->type == TT_STRING) - { - // StripDoubleQuotes - char *string = pc_token->string; - if (*string == '\"') - { - strcpy(string, string + 1); - } - if (string[strlen(string) - 1] == '\"') - { - string[strlen(string) - 1] = '\0'; - } - } - - return ret; - } - std::vector<Game::menuDef_t*> Menus::LoadMenu(Game::menuDef_t* menudef) { std::vector<Game::menuDef_t*> menus; @@ -206,14 +177,14 @@ namespace Components { ZeroMemory(&token, sizeof(token)); - if (!Menus::ReadToken(handle, &token) || token.string[0] == '}') + if (!Game::PC_ReadTokenHandle(handle, &token) || token.string[0] == '}') { break; } if (!_stricmp(token.string, "loadmenu")) { - Menus::ReadToken(handle, &token); + Game::PC_ReadTokenHandle(handle, &token); // Ugly, but does the job ;) Game::menuDef_t _temp; @@ -250,6 +221,11 @@ namespace Components for (int i = 0; i < menuList->menuCount; i++) { + if (!menuList->menus[i]) + { + continue; + } + std::vector<Game::menuDef_t*> newMenus = Menus::LoadMenu(menuList->menus[i]); for (auto newMenu : newMenus) @@ -409,19 +385,16 @@ namespace Components Game::XAssetHeader Menus::MenuFileLoad(Game::XAssetType type, const char* filename) { - Game::XAssetHeader header = { 0 }; + Game::XAssetHeader header = { 0 }; // Check if we already loaded it for (auto menuList : Menus::MenuListList) { if (!_stricmp(menuList->name, filename)) { - // Free it! - // Seems like the game deallocated half of it :P + // Free it, seems like the game deallocated it Menus::RemoveMenuList(menuList); break; - //header.menuList = menuList; - //return header; } } @@ -431,7 +404,7 @@ namespace Components if (menuList) { // Don't parse scriptmenus for now! - if (!Utils::EndsWith(filename, ".menu")) + if (strcmp(menuList->menus[0]->window.name, "default_menu") && !Utils::EndsWith(filename, ".menu")) { header.menuList = Menus::LoadMenuList(menuList); } @@ -440,17 +413,31 @@ namespace Components return header; } + void Menus::AddMenuListHook(int dc, Game::MenuList *menuList, int close) + { + Game::MenuList* menus = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MENUFILE, "ui_mp/menus.txt").menuList; + + Game::UI_AddMenuList(dc, menus, close); + Game::UI_AddMenuList(dc, menuList, close); + } + Menus::Menus() { AssetHandler::On(Game::XAssetType::ASSET_TYPE_MENUFILE, Menus::MenuFileLoad); //Utils::Hook(0x63FE80, Menus::MenuFileLoad, HOOK_JUMP).Install()->Quick(); + // Load menus ingame + //Utils::Hook(0x41C178, Menus::AddMenuListHook, HOOK_CALL).Install()->Quick(); + // disable the 2 new tokens in ItemParse_rect Utils::Hook::Set<BYTE>(0x640693, 0xEB); // don't load ASSET_TYPE_MENU assets for every menu (might cause patch menus to fail) Utils::Hook::Nop(0x453406, 5); + //make Com_Error and similar go back to main_text instead of menu_xboxlive. + strcpy((char*)0x6FC790, "main_text"); + Command::Add("openmenu", [] (Command::Params params) { if (params.Length() != 2) diff --git a/iw4/Components/Menus.hpp b/iw4/Components/Menus.hpp index 4df89f9c..a30457c1 100644 --- a/iw4/Components/Menus.hpp +++ b/iw4/Components/Menus.hpp @@ -9,6 +9,8 @@ namespace Components ~Menus(); const char* GetName() { return "Menus"; }; + static void FreeEverything(); + private: static std::vector<Game::menuDef_t*> MenuList; static std::vector<Game::MenuList*> MenuListList; @@ -23,8 +25,6 @@ namespace Components static int ReserveSourceHandle(); static bool IsValidSourceHandle(int handle); - static int ReadToken(int handle, Game::pc_token_t *pc_token); - static Game::menuDef_t* ParseMenu(int handle); static void FreeMenuSource(int handle); @@ -35,7 +35,7 @@ namespace Components static void RemoveMenu(Game::menuDef_t* menudef); static void RemoveMenuList(Game::MenuList* menuList); - static void FreeEverything(); + static void AddMenuListHook(int dc, Game::MenuList *menuList, int close); // Ugly! static int KeywordHash(char* key); diff --git a/iw4/Components/Network.cpp b/iw4/Components/Network.cpp index a76d81a4..d8cd9a4b 100644 --- a/iw4/Components/Network.cpp +++ b/iw4/Components/Network.cpp @@ -60,7 +60,8 @@ namespace Components { if (Network::PacketHandlers.find(Network::SelectedPacket) != Network::PacketHandlers.end()) { - Network::PacketHandlers[Network::SelectedPacket](from, msg); + size_t offset = Network::SelectedPacket.size() + 4 + 1; + Network::PacketHandlers[Network::SelectedPacket](from, std::string(msg->data + offset, msg->cursize - offset)); } else { @@ -109,48 +110,6 @@ namespace Components // Install packet deploy hook Utils::Hook::Set<int>(0x5AA715, (DWORD)Network::DeployPacketStub - 0x5AA713 - 6); - - Network::Handle("infoResponse", [] (Address address, Game::msg_t* message) - { - OutputDebugStringA(Utils::VA("Inforesponse received: %s %s!", address.GetString(), message->data)); - }); - - Network::Handle("getInfo", [] (Address address, Game::msg_t* message) - { - OutputDebugStringA(Utils::VA("getinfo received: %s!", address.GetString())); - - int clientCount = 0; - - for (int i = 0; i < *Game::svs_numclients; i++) - { - if (Game::svs_clients[i].state >= 3) - { - clientCount++; - } - } - - auto data = std::string(message->data); - auto challenge = data.substr(data.find_first_of(" \n") + 1); - challenge = challenge.substr(0, challenge.find_first_of(" \n")); - - Utils::InfoString info; - info.Set("challenge", challenge.data()); // TODO: Fill! - info.Set("gamename", "IW4"); - info.Set("hostname", Dvar::Var("sv_hostname").Get<const char*>()); - info.Set("mapname", Dvar::Var("mapname").Get<const char*>()); - info.Set("gametype", Dvar::Var("g_gametype").Get<const char*>()); - info.Set("fs_game", Dvar::Var("fs_game").Get<const char*>()); - info.Set("xuid", Utils::VA("%llX", Steam::SteamUser()->GetSteamID().m_Bits)); - info.Set("clients", Utils::VA("%i", clientCount)); - info.Set("sv_maxclients", Utils::VA("%i", *Game::svs_numclients)); - - Network::Send(Game::NS_CLIENT, address, Utils::VA("infoResponse\n%s\n", info.Build().data())); - }); - - Command::Add("zob", [] (Command::Params params) - { - Network::Send(Game::NS_CLIENT, Network::Address("localhost:28960"), "getinfo xxx\n"); - }); } Network::~Network() diff --git a/iw4/Components/Network.hpp b/iw4/Components/Network.hpp index fc845545..958f592a 100644 --- a/iw4/Components/Network.hpp +++ b/iw4/Components/Network.hpp @@ -24,7 +24,7 @@ namespace Components Game::netadr_t address; }; - typedef void(*Callback)(Address address, Game::msg_t* message); + typedef void(*Callback)(Address address, std::string data); Network(); ~Network(); diff --git a/iw4/Components/Party.cpp b/iw4/Components/Party.cpp new file mode 100644 index 00000000..5f881f2d --- /dev/null +++ b/iw4/Components/Party.cpp @@ -0,0 +1,133 @@ +#include "..\STDInclude.hpp" + +namespace Components +{ + Party::JoinContainer Party::Container; + + void Party::Connect(Network::Address target) + { + Party::Container.Valid = true; + Party::Container.JoinTime = Game::Com_Milliseconds(); + Party::Container.Target = target; + Party::Container.Challenge = Utils::VA("%X", Party::Container.JoinTime); + + Network::Send(Game::NS_CLIENT, Party::Container.Target, Utils::VA("getinfo %s\n", Party::Container.Challenge.data())); + + Command::Execute("openmenu popup_reconnectingtoparty"); + } + + Party::Party() + { + // various changes to SV_DirectConnect-y stuff to allow non-party joinees + Utils::Hook::Set<WORD>(0x460D96, 0x90E9); + Utils::Hook::Set<BYTE>(0x460F0A, 0xEB); + Utils::Hook::Set<BYTE>(0x401CA4, 0xEB); + Utils::Hook::Set<BYTE>(0x401C15, 0xEB); + + // disable configstring checksum matching (it's unreliable at most) + Utils::Hook::Set<BYTE>(0x4A75A7, 0xEB); // SV_SpawnServer + Utils::Hook::Set<BYTE>(0x5AC2CF, 0xEB); // CL_ParseGamestate + Utils::Hook::Set<BYTE>(0x5AC2C3, 0xEB); // CL_ParseGamestate + + Command::Add("connect", [] (Command::Params params) + { + if (params.Length() < 2) + { + return; + } + + Party::Connect(Network::Address(params[1])); + }); + + Renderer::OnFrame([] () + { + if (!Party::Container.Valid) return; + + if ((Game::Com_Milliseconds() - Party::Container.JoinTime) > 5000) + { + Party::Container.Valid = false; + + Command::Execute("closemenu popup_reconnectingtoparty"); + Dvar::Var("partyend_reason").Set("Server connection timed out."); + Command::Execute("openmenu menu_xboxlive_partyended"); + } + }); + + // Basic info handler + Network::Handle("getInfo", [] (Network::Address address, std::string data) + { + int clientCount = 0; + + for (int i = 0; i < *Game::svs_numclients; i++) + { + if (Game::svs_clients[i].state >= 3) + { + clientCount++; + } + } + + Utils::InfoString info; + info.Set("challenge", data.substr(0, data.find_first_of("\n")).data()); + info.Set("gamename", "IW4"); + info.Set("hostname", Dvar::Var("sv_hostname").Get<const char*>()); + info.Set("mapname", Dvar::Var("mapname").Get<const char*>()); + info.Set("gametype", Dvar::Var("g_gametype").Get<const char*>()); + info.Set("fs_game", Dvar::Var("fs_game").Get<const char*>()); + info.Set("xuid", Utils::VA("%llX", Steam::SteamUser()->GetSteamID().m_Bits)); + info.Set("clients", Utils::VA("%i", clientCount)); + info.Set("sv_maxclients", Utils::VA("%i", *Game::svs_numclients)); + + Network::Send(Game::NS_CLIENT, address, Utils::VA("infoResponse\n%s\n", info.Build().data())); + }); + + Network::Handle("infoResponse", [] (Network::Address address, std::string data) + { + // Handle connection + if (Party::Container.Valid) + { + if (Party::Container.Target == address) + { + // Invalidate handler for future packets + Party::Container.Valid = false; + + Utils::InfoString info(data); + + OutputDebugStringA(data.data()); + + if (info.Get("challenge") != Party::Container.Challenge) + { + OutputDebugStringA(Utils::VA("\"%s\" vs. \"%s\"", info.Get("challenge").data(), Party::Container.Challenge.data())); + Command::Execute("closemenu popup_reconnectingtoparty"); + Dvar::Var("partyend_reason").Set("Invalid join response: Challenge mismatch."); + Command::Execute("openmenu menu_xboxlive_partyended"); + } + else if (atoi(info.Get("clients").data()) >= atoi(info.Get("sv_maxclients").data())) + { + Command::Execute("closemenu popup_reconnectingtoparty"); + Dvar::Var("partyend_reason").Set("@EXE_SERVERISFULL"); + Command::Execute("openmenu menu_xboxlive_partyended"); + } + else if (info.Get("mapname") == "" || info.Get("gametype") == "") + { + Command::Execute("closemenu popup_reconnectingtoparty"); + Dvar::Var("partyend_reason").Set("Invalid map or gametype."); + Command::Execute("openmenu menu_xboxlive_partyended"); + } + else + { + Dvar::Var("xblive_privatematch").Set(1); + Game::Menus_CloseAll(0x62E2858); + + char xnaddr[32]; + Game::CL_ConnectFromParty(0, xnaddr, *address.Get(), 0, 0, info.Get("mapname").data(), info.Get("gametype").data()); + } + } + } + }); + } + + Party::~Party() + { + + } +} diff --git a/iw4/Components/Party.hpp b/iw4/Components/Party.hpp new file mode 100644 index 00000000..9f2d6237 --- /dev/null +++ b/iw4/Components/Party.hpp @@ -0,0 +1,23 @@ +namespace Components +{ + class Party : public Component + { + public: + Party(); + ~Party(); + const char* GetName() { return "Party"; }; + + static void Connect(Network::Address target); + + private: + struct JoinContainer + { + Network::Address Target; + std::string Challenge; + DWORD JoinTime; + bool Valid; + }; + + static JoinContainer Container; + }; +} diff --git a/iw4/Components/QuickPatch.cpp b/iw4/Components/QuickPatch.cpp index e269a21a..5f6d0d33 100644 --- a/iw4/Components/QuickPatch.cpp +++ b/iw4/Components/QuickPatch.cpp @@ -2,6 +2,12 @@ namespace Components { + __int64* QuickPatch::GetStatsID() + { + static __int64 id = 0x110000100001337; + return &id; + } + QuickPatch::QuickPatch() { // remove system pre-init stuff (improper quit, disk full) @@ -54,6 +60,16 @@ namespace Components // default sv_pure to 0 Utils::Hook::Set<BYTE>(0x4D3A74, 0); + // Force debug logging + Utils::Hook::Nop(0x4AA89F, 2); + Utils::Hook::Nop(0x4AA8A1, 6); + + // Patch stats steamid + Utils::Hook::Nop(0x682EBF, 20); + Utils::Hook::Nop(0x6830B1, 20); + Utils::Hook(0x682EBF, QuickPatch::GetStatsID, HOOK_CALL).Install()->Quick(); + Utils::Hook(0x6830B1, QuickPatch::GetStatsID, HOOK_CALL).Install()->Quick(); + // Why? Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_WEAPON, 2400); } diff --git a/iw4/Components/QuickPatch.hpp b/iw4/Components/QuickPatch.hpp index 11984c3f..7054ce0b 100644 --- a/iw4/Components/QuickPatch.hpp +++ b/iw4/Components/QuickPatch.hpp @@ -5,5 +5,8 @@ namespace Components public: QuickPatch(); const char* GetName() { return "QuickPatch"; }; + + private: + static _int64* GetStatsID(); }; } diff --git a/iw4/Game/Functions.cpp b/iw4/Game/Functions.cpp index bc7fde52..654b8d6c 100644 --- a/iw4/Game/Functions.cpp +++ b/iw4/Game/Functions.cpp @@ -5,6 +5,7 @@ namespace Game Cbuf_AddText_t Cbuf_AddText = (Cbuf_AddText_t)0x404B20; CL_IsCgameInitialized_t CL_IsCgameInitialized = (CL_IsCgameInitialized_t)0x43EB20; + CL_ConnectFromParty_t CL_ConnectFromParty = (CL_ConnectFromParty_t)0x433D30; Cmd_AddCommand_t Cmd_AddCommand = (Cmd_AddCommand_t)0x470090; Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand = (Cmd_ExecuteSingleCommand_t)0x609540; @@ -34,8 +35,23 @@ namespace Game FreeMemory_t FreeMemory = (FreeMemory_t)0x4D6640; + FS_FileExists_t FS_FileExists = (FS_FileExists_t)0x4DEFA0; FS_FreeFile_t FS_FreeFile = (FS_FreeFile_t)0x4416B0; FS_ReadFile_t FS_ReadFile = (FS_ReadFile_t)0x4F4B90; + FS_ListFiles_t FS_ListFiles = (FS_ListFiles_t)0x441BB0; + FS_FreeFileList_t FS_FreeFileList = (FS_FreeFileList_t)0x4A5DE0; + FS_FOpenFileAppend_t FS_FOpenFileAppend = (FS_FOpenFileAppend_t)0x410BB0; + FS_FOpenFileAppend_t FS_FOpenFileWrite = (FS_FOpenFileAppend_t)0x4BA530; + FS_FOpenFileRead_t FS_FOpenFileRead = (FS_FOpenFileRead_t)0x46CBF0; + FS_FCloseFile_t FS_FCloseFile = (FS_FCloseFile_t)0x462000; + FS_WriteFile_t FS_WriteFile = (FS_WriteFile_t)0x426450; + FS_Write_t FS_Write = (FS_Write_t)0x4C06E0; + FS_Read_t FS_Read = (FS_Read_t)0x4A04C0; + FS_Seek_t FS_Seek = (FS_Seek_t)0x4A63D0; + FS_FTell_t FS_FTell = (FS_FTell_t)0x4E6760; + FS_Remove_t FS_Remove = (FS_Remove_t)0x4660F0; + FS_Restart_t FS_Restart = (FS_Restart_t)0x461A50; + FS_BuildPathToFile_t FS_BuildPathToFile = (FS_BuildPathToFile_t)0x4702C0; Menus_CloseAll_t Menus_CloseAll = (Menus_CloseAll_t)0x4BA5B0; Menus_OpenByName_t Menus_OpenByName = (Menus_OpenByName_t)0x4CCE60; @@ -49,12 +65,17 @@ namespace Game sendOOB_t OOBPrint = (sendOOB_t)0x4AEF00; PC_ReadToken_t PC_ReadToken = (PC_ReadToken_t)0x4ACCD0; + PC_ReadTokenHandle_t PC_ReadTokenHandle = (PC_ReadTokenHandle_t)0x4D2060; PC_SourceError_t PC_SourceError = (PC_SourceError_t)0x467A00; Script_Alloc_t Script_Alloc = (Script_Alloc_t)0x422E70; Script_SetupTokens_t Script_SetupTokens = (Script_SetupTokens_t)0x4E6950; Script_CleanString_t Script_CleanString = (Script_CleanString_t)0x498220; + SetConsole_t SetConsole = (SetConsole_t)0x44F060; + + UI_AddMenuList_t UI_AddMenuList = (UI_AddMenuList_t)0x4533C0; + Win_GetLanguage_t Win_GetLanguage = (Win_GetLanguage_t)0x45CBA0; void** DB_XAssetPool = (void**)0x7998A8; diff --git a/iw4/Game/Functions.hpp b/iw4/Game/Functions.hpp index 70717d5e..b97116bc 100644 --- a/iw4/Game/Functions.hpp +++ b/iw4/Game/Functions.hpp @@ -6,6 +6,9 @@ namespace Game typedef int(__cdecl * CL_IsCgameInitialized_t)(); extern CL_IsCgameInitialized_t CL_IsCgameInitialized; + typedef void(__cdecl * CL_ConnectFromParty_t)(int controller, void*, netadr_t adr, int, int, const char*, const char*); + extern CL_ConnectFromParty_t CL_ConnectFromParty; + typedef void(__cdecl * Cmd_AddCommand_t)(const char* name, void(*callback), cmd_function_t* data, char); extern Cmd_AddCommand_t Cmd_AddCommand; @@ -75,6 +78,49 @@ namespace Game typedef int(__cdecl * FS_ReadFile_t)(const char* path, char** buffer); extern FS_ReadFile_t FS_ReadFile; + typedef char** (__cdecl * FS_ListFiles_t)(char* path, char* extension, int noclue, int* amount); + extern FS_ListFiles_t FS_ListFiles; + + typedef void(__cdecl * FS_FreeFileList_t)(char** list); + extern FS_FreeFileList_t FS_FreeFileList; + + typedef int(__cdecl * FS_FOpenFileAppend_t)(char* file); + extern FS_FOpenFileAppend_t FS_FOpenFileAppend; + extern FS_FOpenFileAppend_t FS_FOpenFileWrite; + + typedef int(__cdecl * FS_FOpenFileRead_t)(const char* file, int* fh, int uniqueFile); + extern FS_FOpenFileRead_t FS_FOpenFileRead; + + typedef int(__cdecl * FS_FCloseFile_t)(int fh); + extern FS_FCloseFile_t FS_FCloseFile; + + typedef bool(__cdecl * FS_FileExists_t)(const char* file); + extern FS_FileExists_t FS_FileExists; + + typedef bool(__cdecl * FS_WriteFile_t)(char* filename, char* folder, void* buffer, int size); + extern FS_WriteFile_t FS_WriteFile; + + typedef int(__cdecl * FS_Write_t)(void* buffer, size_t size, int file); + extern FS_Write_t FS_Write; + + typedef int(__cdecl * FS_Read_t)(void* buffer, size_t size, int file); + extern FS_Read_t FS_Read; + + typedef int(__cdecl * FS_Seek_t)(int fileHandle, int seekPosition, int seekOrigin); + extern FS_Seek_t FS_Seek; + + typedef int(__cdecl * FS_FTell_t)(int fileHandle); + extern FS_FTell_t FS_FTell; + + typedef int(__cdecl * FS_Remove_t)(char *); + extern FS_Remove_t FS_Remove; + + typedef int(__cdecl * FS_Restart_t)(int a1, int a2); + extern FS_Restart_t FS_Restart; + + typedef int(__cdecl * FS_BuildPathToFile_t)(const char*, const char*, const char*, char**); + extern FS_BuildPathToFile_t FS_BuildPathToFile; + typedef void(__cdecl * Menus_CloseAll_t)(/*UiContext **/int dc); extern Menus_CloseAll_t Menus_CloseAll; @@ -99,6 +145,9 @@ namespace Game typedef int(__cdecl * PC_ReadToken_t)(source_t*, token_t*); extern PC_ReadToken_t PC_ReadToken; + typedef int(__cdecl * PC_ReadTokenHandle_t)(int handle, pc_token_s *pc_token); + extern PC_ReadTokenHandle_t PC_ReadTokenHandle; + typedef void(__cdecl * PC_SourceError_t)(int, const char*, ...); extern PC_SourceError_t PC_SourceError; @@ -111,6 +160,12 @@ namespace Game typedef int(__cdecl * Script_CleanString_t)(char* buffer); extern Script_CleanString_t Script_CleanString; + typedef void(__cdecl * SetConsole_t)(const char* cvar, const char* value); + extern SetConsole_t SetConsole; + + typedef void(__cdecl * UI_AddMenuList_t)(/*UiContext **/int dc, MenuList *menuList, int close); + extern UI_AddMenuList_t UI_AddMenuList; + typedef const char * (__cdecl * Win_GetLanguage_t)(); extern Win_GetLanguage_t Win_GetLanguage; diff --git a/iw4/STDInclude.hpp b/iw4/STDInclude.hpp index eba6c50f..ae63d275 100644 --- a/iw4/STDInclude.hpp +++ b/iw4/STDInclude.hpp @@ -6,7 +6,10 @@ #include <stdio.h> #include <string.h> #include <wincrypt.h> +#include <time.h> +#include <timeapi.h> +#pragma comment(lib, "Winmm.lib") #pragma comment(lib, "Crypt32.lib") #include <map> @@ -14,6 +17,8 @@ #include <string> #include <vector> #include <algorithm> +#include <sstream> +#include <utility> #include "Game\Structs.hpp" #include "Game\Functions.hpp" diff --git a/iw4/Steam/Interfaces/SteamUser.cpp b/iw4/Steam/Interfaces/SteamUser.cpp index 71330562..e15d00a6 100644 --- a/iw4/Steam/Interfaces/SteamUser.cpp +++ b/iw4/Steam/Interfaces/SteamUser.cpp @@ -14,17 +14,16 @@ namespace Steam SteamID User::GetSteamID() { + static int subId = 0; + SteamID id; - DATA_BLOB DataIn; - DATA_BLOB DataOut; + if (!subId) + { + subId = (Game::Com_Milliseconds() + timeGetTime()); + } - DataIn.pbData = (BYTE *)"AAAAAAAAAA"; - DataIn.cbData = 10; - - CryptProtectData(&DataIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_LOCAL_MACHINE, &DataOut); - - id.m_Bits = 0x110000100000000 | ::Utils::OneAtATime((char*)DataOut.pbData, 52); + id.m_Bits = 0x110000100000000 | subId; return id; } diff --git a/iw4/Utils/Utils.cpp b/iw4/Utils/Utils.cpp index a924646a..7178ff7f 100644 --- a/iw4/Utils/Utils.cpp +++ b/iw4/Utils/Utils.cpp @@ -30,22 +30,17 @@ namespace Utils return (strstr(heystack, needle) == (heystack + strlen(heystack) - strlen(needle))); } - std::vector<std::string> Explode(const std::string& str, const std::string& delimiters) + std::vector<std::string> Explode(const std::string& str, char delim) { - std::vector<std::string> tokens; + std::vector<std::string> result; + std::istringstream iss(str); - auto subStrBeginPos = str.find_first_not_of(delimiters, 0); - auto subStrEndPos = str.find_first_of(delimiters, subStrBeginPos); - - while (std::string::npos != subStrBeginPos || std::string::npos != subStrEndPos) + for (std::string token; std::getline(iss, token, delim);) { - tokens.push_back(str.substr(subStrBeginPos, subStrEndPos - subStrBeginPos)); - - subStrBeginPos = str.find_first_not_of(delimiters, subStrEndPos); - subStrEndPos = str.find_first_of(delimiters, subStrBeginPos); + result.push_back(std::move(token)); } - return tokens; + return result; } void Replace(std::string &string, std::string find, std::string replace) @@ -109,9 +104,17 @@ namespace Utils return infoString; } + void InfoString::Dump() + { + for (auto i = this->KeyValuePairs.begin(); i != this->KeyValuePairs.end(); i++) + { + OutputDebugStringA(Utils::VA("%s: %s", i->first.data(), i->second.data())); + } + } + void InfoString::Parse(std::string buffer) { - std::vector<std::string> KeyValues = Utils::Explode(buffer, "\\"); + std::vector<std::string> KeyValues = Utils::Explode(buffer, '\\'); for (unsigned int i = 0; i < (KeyValues.size() - 1); i+=2) { diff --git a/iw4/Utils/Utils.hpp b/iw4/Utils/Utils.hpp index 8d61dad7..4f13f7e0 100644 --- a/iw4/Utils/Utils.hpp +++ b/iw4/Utils/Utils.hpp @@ -3,7 +3,7 @@ namespace Utils const char *VA(const char *fmt, ...); std::string StrToLower(std::string input); bool EndsWith(const char* heystack, const char* needle); - std::vector<std::string> Explode(const std::string& str, const std::string& delimiters); + std::vector<std::string> Explode(const std::string& str, char delim); void Replace(std::string &string, std::string find, std::string replace); unsigned int OneAtATime(char *key, size_t len); @@ -18,6 +18,8 @@ namespace Utils std::string Build(); + void Dump(); + private: std::map<std::string, std::string> KeyValuePairs; void Parse(std::string buffer); diff --git a/iw4/iw4.vcxproj b/iw4/iw4.vcxproj index aa2eb0f6..ef23a1de 100644 --- a/iw4/iw4.vcxproj +++ b/iw4/iw4.vcxproj @@ -64,6 +64,7 @@ <ClInclude Include="Components\Menus.hpp" /> <ClInclude Include="Components\MusicalTalent.hpp" /> <ClInclude Include="Components\Network.hpp" /> + <ClInclude Include="Components\Party.hpp" /> <ClInclude Include="Components\QuickPatch.hpp" /> <ClInclude Include="Components\RawFiles.hpp" /> <ClInclude Include="Components\Renderer.hpp" /> @@ -97,6 +98,7 @@ <ClCompile Include="Components\Menus.cpp" /> <ClCompile Include="Components\MusicalTalent.cpp" /> <ClCompile Include="Components\Network.cpp" /> + <ClCompile Include="Components\Party.cpp" /> <ClCompile Include="Components\QuickPatch.cpp" /> <ClCompile Include="Components\RawFiles.cpp" /> <ClCompile Include="Components\Renderer.cpp" /> diff --git a/iw4/iw4.vcxproj.filters b/iw4/iw4.vcxproj.filters index 6b74f005..a48432ab 100644 --- a/iw4/iw4.vcxproj.filters +++ b/iw4/iw4.vcxproj.filters @@ -119,6 +119,9 @@ <ClCompile Include="Components\Network.cpp"> <Filter>Source\Components\Modules</Filter> </ClCompile> + <ClCompile Include="Components\Party.cpp"> + <Filter>Source\Components\Modules</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="Steam\Interfaces\SteamUser.hpp"> @@ -214,5 +217,8 @@ <ClInclude Include="Components\Network.hpp"> <Filter>Source\Components\Modules</Filter> </ClInclude> + <ClInclude Include="Components\Party.hpp"> + <Filter>Source\Components\Modules</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file