From f2e373a7933e883cfdcf7a2560e2e5d77743625a Mon Sep 17 00:00:00 2001 From: Michael Maurer II <100047986+maiyuzhe@users.noreply.github.com> Date: Tue, 29 Aug 2023 00:12:56 +0000 Subject: [PATCH 01/14] Update ZoneBuilder.cpp for building CoDOL Maps AssetHandler::ModifyAsset checks the zone version and then applies a patch, this won't work with maps compiled with zonebuilder because the ff version is the same as other iw4 zones. Therefore the sortkey needs to be fixed when the map gets built instead of at runtime. --- src/Components/Modules/ZoneBuilder.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index 3bce1cb6..abee258a 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -259,6 +259,23 @@ namespace Components return false; } + //patch for codol maps dumped with zonetool, the FF version is changed, so the sortKey hack in AssetHandler::ModifyAsset won't work + if (type == Game::XAssetType::ASSET_TYPE_GFXWORLD) + { + if (assetHeader.gfxWorld->sortKeyDistortion == 44) + { + assetHeader.gfxWorld->sortKeyDistortion = 43; + } + } + //likewise if material's sortKey is 44, it needs to be changed to 43. + if (type == Game::XAssetType::ASSET_TYPE_MATERIAL) + { + if (assetHeader.material->info.sortKey == 44) + { + assetHeader.material->info.sortKey = 43; + } + } + Game::XAsset asset; asset.type = type; asset.header = assetHeader; From b0bb9e784384e9d028100636af04e98f06e71f57 Mon Sep 17 00:00:00 2001 From: Michael Maurer II <100047986+maiyuzhe@users.noreply.github.com> Date: Tue, 29 Aug 2023 20:06:11 +0000 Subject: [PATCH 02/14] Update ZoneBuilder.cpp --- src/Components/Modules/ZoneBuilder.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index abee258a..ce8d9e9c 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -266,6 +266,12 @@ namespace Components { assetHeader.gfxWorld->sortKeyDistortion = 43; } + //Absolutely necessary patch for later codol maps. prevents player models from glowing ridiculously + if (assetHeader.gfxWorld->heroOnlyLightCount > 0) + { + Logger::Print("Fixing heroOnlyLightCount...\n"); + assetHeader.gfxWorld->heroOnlyLightCount = 0; + } } //likewise if material's sortKey is 44, it needs to be changed to 43. if (type == Game::XAssetType::ASSET_TYPE_MATERIAL) From 896fd49cf744a046913f41180d07e64f7a21a706 Mon Sep 17 00:00:00 2001 From: Michael Maurer II <100047986+maiyuzhe@users.noreply.github.com> Date: Wed, 30 Aug 2023 03:55:35 +0000 Subject: [PATCH 03/14] Removed code --- src/Components/Modules/ZoneBuilder.cpp | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index ce8d9e9c..3bce1cb6 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -259,29 +259,6 @@ namespace Components return false; } - //patch for codol maps dumped with zonetool, the FF version is changed, so the sortKey hack in AssetHandler::ModifyAsset won't work - if (type == Game::XAssetType::ASSET_TYPE_GFXWORLD) - { - if (assetHeader.gfxWorld->sortKeyDistortion == 44) - { - assetHeader.gfxWorld->sortKeyDistortion = 43; - } - //Absolutely necessary patch for later codol maps. prevents player models from glowing ridiculously - if (assetHeader.gfxWorld->heroOnlyLightCount > 0) - { - Logger::Print("Fixing heroOnlyLightCount...\n"); - assetHeader.gfxWorld->heroOnlyLightCount = 0; - } - } - //likewise if material's sortKey is 44, it needs to be changed to 43. - if (type == Game::XAssetType::ASSET_TYPE_MATERIAL) - { - if (assetHeader.material->info.sortKey == 44) - { - assetHeader.material->info.sortKey = 43; - } - } - Game::XAsset asset; asset.type = type; asset.header = assetHeader; From 585074d03319e9b77800f63401cd85e25d74b34e Mon Sep 17 00:00:00 2001 From: Michael Maurer II <100047986+maiyuzhe@users.noreply.github.com> Date: Wed, 30 Aug 2023 03:59:21 +0000 Subject: [PATCH 04/14] Moved fixes into Zones.cpp Fixes that were previously being done through compiling with zonebuilder are now done when the map dumps. No longer dealing with the heroOnlyLights, only mp_abandon_sh_mk seems to have that problem and that map is done. --- src/Components/Modules/Zones.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Zones.cpp b/src/Components/Modules/Zones.cpp index 89bb812a..f06153ed 100644 --- a/src/Components/Modules/Zones.cpp +++ b/src/Components/Modules/Zones.cpp @@ -1929,9 +1929,12 @@ namespace Components AssetHandler::Relocate(buffer + 0x20, buffer + 0x18, 0x30); AssetHandler::Relocate(buffer + 0x51, buffer + 0x48, 5); AssetHandler::Relocate(buffer + 0x58, buffer + 0x50, 0x10); - + + Game::Material* material = reinterpret_cast(buffer); // fix statebit - reinterpret_cast(buffer)->stateBitsEntry[47] = codol_material[0x50]; + material->stateBitsEntry[47] = codol_material[0x50]; + //check to fix distortion + if (material->info.sortKey == 44) material->info.sortKey = 43; } else if (Zones::ZoneVersion >= 359) { @@ -1975,6 +1978,9 @@ namespace Components // yes it was lol memcpy(&material->info.drawSurf.packed, material359.drawSurfBegin, 8); + //adding this here, situation as with later ff versions + if (material->info.sortKey == 44) material->info.sortKey = 43; + memcpy(&material->info.surfaceTypeBits, &material359.drawSurf[0], 6); // copies both surfaceTypeBits and hashIndex //material->drawSurf[8] = material359.drawSurf[0]; //material->drawSurf[9] = material359.drawSurf[1]; @@ -2025,6 +2031,9 @@ namespace Components int sunDiff = 8; // Stuff that is part of the sunflare we would overwrite std::memmove(buffer + 348 + sunDiff, buffer + 1316 + sunDiff, 280 - sunDiff); AssetHandler::Relocate(buffer + 1316, buffer + 348, 280); + + //all codol zones are like this pretty certain + reinterpret_cast(buffer)->sortKeyDistortion = 43; } return result; From 9a8c3cd65d098194011ff583d3e6ed81838b2bfa Mon Sep 17 00:00:00 2001 From: mxve <68632137+mxve@users.noreply.github.com> Date: Thu, 31 Aug 2023 05:13:37 +0200 Subject: [PATCH 05/14] Fix typo in steam mod --- src/Steam/Steam.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Steam/Steam.cpp b/src/Steam/Steam.cpp index e55b8c1f..37ec9361 100644 --- a/src/Steam/Steam.cpp +++ b/src/Steam/Steam.cpp @@ -130,7 +130,7 @@ namespace Steam } else { - Proxy::SetMod("IW4y: Modern Warfare 2"); + Proxy::SetMod("IW4x: Modern Warfare 2"); Proxy::RunGame(); } From e4cc1ca7fde33cf290ce713e0498639c4c758a98 Mon Sep 17 00:00:00 2001 From: mxve <68632137+mxve@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:17:21 +0200 Subject: [PATCH 06/14] Sort ServerList by players --- src/Components/Modules/ServerList.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 66fb86d1..fd496edb 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -17,8 +17,8 @@ namespace Components { - bool ServerList::SortAsc = true; - int ServerList::SortKey = static_cast>(Column::Ping); + bool ServerList::SortAsc = false; + int ServerList::SortKey = static_cast>(Column::Players); unsigned int ServerList::CurrentServer = 0; ServerList::Container ServerList::RefreshContainer; From 0d937f31f22514f0f6a955c7cb369ef25de5502b Mon Sep 17 00:00:00 2001 From: mxve <68632137+mxve@users.noreply.github.com> Date: Sat, 7 Oct 2023 13:31:32 +0200 Subject: [PATCH 07/14] update cli args --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 229b8703..bddb8f83 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ | `-nosteam` | Disable friends feature and do not update Steam about the game's current status just like an invisible mode. | | `-unprotect-dvars` | Allow the server to modify saved/archive dvars. | | `-zonebuilder` | Start the interactive zonebuilder tool console instead of starting the game. | +| `-disable-notifies` | Disable "Anti-CFG" checks | +| `-disable-mongoose` | Disable Mongoose HTTP server | +| `-disable-rate-limit-check` | Disable RCon rate limit checks | ## Disclaimer From c45aaf62b78c955600e9016ba31332eb2b1ab986 Mon Sep 17 00:00:00 2001 From: Louvenarde Date: Sat, 21 Oct 2023 19:38:12 +0200 Subject: [PATCH 08/14] Signed/Unsigned fixes --- src/Components/Modules/AssetInterfaces/IXAnimParts.cpp | 8 ++++---- src/Game/Structs.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp b/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp index e8b9860c..0a9bd565 100644 --- a/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp +++ b/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp @@ -14,7 +14,7 @@ namespace Assets if (asset->names) { - for (char i = 0; i < asset->boneCount[Game::PART_TYPE_ALL]; ++i) + for (unsigned char i = 0; i < asset->boneCount[Game::PART_TYPE_ALL]; ++i) { builder->addScriptString(asset->names[i]); } @@ -22,7 +22,7 @@ namespace Assets if (asset->notify) { - for (char i = 0; i < asset->notifyCount; ++i) + for (unsigned char i = 0; i < asset->notifyCount; ++i) { builder->addScriptString(asset->notify[i].name); } @@ -165,7 +165,7 @@ namespace Assets unsigned short* destTagnames = buffer->dest(); buffer->saveArray(asset->names, asset->boneCount[Game::PART_TYPE_ALL]); - for (char i = 0; i < asset->boneCount[Game::PART_TYPE_ALL]; ++i) + for (unsigned char i = 0; i < asset->boneCount[Game::PART_TYPE_ALL]; ++i) { builder->mapScriptString(destTagnames[i]); } @@ -181,7 +181,7 @@ namespace Assets Game::XAnimNotifyInfo* destNotetracks = buffer->dest(); buffer->saveArray(asset->notify, asset->notifyCount); - for (char i = 0; i < asset->notifyCount; ++i) + for (unsigned char i = 0; i < asset->notifyCount; ++i) { builder->mapScriptString(destNotetracks[i].name); } diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 4b72f36d..21842c63 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -1044,8 +1044,8 @@ namespace Game unsigned __int16 randomDataIntCount; unsigned __int16 numframes; char flags; - char boneCount[10]; - char notifyCount; + unsigned char boneCount[10]; + unsigned char notifyCount; char assetType; bool isDefault; unsigned int randomDataShortCount; From defdca0b93988a18aa98a3b55e96a745f5e8384f Mon Sep 17 00:00:00 2001 From: Louvenarde Date: Sat, 21 Oct 2023 19:38:40 +0200 Subject: [PATCH 09/14] Bump iW4OF --- deps/iw4-open-formats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/iw4-open-formats b/deps/iw4-open-formats index 6af596a0..aaf4455b 160000 --- a/deps/iw4-open-formats +++ b/deps/iw4-open-formats @@ -1 +1 @@ -Subproject commit 6af596a010eebf727e5d914bf9a01903c14ae128 +Subproject commit aaf4455bdac1ccd07c6eeeac993b7800124244c0 From fd5e229219dbc484576e741773947d9a7dea5c19 Mon Sep 17 00:00:00 2001 From: Louvenarde Date: Sat, 21 Oct 2023 19:52:15 +0200 Subject: [PATCH 10/14] Handle edge cases for IW4x dedicated server (increases stability) --- src/Components/Modules/Download.cpp | 12 ++++++++++++ src/Components/Modules/MapRotation.cpp | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index 282f6e86..04990301 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -437,6 +437,12 @@ namespace Components static std::optional InfoHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) { + if (!(*Game::com_sv_running)->current.enabled) + { + // Game is not running ,cannot return info + return std::nullopt; + } + const auto status = ServerInfo::GetInfo(); const auto host = ServerInfo::GetHostInfo(); @@ -586,6 +592,12 @@ namespace Components Utils::String::Replace(url, "\\", "/"); + if (url.size() <= 5) + { + mg_http_reply(c, 403, "Content-Type: text/html\r\n", "%s", "400 - Bad requestt"); + return {}; + } + url = url.substr(6); // Strip /file Utils::String::Replace(url, "%20", " "); diff --git a/src/Components/Modules/MapRotation.cpp b/src/Components/Modules/MapRotation.cpp index 0648a28f..98148978 100644 --- a/src/Components/Modules/MapRotation.cpp +++ b/src/Components/Modules/MapRotation.cpp @@ -208,7 +208,6 @@ namespace Components nlohmann::json MapRotation::to_json() { - assert(!DedicatedRotation.empty()); return DedicatedRotation.to_json(); } From 3cbda2c803a345b399fac2a753cba44514ea64ce Mon Sep 17 00:00:00 2001 From: Louvenarde Date: Tue, 24 Oct 2023 20:48:57 +0200 Subject: [PATCH 11/14] Cleanup Download.cpp a little bit --- src/Components/Modules/Download.cpp | 49 ++++++++++++++++++++++------- src/Components/Modules/Download.hpp | 14 +++++++++ 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index 04990301..eb33aaef 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -435,7 +435,34 @@ namespace Components MongooseLogBuffer.push_back(c); } - static std::optional InfoHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) + void Download::ReplyError(mg_connection* connection, int code) + { + std::string msg{}; + switch(code) + { + case 400: + msg = "Bad request"; + break; + + case 403: + msg = "Forbidden"; + break; + + case 404: + msg = "Not found"; + break; + } + + mg_http_reply(connection, code, "Content-Type: text/plain\r\n", msg.c_str()); + } + + void Download::Reply(mg_connection* connection, const std::string& contentType, const std::string& data) + { + const auto formatted = std::format("Content-Type: {}\r\n", contentType); + mg_http_reply(connection, 200, formatted.c_str(), data.c_str()); + } + + std::optional Download::InfoHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) { if (!(*Game::com_sv_running)->current.enabled) { @@ -492,7 +519,7 @@ namespace Components return { out }; } - static std::optional ListHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) + std::optional Download::ListHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) { static nlohmann::json jsonList; static std::filesystem::path fsGamePre; @@ -540,7 +567,7 @@ namespace Components return { out }; } - static std::optional MapHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) + std::optional Download::MapHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) { static std::string mapNamePre; static nlohmann::json jsonList; @@ -586,7 +613,7 @@ namespace Components return { out }; } - static std::optional FileHandler(mg_connection* c, const mg_http_message* hm) + std::optional Download::FileHandler(mg_connection* c, const mg_http_message* hm) { std::string url(hm->uri.ptr, hm->uri.len); @@ -594,7 +621,7 @@ namespace Components if (url.size() <= 5) { - mg_http_reply(c, 403, "Content-Type: text/html\r\n", "%s", "400 - Bad requestt"); + ReplyError(c, 400); return {}; } @@ -620,7 +647,7 @@ namespace Components if ((!Maps::GetUserMap()->isValid() && !Party::IsInUserMapLobby()) || !isValidFile) { - mg_http_reply(c, 403, "Content-Type: text/html\r\n", "%s", "403 - Forbidden"); + ReplyError(c, 403); return {}; } @@ -630,7 +657,7 @@ namespace Components { if ((!url.ends_with(".iwd") && url != "mod.ff") || url.find("_svr_") != std::string::npos) { - mg_http_reply(c, 403, "Content-Type: text/html\r\n", "%s", "403 - Forbidden"); + ReplyError(c, 403); return {}; } } @@ -641,7 +668,7 @@ namespace Components std::string file; if ((!isMap && fsGame.empty()) || !Utils::IO::ReadFile(path, &file)) { - mg_http_reply(c, 404, "Content-Type: text/html\r\n", "404 - Not Found %s", path.data()); + ReplyError(c, 404); } else { @@ -656,7 +683,7 @@ namespace Components return {}; } - static std::optional ServerListHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) + std::optional Download::ServerListHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) { std::vector servers; @@ -673,7 +700,7 @@ namespace Components return { out }; } - static void EventHandler(mg_connection* c, const int ev, void* ev_data, [[maybe_unused]] void* fn_data) + void Download::EventHandler(mg_connection* c, const int ev, void* ev_data, [[maybe_unused]] void* fn_data) { using callback = std::function(mg_connection*, const mg_http_message*)>; @@ -705,7 +732,7 @@ namespace Components { if (const auto reply = i->second(c, hm)) { - mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", reply.value().data()); + Reply(c, "application/json", reply.value()); } handled = true; diff --git a/src/Components/Modules/Download.hpp b/src/Components/Modules/Download.hpp index 84ee7584..b4e4dde1 100644 --- a/src/Components/Modules/Download.hpp +++ b/src/Components/Modules/Download.hpp @@ -1,5 +1,9 @@ #pragma once + +struct mg_connection; +struct mg_http_message; + namespace Components { class Download : public Component @@ -71,6 +75,7 @@ namespace Components this->valid_ = false; } } + }; class FileDownload @@ -100,5 +105,14 @@ namespace Components static bool DownloadFile(ClientDownload* download, unsigned int index); static void LogFn(char c, void* param); + static void ReplyError(mg_connection* connection, int code); + static void Reply(mg_connection* connection, const std::string& contentType, const std::string& data); + + static std::optional FileHandler(mg_connection* c, const mg_http_message* hm); + static void EventHandler(mg_connection* c, const int ev, void* ev_data, void* fn_data); + static std::optional ListHandler(mg_connection* c, const mg_http_message* hm); + static std::optional InfoHandler(mg_connection* c, const mg_http_message* hm); + static std::optional ServerListHandler(mg_connection* c, const mg_http_message* hm); + static std::optional MapHandler(mg_connection* c, const mg_http_message* hm); }; } From 5f8c7af7ff8b097e73cf5c5831b3d908558f6ac1 Mon Sep 17 00:00:00 2001 From: Louvenarde Date: Wed, 25 Oct 2023 00:49:09 +0200 Subject: [PATCH 12/14] Woopsie fmt --- src/Components/Modules/Download.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index eb33aaef..43433425 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -453,13 +453,13 @@ namespace Components break; } - mg_http_reply(connection, code, "Content-Type: text/plain\r\n", msg.c_str()); + mg_http_reply(connection, code, "Content-Type: text/plain\r\n", "%s", msg.c_str()); } void Download::Reply(mg_connection* connection, const std::string& contentType, const std::string& data) { const auto formatted = std::format("Content-Type: {}\r\n", contentType); - mg_http_reply(connection, 200, formatted.c_str(), data.c_str()); + mg_http_reply(connection, 200, formatted.c_str(), "%s", data.c_str()); } std::optional Download::InfoHandler([[maybe_unused]] mg_connection* c, [[maybe_unused]] const mg_http_message* hm) From 24231ed24d18956c50009601de1311bde342e693 Mon Sep 17 00:00:00 2001 From: Xerxes <5236639+xerxes-at@users.noreply.github.com> Date: Sat, 28 Oct 2023 22:18:13 +0200 Subject: [PATCH 13/14] Ban another guid that got shipped in a repack of the game. --- src/Components/Modules/Auth.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Components/Modules/Auth.cpp b/src/Components/Modules/Auth.cpp index ef93603f..d48bc2f6 100644 --- a/src/Components/Modules/Auth.cpp +++ b/src/Components/Modules/Auth.cpp @@ -21,7 +21,8 @@ namespace Components { 0xf4d2c30b712ac6e3, 0xf7e33c4081337fa3, - 0x6f5597f103cc50e9 + 0x6f5597f103cc50e9, + 0xecd542eee54ffccf }; bool Auth::HasAccessToReservedSlot; From 56caa5f35b2776c736c1a88508307c0f021afbc6 Mon Sep 17 00:00:00 2001 From: Xerxes <5236639+xerxes-at@users.noreply.github.com> Date: Tue, 31 Oct 2023 13:50:46 +0100 Subject: [PATCH 14/14] Add a trailing comma even though it is the last element. Co-Authored-By: Edo --- src/Components/Modules/Auth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Auth.cpp b/src/Components/Modules/Auth.cpp index d48bc2f6..42269ba9 100644 --- a/src/Components/Modules/Auth.cpp +++ b/src/Components/Modules/Auth.cpp @@ -22,7 +22,7 @@ namespace Components 0xf4d2c30b712ac6e3, 0xf7e33c4081337fa3, 0x6f5597f103cc50e9, - 0xecd542eee54ffccf + 0xecd542eee54ffccf, }; bool Auth::HasAccessToReservedSlot;