From b60698383556eed13df77d31f3fd7680a5fc6a4c Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 17 Oct 2016 20:42:15 +0200 Subject: [PATCH] Add @Dasfonia's menu and gametype stuff --- deps/fmt | 2 +- deps/libtommath | 2 +- deps/mongoose | 2 +- src/Components/Loader.cpp | 1 + src/Components/Loader.hpp | 1 + src/Components/Modules/BitMessage.cpp | 2 +- src/Components/Modules/Gametypes.cpp | 99 +++++++++++++++++++++++++++ src/Components/Modules/Gametypes.hpp | 19 +++++ src/Components/Modules/Maps.cpp | 4 +- src/Components/Modules/Menus.cpp | 11 +++ src/Components/Modules/Network.cpp | 3 + src/Game/Functions.cpp | 2 + src/Game/Functions.hpp | 3 + src/Game/Structs.hpp | 7 +- 14 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 src/Components/Modules/Gametypes.cpp create mode 100644 src/Components/Modules/Gametypes.hpp diff --git a/deps/fmt b/deps/fmt index 4809e295..ed874df2 160000 --- a/deps/fmt +++ b/deps/fmt @@ -1 +1 @@ -Subproject commit 4809e2956a9ec04e97f026c5df224349f61179b0 +Subproject commit ed874df293f8c0831477a2abbdabfb3a0d0441a8 diff --git a/deps/libtommath b/deps/libtommath index 2e1446f9..b8527e92 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit 2e1446f93639d3b619a5b17cdcc44bbd63ca0c7e +Subproject commit b8527e92f8401a79b86e779caaaf00dca83f73c7 diff --git a/deps/mongoose b/deps/mongoose index f9a6403b..31c5ef1b 160000 --- a/deps/mongoose +++ b/deps/mongoose @@ -1 +1 @@ -Subproject commit f9a6403b115f2b62ead2664e57f0dd906d3f51d0 +Subproject commit 31c5ef1bc32fcff6ecd1d774852a2f5506a65aea diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 1b0712ab..a5ff5504 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -52,6 +52,7 @@ namespace Components Loader::Register(new Discovery()); Loader::Register(new Exception()); Loader::Register(new FastFiles()); + Loader::Register(new Gametypes()); Loader::Register(new Materials()); #ifndef DISABLE_BITMESSAGE Loader::Register(new BitMessage()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 66da7218..8d700b9f 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -66,6 +66,7 @@ namespace Components #include "Modules\Discovery.hpp" #include "Modules\Exception.hpp" #include "Modules\FastFiles.hpp" +#include "Modules\Gametypes.hpp" #include "Modules\Materials.hpp" #include "Modules\Singleton.hpp" #include "Modules\BitMessage.hpp" diff --git a/src/Components/Modules/BitMessage.cpp b/src/Components/Modules/BitMessage.cpp index dd174852..27c2df44 100644 --- a/src/Components/Modules/BitMessage.cpp +++ b/src/Components/Modules/BitMessage.cpp @@ -375,4 +375,4 @@ namespace Components } } -#endif \ No newline at end of file +#endif diff --git a/src/Components/Modules/Gametypes.cpp b/src/Components/Modules/Gametypes.cpp new file mode 100644 index 00000000..bdab7189 --- /dev/null +++ b/src/Components/Modules/Gametypes.cpp @@ -0,0 +1,99 @@ +#include "STDInclude.hpp" + +namespace Components +{ + unsigned int Gametypes::GetGametypeCount() + { + return *Game::gameTypeCount; + } + + const char* Gametypes::GetGametypeText(unsigned int index, int) + { + if (static_cast(*Game::gameTypeCount) > index) + { + return Game::SEH_StringEd_GetString(Game::gameTypes[index].uiName); + } + + return ""; + } + + void Gametypes::SelectGametype(unsigned int index) + { + if (!*Game::gameTypeCount) return; + if (static_cast(*Game::gameTypeCount) <= index) index = 0; + + std::string gametype = Game::gameTypes[index].gameType; + + Dvar::Var("ui_gametype").Set(gametype); + Dvar::Var("g_gametype").Set(gametype); + } + + bool Gametypes::BuildGametypeList(const char*, void* buffer, size_t size) + { + std::vector gametypes; + + auto pushGametype = [&] (std::string gametype) + { + auto pos = gametype.find_last_of("/\\"); + if (pos != std::string::npos) + { + gametype = gametype.substr(pos + 1); + } + + if (Utils::String::EndsWith(gametype, ".txt")) + { + gametype = gametype.substr(0, gametype.size() - 4); + } + + // No need for that :) + if (gametype == "_gametypes") return; + + if (std::find(gametypes.begin(), gametypes.end(), gametype) == gametypes.end()) + { + gametypes.push_back(gametype); + } + }; + + // Get the gametypes we can find in the filesystem + std::vector rawGametypes = FileSystem::GetFileList("maps/mp/gametypes/", "txt"); + + // Get the gametypes we can find in the database + Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_RAWFILE, [] (Game::XAssetHeader header, void* data) + { + std::string name = header.rawfile->name; + std::vector* rawGametypes = reinterpret_cast*>(data); + + if (Utils::String::StartsWith(name, "maps/mp/gametypes/") && Utils::String::EndsWith(name, ".txt")) + { + if (std::count(name.begin(), name.end(), '/') == 3 && std::count(name.begin(), name.end(), '\\') == 0) + { + rawGametypes->push_back(name); + } + } + + }, &rawGametypes, false); + + std::for_each(rawGametypes.begin(), rawGametypes.end(), pushGametype); + + std::string data; + for (auto& gametype : gametypes) + { + data.append(gametype); + data.append("\n"); + } + + // Copy to the actual buffer + std::memcpy(buffer, data.data(), std::min(size, data.size())); + + return (!gametypes.empty()); + } + + Gametypes::Gametypes() + { + UIFeeder::Add(29.0f, Gametypes::GetGametypeCount, Gametypes::GetGametypeText, Gametypes::SelectGametype); + + // Dynamically grab gametypes + Utils::Hook(0x5FA46C, Gametypes::BuildGametypeList, HOOK_CALL).Install()->Quick(); // Scr_UpdateGameTypeList + Utils::Hook(0x632155, Gametypes::BuildGametypeList, HOOK_CALL).Install()->Quick(); // UI_UpdateGameTypesList + } +} diff --git a/src/Components/Modules/Gametypes.hpp b/src/Components/Modules/Gametypes.hpp new file mode 100644 index 00000000..c7d417d8 --- /dev/null +++ b/src/Components/Modules/Gametypes.hpp @@ -0,0 +1,19 @@ +namespace Components +{ + class Gametypes : public Component + { + public: + Gametypes(); + +#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) + const char* GetName() { return "Gametypes"; }; +#endif + + private: + static unsigned int GetGametypeCount(); + static const char* GetGametypeText(unsigned int index, int column); + static void SelectGametype(unsigned int index); + + static bool BuildGametypeList(const char* file, void* buffer, size_t size); + }; +} diff --git a/src/Components/Modules/Maps.cpp b/src/Components/Modules/Maps.cpp index 04931bbe..c2daa978 100644 --- a/src/Components/Modules/Maps.cpp +++ b/src/Components/Modules/Maps.cpp @@ -401,7 +401,9 @@ namespace Components Maps::AddDependency("mp_cargoship_sh", "iw4x_dependencies_mp"); Maps::AddDependency("mp_firingrange", "iw4x_dependencies_mp"); Maps::AddDependency("mp_shipment_long", "iw4x_dependencies_mp"); - Maps::AddDependency("mp_firingrange", "iw4x_dependencies_mp"); + Maps::AddDependency("mp_firingrange", "iw4x_dependencies_mp"); + Maps::AddDependency("mp_firingrange", "mp_underpass"); + Maps::AddDependency("mp_underpass", "mp_firingrange"); #if defined(DEBUG) && defined(ENABLE_DXSDK) Command::Add("dumpmap", [] (Command::Params) diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index 9625b7d0..636474d3 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -641,6 +641,12 @@ namespace Components return; } + // Not quite sure if we want to do this if we're not ingame, but it's only needed for ingame menus. + if (Dvar::Var("cl_ingame").Get()) + { + Game::Key_SetCatcher(0, 16); + } + Game::Menus_OpenByName(Game::uiContext, params[1]); }); @@ -667,6 +673,11 @@ namespace Components } }); + Command::Add("mp_QuickMessage", [] (Command::Params) + { + Command::Execute("openmenu quickmessage"); + }); + // Define custom menus here Menus::Add("ui_mp/theater_menu.menu"); Menus::Add("ui_mp/pc_options_multi.menu"); diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp index 1fcee988..a5fccf37 100644 --- a/src/Components/Modules/Network.cpp +++ b/src/Components/Modules/Network.cpp @@ -88,6 +88,9 @@ namespace Components // 172.16.X.X - 172.31.X.X if (this->GetIP().bytes[0] == 172 && (this->GetIP().bytes[1] >= 16) && (this->GetIP().bytes[1] < 32)) return true; + // 127.0.0.1 + if (this->GetIP().full == 0x0100007F) return true; + // TODO: Maybe check for matching localIPs and subnet mask return false; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index ac82b664..347ba22d 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -98,6 +98,8 @@ namespace Game Image_LoadFromFileWithReader_t Image_LoadFromFileWithReader = (Image_LoadFromFileWithReader_t)0x53ABF0; Image_Release_t Image_Release = (Image_Release_t)0x51F010; + Key_SetCatcher_t Key_SetCatcher = (Key_SetCatcher_t)0x43BD00; + LargeLocalInit_t LargeLocalInit = (LargeLocalInit_t)0x4A62A0; Load_Stream_t Load_Stream = (Load_Stream_t)0x470E30; diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 35b56638..4ac3219b 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -233,6 +233,9 @@ namespace Game typedef void(__cdecl * Image_Release_t)(GfxImage* image); extern Image_Release_t Image_Release; + typedef void(__cdecl * Key_SetCatcher_t)(int localClientNum, int catcher); + extern Key_SetCatcher_t Key_SetCatcher; + typedef void(__cdecl * LargeLocalInit_t)(); extern LargeLocalInit_t LargeLocalInit; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 281a56f3..93a0e9ce 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -2545,12 +2545,17 @@ namespace Game struct GfxStaticModelDrawInst { GfxPackedPlacement placement; - XModel *model; + + char pad[24]; + + XModel *model; // 52 float cullDist; char reflectionProbeIndex; char primaryLightIndex; unsigned __int16 lightingHandle; char flags; + + char pad2[8]; }; struct cplane_s