From 7ba5a616cd895c09cae1d59df61ff992b0e06f7e Mon Sep 17 00:00:00 2001 From: Future Date: Sun, 19 May 2024 08:55:06 +0200 Subject: [PATCH 1/4] feat: dump leaderboard definitions on IW4/IW5 --- docs/SupportedAssetTypes.md | 4 +- src/Common/Game/IW5/IW5_Assets.h | 13 +++ .../Game/IW4/Json/JsonLeaderboardDef.h | 58 +++++++++++++ .../Game/IW5/Json/JsonLeaderboardDef.h | 82 +++++++++++++++++++ .../AssetDumperLeaderboardDef.cpp | 29 +++++++ .../AssetDumpers/AssetDumperLeaderboardDef.h | 16 ++++ .../JsonLeaderboardDefWriter.cpp | 70 ++++++++++++++++ .../LeaderboardDef/JsonLeaderboardDefWriter.h | 11 +++ src/ObjWriting/Game/IW4/ZoneDumperIW4.cpp | 3 +- .../AssetDumperLeaderboardDef.cpp | 29 +++++++ .../AssetDumpers/AssetDumperLeaderboardDef.h | 16 ++++ .../JsonLeaderboardDefWriter.cpp | 82 +++++++++++++++++++ .../LeaderboardDef/JsonLeaderboardDefWriter.h | 11 +++ src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp | 3 +- 14 files changed, 423 insertions(+), 4 deletions(-) create mode 100644 src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h create mode 100644 src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h create mode 100644 src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp create mode 100644 src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.h create mode 100644 src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp create mode 100644 src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.h create mode 100644 src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp create mode 100644 src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.h create mode 100644 src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp create mode 100644 src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.h diff --git a/docs/SupportedAssetTypes.md b/docs/SupportedAssetTypes.md index deeca7c4..2de60610 100644 --- a/docs/SupportedAssetTypes.md +++ b/docs/SupportedAssetTypes.md @@ -71,7 +71,7 @@ The following section specify which assets are supported to be dumped to disk (u | FxImpactTable | ❌ | ❌ | | | RawFile | ✅ | ✅ | | | StringTable | ✅ | ✅ | | -| LeaderboardDef | ❌ | ❌ | | +| LeaderboardDef | ✅ | ❌ | | | StructuredDataDefSet | ✅ | ✅ | The format is custom due to lacking information about original format. | | TracerDef | ✅ | ❌ | | | VehicleDef | ✅ | ❌ | | @@ -116,7 +116,7 @@ The following section specify which assets are supported to be dumped to disk (u | RawFile | ✅ | ✅ | | | ScriptFile | ⁉️ | ⁉️ | Can only be dumped/loaded as binary. Editing is possible with [GSC-Tool](https://github.com/xensik/gsc-tool). | | StringTable | ✅ | ✅ | | -| LeaderboardDef | ❌ | ❌ | | +| LeaderboardDef | ✅ | ❌ | | | StructuredDataDefSet | ❌ | ❌ | | | TracerDef | ❌ | ❌ | | | VehicleDef | ❌ | ❌ | | diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index 33a21ada..de4ca847 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -4380,6 +4380,19 @@ namespace IW5 LBUPDATE_TYPE_COUNT = 0x3 }; + enum LbTrackType + { + TRK_ALLTIME = 0x0, + TRK_WEEKLY = 0x1, + TRK_MONTHLY = 0x2, + TRK_PRESTIGE_ALLTIME = 0x3, + TRK_PRESTIGE_WEEKLY = 0x4, + TRK_PRESTIGE_MONTHLY = 0x5, + TRK_DAILY = 0x6, + TRK_PRESTIGE_DAILY = 0x7, + TRK_COUNT + }; + struct LeaderboardDef { const char* name; diff --git a/src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h b/src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h new file mode 100644 index 00000000..e1924223 --- /dev/null +++ b/src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h @@ -0,0 +1,58 @@ +#pragma once + +#include "Game/IW4/IW4.h" + +#include "Json/JsonCommon.h" +#include "Json/JsonExtension.h" +#include +#include +#include +#include +#include + +namespace IW4 +{ + NLOHMANN_JSON_SERIALIZE_ENUM(LbColType, + { + {LBCOL_TYPE_NUMBER, "number" }, + {LBCOL_TYPE_TIME, "time" }, + {LBCOL_TYPE_LEVELXP, "levelxp" }, + {LBCOL_TYPE_PRESTIGE, "prestige" }, + {LBCOL_TYPE_BIGNUMBER, "bignumber"}, + {LBCOL_TYPE_PERCENT, "percent" }, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(LbAggType, + { + {LBAGG_TYPE_MIN, "min" }, + {LBAGG_TYPE_MAX, "max" }, + {LBAGG_TYPE_SUM, "sum" }, + {LBAGG_TYPE_LAST, "last"}, + }); + + class JsonColumnDef + { + public: + std::string name; + int id; + int propertyId; + bool hidden; + std::string statName; + LbColType type; + int precision; + LbAggType agg; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonColumnDef, name, id, propertyId, hidden, statName, type, precision, agg); + + class JsonLeaderboardDef + { + public: + int id; + std::optional xpColId; + std::optional prestigeColId; + std::vector columns; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonLeaderboardDef, id, xpColId, prestigeColId, columns); +} // namespace IW4 diff --git a/src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h b/src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h new file mode 100644 index 00000000..944b0e2e --- /dev/null +++ b/src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h @@ -0,0 +1,82 @@ +#pragma once + +#include "Game/IW5/IW5.h" + +#include "Json/JsonCommon.h" +#include "Json/JsonExtension.h" +#include +#include +#include +#include +#include + +namespace IW5 +{ + NLOHMANN_JSON_SERIALIZE_ENUM(LbColType, + { + {LBCOL_TYPE_NUMBER, "number" }, + {LBCOL_TYPE_TIME, "time" }, + {LBCOL_TYPE_LEVELXP, "levelxp" }, + {LBCOL_TYPE_PRESTIGE, "prestige" }, + {LBCOL_TYPE_BIGNUMBER, "bignumber"}, + {LBCOL_TYPE_PERCENT, "percent" }, + {LBCOL_TYPE_TIME_FULL, "time_full"}, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(LbAggType, + { + {LBAGG_TYPE_MIN, "min" }, + {LBAGG_TYPE_MAX, "max" }, + {LBAGG_TYPE_SUM, "sum" }, + {LBAGG_TYPE_LAST, "last"}, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(LbUpdateType, + { + {LBUPDATE_TYPE_NORMAL, "normal" }, + {LBUPDATE_TYPE_RANK, "rank" }, + {LBUPDATE_TYPE_COMBINE, "combine"}, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(LbTrackType, + { + {TRK_ALLTIME, "ALLTIME" }, + {TRK_WEEKLY, "WEEKLY" }, + {TRK_MONTHLY, "MONTHLY" }, + {TRK_PRESTIGE_ALLTIME, "PRESTIGE_ALLTIME"}, + {TRK_PRESTIGE_WEEKLY, "PRESTIGE_WEEKLY" }, + {TRK_PRESTIGE_MONTHLY, "PRESTIGE_MONTHLY"}, + {TRK_DAILY, "DAILY" }, + {TRK_PRESTIGE_DAILY, "PRESTIGE_DAILY" }, + }); + + class JsonColumnDef + { + public: + std::string name; + int id; + int propertyId; + bool hidden; + std::string statName; + LbColType type; + int precision; + LbAggType agg; + int uiCalColX; + int uiCalColY; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonColumnDef, name, id, propertyId, hidden, statName, type, precision, agg, uiCalColX, uiCalColY); + + class JsonLeaderboardDef + { + public: + int id; + std::optional xpColId; + std::optional prestigeColId; + std::vector columns; + LbUpdateType updateType; + std::vector trackTypes; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonLeaderboardDef, id, xpColId, prestigeColId, columns, updateType, trackTypes); +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp new file mode 100644 index 00000000..d5bb3905 --- /dev/null +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp @@ -0,0 +1,29 @@ +#include "AssetDumperLeaderboardDef.h" + +#include "Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.h" + +#include +#include + +using namespace IW4; + +std::string AssetDumperLeaderboardDef::GetFileNameForAsset(const std::string& assetName) +{ + + return std::format("leaderboards/{}.json", assetName); +} + +bool AssetDumperLeaderboardDef::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +void AssetDumperLeaderboardDef::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) +{ + const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name)); + + if (!assetFile) + return; + + DumpLeaderboardDefAsJson(*assetFile, asset->Asset()); +} diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.h b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.h new file mode 100644 index 00000000..00b9c2c0 --- /dev/null +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW4/IW4.h" + +namespace IW4 +{ + class AssetDumperLeaderboardDef final : public AbstractAssetDumper + { + static std::string GetFileNameForAsset(const std::string& assetName); + + protected: + _NODISCARD bool ShouldDump(XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + }; +} // namespace IW4 diff --git a/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp b/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp new file mode 100644 index 00000000..b556b058 --- /dev/null +++ b/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp @@ -0,0 +1,70 @@ +#include "JsonLeaderboardDefWriter.h" + +#include "Game/IW4/CommonIW4.h" +#include "Game/IW4/Json/JsonLeaderboardDef.h" + +#include +#include + +using namespace nlohmann; +using namespace IW4; + +namespace +{ + class JsonDumper + { + public: + explicit JsonDumper(std::ostream& stream) + : m_stream(stream) + { + } + + void Dump(const LeaderboardDef* leaderboardDef) + { + JsonLeaderboardDef jsonLeaderboardDef; + CreateJsonLeaderboardDef(jsonLeaderboardDef, *leaderboardDef); + + json jRoot = jsonLeaderboardDef; + + jRoot["_type"] = "leaderboard"; + jRoot["_version"] = 1; + + m_stream << std::setw(4) << jRoot << "\n"; + } + + private: + static void CreateJsonColumnDef(JsonColumnDef& jColumnDef, const LbColumnDef& lbColumnDef) + { + jColumnDef.name = lbColumnDef.name; + jColumnDef.id = lbColumnDef.id; + jColumnDef.propertyId = lbColumnDef.propertyId; + jColumnDef.hidden = lbColumnDef.hidden; + jColumnDef.statName = lbColumnDef.statName; + jColumnDef.type = lbColumnDef.type; + jColumnDef.precision = lbColumnDef.precision; + jColumnDef.agg = lbColumnDef.agg; + } + + static void CreateJsonLeaderboardDef(JsonLeaderboardDef& jLeaderboardDef, const LeaderboardDef& leaderboardDef) + { + jLeaderboardDef.id = leaderboardDef.id; + jLeaderboardDef.xpColId = (leaderboardDef.xpColId < 0) ? std::nullopt : std::make_optional(leaderboardDef.xpColId); + jLeaderboardDef.prestigeColId = (leaderboardDef.prestigeColId < 0) ? std::nullopt : std::make_optional(leaderboardDef.prestigeColId); + + jLeaderboardDef.columns.resize(leaderboardDef.columnCount); + for (auto i = 0; i < leaderboardDef.columnCount; ++i) + CreateJsonColumnDef(jLeaderboardDef.columns[i], leaderboardDef.columns[i]); + } + + std::ostream& m_stream; + }; +} // namespace + +namespace IW4 +{ + void DumpLeaderboardDefAsJson(std::ostream& stream, const LeaderboardDef* leaderboardDef) + { + JsonDumper dumper(stream); + dumper.Dump(leaderboardDef); + } +} // namespace IW4 diff --git a/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.h b/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.h new file mode 100644 index 00000000..a1b4546d --- /dev/null +++ b/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Dumping/AssetDumpingContext.h" +#include "Game/IW4/IW4.h" + +#include + +namespace IW4 +{ + void DumpLeaderboardDefAsJson(std::ostream& stream, const LeaderboardDef* leaderboardDef); +} // namespace IW4 diff --git a/src/ObjWriting/Game/IW4/ZoneDumperIW4.cpp b/src/ObjWriting/Game/IW4/ZoneDumperIW4.cpp index b77684d7..94aa8787 100644 --- a/src/ObjWriting/Game/IW4/ZoneDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/ZoneDumperIW4.cpp @@ -3,6 +3,7 @@ #include "AssetDumpers/AssetDumperAddonMapEnts.h" #include "AssetDumpers/AssetDumperGfxImage.h" #include "AssetDumpers/AssetDumperGfxLightDef.h" +#include "AssetDumpers/AssetDumperLeaderboardDef.h" #include "AssetDumpers/AssetDumperLoadedSound.h" #include "AssetDumpers/AssetDumperLocalizeEntry.h" #include "AssetDumpers/AssetDumperMaterial.h" @@ -73,7 +74,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) DUMP_ASSET_POOL(AssetDumperRawFile, m_raw_file, ASSET_TYPE_RAWFILE) DUMP_ASSET_POOL(AssetDumperStringTable, m_string_table, ASSET_TYPE_STRINGTABLE) - // DUMP_ASSET_POOL(AssetDumperLeaderboardDef, m_leaderboard, ASSET_TYPE_LEADERBOARD) + DUMP_ASSET_POOL(AssetDumperLeaderboardDef, m_leaderboard, ASSET_TYPE_LEADERBOARD) DUMP_ASSET_POOL(AssetDumperStructuredDataDefSet, m_structed_data_def_set, ASSET_TYPE_STRUCTURED_DATA_DEF) DUMP_ASSET_POOL(AssetDumperTracer, m_tracer, ASSET_TYPE_TRACER) DUMP_ASSET_POOL(AssetDumperVehicle, m_vehicle, ASSET_TYPE_VEHICLE) diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp new file mode 100644 index 00000000..e4ec8c03 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp @@ -0,0 +1,29 @@ +#include "AssetDumperLeaderboardDef.h" + +#include "Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.h" + +#include +#include + +using namespace IW5; + +std::string AssetDumperLeaderboardDef::GetFileNameForAsset(const std::string& assetName) +{ + + return std::format("leaderboards/{}.json", assetName); +} + +bool AssetDumperLeaderboardDef::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +void AssetDumperLeaderboardDef::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) +{ + const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name)); + + if (!assetFile) + return; + + DumpLeaderboardDefAsJson(*assetFile, asset->Asset()); +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.h new file mode 100644 index 00000000..fad9cb5e --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class AssetDumperLeaderboardDef final : public AbstractAssetDumper + { + static std::string GetFileNameForAsset(const std::string& assetName); + + protected: + _NODISCARD bool ShouldDump(XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + }; +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp b/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp new file mode 100644 index 00000000..3146a3b9 --- /dev/null +++ b/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp @@ -0,0 +1,82 @@ +#include "JsonLeaderboardDefWriter.h" + +#include "Game/IW5/CommonIW5.h" +#include "Game/IW5/Json/JsonLeaderboardDef.h" + +#include +#include + +using namespace nlohmann; +using namespace IW5; + +namespace +{ + class JsonDumper + { + public: + explicit JsonDumper(std::ostream& stream) + : m_stream(stream) + { + } + + void Dump(const LeaderboardDef* leaderboardDef) + { + JsonLeaderboardDef jsonLeaderboardDef; + CreateJsonLeaderboardDef(jsonLeaderboardDef, *leaderboardDef); + + json jRoot = jsonLeaderboardDef; + + jRoot["_type"] = "leaderboard"; + jRoot["_version"] = 1; + + m_stream << std::setw(4) << jRoot << "\n"; + } + + private: + static void CreateJsonColumnDef(JsonColumnDef& jColumnDef, const LbColumnDef& lbColumnDef) + { + jColumnDef.name = lbColumnDef.name; + jColumnDef.id = lbColumnDef.id; + jColumnDef.propertyId = lbColumnDef.propertyId; + jColumnDef.hidden = lbColumnDef.hidden; + jColumnDef.statName = lbColumnDef.statName; + jColumnDef.type = lbColumnDef.type; + jColumnDef.precision = lbColumnDef.precision; + jColumnDef.agg = lbColumnDef.agg; + jColumnDef.uiCalColX = lbColumnDef.uiCalColX; + jColumnDef.uiCalColY = lbColumnDef.uiCalColY; + } + + static void CreateJsonLeaderboardDef(JsonLeaderboardDef& jLeaderboardDef, const LeaderboardDef& leaderboardDef) + { + jLeaderboardDef.id = leaderboardDef.id; + jLeaderboardDef.xpColId = (leaderboardDef.xpColId < 0) ? std::nullopt : std::make_optional(leaderboardDef.xpColId); + jLeaderboardDef.prestigeColId = (leaderboardDef.prestigeColId < 0) ? std::nullopt : std::make_optional(leaderboardDef.prestigeColId); + + jLeaderboardDef.columns.resize(leaderboardDef.columnCount); + for (auto i = 0; i < leaderboardDef.columnCount; ++i) + CreateJsonColumnDef(jLeaderboardDef.columns[i], leaderboardDef.columns[i]); + + jLeaderboardDef.updateType = leaderboardDef.updateType; + + for (auto i = 0; i < LbTrackType::TRK_COUNT; ++i) + { + if ((leaderboardDef.trackTypes & (1 << i)) != 0) + { + jLeaderboardDef.trackTypes.emplace_back(static_cast(i)); + } + } + } + + std::ostream& m_stream; + }; +} // namespace + +namespace IW5 +{ + void DumpLeaderboardDefAsJson(std::ostream& stream, const LeaderboardDef* leaderboardDef) + { + JsonDumper dumper(stream); + dumper.Dump(leaderboardDef); + } +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.h b/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.h new file mode 100644 index 00000000..b992e6b2 --- /dev/null +++ b/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Dumping/AssetDumpingContext.h" +#include "Game/IW5/IW5.h" + +#include + +namespace IW5 +{ + void DumpLeaderboardDefAsJson(std::ostream& stream, const LeaderboardDef* leaderboardDef); +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp index b3cc16d3..ea18d89c 100644 --- a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp @@ -2,6 +2,7 @@ #include "AssetDumpers/AssetDumperAddonMapEnts.h" #include "AssetDumpers/AssetDumperGfxImage.h" +#include "AssetDumpers/AssetDumperLeaderboardDef.h" #include "AssetDumpers/AssetDumperLoadedSound.h" #include "AssetDumpers/AssetDumperLocalizeEntry.h" #include "AssetDumpers/AssetDumperMenuDef.h" @@ -68,7 +69,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const DUMP_ASSET_POOL(AssetDumperRawFile, m_raw_file, ASSET_TYPE_RAWFILE) DUMP_ASSET_POOL(AssetDumperScriptFile, m_script_file, ASSET_TYPE_SCRIPTFILE) DUMP_ASSET_POOL(AssetDumperStringTable, m_string_table, ASSET_TYPE_STRINGTABLE) - // DUMP_ASSET_POOL(AssetDumperLeaderboardDef, m_leaderboard, ASSET_TYPE_LEADERBOARD) + DUMP_ASSET_POOL(AssetDumperLeaderboardDef, m_leaderboard, ASSET_TYPE_LEADERBOARD) // DUMP_ASSET_POOL(AssetDumperStructuredDataDefSet, m_structed_data_def_set, ASSET_TYPE_STRUCTURED_DATA_DEF) // DUMP_ASSET_POOL(AssetDumperTracerDef, m_tracer, ASSET_TYPE_TRACER) // DUMP_ASSET_POOL(AssetDumperVehicleDef, m_vehicle, ASSET_TYPE_VEHICLE) From 489e4d033e2872dfdb7b106ead0f3735cec16ae0 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 19 May 2024 11:38:20 +0200 Subject: [PATCH 2/4] chore: only dump leaderboard values when they are relevant for the column --- .../Game/IW4/Json/JsonLeaderboardDef.h | 4 +- .../Game/IW5/Json/JsonLeaderboardDef.h | 16 +++---- .../JsonLeaderboardDefWriter.cpp | 29 ++++++++---- .../JsonLeaderboardDefWriter.cpp | 45 +++++++++++++------ 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h b/src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h index e1924223..b4ba09ef 100644 --- a/src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h +++ b/src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h @@ -40,10 +40,10 @@ namespace IW4 std::string statName; LbColType type; int precision; - LbAggType agg; + LbAggType aggregationFunction; }; - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonColumnDef, name, id, propertyId, hidden, statName, type, precision, agg); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonColumnDef, name, id, propertyId, hidden, statName, type, precision, aggregationFunction); class JsonLeaderboardDef { diff --git a/src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h b/src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h index 944b0e2e..8b3c6687 100644 --- a/src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h +++ b/src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h @@ -55,17 +55,17 @@ namespace IW5 public: std::string name; int id; - int propertyId; - bool hidden; - std::string statName; + std::optional propertyId; + std::optional hidden; + std::optional statName; LbColType type; - int precision; - LbAggType agg; - int uiCalColX; - int uiCalColY; + std::optional precision; + LbAggType aggregationFunction; + std::optional uiCalColX; + std::optional uiCalColY; }; - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonColumnDef, name, id, propertyId, hidden, statName, type, precision, agg, uiCalColX, uiCalColY); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonColumnDef, name, id, propertyId, hidden, statName, type, precision, aggregationFunction, uiCalColX, uiCalColY); class JsonLeaderboardDef { diff --git a/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp b/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp index b556b058..c4be851e 100644 --- a/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp +++ b/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp @@ -19,7 +19,7 @@ namespace { } - void Dump(const LeaderboardDef* leaderboardDef) + void Dump(const LeaderboardDef* leaderboardDef) const { JsonLeaderboardDef jsonLeaderboardDef; CreateJsonLeaderboardDef(jsonLeaderboardDef, *leaderboardDef); @@ -37,19 +37,32 @@ namespace { jColumnDef.name = lbColumnDef.name; jColumnDef.id = lbColumnDef.id; - jColumnDef.propertyId = lbColumnDef.propertyId; - jColumnDef.hidden = lbColumnDef.hidden; - jColumnDef.statName = lbColumnDef.statName; + + if (lbColumnDef.propertyId != 0) + jColumnDef.propertyId = lbColumnDef.propertyId; + + if (lbColumnDef.hidden) + jColumnDef.hidden = lbColumnDef.hidden; + + if (lbColumnDef.statName && lbColumnDef.statName[0]) + jColumnDef.statName = lbColumnDef.statName; + jColumnDef.type = lbColumnDef.type; - jColumnDef.precision = lbColumnDef.precision; - jColumnDef.agg = lbColumnDef.agg; + + if (lbColumnDef.precision != 0) + jColumnDef.precision = lbColumnDef.precision; + + jColumnDef.aggregationFunction = lbColumnDef.agg; } static void CreateJsonLeaderboardDef(JsonLeaderboardDef& jLeaderboardDef, const LeaderboardDef& leaderboardDef) { jLeaderboardDef.id = leaderboardDef.id; - jLeaderboardDef.xpColId = (leaderboardDef.xpColId < 0) ? std::nullopt : std::make_optional(leaderboardDef.xpColId); - jLeaderboardDef.prestigeColId = (leaderboardDef.prestigeColId < 0) ? std::nullopt : std::make_optional(leaderboardDef.prestigeColId); + + if (leaderboardDef.xpColId != 0) + jLeaderboardDef.xpColId = leaderboardDef.xpColId; + if (leaderboardDef.prestigeColId != 0) + jLeaderboardDef.prestigeColId = leaderboardDef.prestigeColId; jLeaderboardDef.columns.resize(leaderboardDef.columnCount); for (auto i = 0; i < leaderboardDef.columnCount; ++i) diff --git a/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp b/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp index 3146a3b9..250ca39d 100644 --- a/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp +++ b/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp @@ -19,7 +19,7 @@ namespace { } - void Dump(const LeaderboardDef* leaderboardDef) + void Dump(const LeaderboardDef* leaderboardDef) const { JsonLeaderboardDef jsonLeaderboardDef; CreateJsonLeaderboardDef(jsonLeaderboardDef, *leaderboardDef); @@ -37,21 +37,38 @@ namespace { jColumnDef.name = lbColumnDef.name; jColumnDef.id = lbColumnDef.id; - jColumnDef.propertyId = lbColumnDef.propertyId; - jColumnDef.hidden = lbColumnDef.hidden; - jColumnDef.statName = lbColumnDef.statName; + + if (lbColumnDef.propertyId != 0) + jColumnDef.propertyId = lbColumnDef.propertyId; + + if (lbColumnDef.hidden) + jColumnDef.hidden = lbColumnDef.hidden; + + if (lbColumnDef.statName && lbColumnDef.statName[0]) + jColumnDef.statName = lbColumnDef.statName; + jColumnDef.type = lbColumnDef.type; - jColumnDef.precision = lbColumnDef.precision; - jColumnDef.agg = lbColumnDef.agg; - jColumnDef.uiCalColX = lbColumnDef.uiCalColX; - jColumnDef.uiCalColY = lbColumnDef.uiCalColY; + + if (lbColumnDef.precision != 0) + jColumnDef.precision = lbColumnDef.precision; + + jColumnDef.aggregationFunction = lbColumnDef.agg; + + if (lbColumnDef.uiCalColX != 0 || lbColumnDef.uiCalColY != 0) + { + jColumnDef.uiCalColX = lbColumnDef.uiCalColX; + jColumnDef.uiCalColY = lbColumnDef.uiCalColY; + } } static void CreateJsonLeaderboardDef(JsonLeaderboardDef& jLeaderboardDef, const LeaderboardDef& leaderboardDef) { jLeaderboardDef.id = leaderboardDef.id; - jLeaderboardDef.xpColId = (leaderboardDef.xpColId < 0) ? std::nullopt : std::make_optional(leaderboardDef.xpColId); - jLeaderboardDef.prestigeColId = (leaderboardDef.prestigeColId < 0) ? std::nullopt : std::make_optional(leaderboardDef.prestigeColId); + + if (leaderboardDef.xpColId != 0) + jLeaderboardDef.xpColId = leaderboardDef.xpColId; + if (leaderboardDef.prestigeColId != 0) + jLeaderboardDef.prestigeColId = leaderboardDef.prestigeColId; jLeaderboardDef.columns.resize(leaderboardDef.columnCount); for (auto i = 0; i < leaderboardDef.columnCount; ++i) @@ -59,12 +76,12 @@ namespace jLeaderboardDef.updateType = leaderboardDef.updateType; - for (auto i = 0; i < LbTrackType::TRK_COUNT; ++i) + for (auto i = 0; i < TRK_COUNT; ++i) { - if ((leaderboardDef.trackTypes & (1 << i)) != 0) - { + const auto trackTypeMask = 1 << i; + + if (leaderboardDef.trackTypes & trackTypeMask) jLeaderboardDef.trackTypes.emplace_back(static_cast(i)); - } } } From dc090c137103431791b7ff83e8f97da6c8d03dc8 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 19 May 2024 11:52:29 +0200 Subject: [PATCH 3/4] chore: update count properties of leaderboard enums --- src/Common/Game/IW4/IW4_Assets.h | 6 ++++-- src/Common/Game/IW5/IW5_Assets.h | 16 +++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Common/Game/IW4/IW4_Assets.h b/src/Common/Game/IW4/IW4_Assets.h index 7f606455..ca60a53a 100644 --- a/src/Common/Game/IW4/IW4_Assets.h +++ b/src/Common/Game/IW4/IW4_Assets.h @@ -2549,7 +2549,8 @@ namespace IW4 LBCOL_TYPE_PRESTIGE = 0x3, LBCOL_TYPE_BIGNUMBER = 0x4, LBCOL_TYPE_PERCENT = 0x5, - LBCOL_TYPE_COUNT = 0x6, + + LBCOL_TYPE_COUNT }; enum LbAggType @@ -2558,7 +2559,8 @@ namespace IW4 LBAGG_TYPE_MAX = 0x1, LBAGG_TYPE_SUM = 0x2, LBAGG_TYPE_LAST = 0x3, - LBAGG_TYPE_COUNT = 0x4, + + LBAGG_TYPE_COUNT }; struct LbColumnDef diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index de4ca847..fea3e995 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -4346,7 +4346,8 @@ namespace IW5 LBCOL_TYPE_BIGNUMBER = 0x4, LBCOL_TYPE_PERCENT = 0x5, LBCOL_TYPE_TIME_FULL = 0x6, - LBCOL_TYPE_COUNT = 0x7 + + LBCOL_TYPE_COUNT }; enum LbAggType @@ -4355,7 +4356,8 @@ namespace IW5 LBAGG_TYPE_MAX = 0x1, LBAGG_TYPE_SUM = 0x2, LBAGG_TYPE_LAST = 0x3, - LBAGG_TYPE_COUNT = 0x4 + + LBAGG_TYPE_COUNT }; struct LbColumnDef @@ -4377,7 +4379,8 @@ namespace IW5 LBUPDATE_TYPE_NORMAL = 0x0, LBUPDATE_TYPE_RANK = 0x1, LBUPDATE_TYPE_COMBINE = 0x2, - LBUPDATE_TYPE_COUNT = 0x3 + + LBUPDATE_TYPE_COUNT }; enum LbTrackType @@ -4390,6 +4393,7 @@ namespace IW5 TRK_PRESTIGE_MONTHLY = 0x5, TRK_DAILY = 0x6, TRK_PRESTIGE_DAILY = 0x7, + TRK_COUNT }; @@ -4430,7 +4434,8 @@ namespace IW5 DATA_ENUM_ARRAY = 0x7, DATA_FLOAT = 0x8, DATA_SHORT = 0x9, - DATA_COUNT = 0xA + + DATA_COUNT }; union StructuredDataTypeUnion @@ -4457,7 +4462,8 @@ namespace IW5 VALIDATION_DELTACLAMP = 0x4, VALIDATION_DELTASTRICT = 0x5, VALIDATION_XP = 0x6, - VALIDATION_COUNT = 0x7 + + VALIDATION_COUNT }; struct StructuredDataStructProperty From 0c0103c99809d2a4db49021436dbbd18f0a84713 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 19 May 2024 12:09:26 +0200 Subject: [PATCH 4/4] chore: rename leaderboardDef folder to leaderboard --- .../Game/IW4/{Json => Leaderboard}/JsonLeaderboardDef.h | 0 .../Game/IW5/{Json => Leaderboard}/JsonLeaderboardDef.h | 0 .../Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp | 2 +- .../JsonLeaderboardDefWriter.cpp | 2 +- .../{LeaderboardDef => Leaderboard}/JsonLeaderboardDefWriter.h | 0 .../Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp | 2 +- .../JsonLeaderboardDefWriter.cpp | 2 +- .../{LeaderboardDef => Leaderboard}/JsonLeaderboardDefWriter.h | 0 8 files changed, 4 insertions(+), 4 deletions(-) rename src/ObjCommon/Game/IW4/{Json => Leaderboard}/JsonLeaderboardDef.h (100%) rename src/ObjCommon/Game/IW5/{Json => Leaderboard}/JsonLeaderboardDef.h (100%) rename src/ObjWriting/Game/IW4/{LeaderboardDef => Leaderboard}/JsonLeaderboardDefWriter.cpp (97%) rename src/ObjWriting/Game/IW4/{LeaderboardDef => Leaderboard}/JsonLeaderboardDefWriter.h (100%) rename src/ObjWriting/Game/IW5/{LeaderboardDef => Leaderboard}/JsonLeaderboardDefWriter.cpp (98%) rename src/ObjWriting/Game/IW5/{LeaderboardDef => Leaderboard}/JsonLeaderboardDefWriter.h (100%) diff --git a/src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h b/src/ObjCommon/Game/IW4/Leaderboard/JsonLeaderboardDef.h similarity index 100% rename from src/ObjCommon/Game/IW4/Json/JsonLeaderboardDef.h rename to src/ObjCommon/Game/IW4/Leaderboard/JsonLeaderboardDef.h diff --git a/src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h b/src/ObjCommon/Game/IW5/Leaderboard/JsonLeaderboardDef.h similarity index 100% rename from src/ObjCommon/Game/IW5/Json/JsonLeaderboardDef.h rename to src/ObjCommon/Game/IW5/Leaderboard/JsonLeaderboardDef.h diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp index d5bb3905..8e2f5ee7 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLeaderboardDef.cpp @@ -1,6 +1,6 @@ #include "AssetDumperLeaderboardDef.h" -#include "Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.h" +#include "Game/IW4/Leaderboard/JsonLeaderboardDefWriter.h" #include #include diff --git a/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp b/src/ObjWriting/Game/IW4/Leaderboard/JsonLeaderboardDefWriter.cpp similarity index 97% rename from src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp rename to src/ObjWriting/Game/IW4/Leaderboard/JsonLeaderboardDefWriter.cpp index c4be851e..c6daa2d4 100644 --- a/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.cpp +++ b/src/ObjWriting/Game/IW4/Leaderboard/JsonLeaderboardDefWriter.cpp @@ -1,7 +1,7 @@ #include "JsonLeaderboardDefWriter.h" #include "Game/IW4/CommonIW4.h" -#include "Game/IW4/Json/JsonLeaderboardDef.h" +#include "Game/IW4/Leaderboard/JsonLeaderboardDef.h" #include #include diff --git a/src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.h b/src/ObjWriting/Game/IW4/Leaderboard/JsonLeaderboardDefWriter.h similarity index 100% rename from src/ObjWriting/Game/IW4/LeaderboardDef/JsonLeaderboardDefWriter.h rename to src/ObjWriting/Game/IW4/Leaderboard/JsonLeaderboardDefWriter.h diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp index e4ec8c03..6587432b 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLeaderboardDef.cpp @@ -1,6 +1,6 @@ #include "AssetDumperLeaderboardDef.h" -#include "Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.h" +#include "Game/IW5/Leaderboard/JsonLeaderboardDefWriter.h" #include #include diff --git a/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp b/src/ObjWriting/Game/IW5/Leaderboard/JsonLeaderboardDefWriter.cpp similarity index 98% rename from src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp rename to src/ObjWriting/Game/IW5/Leaderboard/JsonLeaderboardDefWriter.cpp index 250ca39d..51fd5703 100644 --- a/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.cpp +++ b/src/ObjWriting/Game/IW5/Leaderboard/JsonLeaderboardDefWriter.cpp @@ -1,7 +1,7 @@ #include "JsonLeaderboardDefWriter.h" #include "Game/IW5/CommonIW5.h" -#include "Game/IW5/Json/JsonLeaderboardDef.h" +#include "Game/IW5/Leaderboard/JsonLeaderboardDef.h" #include #include diff --git a/src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.h b/src/ObjWriting/Game/IW5/Leaderboard/JsonLeaderboardDefWriter.h similarity index 100% rename from src/ObjWriting/Game/IW5/LeaderboardDef/JsonLeaderboardDefWriter.h rename to src/ObjWriting/Game/IW5/Leaderboard/JsonLeaderboardDefWriter.h