diff --git a/.gitmodules b/.gitmodules index 4387e293..5670c6e7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,7 +17,7 @@ [submodule "deps/mongoose"] path = deps/mongoose url = https://github.com/cesanta/mongoose.git - branch = master + branch = 7.8 [submodule "deps/protobuf"] path = deps/protobuf url = https://github.com/google/protobuf.git diff --git a/deps/mongoose b/deps/mongoose index 73813a83..0a265e79 160000 --- a/deps/mongoose +++ b/deps/mongoose @@ -1 +1 @@ -Subproject commit 73813a838386f6ebca447eb54c626803163ee257 +Subproject commit 0a265e79a67d7bfcdca27f2ccb98ccb474677ec6 diff --git a/src/Components/Modules/AssetInterfaces/IXModel.cpp b/src/Components/Modules/AssetInterfaces/IXModel.cpp index 305a624c..c8173537 100644 --- a/src/Components/Modules/AssetInterfaces/IXModel.cpp +++ b/src/Components/Modules/AssetInterfaces/IXModel.cpp @@ -77,7 +77,7 @@ namespace Assets { Components::FileSystem::File modelFile(std::format("xmodel/{}.iw4xModel", name)); - if (!builder->isPrimaryAsset() && (!Components::ZoneBuilder::PreferDiskAssetsDvar.get() || !modelFile.exists())) + if (!builder->isPrimaryAsset() && (!Components::ZoneBuilder::ZBPreferDiskAssets.get() || !modelFile.exists())) { header->model = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).model; if (header->model) return; diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index 3c1b5828..6d66c7b7 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -455,35 +455,40 @@ namespace Components static std::string ListHandler() { static nlohmann::json jsonList; - static auto handled = false; + static std::filesystem::path fsGamePre; - const std::filesystem::path fs_gameDirVar((*Game::fs_gameDirVar)->current.string); + const std::filesystem::path fsGame = (*Game::fs_gameDirVar)->current.string; - if (!fs_gameDirVar.empty() && !handled) + if (!fsGame.empty() && (fsGamePre != fsGame)) { - handled = true; + fsGamePre = fsGame; std::vector fileList; - const auto path = (*Game::fs_basepath)->current.string / fs_gameDirVar; - auto list = FileSystem::GetSysFileList(path.generic_string(), "iwd", false); + const auto path = (*Game::fs_basepath)->current.string / fsGame; + auto list = Utils::IO::ListFiles(path, false); list.emplace_back("mod.ff"); for (const auto& file : list) { auto filename = path / file; - if (file.find("_svr_") != std::string::npos) + if (filename.extension() != ".iwd"s) // We don't want to serve other files + { + continue; + } + + if (file.find("_svr_") != std::string::npos) // Files that are 'server only' are skipped { continue; } - std::unordered_map jsonFileList; auto fileBuffer = Utils::IO::ReadFile(filename.generic_string()); if (fileBuffer.empty()) { continue; } + std::unordered_map jsonFileList; jsonFileList["name"] = file; jsonFileList["size"] = fileBuffer.size(); jsonFileList["hash"] = Utils::Cryptography::SHA256::Compute(fileBuffer, true); diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index 69ca4d78..286ac544 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -543,17 +543,22 @@ namespace Components } std::vector fastFiles; - - if (param->get(1) == "all"s) + if (std::strcmp(param->get(1), "all") == 0) { - for (const auto& f : Utils::IO::ListFiles("zone/english")) + for (const auto& f : Utils::IO::ListFiles("zone/english", false)) + { fastFiles.emplace_back(f.substr(7, f.length() - 10)); + } - for (const auto& f : Utils::IO::ListFiles("zone/dlc")) + for (const auto& f : Utils::IO::ListFiles("zone/dlc", false)) + { fastFiles.emplace_back(f.substr(3, f.length() - 6)); + } - for (const auto& f : Utils::IO::ListFiles("zone/patch")) + for (const auto& f : Utils::IO::ListFiles("zone/patch", false)) + { fastFiles.emplace_back(f.substr(5, f.length() - 8)); + } } else { @@ -599,7 +604,7 @@ namespace Components { Utils::IO::CreateDir("userraw/techsets"); Utils::Stream buffer(0x1000); - Game::MaterialTechniqueSet* dest = buffer.dest(); + auto* dest = buffer.dest(); buffer.save(asset.techniqueSet); if (asset.techniqueSet->name) diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index 430afeb2..5b33b4cc 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -21,7 +21,7 @@ namespace Components volatile bool ZoneBuilder::CommandThreadTerminate = false; std::thread ZoneBuilder::CommandThread; - Dvar::Var ZoneBuilder::PreferDiskAssetsDvar; + Dvar::Var ZoneBuilder::ZBPreferDiskAssets; ZoneBuilder::Zone::Zone(const std::string& name) : indexStart(0), externalSize(0), // Reserve 100MB by default. @@ -1101,18 +1101,6 @@ namespace Components Utils::Hook::Set(0x5BC759, g_copyInfo_new); Utils::Hook::Set(0x5BB9AD, newLimit); // limit check - // this one lets us keep loading zones and it will ignore assets when the pool is filled - /* - AssetHandler::OnLoad([](Game::XAssetType type, Game::XAssetHeader, const std::string&, bool* restrict) - { - //if (*static_cast(Game::DB_XAssetPool[type].data) == 0) - if (Game::g_poolSize[type] == 0) - { - *restrict = true; - } - }); - */ - // hunk size (was 300 MiB) Utils::Hook::Set(0x64A029, 0x38400000); // 900 MiB Utils::Hook::Set(0x64A057, 0x38400000); @@ -1289,7 +1277,8 @@ namespace Components std::string csvStr; - auto fileList = Utils::IO::ListFiles(Utils::String::VA("zone/%s", Game::Win_GetLanguage())); + const auto dir = std::format("zone/{}", Game::Win_GetLanguage()); + auto fileList = Utils::IO::ListFiles(dir, false); for (auto zone : fileList) { Utils::String::Replace(zone, Utils::String::VA("zone/%s/", Game::Win_GetLanguage()), ""); @@ -1325,7 +1314,7 @@ namespace Components while (!Game::Sys_IsDatabaseReady()) std::this_thread::sleep_for(100ms); // wait till its fully loaded - if (curTechsets_list.size() == 0) + if (curTechsets_list.empty()) { Logger::Print("Skipping empty zone {}\n", zone); // unload zone @@ -1352,7 +1341,7 @@ namespace Components } // save csv - Utils::IO::WriteFile("zone_source/techsets/" + zone + "_techsets.csv", csvStr.data()); + Utils::IO::WriteFile("zone_source/techsets/" + zone + "_techsets.csv", csvStr); // build the techset zone std::string zoneName = "techsets/" + zone + "_techsets"; @@ -1382,7 +1371,7 @@ namespace Components Utils::Hook::Set(0x649E740, "techsets"); // load generated techset fastfiles - auto list = Utils::IO::ListFiles("zone/techsets"); + auto list = Utils::IO::ListFiles("zone/techsets", false); int i = 0; int subCount = 0; for (auto it : list) @@ -1427,7 +1416,7 @@ namespace Components std::string tempZoneFile = Utils::String::VA("zone_source/techsets/techsets%d.csv", subCount); std::string tempZone = Utils::String::VA("techsets/techsets%d", subCount); - Utils::IO::WriteFile(tempZoneFile, csvStr.data()); + Utils::IO::WriteFile(tempZoneFile, csvStr); Logger::Print("Building zone '{}'...\n", tempZone); Zone(tempZone).build(); @@ -1472,7 +1461,7 @@ namespace Components std::string tempZoneFile = Utils::String::VA("zone_source/techsets/techsets%d.csv", subCount); std::string tempZone = Utils::String::VA("techsets/techsets%d", subCount); - Utils::IO::WriteFile(tempZoneFile, csvStr.data()); + Utils::IO::WriteFile(tempZoneFile, csvStr); Logger::Print("Building zone '{}'...\n", tempZone); Zone(tempZone).build(); @@ -1511,7 +1500,7 @@ namespace Components csvStr.clear(); for (auto tech : curTechsets_list) { - std::string mat = ZoneBuilder::FindMaterialByTechnique(tech); + auto mat = ZoneBuilder::FindMaterialByTechnique(tech); if (mat.length() == 0) { csvStr.append("techset," + tech + "\n"); @@ -1522,7 +1511,7 @@ namespace Components } } - Utils::IO::WriteFile("zone_source/techsets/techsets.csv", csvStr.data()); + Utils::IO::WriteFile("zone_source/techsets/techsets.csv", csvStr); // set language back Utils::Hook::Set(0x649E740, language); @@ -1605,7 +1594,7 @@ namespace Components }); // True by default, but can be put to zero for backward compatibility if needed - ZoneBuilder::PreferDiskAssetsDvar = Dvar::Register("zb_prefer_disk_assets", true, Game::DVAR_NONE, "Should zonebuilder prefer in-memory assets (requirements) or disk assets, when both are present?"); + ZoneBuilder::ZBPreferDiskAssets = Dvar::Register("zb_prefer_disk_assets", true, Game::DVAR_NONE, "Should ZoneBuilder prefer in-memory assets (requirements) or disk assets, when both are present"); } } diff --git a/src/Components/Modules/ZoneBuilder.hpp b/src/Components/Modules/ZoneBuilder.hpp index f61b140f..46cd387a 100644 --- a/src/Components/Modules/ZoneBuilder.hpp +++ b/src/Components/Modules/ZoneBuilder.hpp @@ -131,7 +131,7 @@ namespace Components static std::vector> EndAssetTrace(); static Game::XAssetHeader GetEmptyAssetIfCommon(Game::XAssetType type, const std::string& name, Zone* builder); - static Dvar::Var PreferDiskAssetsDvar; + static Dvar::Var ZBPreferDiskAssets; private: static int StoreTexture(Game::GfxImageLoadDef **loadDef, Game::GfxImage *image); diff --git a/src/Utils/IO.cpp b/src/Utils/IO.cpp index d05b887f..f24222dd 100644 --- a/src/Utils/IO.cpp +++ b/src/Utils/IO.cpp @@ -97,13 +97,23 @@ namespace Utils::IO return std::filesystem::is_empty(directory); } - std::vector ListFiles(const std::filesystem::path& directory) + std::vector ListFiles(const std::filesystem::path& directory, const bool recursive) { std::vector files; - for (auto& file : std::filesystem::directory_iterator(directory)) + if (recursive) { - files.push_back(file.path().generic_string()); + for (auto& file : std::filesystem::recursive_directory_iterator(directory)) + { + files.push_back(file.path().generic_string()); + } + } + else + { + for (auto& file : std::filesystem::directory_iterator(directory)) + { + files.push_back(file.path().generic_string()); + } } return files; diff --git a/src/Utils/IO.hpp b/src/Utils/IO.hpp index 199a8e16..ae68a5ce 100644 --- a/src/Utils/IO.hpp +++ b/src/Utils/IO.hpp @@ -11,5 +11,5 @@ namespace Utils::IO bool CreateDir(const std::string& dir); bool DirectoryExists(const std::filesystem::path& file); bool DirectoryIsEmpty(const std::filesystem::path& file); - std::vector ListFiles(const std::filesystem::path& directory); + std::vector ListFiles(const std::filesystem::path& directory, bool recursive = false); }