From 8be1dd54bb17b3ba3e20960aa3c3f696d09facf7 Mon Sep 17 00:00:00 2001 From: nshah25 <68348722+nshah25@users.noreply.github.com> Date: Mon, 3 May 2021 16:07:09 -0400 Subject: [PATCH] Add player statistics to API (#5193) * Fixed issue #5166 Co-authored-by: 12xx12 <44411062+12xx12@users.noreply.github.com> Co-authored-by: Tiger Wang --- CMake/GenerateBindings.cmake | 1 + Server/Plugins/APIDump/APIDesc.lua | 419 +++++++++++++++++++-- Server/Plugins/APIDump/main_APIDump.lua | 12 +- src/Bindings/AllToLua.pkg | 2 + src/Bindings/LuaState.cpp | 15 + src/Bindings/LuaState.h | 2 + src/Bindings/ManualBindings.cpp | 69 ++++ src/BlockEntities/BeaconEntity.cpp | 4 +- src/BlockEntities/BrewingstandEntity.cpp | 2 +- src/BlockEntities/ChestEntity.cpp | 4 +- src/BlockEntities/DropSpenserEntity.cpp | 4 +- src/BlockEntities/EnderChestEntity.cpp | 2 +- src/BlockEntities/FlowerPotEntity.cpp | 2 +- src/BlockEntities/FurnaceEntity.cpp | 2 +- src/BlockEntities/HopperEntity.cpp | 2 +- src/BlockEntities/JukeboxEntity.cpp | 3 +- src/BlockEntities/NoteEntity.cpp | 2 +- src/Blocks/BlockBed.cpp | 2 +- src/Blocks/BlockCake.h | 2 +- src/Blocks/BlockCauldron.h | 4 +- src/Blocks/BlockWorkbench.h | 2 +- src/ClientHandle.cpp | 4 +- src/ClientHandle.h | 6 +- src/Entities/Entity.cpp | 2 +- src/Entities/Pickup.cpp | 8 +- src/Entities/Player.cpp | 68 ++-- src/Entities/Player.h | 10 +- src/Items/ItemFishingRod.h | 6 +- src/Items/ItemMobHead.h | 2 +- src/Mobs/Monster.cpp | 4 +- src/Mobs/Wither.cpp | 2 +- src/Protocol/Palettes/Palette_1_13.cpp | 106 +++--- src/Protocol/Palettes/Palette_1_13.h | 2 +- src/Protocol/Palettes/Palette_1_13_1.cpp | 118 +++--- src/Protocol/Palettes/Palette_1_13_1.h | 2 +- src/Protocol/Palettes/Palette_1_14.cpp | 140 +++---- src/Protocol/Palettes/Palette_1_14.h | 2 +- src/Protocol/Palettes/Palette_1_15.cpp | 144 ++++---- src/Protocol/Palettes/Palette_1_15.h | 2 +- src/Protocol/Palettes/Palette_1_16.cpp | 150 ++++---- src/Protocol/Palettes/Palette_1_16.h | 2 +- src/Protocol/Protocol.h | 5 +- src/Protocol/Protocol_1_13.cpp | 49 ++- src/Protocol/Protocol_1_13.h | 6 +- src/Protocol/Protocol_1_14.cpp | 2 +- src/Protocol/Protocol_1_14.h | 2 +- src/Protocol/Protocol_1_8.cpp | 199 +++++----- src/Protocol/Protocol_1_8.h | 4 +- src/Registries/Statistics.h | 8 +- src/Statistics.cpp | 92 ++--- src/Statistics.h | 26 +- src/UI/SlotArea.cpp | 26 +- src/WorldStorage/NamespaceSerializer.cpp | 442 +++++++++++------------ src/WorldStorage/NamespaceSerializer.h | 4 +- src/WorldStorage/StatSerializer.cpp | 201 +++++------ src/WorldStorage/StatSerializer.h | 7 +- 56 files changed, 1408 insertions(+), 1002 deletions(-) diff --git a/CMake/GenerateBindings.cmake b/CMake/GenerateBindings.cmake index 6d702a778..924202f21 100644 --- a/CMake/GenerateBindings.cmake +++ b/CMake/GenerateBindings.cmake @@ -79,6 +79,7 @@ function(enable_bindings_generation) Mobs/MonsterTypes.h OSSupport/File.h Protocol/MojangAPI.h + Registries/Statistics.h Root.h Scoreboard.h Server.h diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua index 888ce9aef..0e616a35c 100644 --- a/Server/Plugins/APIDump/APIDesc.lua +++ b/Server/Plugins/APIDump/APIDesc.lua @@ -10245,36 +10245,6 @@ a_Player:OpenWindow(Window); }, Notes = "Returns the full color code to be used for this player's messages (based on their rank). Prefix player messages with this code.", }, - GetDraggingItem = - { - Returns = - { - { - Type = "cItem", - }, - }, - Notes = "Returns the item the player is dragging in a UI window." - }, - GetPrefix = - { - Returns = - { - { - Type = "string", - }, - }, - Notes = "Returns the prefix to player names for messages (based on their rank), may contain @ format codes.", - }, - GetSuffix = - { - Returns = - { - { - Type = "string", - }, - }, - Notes = "Returns the suffix to player names for messages (based on their rank), may contain @ format codes.", - }, GetCurrentXp = { Returns = @@ -10295,6 +10265,16 @@ a_Player:OpenWindow(Window); }, Notes = "Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string.", }, + GetDraggingItem = + { + Returns = + { + { + Type = "cItem", + }, + }, + Notes = "Returns the item the player is dragging in a UI window." + }, GetEffectiveGameMode = { Returns = @@ -10489,6 +10469,16 @@ a_Player:OpenWindow(Window); }, Notes = "Returns the name that is used in the playerlist.", }, + GetPrefix = + { + Returns = + { + { + Type = "string", + }, + }, + Notes = "Returns the prefix to player names for messages (based on their rank), may contain @ format codes.", + }, GetRestrictions = { Returns = @@ -10519,6 +10509,26 @@ a_Player:OpenWindow(Window); }, Notes = "Returns the player's current set of skin part flags. This is a bitwise OR of various {{Globals#eSkinPart|eSkinPart}} constants. Note that HasSkinPart may be easier to use in most situations.", }, + GetStatistics = + { + Returns = + { + { + Type = "StatisticsManager", + }, + }, + Notes = "Returns the player's statistics manager." + }, + GetSuffix = + { + Returns = + { + { + Type = "string", + }, + }, + Notes = "Returns the suffix to player names for messages (based on their rank), may contain @ format codes.", + }, GetTeam = { Returns = @@ -13219,7 +13229,41 @@ end Include = { "wt.*" }, } }, -- ConstantGroups - }, -- cWindow + }, + StatisticsManager = + { + Desc = [[ + This class provides a store for various types of player statistics. The store will be read and sent to the client when the Statistics button is pressed. + ]], + Variables = + { + Custom = + { + Type = "Map of {{CustomStatistic}} to number", + Notes = "Gets or sets the value of a custom statistic.", + }, + }, + AdditionalInfo = + { + { + Header = "Example usage", + Contents = [[ + Each store is a table, keyed by the statistic that the entry tracks, with value typically representing the number of times the event happened: +
+function ModifyPlayerFurnaceInteractions(Player)
+	local Statistics = Player:GetStatistics()
+
+	if (Statistics.Custom[CustomStatistic.WalkOneCm] > 10) then
+		Statistics.Custom[CustomStatistic.InteractWithFurnace] = 1337
+	end
+
+	-- Next time the player presses Statistics they will see the updated value for furnace interactions.
+end
+
+ ]], + }, + }, + }, BannerPattern = { @@ -13700,6 +13744,319 @@ end }, } }, + CustomStatistic = + { + Desc = [[ + An enumeration of statistics of the custom type to be used with the {{StatisticsManager#Custom|Custom}} statistics store. + ]], + Constants = + { + AnimalsBred = + { + Notes = "", + }, + AviateOneCm = + { + Notes = "", + }, + BellRing = + { + Notes = "", + }, + BoatOneCm = + { + Notes = "", + }, + CleanArmor = + { + Notes = "", + }, + CleanBanner = + { + Notes = "", + }, + CleanShulkerBox = + { + Notes = "", + }, + ClimbOneCm = + { + Notes = "", + }, + CrouchOneCm = + { + Notes = "", + }, + DamageAbsorbed = + { + Notes = "", + }, + DamageBlockedByShield = + { + Notes = "", + }, + DamageDealt = + { + Notes = "", + }, + DamageDealtAbsorbed = + { + Notes = "", + }, + DamageDealtResisted = + { + Notes = "", + }, + DamageResisted = + { + Notes = "", + }, + DamageTaken = + { + Notes = "", + }, + Deaths = + { + Notes = "", + }, + Drop = + { + Notes = "", + }, + EatCakeSlice = + { + Notes = "", + }, + EnchantItem = + { + Notes = "", + }, + FallOneCm = + { + Notes = "", + }, + FillCauldron = + { + Notes = "", + }, + FishCaught = + { + Notes = "", + }, + FlyOneCm = + { + Notes = "", + }, + HorseOneCm = + { + Notes = "", + }, + InspectDispenser = + { + Notes = "", + }, + InspectDropper = + { + Notes = "", + }, + InspectHopper = + { + Notes = "", + }, + InteractWithAnvil = + { + Notes = "", + }, + InteractWithBeacon = + { + Notes = "", + }, + InteractWithBlastFurnace = + { + Notes = "", + }, + InteractWithBrewingstand = + { + Notes = "", + }, + InteractWithCampfire = + { + Notes = "", + }, + InteractWithCartographyTable = + { + Notes = "", + }, + InteractWithCraftingTable = + { + Notes = "", + }, + InteractWithFurnace = + { + Notes = "", + }, + InteractWithGrindstone = + { + Notes = "", + }, + InteractWithLectern = + { + Notes = "", + }, + InteractWithLoom = + { + Notes = "", + }, + InteractWithSmithingTable = + { + Notes = "", + }, + InteractWithSmoker = + { + Notes = "", + }, + InteractWithStonecutter = + { + Notes = "", + }, + JunkFished = + { + Notes = "", + }, + Jump = + { + Notes = "", + }, + LeaveGame = + { + Notes = "", + }, + MinecartOneCm = + { + Notes = "", + }, + MobKills = + { + Notes = "", + }, + OpenBarrel = + { + Notes = "", + }, + OpenChest = + { + Notes = "", + }, + OpenEnderchest = + { + Notes = "", + }, + OpenShulkerBox = + { + Notes = "", + }, + PigOneCm = + { + Notes = "", + }, + PlayNoteblock = + { + Notes = "", + }, + PlayOneMinute = + { + Notes = "", + }, + PlayRecord = + { + Notes = "", + }, + PlayerKills = + { + Notes = "", + }, + PotFlower = + { + Notes = "", + }, + RaidTrigger = + { + Notes = "", + }, + RaidWin = + { + Notes = "", + }, + SleepInBed = + { + Notes = "", + }, + SneakTime = + { + Notes = "", + }, + SprintOneCm = + { + Notes = "", + }, + StriderOneCm = + { + Notes = "", + }, + SwimOneCm = + { + Notes = "", + }, + TalkedToVillager = + { + Notes = "", + }, + TargetHit = + { + Notes = "", + }, + TimeSinceDeath = + { + Notes = "", + }, + TimeSinceRest = + { + Notes = "", + }, + TradedWithVillager = + { + Notes = "", + }, + TreasureFished = + { + Notes = "", + }, + TriggerTrappedChest = + { + Notes = "", + }, + TuneNoteblock = + { + Notes = "", + }, + UseCauldron = + { + Notes = "", + }, + WalkOnWaterOneCm = + { + Notes = "", + }, + WalkOneCm = + { + Notes = "", + }, + WalkUnderWaterOneCm = + { + Notes = "", + }, + }, + }, Globals = { Desc = [[ diff --git a/Server/Plugins/APIDump/main_APIDump.lua b/Server/Plugins/APIDump/main_APIDump.lua index f92abb932..61dd1e66c 100644 --- a/Server/Plugins/APIDump/main_APIDump.lua +++ b/Server/Plugins/APIDump/main_APIDump.lua @@ -52,7 +52,6 @@ end - --- Returns the API currently detected from the global environment local function CreateAPITables() --[[ @@ -121,14 +120,15 @@ local function CreateAPITables() end -- Member variables: + local GetField = a_ClassObj[".get"]; local SetField = a_ClassObj[".set"] or {}; - if ((a_ClassObj[".get"] ~= nil) and (type(a_ClassObj[".get"]) == "table")) then - for k in pairs(a_ClassObj[".get"]) do - if (SetField[k] == nil) then - -- It is a read-only variable, add it as a constant: + if ((GetField ~= nil) and (type(GetField) == "table")) then + for k, v in pairs(GetField) do + if ((SetField[k] == nil) and ((type(v) ~= "table") or (v["__newindex"] == nil))) then + -- It is a read-only variable or array, add it as a constant: table.insert(res.Constants, {Name = k, Value = ""}); else - -- It is a read-write variable, add it as a variable: + -- It is a read-write variable or array, add it as a variable: table.insert(res.Variables, { Name = k }); end end diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index dc25ca379..e6787b70d 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -123,6 +123,8 @@ $cfile "../BlockEntities/MobHeadEntity.h" $cfile "../BlockEntities/MobSpawnerEntity.h" $cfile "../BlockEntities/FlowerPotEntity.h" +// Registries: +$cfile "../Registries/Statistics.h" diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 8c47ab322..ccd7244fa 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -1378,6 +1378,21 @@ bool cLuaState::GetStackValue(int a_StackPos, ContiguousByteBuffer & a_Data) +bool cLuaState::GetStackValue(int a_StackPos, CustomStatistic & a_Value) +{ + if (lua_isnumber(m_LuaState, a_StackPos)) + { + a_Value = static_cast(static_cast>(lua_tonumber(m_LuaState, a_StackPos))); + return true; + } + + return true; +} + + + + + bool cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal) { if (lua_isnumber(m_LuaState, a_StackPos)) diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 0493804e5..f615ef0a6 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -37,6 +37,7 @@ extern "C" #include "../Defines.h" #include "../FunctionRef.h" +#include "../Registries/Statistics.h" #include "PluginManager.h" #include "LuaState_Typedefs.inc" @@ -657,6 +658,7 @@ public: bool GetStackValue(int a_StackPos, cTrackedRefPtr & a_Ref); bool GetStackValue(int a_StackPos, cTrackedRefSharedPtr & a_Ref); bool GetStackValue(int a_StackPos, ContiguousByteBuffer & a_Data); + bool GetStackValue(int a_StackPos, CustomStatistic & a_Value); bool GetStackValue(int a_StackPos, double & a_Value); bool GetStackValue(int a_StackPos, eBlockFace & a_Value); bool GetStackValue(int a_StackPos, eWeather & a_Value); diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index cd5e69b22..f06f4da37 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -4348,6 +4348,69 @@ static int tolua_cEntity_GetSpeed(lua_State * tolua_S) +static int tolua_get_StatisticsManager_Custom(lua_State * tolua_S) +{ + // Check the params: + cLuaState L(tolua_S); + if (!L.CheckParamNumber(2)) + { + return 0; + } + + // Get the params: + lua_pushstring(tolua_S, ".self"); + lua_rawget(tolua_S, 1); + StatisticsManager * Self = static_cast(lua_touserdata(tolua_S, -1)); + CustomStatistic Statistic; + if (!L.GetStackValue(2, Statistic)) + { + return L.ApiParamError("Expected a valid custom statistic ID"); + } + + // Push result if statistic exists: + if (const auto Result = Self->Custom.find(Statistic); Result != Self->Custom.end()) + { + L.Push(Result->second); + return 1; + } + + return 0; +} + + + + + +static int tolua_set_StatisticsManager_Custom(lua_State * tolua_S) +{ + // Check the params: + cLuaState L(tolua_S); + if (!L.CheckParamNumber(2)) + { + return 0; + } + + // Get the params: + lua_pushstring(tolua_S, ".self"); + lua_rawget(tolua_S, 1); + StatisticsManager * Self = static_cast(lua_touserdata(tolua_S, -1)); + CustomStatistic Statistic; + StatisticsManager::StatValue Value; + if (!L.GetStackValues(2, Statistic, Value)) + { + return L.ApiParamError("Expected a valid custom statistic ID and value"); + } + + // Set the value: + Self->Custom[Statistic] = Value; + + return 0; +} + + + + + void cManualBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, nullptr); @@ -4357,10 +4420,12 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_usertype(tolua_S, "cLineBlockTracer"); tolua_usertype(tolua_S, "cStringCompression"); tolua_usertype(tolua_S, "cUrlParser"); + // StatisticsManager was already created by cPlayer::GetStatistics' autogenerated bindings. tolua_cclass(tolua_S, "cCryptoHash", "cCryptoHash", "", nullptr); tolua_cclass(tolua_S, "cLineBlockTracer", "cLineBlockTracer", "", nullptr); tolua_cclass(tolua_S, "cStringCompression", "cStringCompression", "", nullptr); tolua_cclass(tolua_S, "cUrlParser", "cUrlParser", "", nullptr); + tolua_cclass(tolua_S, "StatisticsManager", "StatisticsManager", "", nullptr); // Globals: tolua_function(tolua_S, "Clamp", tolua_Clamp); @@ -4592,6 +4657,10 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_variable(tolua_S, "PostParams", tolua_get_HTTPRequest_PostParams, nullptr); tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "StatisticsManager"); + tolua_array(tolua_S, "Custom", tolua_get_StatisticsManager_Custom, tolua_set_StatisticsManager_Custom); + tolua_endmodule(tolua_S); + BindNetwork(tolua_S); BindRankManager(tolua_S); BindWorld(tolua_S); diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index 6a7916dd1..87d25e57a 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -206,7 +206,7 @@ void cBeaconEntity::UpdateBeacon(void) (std::abs(Distance.z) <= 20) ) { - a_Player.AwardAchievement(Statistic::AchFullBeacon); + a_Player.AwardAchievement(CustomStatistic::AchFullBeacon); } return false; } @@ -313,7 +313,7 @@ bool cBeaconEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) bool cBeaconEntity::UsedBy(cPlayer * a_Player) { - a_Player->GetStatManager().AddValue(Statistic::InteractWithBeacon); + a_Player->GetStatistics().Custom[CustomStatistic::InteractWithBeacon]++; cWindow * Window = GetWindow(); if (Window == nullptr) diff --git a/src/BlockEntities/BrewingstandEntity.cpp b/src/BlockEntities/BrewingstandEntity.cpp index bdac1b327..ff7b49821 100644 --- a/src/BlockEntities/BrewingstandEntity.cpp +++ b/src/BlockEntities/BrewingstandEntity.cpp @@ -145,7 +145,7 @@ bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) bool cBrewingstandEntity::UsedBy(cPlayer * a_Player) { - a_Player->GetStatManager().AddValue(Statistic::InteractWithBrewingstand); + a_Player->GetStatistics().Custom[CustomStatistic::InteractWithBrewingstand]++; cWindow * Window = GetWindow(); if (Window == nullptr) diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index c2c31b30a..11146bf46 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -204,11 +204,11 @@ bool cChestEntity::UsedBy(cPlayer * a_Player) if (m_BlockType == E_BLOCK_CHEST) { - a_Player->GetStatManager().AddValue(Statistic::OpenChest); + a_Player->GetStatistics().Custom[CustomStatistic::OpenChest]++; } else // E_BLOCK_TRAPPED_CHEST { - a_Player->GetStatManager().AddValue(Statistic::TriggerTrappedChest); + a_Player->GetStatistics().Custom[CustomStatistic::TriggerTrappedChest]++; } auto & PrimaryChest = GetPrimaryChest(); diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index 814b0c147..b067e1081 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -163,11 +163,11 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player) { if (m_BlockType == E_BLOCK_DISPENSER) { - a_Player->GetStatManager().AddValue(Statistic::InspectDispenser); + a_Player->GetStatistics().Custom[CustomStatistic::InspectDispenser]++; } else // E_BLOCK_DROPPER { - a_Player->GetStatManager().AddValue(Statistic::InspectDropper); + a_Player->GetStatistics().Custom[CustomStatistic::InspectDropper]++; } cWindow * Window = GetWindow(); diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp index efc5dce4f..ba9ca5609 100644 --- a/src/BlockEntities/EnderChestEntity.cpp +++ b/src/BlockEntities/EnderChestEntity.cpp @@ -62,7 +62,7 @@ bool cEnderChestEntity::UsedBy(cPlayer * a_Player) return false; } - a_Player->GetStatManager().AddValue(Statistic::OpenEnderchest); + a_Player->GetStatistics().Custom[CustomStatistic::OpenEnderchest]++; // If the window is not created, open it anew: cWindow * Window = GetWindow(); diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp index bc936c246..df14acc8e 100644 --- a/src/BlockEntities/FlowerPotEntity.cpp +++ b/src/BlockEntities/FlowerPotEntity.cpp @@ -50,7 +50,7 @@ bool cFlowerPotEntity::UsedBy(cPlayer * a_Player) return false; } - a_Player->GetStatManager().AddValue(Statistic::PotFlower); + a_Player->GetStatistics().Custom[CustomStatistic::PotFlower]++; cItem SelectedItem = a_Player->GetInventory().GetEquippedItem(); if (IsFlower(SelectedItem.m_ItemType, SelectedItem.m_ItemDamage)) diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index d36b19791..8ca539170 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -127,7 +127,7 @@ bool cFurnaceEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) bool cFurnaceEntity::UsedBy(cPlayer * a_Player) { - a_Player->GetStatManager().AddValue(Statistic::InteractWithFurnace); + a_Player->GetStatistics().Custom[CustomStatistic::InteractWithFurnace]++; cWindow * Window = GetWindow(); if (Window == nullptr) diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 82e07f6a0..1e5c59c94 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -113,7 +113,7 @@ void cHopperEntity::SendTo(cClientHandle & a_Client) bool cHopperEntity::UsedBy(cPlayer * a_Player) { - a_Player->GetStatManager().AddValue(Statistic::InspectHopper); + a_Player->GetStatistics().Custom[CustomStatistic::InspectHopper]++; // If the window is not created, open it anew: cWindow * Window = GetWindow(); diff --git a/src/BlockEntities/JukeboxEntity.cpp b/src/BlockEntities/JukeboxEntity.cpp index b99d9d39c..065f9cb46 100644 --- a/src/BlockEntities/JukeboxEntity.cpp +++ b/src/BlockEntities/JukeboxEntity.cpp @@ -65,7 +65,8 @@ bool cJukeboxEntity::UsedBy(cPlayer * a_Player) const cItem & HeldItem = a_Player->GetEquippedItem(); if (PlayRecord(HeldItem.m_ItemType)) { - a_Player->GetStatManager().AddValue(Statistic::PlayRecord); + a_Player->GetStatistics().Custom[CustomStatistic::PlayRecord]++; + if (!a_Player->IsGameModeCreative()) { a_Player->GetInventory().RemoveOneEquippedItem(); diff --git a/src/BlockEntities/NoteEntity.cpp b/src/BlockEntities/NoteEntity.cpp index 419d084b2..b4696f7b1 100644 --- a/src/BlockEntities/NoteEntity.cpp +++ b/src/BlockEntities/NoteEntity.cpp @@ -34,7 +34,7 @@ void cNoteEntity::CopyFrom(const cBlockEntity & a_Src) bool cNoteEntity::UsedBy(cPlayer * a_Player) { - a_Player->GetStatManager().AddValue(Statistic::TuneNoteblock); + a_Player->GetStatistics().Custom[CustomStatistic::TuneNoteblock]++; IncrementNote(); MakeSound(); return true; diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index ef4359416..37c57b6b3 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -134,7 +134,7 @@ bool cBlockBedHandler::OnUse( // Occupy the bed, where 0x4 = occupied bit: a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta | 0x04); - a_Player.GetStatManager().AddValue(Statistic::SleepInBed); + a_Player.GetStatistics().Custom[CustomStatistic::SleepInBed]++; // When sleeping, the player's bounding box moves to approximately where his head is. // Set the player's position to somewhere close to the edge of the pillow block: diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h index ae8cd0228..4b238fa48 100644 --- a/src/Blocks/BlockCake.h +++ b/src/Blocks/BlockCake.h @@ -33,7 +33,7 @@ private: return false; } - a_Player.GetStatManager().AddValue(Statistic::EatCakeSlice); + a_Player.GetStatistics().Custom[CustomStatistic::EatCakeSlice]++; if (Meta >= 5) { a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockPos, &a_Player); diff --git a/src/Blocks/BlockCauldron.h b/src/Blocks/BlockCauldron.h index 37e638d72..80f95164f 100644 --- a/src/Blocks/BlockCauldron.h +++ b/src/Blocks/BlockCauldron.h @@ -65,7 +65,7 @@ private: { a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_BUCKET)); } - a_Player.GetStatManager().AddValue(Statistic::FillCauldron); + a_Player.GetStatistics().Custom[CustomStatistic::FillCauldron]++; } break; } @@ -79,7 +79,7 @@ private: { a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_POTION)); } - a_Player.GetStatManager().AddValue(Statistic::UseCauldron); + a_Player.GetStatistics().Custom[CustomStatistic::UseCauldron]++; } break; } diff --git a/src/Blocks/BlockWorkbench.h b/src/Blocks/BlockWorkbench.h index e654a6b84..a0ec3df4a 100644 --- a/src/Blocks/BlockWorkbench.h +++ b/src/Blocks/BlockWorkbench.h @@ -29,7 +29,7 @@ private: const Vector3i a_CursorPos ) const override { - a_Player.GetStatManager().AddValue(Statistic::InteractWithCraftingTable); + a_Player.GetStatistics().Custom[CustomStatistic::InteractWithCraftingTable]++; cWindow * Window = new cCraftingWindow(); a_Player.OpenWindow(*Window); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 2a1ae2357..4ee5a1c65 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -369,7 +369,7 @@ void cClientHandle::FinishAuthenticate(const AString & a_Name, const cUUID & a_U cRoot::Get()->SendPlayerLists(m_Player); // Add everyone else to ourself // Send statistics: - SendStatistics(m_Player->GetStatManager()); + SendStatistics(m_Player->GetStatistics()); // Delay the first ping until the client "settles down" // This should fix #889, "BadCast exception, cannot convert bit to fm" error in client @@ -2970,7 +2970,7 @@ void cClientHandle::SendSpawnMob(const cMonster & a_Mob) -void cClientHandle::SendStatistics(const cStatManager & a_Manager) +void cClientHandle::SendStatistics(const StatisticsManager & a_Manager) { m_Protocol->SendStatistics(a_Manager); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 00d5051d2..17dbefbeb 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -35,9 +35,11 @@ class cProtocol; class cWindow; class cFallingBlock; class cCompositeChat; -class cStatManager; class cMap; class cClientHandle; + +struct StatisticsManager; + typedef std::shared_ptr cClientHandlePtr; @@ -211,7 +213,7 @@ public: // tolua_export void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); void SendSpawnEntity (const cEntity & a_Entity); void SendSpawnMob (const cMonster & a_Mob); - void SendStatistics (const cStatManager & a_Manager); + void SendStatistics (const StatisticsManager & a_Manager); void SendTabCompletionResults (const AStringVector & a_Results); void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks); // tolua_export diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 1d95ec56e..5c79e58d1 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -528,7 +528,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } } - Player->GetStatManager().AddValue(Statistic::DamageDealt, FloorC(a_TDI.FinalDamage * 10 + 0.5)); + Player->GetStatistics().Custom[CustomStatistic::DamageDealt] += FloorC(a_TDI.FinalDamage * 10 + 0.5); } m_Health -= a_TDI.FinalDamage; diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 39fff913d..fd2cc3a4b 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -242,10 +242,10 @@ bool cPickup::CollectedBy(cPlayer & a_Dest) // Check achievements switch (m_Item.m_ItemType) { - case E_BLOCK_LOG: a_Dest.AwardAchievement(Statistic::AchMineWood); break; - case E_ITEM_LEATHER: a_Dest.AwardAchievement(Statistic::AchKillCow); break; - case E_ITEM_DIAMOND: a_Dest.AwardAchievement(Statistic::AchDiamonds); break; - case E_ITEM_BLAZE_ROD: a_Dest.AwardAchievement(Statistic::AchBlazeRod); break; + case E_BLOCK_LOG: a_Dest.AwardAchievement(CustomStatistic::AchMineWood); break; + case E_ITEM_LEATHER: a_Dest.AwardAchievement(CustomStatistic::AchKillCow); break; + case E_ITEM_DIAMOND: a_Dest.AwardAchievement(CustomStatistic::AchDiamonds); break; + case E_ITEM_BLAZE_ROD: a_Dest.AwardAchievement(CustomStatistic::AchBlazeRod); break; default: break; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 233c0a8c3..1e7c8df98 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -167,7 +167,7 @@ cPlayer::~cPlayer(void) LOGD("Deleting cPlayer \"%s\" at %p, ID %d", GetName().c_str(), static_cast(this), GetUniqueID()); // "Times ragequit": - m_Stats.AddValue(Statistic::LeaveGame); + m_Stats.Custom[CustomStatistic::LeaveGame]++; SaveToDisk(); @@ -482,7 +482,7 @@ void cPlayer::TossItems(const cItems & a_Items) return; } - m_Stats.AddValue(Statistic::Drop, static_cast(a_Items.Size())); + m_Stats.Custom[CustomStatistic::Drop] += static_cast(a_Items.Size()); const auto Speed = (GetLookVector() + Vector3d(0, 0.2, 0)) * 6; // A dash of height and a dollop of speed const auto Position = GetEyePosition() - Vector3d(0, 0.2, 0); // Correct for eye-height weirdness @@ -859,7 +859,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) { Pickups.Add(cItem(E_ITEM_RED_APPLE)); } - m_Stats.AddValue(Statistic::Drop, static_cast(Pickups.Size())); + m_Stats.Custom[CustomStatistic::Drop] += static_cast(Pickups.Size()); m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); SaveToDisk(); // Save it, yeah the world is a tough place ! @@ -923,8 +923,8 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) } } - m_Stats.AddValue(Statistic::Deaths); - m_Stats.SetValue(Statistic::TimeSinceDeath, 0); + m_Stats.Custom[CustomStatistic::Deaths]++; + m_Stats.Custom[CustomStatistic::TimeSinceDeath] = 0; m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::otDeathCount, 1); } @@ -939,7 +939,7 @@ void cPlayer::Killed(cEntity * a_Victim) if (a_Victim->IsPlayer()) { - m_Stats.AddValue(Statistic::PlayerKills); + m_Stats.Custom[CustomStatistic::PlayerKills]++; ScoreBoard.AddPlayerScore(GetName(), cObjective::otPlayerKillCount, 1); } @@ -947,10 +947,10 @@ void cPlayer::Killed(cEntity * a_Victim) { if (static_cast(a_Victim)->GetMobFamily() == cMonster::mfHostile) { - AwardAchievement(Statistic::AchKillEnemy); + AwardAchievement(CustomStatistic::AchKillEnemy); } - m_Stats.AddValue(Statistic::MobKills); + m_Stats.Custom[CustomStatistic::MobKills]++; } ScoreBoard.AddPlayerScore(GetName(), cObjective::otTotalKillCount, 1); @@ -1373,7 +1373,7 @@ void cPlayer::UpdateCapabilities() -void cPlayer::AwardAchievement(const Statistic a_Ach) +void cPlayer::AwardAchievement(const CustomStatistic a_Ach) { // Check if the prerequisites are met: if (!m_Stats.SatisfiesPrerequisite(a_Ach)) @@ -1382,7 +1382,7 @@ void cPlayer::AwardAchievement(const Statistic a_Ach) } // Increment the statistic and check if we already have it: - if (m_Stats.AddValue(a_Ach) != 1) + if (m_Stats.Custom[a_Ach]++ != 1) { return; } @@ -2262,12 +2262,12 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs return; } - const auto Value = FloorC(a_DeltaPos.Length() * 100 + 0.5); + const auto Value = FloorC(a_DeltaPos.Length() * 100 + 0.5); if (m_AttachedTo == nullptr) { if (IsFlying()) { - m_Stats.AddValue(Statistic::FlyOneCm, Value); + m_Stats.Custom[CustomStatistic::FlyOneCm] += Value; // May be flying and doing any of the following: } @@ -2275,18 +2275,18 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs { if (a_DeltaPos.y > 0.0) // Going up { - m_Stats.AddValue(Statistic::ClimbOneCm, FloorC(a_DeltaPos.y * 100 + 0.5)); + m_Stats.Custom[CustomStatistic::ClimbOneCm] += FloorC(a_DeltaPos.y * 100 + 0.5); } } else if (IsInWater()) { if (m_IsHeadInWater) { - m_Stats.AddValue(Statistic::WalkUnderWaterOneCm, Value); + m_Stats.Custom[CustomStatistic::WalkUnderWaterOneCm] += Value; } else { - m_Stats.AddValue(Statistic::WalkOnWaterOneCm, Value); + m_Stats.Custom[CustomStatistic::WalkOnWaterOneCm] += Value; } AddFoodExhaustion(0.00015 * static_cast(Value)); } @@ -2294,17 +2294,17 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs { if (IsCrouched()) { - m_Stats.AddValue(Statistic::CrouchOneCm, Value); + m_Stats.Custom[CustomStatistic::CrouchOneCm] += Value; AddFoodExhaustion(0.0001 * static_cast(Value)); } if (IsSprinting()) { - m_Stats.AddValue(Statistic::SprintOneCm, Value); + m_Stats.Custom[CustomStatistic::SprintOneCm] += Value; AddFoodExhaustion(0.001 * static_cast(Value)); } else { - m_Stats.AddValue(Statistic::WalkOneCm, Value); + m_Stats.Custom[CustomStatistic::WalkOneCm] += Value; AddFoodExhaustion(0.0001 * static_cast(Value)); } } @@ -2313,13 +2313,13 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs // If a jump just started, process food exhaustion: if ((a_DeltaPos.y > 0.0) && a_PreviousIsOnGround) { - m_Stats.AddValue(Statistic::Jump, 1); + m_Stats.Custom[CustomStatistic::Jump]++; AddFoodExhaustion((IsSprinting() ? 0.008 : 0.002) * static_cast(Value)); } else if (a_DeltaPos.y < 0.0) { // Increment statistic - m_Stats.AddValue(Statistic::FallOneCm, static_cast(std::abs(a_DeltaPos.y) * 100 + 0.5)); + m_Stats.Custom[CustomStatistic::FallOneCm] += static_cast(-a_DeltaPos.y * 100 + 0.5); } // TODO: good opportunity to detect illegal flight (check for falling tho) } @@ -2328,15 +2328,15 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIs { switch (m_AttachedTo->GetEntityType()) { - case cEntity::etMinecart: m_Stats.AddValue(Statistic::MinecartOneCm, Value); break; - case cEntity::etBoat: m_Stats.AddValue(Statistic::BoatOneCm, Value); break; + case cEntity::etMinecart: m_Stats.Custom[CustomStatistic::MinecartOneCm] += Value; break; + case cEntity::etBoat: m_Stats.Custom[CustomStatistic::BoatOneCm] += Value; break; case cEntity::etMonster: { cMonster * Monster = static_cast(m_AttachedTo); switch (Monster->GetMobType()) { - case mtPig: m_Stats.AddValue(Statistic::PigOneCm, Value); break; - case mtHorse: m_Stats.AddValue(Statistic::HorseOneCm, Value); break; + case mtPig: m_Stats.Custom[CustomStatistic::PigOneCm] += Value; break; + case mtHorse: m_Stats.Custom[CustomStatistic::HorseOneCm] += Value; break; default: break; } break; @@ -3004,7 +3004,7 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) NotifyNearbyWolves(static_cast(a_TDI.Attacker), true); } } - m_Stats.AddValue(Statistic::DamageTaken, FloorC(a_TDI.FinalDamage * 10 + 0.5)); + m_Stats.Custom[CustomStatistic::DamageTaken] += FloorC(a_TDI.FinalDamage * 10 + 0.5); return true; } return false; @@ -3154,11 +3154,11 @@ void cPlayer::OnRemoveFromWorld(cWorld & a_World) // Award relevant achievements: if (DestinationDimension == dimEnd) { - AwardAchievement(Statistic::AchTheEnd); + AwardAchievement(CustomStatistic::AchTheEnd); } else if (DestinationDimension == dimNether) { - AwardAchievement(Statistic::AchPortal); + AwardAchievement(CustomStatistic::AchPortal); } // Set capabilities based on new world: @@ -3218,12 +3218,16 @@ void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) return; } - m_Stats.AddValue(Statistic::PlayOneMinute); - m_Stats.AddValue(Statistic::TimeSinceDeath); - - if (IsCrouched()) { - m_Stats.AddValue(Statistic::SneakTime); + const auto TicksElapsed = static_cast(std::chrono::duration_cast(a_Dt).count()); + + m_Stats.Custom[CustomStatistic::PlayOneMinute] += TicksElapsed; + m_Stats.Custom[CustomStatistic::TimeSinceDeath] += TicksElapsed; + + if (IsCrouched()) + { + m_Stats.Custom[CustomStatistic::SneakTime] += TicksElapsed; + } } // Handle the player detach, when the player is in spectator mode diff --git a/src/Entities/Player.h b/src/Entities/Player.h index df84d25e0..e7b18f3b6 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -230,6 +230,9 @@ public: AString GetIP(void) const; // tolua_export + /** Return the associated statistic and achievement manager. */ + StatisticsManager & GetStatistics() { return m_Stats; } + /** Returns the associated team, nullptr if none */ cTeam * GetTeam(void) { return m_Team; } // tolua_export @@ -244,13 +247,10 @@ public: /** Forces the player to query the scoreboard for his team */ cTeam * UpdateTeam(void); - /** Return the associated statistic and achievement manager. */ - cStatManager & GetStatManager() { return m_Stats; } - /** Awards the player an achievement. If all prerequisites are met, this method will award the achievement and will broadcast a chat message. If the achievement has been already awarded to the player, this method will just increment the stat counter. */ - void AwardAchievement(Statistic a_Ach); + void AwardAchievement(CustomStatistic a_Ach); /** Forces the player to move in the given direction. @deprecated Use SetSpeed instead. */ @@ -735,7 +735,7 @@ private: cTeam * m_Team; - cStatManager m_Stats; + StatisticsManager m_Stats; /** How long till the player's inventory will be saved Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */ diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h index ec59763ed..183c9756c 100644 --- a/src/Items/ItemFishingRod.h +++ b/src/Items/ItemFishingRod.h @@ -210,7 +210,7 @@ public: } } - a_Player.GetStatManager().AddValue(Statistic::TreasureFished, 1); + a_Player.GetStatistics().Custom[CustomStatistic::TreasureFished]++; } else if (ItemCategory < JunkChances[LotSLevel]) { @@ -262,7 +262,7 @@ public: Drops.Add(cItem(E_BLOCK_TRIPWIRE_HOOK)); } - a_Player.GetStatManager().AddValue(Statistic::JunkFished, 1); + a_Player.GetStatistics().Custom[CustomStatistic::JunkFished]++; } else { @@ -284,7 +284,7 @@ public: Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_FISH)); } - a_Player.GetStatManager().AddValue(Statistic::FishCaught, 1); + a_Player.GetStatistics().Custom[CustomStatistic::FishCaught]++; } // Check with plugins if this loot is acceptable: diff --git a/src/Items/ItemMobHead.h b/src/Items/ItemMobHead.h index 07c628ceb..90d67b02b 100644 --- a/src/Items/ItemMobHead.h +++ b/src/Items/ItemMobHead.h @@ -285,7 +285,7 @@ public: double Dist = (a_Player.GetPosition() - Pos).Length(); if (Dist < 50.0) { - a_Player.AwardAchievement(Statistic::AchSpawnWither); + a_Player.AwardAchievement(CustomStatistic::AchSpawnWither); } return false; } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index c1a244a9f..ae186d2bb 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -1361,10 +1361,10 @@ void cMonster::LoveTick(void) m_World->DoWithPlayerByUUID(m_Feeder, [&] (cPlayer & a_Player) { - a_Player.GetStatManager().AddValue(Statistic::AnimalsBred); + a_Player.GetStatistics().Custom[CustomStatistic::AnimalsBred]++; if (GetMobType() == eMonsterType::mtCow) { - a_Player.AwardAchievement(Statistic::AchBreedCow); + a_Player.AwardAchievement(CustomStatistic::AchBreedCow); } return true; }); diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 77a31a0bd..87f5e170d 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -84,7 +84,7 @@ void cWither::KilledBy(TakeDamageInfo & a_TDI) if (Dist < 50.0) { // If player is close, award achievement - a_Player.AwardAchievement(Statistic::AchKillWither); + a_Player.AwardAchievement(CustomStatistic::AchKillWither); } return false; } diff --git a/src/Protocol/Palettes/Palette_1_13.cpp b/src/Protocol/Palettes/Palette_1_13.cpp index 513763b2a..d60c7a516 100644 --- a/src/Protocol/Palettes/Palette_1_13.cpp +++ b/src/Protocol/Palettes/Palette_1_13.cpp @@ -7859,62 +7859,62 @@ namespace Palette_1_13 } } - UInt32 From(const Statistic ID) + UInt32 From(const CustomStatistic ID) { switch (ID) { - case Statistic::AnimalsBred: return 25; - case Statistic::AviateOneCm: return 17; - case Statistic::BoatOneCm: return 14; - case Statistic::CleanArmor: return 33; - case Statistic::CleanBanner: return 34; - case Statistic::ClimbOneCm: return 10; - case Statistic::CrouchOneCm: return 6; - case Statistic::DamageDealt: return 21; - case Statistic::DamageTaken: return 22; - case Statistic::Deaths: return 23; - case Statistic::Drop: return 20; - case Statistic::EatCakeSlice: return 30; - case Statistic::EnchantItem: return 45; - case Statistic::FallOneCm: return 9; - case Statistic::FillCauldron: return 31; - case Statistic::FishCaught: return 27; - case Statistic::FlyOneCm: return 11; - case Statistic::HorseOneCm: return 16; - case Statistic::InspectDispenser: return 39; - case Statistic::InspectDropper: return 37; - case Statistic::InspectHopper: return 38; - case Statistic::InteractWithBeacon: return 36; - case Statistic::InteractWithBrewingstand: return 35; - case Statistic::InteractWithCraftingTable: return 48; - case Statistic::InteractWithFurnace: return 47; - case Statistic::Jump: return 19; - case Statistic::LeaveGame: return 0; - case Statistic::MinecartOneCm: return 13; - case Statistic::MobKills: return 24; - case Statistic::OpenChest: return 49; - case Statistic::OpenEnderchest: return 44; - case Statistic::OpenShulkerBox: return 51; - case Statistic::PigOneCm: return 15; - case Statistic::PlayerKills: return 26; - case Statistic::PlayNoteblock: return 40; - case Statistic::PlayOneMinute: return 1; - case Statistic::PlayRecord: return 46; - case Statistic::PotFlower: return 42; - case Statistic::SleepInBed: return 50; - case Statistic::SneakTime: return 4; - case Statistic::SprintOneCm: return 7; - case Statistic::SwimOneCm: return 8; - case Statistic::TalkedToVillager: return 28; - case Statistic::TimeSinceDeath: return 2; - case Statistic::TimeSinceRest: return 3; - case Statistic::TradedWithVillager: return 29; - case Statistic::TriggerTrappedChest: return 43; - case Statistic::TuneNoteblock: return 41; - case Statistic::UseCauldron: return 32; - case Statistic::WalkOneCm: return 5; - case Statistic::WalkOnWaterOneCm: return 18; - case Statistic::WalkUnderWaterOneCm: return 12; + case CustomStatistic::AnimalsBred: return 25; + case CustomStatistic::AviateOneCm: return 17; + case CustomStatistic::BoatOneCm: return 14; + case CustomStatistic::CleanArmor: return 33; + case CustomStatistic::CleanBanner: return 34; + case CustomStatistic::ClimbOneCm: return 10; + case CustomStatistic::CrouchOneCm: return 6; + case CustomStatistic::DamageDealt: return 21; + case CustomStatistic::DamageTaken: return 22; + case CustomStatistic::Deaths: return 23; + case CustomStatistic::Drop: return 20; + case CustomStatistic::EatCakeSlice: return 30; + case CustomStatistic::EnchantItem: return 45; + case CustomStatistic::FallOneCm: return 9; + case CustomStatistic::FillCauldron: return 31; + case CustomStatistic::FishCaught: return 27; + case CustomStatistic::FlyOneCm: return 11; + case CustomStatistic::HorseOneCm: return 16; + case CustomStatistic::InspectDispenser: return 39; + case CustomStatistic::InspectDropper: return 37; + case CustomStatistic::InspectHopper: return 38; + case CustomStatistic::InteractWithBeacon: return 36; + case CustomStatistic::InteractWithBrewingstand: return 35; + case CustomStatistic::InteractWithCraftingTable: return 48; + case CustomStatistic::InteractWithFurnace: return 47; + case CustomStatistic::Jump: return 19; + case CustomStatistic::LeaveGame: return 0; + case CustomStatistic::MinecartOneCm: return 13; + case CustomStatistic::MobKills: return 24; + case CustomStatistic::OpenChest: return 49; + case CustomStatistic::OpenEnderchest: return 44; + case CustomStatistic::OpenShulkerBox: return 51; + case CustomStatistic::PigOneCm: return 15; + case CustomStatistic::PlayerKills: return 26; + case CustomStatistic::PlayNoteblock: return 40; + case CustomStatistic::PlayOneMinute: return 1; + case CustomStatistic::PlayRecord: return 46; + case CustomStatistic::PotFlower: return 42; + case CustomStatistic::SleepInBed: return 50; + case CustomStatistic::SneakTime: return 4; + case CustomStatistic::SprintOneCm: return 7; + case CustomStatistic::SwimOneCm: return 8; + case CustomStatistic::TalkedToVillager: return 28; + case CustomStatistic::TimeSinceDeath: return 2; + case CustomStatistic::TimeSinceRest: return 3; + case CustomStatistic::TradedWithVillager: return 29; + case CustomStatistic::TriggerTrappedChest: return 43; + case CustomStatistic::TuneNoteblock: return 41; + case CustomStatistic::UseCauldron: return 32; + case CustomStatistic::WalkOneCm: return 5; + case CustomStatistic::WalkOnWaterOneCm: return 18; + case CustomStatistic::WalkUnderWaterOneCm: return 12; default: return UInt32(-1); } } diff --git a/src/Protocol/Palettes/Palette_1_13.h b/src/Protocol/Palettes/Palette_1_13.h index 6f8ceec2e..5b2a5ccb5 100644 --- a/src/Protocol/Palettes/Palette_1_13.h +++ b/src/Protocol/Palettes/Palette_1_13.h @@ -8,6 +8,6 @@ namespace Palette_1_13 { UInt32 From(BlockState Block); UInt32 From(Item ID); - UInt32 From(Statistic ID); + UInt32 From(CustomStatistic ID); Item ToItem(UInt32 ID); } diff --git a/src/Protocol/Palettes/Palette_1_13_1.cpp b/src/Protocol/Palettes/Palette_1_13_1.cpp index cfc4ed5f4..1dba4caf8 100644 --- a/src/Protocol/Palettes/Palette_1_13_1.cpp +++ b/src/Protocol/Palettes/Palette_1_13_1.cpp @@ -7870,68 +7870,68 @@ namespace Palette_1_13_1 } } - UInt32 From(const Statistic ID) + UInt32 From(const CustomStatistic ID) { switch (ID) { - case Statistic::AnimalsBred: return 30; - case Statistic::AviateOneCm: return 17; - case Statistic::BoatOneCm: return 14; - case Statistic::CleanArmor: return 38; - case Statistic::CleanBanner: return 39; - case Statistic::CleanShulkerBox: return 40; - case Statistic::ClimbOneCm: return 10; - case Statistic::CrouchOneCm: return 6; - case Statistic::DamageAbsorbed: return 26; - case Statistic::DamageBlockedByShield: return 25; - case Statistic::DamageDealt: return 21; - case Statistic::DamageDealtAbsorbed: return 22; - case Statistic::DamageDealtResisted: return 23; - case Statistic::DamageResisted: return 27; - case Statistic::DamageTaken: return 24; - case Statistic::Deaths: return 28; - case Statistic::Drop: return 20; - case Statistic::EatCakeSlice: return 35; - case Statistic::EnchantItem: return 51; - case Statistic::FallOneCm: return 9; - case Statistic::FillCauldron: return 36; - case Statistic::FishCaught: return 32; - case Statistic::FlyOneCm: return 11; - case Statistic::HorseOneCm: return 16; - case Statistic::InspectDispenser: return 45; - case Statistic::InspectDropper: return 43; - case Statistic::InspectHopper: return 44; - case Statistic::InteractWithBeacon: return 42; - case Statistic::InteractWithBrewingstand: return 41; - case Statistic::InteractWithCraftingTable: return 54; - case Statistic::InteractWithFurnace: return 53; - case Statistic::Jump: return 19; - case Statistic::LeaveGame: return 0; - case Statistic::MinecartOneCm: return 13; - case Statistic::MobKills: return 29; - case Statistic::OpenChest: return 55; - case Statistic::OpenEnderchest: return 50; - case Statistic::OpenShulkerBox: return 57; - case Statistic::PigOneCm: return 15; - case Statistic::PlayerKills: return 31; - case Statistic::PlayNoteblock: return 46; - case Statistic::PlayOneMinute: return 1; - case Statistic::PlayRecord: return 52; - case Statistic::PotFlower: return 48; - case Statistic::SleepInBed: return 56; - case Statistic::SneakTime: return 4; - case Statistic::SprintOneCm: return 7; - case Statistic::SwimOneCm: return 8; - case Statistic::TalkedToVillager: return 33; - case Statistic::TimeSinceDeath: return 2; - case Statistic::TimeSinceRest: return 3; - case Statistic::TradedWithVillager: return 34; - case Statistic::TriggerTrappedChest: return 49; - case Statistic::TuneNoteblock: return 47; - case Statistic::UseCauldron: return 37; - case Statistic::WalkOneCm: return 5; - case Statistic::WalkOnWaterOneCm: return 18; - case Statistic::WalkUnderWaterOneCm: return 12; + case CustomStatistic::AnimalsBred: return 30; + case CustomStatistic::AviateOneCm: return 17; + case CustomStatistic::BoatOneCm: return 14; + case CustomStatistic::CleanArmor: return 38; + case CustomStatistic::CleanBanner: return 39; + case CustomStatistic::CleanShulkerBox: return 40; + case CustomStatistic::ClimbOneCm: return 10; + case CustomStatistic::CrouchOneCm: return 6; + case CustomStatistic::DamageAbsorbed: return 26; + case CustomStatistic::DamageBlockedByShield: return 25; + case CustomStatistic::DamageDealt: return 21; + case CustomStatistic::DamageDealtAbsorbed: return 22; + case CustomStatistic::DamageDealtResisted: return 23; + case CustomStatistic::DamageResisted: return 27; + case CustomStatistic::DamageTaken: return 24; + case CustomStatistic::Deaths: return 28; + case CustomStatistic::Drop: return 20; + case CustomStatistic::EatCakeSlice: return 35; + case CustomStatistic::EnchantItem: return 51; + case CustomStatistic::FallOneCm: return 9; + case CustomStatistic::FillCauldron: return 36; + case CustomStatistic::FishCaught: return 32; + case CustomStatistic::FlyOneCm: return 11; + case CustomStatistic::HorseOneCm: return 16; + case CustomStatistic::InspectDispenser: return 45; + case CustomStatistic::InspectDropper: return 43; + case CustomStatistic::InspectHopper: return 44; + case CustomStatistic::InteractWithBeacon: return 42; + case CustomStatistic::InteractWithBrewingstand: return 41; + case CustomStatistic::InteractWithCraftingTable: return 54; + case CustomStatistic::InteractWithFurnace: return 53; + case CustomStatistic::Jump: return 19; + case CustomStatistic::LeaveGame: return 0; + case CustomStatistic::MinecartOneCm: return 13; + case CustomStatistic::MobKills: return 29; + case CustomStatistic::OpenChest: return 55; + case CustomStatistic::OpenEnderchest: return 50; + case CustomStatistic::OpenShulkerBox: return 57; + case CustomStatistic::PigOneCm: return 15; + case CustomStatistic::PlayerKills: return 31; + case CustomStatistic::PlayNoteblock: return 46; + case CustomStatistic::PlayOneMinute: return 1; + case CustomStatistic::PlayRecord: return 52; + case CustomStatistic::PotFlower: return 48; + case CustomStatistic::SleepInBed: return 56; + case CustomStatistic::SneakTime: return 4; + case CustomStatistic::SprintOneCm: return 7; + case CustomStatistic::SwimOneCm: return 8; + case CustomStatistic::TalkedToVillager: return 33; + case CustomStatistic::TimeSinceDeath: return 2; + case CustomStatistic::TimeSinceRest: return 3; + case CustomStatistic::TradedWithVillager: return 34; + case CustomStatistic::TriggerTrappedChest: return 49; + case CustomStatistic::TuneNoteblock: return 47; + case CustomStatistic::UseCauldron: return 37; + case CustomStatistic::WalkOneCm: return 5; + case CustomStatistic::WalkOnWaterOneCm: return 18; + case CustomStatistic::WalkUnderWaterOneCm: return 12; default: return UInt32(-1); } } diff --git a/src/Protocol/Palettes/Palette_1_13_1.h b/src/Protocol/Palettes/Palette_1_13_1.h index 02085aa2b..fda47e5c4 100644 --- a/src/Protocol/Palettes/Palette_1_13_1.h +++ b/src/Protocol/Palettes/Palette_1_13_1.h @@ -8,6 +8,6 @@ namespace Palette_1_13_1 { UInt32 From(BlockState Block); UInt32 From(Item ID); - UInt32 From(Statistic ID); + UInt32 From(CustomStatistic ID); Item ToItem(UInt32 ID); } diff --git a/src/Protocol/Palettes/Palette_1_14.cpp b/src/Protocol/Palettes/Palette_1_14.cpp index 02c871331..0dca7c142 100644 --- a/src/Protocol/Palettes/Palette_1_14.cpp +++ b/src/Protocol/Palettes/Palette_1_14.cpp @@ -9505,79 +9505,79 @@ namespace Palette_1_14 } } - UInt32 From(const Statistic ID) + UInt32 From(const CustomStatistic ID) { switch (ID) { - case Statistic::AnimalsBred: return 30; - case Statistic::AviateOneCm: return 17; - case Statistic::BellRing: return 66; - case Statistic::BoatOneCm: return 14; - case Statistic::CleanArmor: return 38; - case Statistic::CleanBanner: return 39; - case Statistic::CleanShulkerBox: return 40; - case Statistic::ClimbOneCm: return 10; - case Statistic::CrouchOneCm: return 6; - case Statistic::DamageAbsorbed: return 26; - case Statistic::DamageBlockedByShield: return 25; - case Statistic::DamageDealt: return 21; - case Statistic::DamageDealtAbsorbed: return 22; - case Statistic::DamageDealtResisted: return 23; - case Statistic::DamageResisted: return 27; - case Statistic::DamageTaken: return 24; - case Statistic::Deaths: return 28; - case Statistic::Drop: return 20; - case Statistic::EatCakeSlice: return 35; - case Statistic::EnchantItem: return 51; - case Statistic::FallOneCm: return 9; - case Statistic::FillCauldron: return 36; - case Statistic::FishCaught: return 32; - case Statistic::FlyOneCm: return 11; - case Statistic::HorseOneCm: return 16; - case Statistic::InspectDispenser: return 45; - case Statistic::InspectDropper: return 43; - case Statistic::InspectHopper: return 44; - case Statistic::InteractWithBeacon: return 42; - case Statistic::InteractWithBlastFurnace: return 59; - case Statistic::InteractWithBrewingstand: return 41; - case Statistic::InteractWithCampfire: return 62; - case Statistic::InteractWithCartographyTable: return 63; - case Statistic::InteractWithCraftingTable: return 54; - case Statistic::InteractWithFurnace: return 53; - case Statistic::InteractWithLectern: return 61; - case Statistic::InteractWithLoom: return 64; - case Statistic::InteractWithSmoker: return 60; - case Statistic::InteractWithStonecutter: return 65; - case Statistic::Jump: return 19; - case Statistic::LeaveGame: return 0; - case Statistic::MinecartOneCm: return 13; - case Statistic::MobKills: return 29; - case Statistic::OpenBarrel: return 58; - case Statistic::OpenChest: return 55; - case Statistic::OpenEnderchest: return 50; - case Statistic::OpenShulkerBox: return 57; - case Statistic::PigOneCm: return 15; - case Statistic::PlayerKills: return 31; - case Statistic::PlayNoteblock: return 46; - case Statistic::PlayOneMinute: return 1; - case Statistic::PlayRecord: return 52; - case Statistic::PotFlower: return 48; - case Statistic::RaidTrigger: return 67; - case Statistic::RaidWin: return 68; - case Statistic::SleepInBed: return 56; - case Statistic::SneakTime: return 4; - case Statistic::SprintOneCm: return 7; - case Statistic::SwimOneCm: return 18; - case Statistic::TalkedToVillager: return 33; - case Statistic::TimeSinceDeath: return 2; - case Statistic::TimeSinceRest: return 3; - case Statistic::TradedWithVillager: return 34; - case Statistic::TriggerTrappedChest: return 49; - case Statistic::TuneNoteblock: return 47; - case Statistic::UseCauldron: return 37; - case Statistic::WalkOneCm: return 5; - case Statistic::WalkOnWaterOneCm: return 8; - case Statistic::WalkUnderWaterOneCm: return 12; + case CustomStatistic::AnimalsBred: return 30; + case CustomStatistic::AviateOneCm: return 17; + case CustomStatistic::BellRing: return 66; + case CustomStatistic::BoatOneCm: return 14; + case CustomStatistic::CleanArmor: return 38; + case CustomStatistic::CleanBanner: return 39; + case CustomStatistic::CleanShulkerBox: return 40; + case CustomStatistic::ClimbOneCm: return 10; + case CustomStatistic::CrouchOneCm: return 6; + case CustomStatistic::DamageAbsorbed: return 26; + case CustomStatistic::DamageBlockedByShield: return 25; + case CustomStatistic::DamageDealt: return 21; + case CustomStatistic::DamageDealtAbsorbed: return 22; + case CustomStatistic::DamageDealtResisted: return 23; + case CustomStatistic::DamageResisted: return 27; + case CustomStatistic::DamageTaken: return 24; + case CustomStatistic::Deaths: return 28; + case CustomStatistic::Drop: return 20; + case CustomStatistic::EatCakeSlice: return 35; + case CustomStatistic::EnchantItem: return 51; + case CustomStatistic::FallOneCm: return 9; + case CustomStatistic::FillCauldron: return 36; + case CustomStatistic::FishCaught: return 32; + case CustomStatistic::FlyOneCm: return 11; + case CustomStatistic::HorseOneCm: return 16; + case CustomStatistic::InspectDispenser: return 45; + case CustomStatistic::InspectDropper: return 43; + case CustomStatistic::InspectHopper: return 44; + case CustomStatistic::InteractWithBeacon: return 42; + case CustomStatistic::InteractWithBlastFurnace: return 59; + case CustomStatistic::InteractWithBrewingstand: return 41; + case CustomStatistic::InteractWithCampfire: return 62; + case CustomStatistic::InteractWithCartographyTable: return 63; + case CustomStatistic::InteractWithCraftingTable: return 54; + case CustomStatistic::InteractWithFurnace: return 53; + case CustomStatistic::InteractWithLectern: return 61; + case CustomStatistic::InteractWithLoom: return 64; + case CustomStatistic::InteractWithSmoker: return 60; + case CustomStatistic::InteractWithStonecutter: return 65; + case CustomStatistic::Jump: return 19; + case CustomStatistic::LeaveGame: return 0; + case CustomStatistic::MinecartOneCm: return 13; + case CustomStatistic::MobKills: return 29; + case CustomStatistic::OpenBarrel: return 58; + case CustomStatistic::OpenChest: return 55; + case CustomStatistic::OpenEnderchest: return 50; + case CustomStatistic::OpenShulkerBox: return 57; + case CustomStatistic::PigOneCm: return 15; + case CustomStatistic::PlayerKills: return 31; + case CustomStatistic::PlayNoteblock: return 46; + case CustomStatistic::PlayOneMinute: return 1; + case CustomStatistic::PlayRecord: return 52; + case CustomStatistic::PotFlower: return 48; + case CustomStatistic::RaidTrigger: return 67; + case CustomStatistic::RaidWin: return 68; + case CustomStatistic::SleepInBed: return 56; + case CustomStatistic::SneakTime: return 4; + case CustomStatistic::SprintOneCm: return 7; + case CustomStatistic::SwimOneCm: return 18; + case CustomStatistic::TalkedToVillager: return 33; + case CustomStatistic::TimeSinceDeath: return 2; + case CustomStatistic::TimeSinceRest: return 3; + case CustomStatistic::TradedWithVillager: return 34; + case CustomStatistic::TriggerTrappedChest: return 49; + case CustomStatistic::TuneNoteblock: return 47; + case CustomStatistic::UseCauldron: return 37; + case CustomStatistic::WalkOneCm: return 5; + case CustomStatistic::WalkOnWaterOneCm: return 8; + case CustomStatistic::WalkUnderWaterOneCm: return 12; default: return static_cast(-1); } } diff --git a/src/Protocol/Palettes/Palette_1_14.h b/src/Protocol/Palettes/Palette_1_14.h index 037d9b4c1..c92a19eba 100644 --- a/src/Protocol/Palettes/Palette_1_14.h +++ b/src/Protocol/Palettes/Palette_1_14.h @@ -8,6 +8,6 @@ namespace Palette_1_14 { UInt32 From(BlockState Block); UInt32 From(Item ID); - UInt32 From(Statistic ID); + UInt32 From(CustomStatistic ID); Item ToItem(UInt32 ID); } diff --git a/src/Protocol/Palettes/Palette_1_15.cpp b/src/Protocol/Palettes/Palette_1_15.cpp index 4070a3715..29467d6d7 100644 --- a/src/Protocol/Palettes/Palette_1_15.cpp +++ b/src/Protocol/Palettes/Palette_1_15.cpp @@ -9578,81 +9578,81 @@ namespace Palette_1_15 } } - UInt32 From(const Statistic ID) + UInt32 From(const CustomStatistic ID) { switch (ID) { - case Statistic::AnimalsBred: return 30; - case Statistic::AviateOneCm: return 17; - case Statistic::BellRing: return 66; - case Statistic::BoatOneCm: return 14; - case Statistic::CleanArmor: return 38; - case Statistic::CleanBanner: return 39; - case Statistic::CleanShulkerBox: return 40; - case Statistic::ClimbOneCm: return 10; - case Statistic::CrouchOneCm: return 6; - case Statistic::DamageAbsorbed: return 26; - case Statistic::DamageBlockedByShield: return 25; - case Statistic::DamageDealt: return 21; - case Statistic::DamageDealtAbsorbed: return 22; - case Statistic::DamageDealtResisted: return 23; - case Statistic::DamageResisted: return 27; - case Statistic::DamageTaken: return 24; - case Statistic::Deaths: return 28; - case Statistic::Drop: return 20; - case Statistic::EatCakeSlice: return 35; - case Statistic::EnchantItem: return 51; - case Statistic::FallOneCm: return 9; - case Statistic::FillCauldron: return 36; - case Statistic::FishCaught: return 32; - case Statistic::FlyOneCm: return 11; - case Statistic::HorseOneCm: return 16; - case Statistic::InspectDispenser: return 45; - case Statistic::InspectDropper: return 43; - case Statistic::InspectHopper: return 44; - case Statistic::InteractWithAnvil: return 69; - case Statistic::InteractWithBeacon: return 42; - case Statistic::InteractWithBlastFurnace: return 59; - case Statistic::InteractWithBrewingstand: return 41; - case Statistic::InteractWithCampfire: return 62; - case Statistic::InteractWithCartographyTable: return 63; - case Statistic::InteractWithCraftingTable: return 54; - case Statistic::InteractWithFurnace: return 53; - case Statistic::InteractWithGrindstone: return 70; - case Statistic::InteractWithLectern: return 61; - case Statistic::InteractWithLoom: return 64; - case Statistic::InteractWithSmoker: return 60; - case Statistic::InteractWithStonecutter: return 65; - case Statistic::Jump: return 19; - case Statistic::LeaveGame: return -0; - case Statistic::MinecartOneCm: return 13; - case Statistic::MobKills: return 29; - case Statistic::OpenBarrel: return 58; - case Statistic::OpenChest: return 55; - case Statistic::OpenEnderchest: return 50; - case Statistic::OpenShulkerBox: return 57; - case Statistic::PigOneCm: return 15; - case Statistic::PlayNoteblock: return 46; - case Statistic::PlayOneMinute: return 1; - case Statistic::PlayRecord: return 52; - case Statistic::PlayerKills: return 31; - case Statistic::PotFlower: return 48; - case Statistic::RaidTrigger: return 67; - case Statistic::RaidWin: return 68; - case Statistic::SleepInBed: return 56; - case Statistic::SneakTime: return 4; - case Statistic::SprintOneCm: return 7; - case Statistic::SwimOneCm: return 18; - case Statistic::TalkedToVillager: return 33; - case Statistic::TimeSinceDeath: return 2; - case Statistic::TimeSinceRest: return 3; - case Statistic::TradedWithVillager: return 34; - case Statistic::TriggerTrappedChest: return 49; - case Statistic::TuneNoteblock: return 47; - case Statistic::UseCauldron: return 37; - case Statistic::WalkOnWaterOneCm: return 8; - case Statistic::WalkOneCm: return 5; - case Statistic::WalkUnderWaterOneCm: return 12; + case CustomStatistic::AnimalsBred: return 30; + case CustomStatistic::AviateOneCm: return 17; + case CustomStatistic::BellRing: return 66; + case CustomStatistic::BoatOneCm: return 14; + case CustomStatistic::CleanArmor: return 38; + case CustomStatistic::CleanBanner: return 39; + case CustomStatistic::CleanShulkerBox: return 40; + case CustomStatistic::ClimbOneCm: return 10; + case CustomStatistic::CrouchOneCm: return 6; + case CustomStatistic::DamageAbsorbed: return 26; + case CustomStatistic::DamageBlockedByShield: return 25; + case CustomStatistic::DamageDealt: return 21; + case CustomStatistic::DamageDealtAbsorbed: return 22; + case CustomStatistic::DamageDealtResisted: return 23; + case CustomStatistic::DamageResisted: return 27; + case CustomStatistic::DamageTaken: return 24; + case CustomStatistic::Deaths: return 28; + case CustomStatistic::Drop: return 20; + case CustomStatistic::EatCakeSlice: return 35; + case CustomStatistic::EnchantItem: return 51; + case CustomStatistic::FallOneCm: return 9; + case CustomStatistic::FillCauldron: return 36; + case CustomStatistic::FishCaught: return 32; + case CustomStatistic::FlyOneCm: return 11; + case CustomStatistic::HorseOneCm: return 16; + case CustomStatistic::InspectDispenser: return 45; + case CustomStatistic::InspectDropper: return 43; + case CustomStatistic::InspectHopper: return 44; + case CustomStatistic::InteractWithAnvil: return 69; + case CustomStatistic::InteractWithBeacon: return 42; + case CustomStatistic::InteractWithBlastFurnace: return 59; + case CustomStatistic::InteractWithBrewingstand: return 41; + case CustomStatistic::InteractWithCampfire: return 62; + case CustomStatistic::InteractWithCartographyTable: return 63; + case CustomStatistic::InteractWithCraftingTable: return 54; + case CustomStatistic::InteractWithFurnace: return 53; + case CustomStatistic::InteractWithGrindstone: return 70; + case CustomStatistic::InteractWithLectern: return 61; + case CustomStatistic::InteractWithLoom: return 64; + case CustomStatistic::InteractWithSmoker: return 60; + case CustomStatistic::InteractWithStonecutter: return 65; + case CustomStatistic::Jump: return 19; + case CustomStatistic::LeaveGame: return -0; + case CustomStatistic::MinecartOneCm: return 13; + case CustomStatistic::MobKills: return 29; + case CustomStatistic::OpenBarrel: return 58; + case CustomStatistic::OpenChest: return 55; + case CustomStatistic::OpenEnderchest: return 50; + case CustomStatistic::OpenShulkerBox: return 57; + case CustomStatistic::PigOneCm: return 15; + case CustomStatistic::PlayNoteblock: return 46; + case CustomStatistic::PlayOneMinute: return 1; + case CustomStatistic::PlayRecord: return 52; + case CustomStatistic::PlayerKills: return 31; + case CustomStatistic::PotFlower: return 48; + case CustomStatistic::RaidTrigger: return 67; + case CustomStatistic::RaidWin: return 68; + case CustomStatistic::SleepInBed: return 56; + case CustomStatistic::SneakTime: return 4; + case CustomStatistic::SprintOneCm: return 7; + case CustomStatistic::SwimOneCm: return 18; + case CustomStatistic::TalkedToVillager: return 33; + case CustomStatistic::TimeSinceDeath: return 2; + case CustomStatistic::TimeSinceRest: return 3; + case CustomStatistic::TradedWithVillager: return 34; + case CustomStatistic::TriggerTrappedChest: return 49; + case CustomStatistic::TuneNoteblock: return 47; + case CustomStatistic::UseCauldron: return 37; + case CustomStatistic::WalkOnWaterOneCm: return 8; + case CustomStatistic::WalkOneCm: return 5; + case CustomStatistic::WalkUnderWaterOneCm: return 12; default: return UInt32(-1); } } diff --git a/src/Protocol/Palettes/Palette_1_15.h b/src/Protocol/Palettes/Palette_1_15.h index 7fcac7e72..22c993de7 100644 --- a/src/Protocol/Palettes/Palette_1_15.h +++ b/src/Protocol/Palettes/Palette_1_15.h @@ -8,6 +8,6 @@ namespace Palette_1_15 { UInt32 From(BlockState Block); UInt32 From(Item ID); - UInt32 From(Statistic ID); + UInt32 From(CustomStatistic ID); Item ToItem(UInt32 ID); } diff --git a/src/Protocol/Palettes/Palette_1_16.cpp b/src/Protocol/Palettes/Palette_1_16.cpp index fae43766d..86b684cb8 100644 --- a/src/Protocol/Palettes/Palette_1_16.cpp +++ b/src/Protocol/Palettes/Palette_1_16.cpp @@ -12762,84 +12762,84 @@ namespace Palette_1_16 UNREACHABLE("Invalid item"); } - UInt32 From(const Statistic ID) + UInt32 From(const CustomStatistic ID) { switch (ID) { - case Statistic::AnimalsBred: return 31; - case Statistic::AviateOneCm: return 17; - case Statistic::BellRing: return 67; - case Statistic::BoatOneCm: return 14; - case Statistic::CleanArmor: return 39; - case Statistic::CleanBanner: return 40; - case Statistic::CleanShulkerBox: return 41; - case Statistic::ClimbOneCm: return 10; - case Statistic::CrouchOneCm: return 6; - case Statistic::DamageAbsorbed: return 27; - case Statistic::DamageBlockedByShield: return 26; - case Statistic::DamageDealt: return 22; - case Statistic::DamageDealtAbsorbed: return 23; - case Statistic::DamageDealtResisted: return 24; - case Statistic::DamageResisted: return 28; - case Statistic::DamageTaken: return 25; - case Statistic::Deaths: return 29; - case Statistic::Drop: return 21; - case Statistic::EatCakeSlice: return 36; - case Statistic::EnchantItem: return 52; - case Statistic::FallOneCm: return 9; - case Statistic::FillCauldron: return 37; - case Statistic::FishCaught: return 33; - case Statistic::FlyOneCm: return 11; - case Statistic::HorseOneCm: return 16; - case Statistic::InspectDispenser: return 46; - case Statistic::InspectDropper: return 44; - case Statistic::InspectHopper: return 45; - case Statistic::InteractWithAnvil: return 70; - case Statistic::InteractWithBeacon: return 43; - case Statistic::InteractWithBlastFurnace: return 60; - case Statistic::InteractWithBrewingstand: return 42; - case Statistic::InteractWithCampfire: return 63; - case Statistic::InteractWithCartographyTable: return 64; - case Statistic::InteractWithCraftingTable: return 55; - case Statistic::InteractWithFurnace: return 54; - case Statistic::InteractWithGrindstone: return 71; - case Statistic::InteractWithLectern: return 62; - case Statistic::InteractWithLoom: return 65; - case Statistic::InteractWithSmithingTable: return 73; - case Statistic::InteractWithSmoker: return 61; - case Statistic::InteractWithStonecutter: return 66; - case Statistic::Jump: return 20; - case Statistic::LeaveGame: return -0; - case Statistic::MinecartOneCm: return 13; - case Statistic::MobKills: return 30; - case Statistic::OpenBarrel: return 59; - case Statistic::OpenChest: return 56; - case Statistic::OpenEnderchest: return 51; - case Statistic::OpenShulkerBox: return 58; - case Statistic::PigOneCm: return 15; - case Statistic::PlayNoteblock: return 47; - case Statistic::PlayOneMinute: return 1; - case Statistic::PlayRecord: return 53; - case Statistic::PlayerKills: return 32; - case Statistic::PotFlower: return 49; - case Statistic::RaidTrigger: return 68; - case Statistic::RaidWin: return 69; - case Statistic::SleepInBed: return 57; - case Statistic::SneakTime: return 4; - case Statistic::SprintOneCm: return 7; - case Statistic::StriderOneCm: return 19; - case Statistic::SwimOneCm: return 18; - case Statistic::TalkedToVillager: return 34; - case Statistic::TargetHit: return 72; - case Statistic::TimeSinceDeath: return 2; - case Statistic::TimeSinceRest: return 3; - case Statistic::TradedWithVillager: return 35; - case Statistic::TriggerTrappedChest: return 50; - case Statistic::TuneNoteblock: return 48; - case Statistic::UseCauldron: return 38; - case Statistic::WalkOnWaterOneCm: return 8; - case Statistic::WalkOneCm: return 5; - case Statistic::WalkUnderWaterOneCm: return 12; + case CustomStatistic::AnimalsBred: return 31; + case CustomStatistic::AviateOneCm: return 17; + case CustomStatistic::BellRing: return 67; + case CustomStatistic::BoatOneCm: return 14; + case CustomStatistic::CleanArmor: return 39; + case CustomStatistic::CleanBanner: return 40; + case CustomStatistic::CleanShulkerBox: return 41; + case CustomStatistic::ClimbOneCm: return 10; + case CustomStatistic::CrouchOneCm: return 6; + case CustomStatistic::DamageAbsorbed: return 27; + case CustomStatistic::DamageBlockedByShield: return 26; + case CustomStatistic::DamageDealt: return 22; + case CustomStatistic::DamageDealtAbsorbed: return 23; + case CustomStatistic::DamageDealtResisted: return 24; + case CustomStatistic::DamageResisted: return 28; + case CustomStatistic::DamageTaken: return 25; + case CustomStatistic::Deaths: return 29; + case CustomStatistic::Drop: return 21; + case CustomStatistic::EatCakeSlice: return 36; + case CustomStatistic::EnchantItem: return 52; + case CustomStatistic::FallOneCm: return 9; + case CustomStatistic::FillCauldron: return 37; + case CustomStatistic::FishCaught: return 33; + case CustomStatistic::FlyOneCm: return 11; + case CustomStatistic::HorseOneCm: return 16; + case CustomStatistic::InspectDispenser: return 46; + case CustomStatistic::InspectDropper: return 44; + case CustomStatistic::InspectHopper: return 45; + case CustomStatistic::InteractWithAnvil: return 70; + case CustomStatistic::InteractWithBeacon: return 43; + case CustomStatistic::InteractWithBlastFurnace: return 60; + case CustomStatistic::InteractWithBrewingstand: return 42; + case CustomStatistic::InteractWithCampfire: return 63; + case CustomStatistic::InteractWithCartographyTable: return 64; + case CustomStatistic::InteractWithCraftingTable: return 55; + case CustomStatistic::InteractWithFurnace: return 54; + case CustomStatistic::InteractWithGrindstone: return 71; + case CustomStatistic::InteractWithLectern: return 62; + case CustomStatistic::InteractWithLoom: return 65; + case CustomStatistic::InteractWithSmithingTable: return 73; + case CustomStatistic::InteractWithSmoker: return 61; + case CustomStatistic::InteractWithStonecutter: return 66; + case CustomStatistic::Jump: return 20; + case CustomStatistic::LeaveGame: return -0; + case CustomStatistic::MinecartOneCm: return 13; + case CustomStatistic::MobKills: return 30; + case CustomStatistic::OpenBarrel: return 59; + case CustomStatistic::OpenChest: return 56; + case CustomStatistic::OpenEnderchest: return 51; + case CustomStatistic::OpenShulkerBox: return 58; + case CustomStatistic::PigOneCm: return 15; + case CustomStatistic::PlayNoteblock: return 47; + case CustomStatistic::PlayOneMinute: return 1; + case CustomStatistic::PlayRecord: return 53; + case CustomStatistic::PlayerKills: return 32; + case CustomStatistic::PotFlower: return 49; + case CustomStatistic::RaidTrigger: return 68; + case CustomStatistic::RaidWin: return 69; + case CustomStatistic::SleepInBed: return 57; + case CustomStatistic::SneakTime: return 4; + case CustomStatistic::SprintOneCm: return 7; + case CustomStatistic::StriderOneCm: return 19; + case CustomStatistic::SwimOneCm: return 18; + case CustomStatistic::TalkedToVillager: return 34; + case CustomStatistic::TargetHit: return 72; + case CustomStatistic::TimeSinceDeath: return 2; + case CustomStatistic::TimeSinceRest: return 3; + case CustomStatistic::TradedWithVillager: return 35; + case CustomStatistic::TriggerTrappedChest: return 50; + case CustomStatistic::TuneNoteblock: return 48; + case CustomStatistic::UseCauldron: return 38; + case CustomStatistic::WalkOnWaterOneCm: return 8; + case CustomStatistic::WalkOneCm: return 5; + case CustomStatistic::WalkUnderWaterOneCm: return 12; default: return UInt32(-1); } } diff --git a/src/Protocol/Palettes/Palette_1_16.h b/src/Protocol/Palettes/Palette_1_16.h index 6e6e632ce..ae6cf9484 100644 --- a/src/Protocol/Palettes/Palette_1_16.h +++ b/src/Protocol/Palettes/Palette_1_16.h @@ -8,6 +8,6 @@ namespace Palette_1_16 { UInt32 From(BlockState Block); UInt32 From(Item ID); - UInt32 From(Statistic ID); + UInt32 From(CustomStatistic ID); Item ToItem(UInt32 ID); } diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index c87ab4a7d..334d8d56b 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -29,9 +29,10 @@ class cPainting; class cWorld; class cMonster; class cCompositeChat; -class cStatManager; class cPacketizer; +struct StatisticsManager; + @@ -422,7 +423,7 @@ public: virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; virtual void SendSpawnEntity (const cEntity & a_Entity) = 0; virtual void SendSpawnMob (const cMonster & a_Mob) = 0; - virtual void SendStatistics (const cStatManager & a_Manager) = 0; + virtual void SendStatistics (const StatisticsManager & a_Manager) = 0; virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) = 0; diff --git a/src/Protocol/Protocol_1_13.cpp b/src/Protocol/Protocol_1_13.cpp index 44a011c76..336f3c339 100644 --- a/src/Protocol/Protocol_1_13.cpp +++ b/src/Protocol/Protocol_1_13.cpp @@ -142,24 +142,22 @@ void cProtocol_1_13::SendScoreboardObjective(const AString & a_Name, const AStri -void cProtocol_1_13::SendStatistics(const cStatManager & a_Manager) +void cProtocol_1_13::SendStatistics(const StatisticsManager & a_Manager) { ASSERT(m_State == 3); // In game mode? UInt32 Size = 0; - a_Manager.ForEachStatisticType([this, &Size](const auto & Store) - { - for (const auto & Item : Store) - { - // Client balks at out-of-range values so there is no good default value - // We're forced to not send the statistics this protocol version doesn't support - if (GetProtocolStatisticType(Item.first) != static_cast(-1)) - { - Size++; - } + for (const auto & [Statistic, Value] : a_Manager.Custom) + { + // Client balks at out-of-range values so there is no good default value. + // We're forced to not send the statistics this protocol version doesn't support. + + if (GetProtocolStatisticType(Statistic) != static_cast(-1)) + { + Size++; } - }); + } // No need to check Size != 0 // Assume that the vast majority of the time there's at least one statistic to send @@ -167,22 +165,19 @@ void cProtocol_1_13::SendStatistics(const cStatManager & a_Manager) cPacketizer Pkt(*this, pktStatistics); Pkt.WriteVarInt32(Size); - a_Manager.ForEachStatisticType([this, &Pkt](const cStatManager::CustomStore & Store) + for (const auto & [Statistic, Value] : a_Manager.Custom) { - for (const auto & Item : Store) + const auto ID = GetProtocolStatisticType(Statistic); + if (ID == static_cast(-1)) { - const auto ID = GetProtocolStatisticType(Item.first); - if (ID == static_cast(-1)) - { - // Unsupported, don't send: - continue; - } - - Pkt.WriteVarInt32(8); // "Custom" category - Pkt.WriteVarInt32(ID); - Pkt.WriteVarInt32(static_cast(Item.second)); + // Unsupported, don't send: + continue; } - }); + + Pkt.WriteVarInt32(8); // "Custom" category. + Pkt.WriteVarInt32(ID); + Pkt.WriteVarInt32(static_cast(Value)); + } } @@ -588,7 +583,7 @@ UInt32 cProtocol_1_13::GetProtocolMobType(eMonsterType a_MobType) const -UInt32 cProtocol_1_13::GetProtocolStatisticType(Statistic a_Statistic) const +UInt32 cProtocol_1_13::GetProtocolStatisticType(const CustomStatistic a_Statistic) const { return Palette_1_13::From(a_Statistic); } @@ -1480,7 +1475,7 @@ UInt32 cProtocol_1_13_1::GetProtocolItemType(short a_ItemID, short a_ItemDamage) -UInt32 cProtocol_1_13_1::GetProtocolStatisticType(Statistic a_Statistic) const +UInt32 cProtocol_1_13_1::GetProtocolStatisticType(const CustomStatistic a_Statistic) const { return Palette_1_13_1::From(a_Statistic); } diff --git a/src/Protocol/Protocol_1_13.h b/src/Protocol/Protocol_1_13.h index b478fe5ed..53e7cdc91 100644 --- a/src/Protocol/Protocol_1_13.h +++ b/src/Protocol/Protocol_1_13.h @@ -42,7 +42,7 @@ protected: virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) override; virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; - virtual void SendStatistics (const cStatManager & a_Manager) override; + virtual void SendStatistics (const StatisticsManager & a_Manager) override; virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; virtual UInt8 GetEntityMetadataID(EntityMetadata a_Metadata) const; @@ -53,7 +53,7 @@ protected: virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override; virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const; virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override; - virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const; + virtual UInt32 GetProtocolStatisticType(CustomStatistic a_Statistic) const; virtual Version GetProtocolVersion() const override; virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override; @@ -88,7 +88,7 @@ protected: virtual std::pair GetItemFromProtocolID(UInt32 a_ProtocolID) const override; virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override; virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const override; - virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const override; + virtual UInt32 GetProtocolStatisticType(CustomStatistic a_Statistic) const override; virtual Version GetProtocolVersion() const override; }; diff --git a/src/Protocol/Protocol_1_14.cpp b/src/Protocol/Protocol_1_14.cpp index f2bbdd955..161bf2f4d 100644 --- a/src/Protocol/Protocol_1_14.cpp +++ b/src/Protocol/Protocol_1_14.cpp @@ -238,7 +238,7 @@ UInt32 cProtocol_1_14::GetProtocolItemType(short a_ItemID, short a_ItemDamage) c -UInt32 cProtocol_1_14::GetProtocolStatisticType(Statistic a_Statistic) const +UInt32 cProtocol_1_14::GetProtocolStatisticType(const CustomStatistic a_Statistic) const { return Palette_1_14::From(a_Statistic); } diff --git a/src/Protocol/Protocol_1_14.h b/src/Protocol/Protocol_1_14.h index 32ae6640e..f4907a7d0 100644 --- a/src/Protocol/Protocol_1_14.h +++ b/src/Protocol/Protocol_1_14.h @@ -45,7 +45,7 @@ protected: virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override; virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override; virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const override; - virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const override; + virtual UInt32 GetProtocolStatisticType(CustomStatistic a_Statistic) const override; virtual Version GetProtocolVersion() const override; virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override; diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index 78483a45d..980348887 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -1458,30 +1458,21 @@ void cProtocol_1_8_0::SendSpawnMob(const cMonster & a_Mob) -void cProtocol_1_8_0::SendStatistics(const cStatManager & a_Manager) +void cProtocol_1_8_0::SendStatistics(const StatisticsManager & a_Manager) { ASSERT(m_State == 3); // In game mode? - UInt32 Size = 0; - a_Manager.ForEachStatisticType([&Size](const auto & Store) - { - Size += static_cast(Store.size()); - }); - - // No need to check Size != 0 - // Assume that the vast majority of the time there's at least one statistic to send - cPacketizer Pkt(*this, pktStatistics); - Pkt.WriteVarInt32(Size); - a_Manager.ForEachStatisticType([&Pkt](const cStatManager::CustomStore & Store) + // No need to check Size != 0. + // Assume that the vast majority of the time there's at least one statistic to send: + Pkt.WriteVarInt32(static_cast(a_Manager.Custom.size())); + + for (const auto & [Statistic, Value] : a_Manager.Custom) { - for (const auto & Item : Store) - { - Pkt.WriteString(GetProtocolStatisticName(Item.first)); - Pkt.WriteVarInt32(static_cast(Item.second)); - } - }); + Pkt.WriteString(GetProtocolStatisticName(Statistic)); + Pkt.WriteVarInt32(static_cast(Value)); + } } @@ -2401,15 +2392,13 @@ void cProtocol_1_8_0::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) case 1: { // Request stats - const cStatManager & Manager = m_Client->GetPlayer()->GetStatManager(); - SendStatistics(Manager); - + SendStatistics(m_Client->GetPlayer()->GetStatistics()); break; } case 2: { // Open Inventory achievement - m_Client->GetPlayer()->AwardAchievement(Statistic::AchOpenInventory); + m_Client->GetPlayer()->AwardAchievement(CustomStatistic::AchOpenInventory); break; } } @@ -4042,99 +4031,99 @@ int cProtocol_1_8_0::GetProtocolParticleID(const AString & a_ParticleName) -const char * cProtocol_1_8_0::GetProtocolStatisticName(Statistic a_Statistic) +const char * cProtocol_1_8_0::GetProtocolStatisticName(const CustomStatistic a_Statistic) { switch (a_Statistic) { // V1.8 Achievements - case Statistic::AchOpenInventory: return "achievement.openInventory"; - case Statistic::AchMineWood: return "achievement.mineWood"; - case Statistic::AchBuildWorkBench: return "achievement.buildWorkBench"; - case Statistic::AchBuildPickaxe: return "achievement.buildPickaxe"; - case Statistic::AchBuildFurnace: return "achievement.buildFurnace"; - case Statistic::AchAcquireIron: return "achievement.acquireIron"; - case Statistic::AchBuildHoe: return "achievement.buildHoe"; - case Statistic::AchMakeBread: return "achievement.makeBread"; - case Statistic::AchBakeCake: return "achievement.bakeCake"; - case Statistic::AchBuildBetterPickaxe: return "achievement.buildBetterPickaxe"; - case Statistic::AchCookFish: return "achievement.cookFish"; - case Statistic::AchOnARail: return "achievement.onARail"; - case Statistic::AchBuildSword: return "achievement.buildSword"; - case Statistic::AchKillEnemy: return "achievement.killEnemy"; - case Statistic::AchKillCow: return "achievement.killCow"; - case Statistic::AchFlyPig: return "achievement.flyPig"; - case Statistic::AchSnipeSkeleton: return "achievement.snipeSkeleton"; - case Statistic::AchDiamonds: return "achievement.diamonds"; - case Statistic::AchPortal: return "achievement.portal"; - case Statistic::AchGhast: return "achievement.ghast"; - case Statistic::AchBlazeRod: return "achievement.blazeRod"; - case Statistic::AchPotion: return "achievement.potion"; - case Statistic::AchTheEnd: return "achievement.theEnd"; - case Statistic::AchTheEnd2: return "achievement.theEnd2"; - case Statistic::AchEnchantments: return "achievement.enchantments"; - case Statistic::AchOverkill: return "achievement.overkill"; - case Statistic::AchBookcase: return "achievement.bookcase"; - case Statistic::AchExploreAllBiomes: return "achievement.exploreAllBiomes"; - case Statistic::AchSpawnWither: return "achievement.spawnWither"; - case Statistic::AchKillWither: return "achievement.killWither"; - case Statistic::AchFullBeacon: return "achievement.fullBeacon"; - case Statistic::AchBreedCow: return "achievement.breedCow"; - case Statistic::AchDiamondsToYou: return "achievement.diamondsToYou"; + case CustomStatistic::AchOpenInventory: return "achievement.openInventory"; + case CustomStatistic::AchMineWood: return "achievement.mineWood"; + case CustomStatistic::AchBuildWorkBench: return "achievement.buildWorkBench"; + case CustomStatistic::AchBuildPickaxe: return "achievement.buildPickaxe"; + case CustomStatistic::AchBuildFurnace: return "achievement.buildFurnace"; + case CustomStatistic::AchAcquireIron: return "achievement.acquireIron"; + case CustomStatistic::AchBuildHoe: return "achievement.buildHoe"; + case CustomStatistic::AchMakeBread: return "achievement.makeBread"; + case CustomStatistic::AchBakeCake: return "achievement.bakeCake"; + case CustomStatistic::AchBuildBetterPickaxe: return "achievement.buildBetterPickaxe"; + case CustomStatistic::AchCookFish: return "achievement.cookFish"; + case CustomStatistic::AchOnARail: return "achievement.onARail"; + case CustomStatistic::AchBuildSword: return "achievement.buildSword"; + case CustomStatistic::AchKillEnemy: return "achievement.killEnemy"; + case CustomStatistic::AchKillCow: return "achievement.killCow"; + case CustomStatistic::AchFlyPig: return "achievement.flyPig"; + case CustomStatistic::AchSnipeSkeleton: return "achievement.snipeSkeleton"; + case CustomStatistic::AchDiamonds: return "achievement.diamonds"; + case CustomStatistic::AchPortal: return "achievement.portal"; + case CustomStatistic::AchGhast: return "achievement.ghast"; + case CustomStatistic::AchBlazeRod: return "achievement.blazeRod"; + case CustomStatistic::AchPotion: return "achievement.potion"; + case CustomStatistic::AchTheEnd: return "achievement.theEnd"; + case CustomStatistic::AchTheEnd2: return "achievement.theEnd2"; + case CustomStatistic::AchEnchantments: return "achievement.enchantments"; + case CustomStatistic::AchOverkill: return "achievement.overkill"; + case CustomStatistic::AchBookcase: return "achievement.bookcase"; + case CustomStatistic::AchExploreAllBiomes: return "achievement.exploreAllBiomes"; + case CustomStatistic::AchSpawnWither: return "achievement.spawnWither"; + case CustomStatistic::AchKillWither: return "achievement.killWither"; + case CustomStatistic::AchFullBeacon: return "achievement.fullBeacon"; + case CustomStatistic::AchBreedCow: return "achievement.breedCow"; + case CustomStatistic::AchDiamondsToYou: return "achievement.diamondsToYou"; // V1.8 stats - case Statistic::AnimalsBred: return "stat.animalsBred"; - case Statistic::BoatOneCm: return "stat.boatOneCm"; - case Statistic::ClimbOneCm: return "stat.climbOneCm"; - case Statistic::CrouchOneCm: return "stat.crouchOneCm"; - case Statistic::DamageDealt: return "stat.damageDealt"; - case Statistic::DamageTaken: return "stat.damageTaken"; - case Statistic::Deaths: return "stat.deaths"; - case Statistic::Drop: return "stat.drop"; - case Statistic::FallOneCm: return "stat.fallOneCm"; - case Statistic::FishCaught: return "stat.fishCaught"; - case Statistic::FlyOneCm: return "stat.flyOneCm"; - case Statistic::HorseOneCm: return "stat.horseOneCm"; - case Statistic::Jump: return "stat.jump"; - case Statistic::LeaveGame: return "stat.leaveGame"; - case Statistic::MinecartOneCm: return "stat.minecartOneCm"; - case Statistic::MobKills: return "stat.mobKills"; - case Statistic::PigOneCm: return "stat.pigOneCm"; - case Statistic::PlayerKills: return "stat.playerKills"; - case Statistic::PlayOneMinute: return "stat.playOneMinute"; - case Statistic::SprintOneCm: return "stat.sprintOneCm"; - case Statistic::SwimOneCm: return "stat.swimOneCm"; - case Statistic::TalkedToVillager: return "stat.talkedToVillager"; - case Statistic::TimeSinceDeath: return "stat.timeSinceDeath"; - case Statistic::TradedWithVillager: return "stat.tradedWithVillager"; - case Statistic::WalkOneCm: return "stat.walkOneCm"; - case Statistic::WalkUnderWaterOneCm: return "stat.diveOneCm"; + case CustomStatistic::AnimalsBred: return "stat.animalsBred"; + case CustomStatistic::BoatOneCm: return "stat.boatOneCm"; + case CustomStatistic::ClimbOneCm: return "stat.climbOneCm"; + case CustomStatistic::CrouchOneCm: return "stat.crouchOneCm"; + case CustomStatistic::DamageDealt: return "stat.damageDealt"; + case CustomStatistic::DamageTaken: return "stat.damageTaken"; + case CustomStatistic::Deaths: return "stat.deaths"; + case CustomStatistic::Drop: return "stat.drop"; + case CustomStatistic::FallOneCm: return "stat.fallOneCm"; + case CustomStatistic::FishCaught: return "stat.fishCaught"; + case CustomStatistic::FlyOneCm: return "stat.flyOneCm"; + case CustomStatistic::HorseOneCm: return "stat.horseOneCm"; + case CustomStatistic::Jump: return "stat.jump"; + case CustomStatistic::LeaveGame: return "stat.leaveGame"; + case CustomStatistic::MinecartOneCm: return "stat.minecartOneCm"; + case CustomStatistic::MobKills: return "stat.mobKills"; + case CustomStatistic::PigOneCm: return "stat.pigOneCm"; + case CustomStatistic::PlayerKills: return "stat.playerKills"; + case CustomStatistic::PlayOneMinute: return "stat.playOneMinute"; + case CustomStatistic::SprintOneCm: return "stat.sprintOneCm"; + case CustomStatistic::SwimOneCm: return "stat.swimOneCm"; + case CustomStatistic::TalkedToVillager: return "stat.talkedToVillager"; + case CustomStatistic::TimeSinceDeath: return "stat.timeSinceDeath"; + case CustomStatistic::TradedWithVillager: return "stat.tradedWithVillager"; + case CustomStatistic::WalkOneCm: return "stat.walkOneCm"; + case CustomStatistic::WalkUnderWaterOneCm: return "stat.diveOneCm"; // V1.8.2 stats - case Statistic::CleanArmor: return "stat.armorCleaned"; - case Statistic::CleanBanner: return "stat.bannerCleaned"; - case Statistic::EatCakeSlice: return "stat.cakeSlicesEaten"; - case Statistic::EnchantItem: return "stat.itemEnchanted"; - case Statistic::FillCauldron: return "stat.cauldronFilled"; - case Statistic::InspectDispenser: return "stat.dispenserInspected"; - case Statistic::InspectDropper: return "stat.dropperInspected"; - case Statistic::InspectHopper: return "stat.hopperInspected"; - case Statistic::InteractWithBeacon: return "stat.beaconInteraction"; - case Statistic::InteractWithBrewingstand: return "stat.brewingstandInteraction"; - case Statistic::InteractWithCraftingTable: return "stat.craftingTableInteraction"; - case Statistic::InteractWithFurnace: return "stat.furnaceInteraction"; - case Statistic::OpenChest: return "stat.chestOpened"; - case Statistic::OpenEnderchest: return "stat.enderchestOpened"; - case Statistic::PlayNoteblock: return "stat.noteblockPlayed"; - case Statistic::PlayRecord: return "stat.recordPlayed"; - case Statistic::PotFlower: return "stat.flowerPotted"; - case Statistic::TriggerTrappedChest: return "stat.trappedChestTriggered"; - case Statistic::TuneNoteblock: return "stat.noteblockTuned"; - case Statistic::UseCauldron: return "stat.cauldronUsed"; + case CustomStatistic::CleanArmor: return "stat.armorCleaned"; + case CustomStatistic::CleanBanner: return "stat.bannerCleaned"; + case CustomStatistic::EatCakeSlice: return "stat.cakeSlicesEaten"; + case CustomStatistic::EnchantItem: return "stat.itemEnchanted"; + case CustomStatistic::FillCauldron: return "stat.cauldronFilled"; + case CustomStatistic::InspectDispenser: return "stat.dispenserInspected"; + case CustomStatistic::InspectDropper: return "stat.dropperInspected"; + case CustomStatistic::InspectHopper: return "stat.hopperInspected"; + case CustomStatistic::InteractWithBeacon: return "stat.beaconInteraction"; + case CustomStatistic::InteractWithBrewingstand: return "stat.brewingstandInteraction"; + case CustomStatistic::InteractWithCraftingTable: return "stat.craftingTableInteraction"; + case CustomStatistic::InteractWithFurnace: return "stat.furnaceInteraction"; + case CustomStatistic::OpenChest: return "stat.chestOpened"; + case CustomStatistic::OpenEnderchest: return "stat.enderchestOpened"; + case CustomStatistic::PlayNoteblock: return "stat.noteblockPlayed"; + case CustomStatistic::PlayRecord: return "stat.recordPlayed"; + case CustomStatistic::PotFlower: return "stat.flowerPotted"; + case CustomStatistic::TriggerTrappedChest: return "stat.trappedChestTriggered"; + case CustomStatistic::TuneNoteblock: return "stat.noteblockTuned"; + case CustomStatistic::UseCauldron: return "stat.cauldronUsed"; // V1.9 stats - case Statistic::AviateOneCm: return "stat.aviateOneCm"; - case Statistic::SleepInBed: return "stat.sleepInBed"; - case Statistic::SneakTime: return "stat.sneakTime"; + case CustomStatistic::AviateOneCm: return "stat.aviateOneCm"; + case CustomStatistic::SleepInBed: return "stat.sleepInBed"; + case CustomStatistic::SneakTime: return "stat.sneakTime"; default: return ""; } } diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h index 652ef69c5..faea84e57 100644 --- a/src/Protocol/Protocol_1_8.h +++ b/src/Protocol/Protocol_1_8.h @@ -113,7 +113,7 @@ public: virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnEntity (const cEntity & a_Entity) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendStatistics (const cStatManager & a_Manager) override; + virtual void SendStatistics (const StatisticsManager & a_Manager) override; virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override; @@ -267,7 +267,7 @@ private: /** Converts a statistic to a protocol-specific string. Protocols <= 1.12 use strings, hence this is a static as the string-mapping was append-only for the versions that used it. Returns an empty string, handled correctly by the client, for newer, unsupported statistics. */ - static const char * GetProtocolStatisticName(Statistic a_Statistic); + static const char * GetProtocolStatisticName(CustomStatistic a_Statistic); /** Handle a complete packet stored in the given buffer. */ void HandlePacket(cByteBuffer & a_Buffer); diff --git a/src/Registries/Statistics.h b/src/Registries/Statistics.h index 82aef5442..c0edba191 100644 --- a/src/Registries/Statistics.h +++ b/src/Registries/Statistics.h @@ -1,7 +1,10 @@ #pragma once -enum class Statistic +// tolua_begin +enum class CustomStatistic { + // tolua_end + /* Achievements */ AchOpenInventory, /* Taking Inventory */ AchMineWood, /* Getting Wood */ @@ -37,6 +40,8 @@ enum class Statistic AchBreedCow, /* Repopulation */ AchDiamondsToYou, /* Diamonds to you! */ + // tolua_begin + /* Statistics */ AnimalsBred, AviateOneCm, @@ -117,3 +122,4 @@ enum class Statistic JunkFished, TreasureFished, }; +// tolua_end diff --git a/src/Statistics.cpp b/src/Statistics.cpp index 7bc5ae413..f037ec7b1 100644 --- a/src/Statistics.cpp +++ b/src/Statistics.cpp @@ -9,61 +9,43 @@ -void cStatManager::SetValue(const Statistic a_Stat, const StatValue a_Value) -{ - m_CustomStatistics[a_Stat] = a_Value; -} - - - - - -cStatManager::StatValue cStatManager::AddValue(const Statistic a_Stat, const StatValue a_Delta) -{ - return m_CustomStatistics[a_Stat] += a_Delta; -} - - - - - -bool cStatManager::SatisfiesPrerequisite(const Statistic a_Stat) +bool StatisticsManager::SatisfiesPrerequisite(const CustomStatistic a_Stat) const { switch (a_Stat) { - case Statistic::AchMineWood: return IsStatisticPresent(Statistic::AchOpenInventory); - case Statistic::AchBuildWorkBench: return IsStatisticPresent(Statistic::AchMineWood); - case Statistic::AchBuildHoe: return IsStatisticPresent(Statistic::AchBuildWorkBench); - case Statistic::AchBakeCake: return IsStatisticPresent(Statistic::AchBuildHoe); - case Statistic::AchMakeBread: return IsStatisticPresent(Statistic::AchBuildHoe); - case Statistic::AchBuildSword: return IsStatisticPresent(Statistic::AchBuildWorkBench); - case Statistic::AchKillCow: return IsStatisticPresent(Statistic::AchBuildSword); - case Statistic::AchFlyPig: return IsStatisticPresent(Statistic::AchKillCow); - case Statistic::AchBreedCow: return IsStatisticPresent(Statistic::AchKillCow); - case Statistic::AchKillEnemy: return IsStatisticPresent(Statistic::AchBuildSword); - case Statistic::AchSnipeSkeleton: return IsStatisticPresent(Statistic::AchKillEnemy); - case Statistic::AchBuildPickaxe: return IsStatisticPresent(Statistic::AchBuildWorkBench); - case Statistic::AchBuildBetterPickaxe: return IsStatisticPresent(Statistic::AchBuildPickaxe); - case Statistic::AchBuildFurnace: return IsStatisticPresent(Statistic::AchBuildWorkBench); - case Statistic::AchCookFish: return IsStatisticPresent(Statistic::AchBuildFurnace); - case Statistic::AchAcquireIron: return IsStatisticPresent(Statistic::AchBuildFurnace); - case Statistic::AchOnARail: return IsStatisticPresent(Statistic::AchAcquireIron); - case Statistic::AchDiamonds: return IsStatisticPresent(Statistic::AchAcquireIron); - case Statistic::AchPortal: return IsStatisticPresent(Statistic::AchDiamonds); - case Statistic::AchGhast: return IsStatisticPresent(Statistic::AchPortal); - case Statistic::AchBlazeRod: return IsStatisticPresent(Statistic::AchPortal); - case Statistic::AchPotion: return IsStatisticPresent(Statistic::AchBlazeRod); - case Statistic::AchTheEnd: return IsStatisticPresent(Statistic::AchBlazeRod); - case Statistic::AchTheEnd2: return IsStatisticPresent(Statistic::AchTheEnd); - case Statistic::AchEnchantments: return IsStatisticPresent(Statistic::AchDiamonds); - case Statistic::AchOverkill: return IsStatisticPresent(Statistic::AchEnchantments); - case Statistic::AchBookcase: return IsStatisticPresent(Statistic::AchEnchantments); - case Statistic::AchExploreAllBiomes: return IsStatisticPresent(Statistic::AchTheEnd); - case Statistic::AchSpawnWither: return IsStatisticPresent(Statistic::AchTheEnd2); - case Statistic::AchKillWither: return IsStatisticPresent(Statistic::AchSpawnWither); - case Statistic::AchFullBeacon: return IsStatisticPresent(Statistic::AchKillWither); - case Statistic::AchDiamondsToYou: return IsStatisticPresent(Statistic::AchDiamonds); - default: return true; + case CustomStatistic::AchMineWood: return IsStatisticPresent(CustomStatistic::AchOpenInventory); + case CustomStatistic::AchBuildWorkBench: return IsStatisticPresent(CustomStatistic::AchMineWood); + case CustomStatistic::AchBuildHoe: return IsStatisticPresent(CustomStatistic::AchBuildWorkBench); + case CustomStatistic::AchBakeCake: return IsStatisticPresent(CustomStatistic::AchBuildHoe); + case CustomStatistic::AchMakeBread: return IsStatisticPresent(CustomStatistic::AchBuildHoe); + case CustomStatistic::AchBuildSword: return IsStatisticPresent(CustomStatistic::AchBuildWorkBench); + case CustomStatistic::AchKillCow: return IsStatisticPresent(CustomStatistic::AchBuildSword); + case CustomStatistic::AchFlyPig: return IsStatisticPresent(CustomStatistic::AchKillCow); + case CustomStatistic::AchBreedCow: return IsStatisticPresent(CustomStatistic::AchKillCow); + case CustomStatistic::AchKillEnemy: return IsStatisticPresent(CustomStatistic::AchBuildSword); + case CustomStatistic::AchSnipeSkeleton: return IsStatisticPresent(CustomStatistic::AchKillEnemy); + case CustomStatistic::AchBuildPickaxe: return IsStatisticPresent(CustomStatistic::AchBuildWorkBench); + case CustomStatistic::AchBuildBetterPickaxe: return IsStatisticPresent(CustomStatistic::AchBuildPickaxe); + case CustomStatistic::AchBuildFurnace: return IsStatisticPresent(CustomStatistic::AchBuildWorkBench); + case CustomStatistic::AchCookFish: return IsStatisticPresent(CustomStatistic::AchBuildFurnace); + case CustomStatistic::AchAcquireIron: return IsStatisticPresent(CustomStatistic::AchBuildFurnace); + case CustomStatistic::AchOnARail: return IsStatisticPresent(CustomStatistic::AchAcquireIron); + case CustomStatistic::AchDiamonds: return IsStatisticPresent(CustomStatistic::AchAcquireIron); + case CustomStatistic::AchPortal: return IsStatisticPresent(CustomStatistic::AchDiamonds); + case CustomStatistic::AchGhast: return IsStatisticPresent(CustomStatistic::AchPortal); + case CustomStatistic::AchBlazeRod: return IsStatisticPresent(CustomStatistic::AchPortal); + case CustomStatistic::AchPotion: return IsStatisticPresent(CustomStatistic::AchBlazeRod); + case CustomStatistic::AchTheEnd: return IsStatisticPresent(CustomStatistic::AchBlazeRod); + case CustomStatistic::AchTheEnd2: return IsStatisticPresent(CustomStatistic::AchTheEnd); + case CustomStatistic::AchEnchantments: return IsStatisticPresent(CustomStatistic::AchDiamonds); + case CustomStatistic::AchOverkill: return IsStatisticPresent(CustomStatistic::AchEnchantments); + case CustomStatistic::AchBookcase: return IsStatisticPresent(CustomStatistic::AchEnchantments); + case CustomStatistic::AchExploreAllBiomes: return IsStatisticPresent(CustomStatistic::AchTheEnd); + case CustomStatistic::AchSpawnWither: return IsStatisticPresent(CustomStatistic::AchTheEnd2); + case CustomStatistic::AchKillWither: return IsStatisticPresent(CustomStatistic::AchSpawnWither); + case CustomStatistic::AchFullBeacon: return IsStatisticPresent(CustomStatistic::AchKillWither); + case CustomStatistic::AchDiamondsToYou: return IsStatisticPresent(CustomStatistic::AchDiamonds); + default: UNREACHABLE("Unsupported achievement type"); } } @@ -71,10 +53,10 @@ bool cStatManager::SatisfiesPrerequisite(const Statistic a_Stat) -bool cStatManager::IsStatisticPresent(const Statistic a_Stat) const +bool StatisticsManager::IsStatisticPresent(const CustomStatistic a_Stat) const { - const auto Result = m_CustomStatistics.find(a_Stat); - if (Result != m_CustomStatistics.end()) + const auto Result = Custom.find(a_Stat); + if (Result != Custom.end()) { return Result->second > 0; } diff --git a/src/Statistics.h b/src/Statistics.h index 5944ba8fa..38d2f0f7e 100644 --- a/src/Statistics.h +++ b/src/Statistics.h @@ -25,35 +25,19 @@ exported from the server https://wiki.vg/Data_Generators /** Class that manages the statistics and achievements of a single player. */ -class cStatManager +struct StatisticsManager { -public: - typedef unsigned StatValue; - typedef std::unordered_map CustomStore; - /** Set the value of the specified statistic. */ - void SetValue(Statistic a_Stat, StatValue a_Value); + // TODO: Block tallies, entities killed, all the others - /** Increments the specified statistic. Returns the new value. */ - StatValue AddValue(Statistic a_Stat, StatValue a_Delta = 1); + std::unordered_map Custom; /** Returns whether the prerequisite for awarding an achievement are satisfied. */ - bool SatisfiesPrerequisite(Statistic a_Stat); - - /** Invokes the given callbacks for each category of tracked statistics. */ - template - void ForEachStatisticType(CustomCallback a_Custom) const - { - a_Custom(m_CustomStatistics); - } + bool SatisfiesPrerequisite(CustomStatistic a_Stat) const; private: /** Returns if a statistic is both present and has nonzero value. */ - bool IsStatisticPresent(Statistic a_Stat) const; - - // TODO: Block tallies, entities killed, all the others - - CustomStore m_CustomStatistics; + bool IsStatisticPresent(CustomStatistic a_Stat) const; }; diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 2d5d0cedd..6d27ea834 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -766,16 +766,16 @@ void cSlotAreaCrafting::HandleCraftItem(const cItem & a_Result, cPlayer & a_Play { switch (a_Result.m_ItemType) { - case E_BLOCK_WORKBENCH: a_Player.AwardAchievement(Statistic::AchBuildWorkBench); break; - case E_BLOCK_FURNACE: a_Player.AwardAchievement(Statistic::AchBuildFurnace); break; - case E_BLOCK_CAKE: a_Player.AwardAchievement(Statistic::AchBakeCake); break; - case E_BLOCK_ENCHANTMENT_TABLE: a_Player.AwardAchievement(Statistic::AchEnchantments); break; - case E_BLOCK_BOOKCASE: a_Player.AwardAchievement(Statistic::AchBookcase); break; - case E_ITEM_WOODEN_PICKAXE: a_Player.AwardAchievement(Statistic::AchBuildPickaxe); break; - case E_ITEM_WOODEN_SWORD: a_Player.AwardAchievement(Statistic::AchBuildSword); break; - case E_ITEM_STONE_PICKAXE: a_Player.AwardAchievement(Statistic::AchBuildBetterPickaxe); break; - case E_ITEM_WOODEN_HOE: a_Player.AwardAchievement(Statistic::AchBuildHoe); break; - case E_ITEM_BREAD: a_Player.AwardAchievement(Statistic::AchMakeBread); break; + case E_BLOCK_WORKBENCH: a_Player.AwardAchievement(CustomStatistic::AchBuildWorkBench); break; + case E_BLOCK_FURNACE: a_Player.AwardAchievement(CustomStatistic::AchBuildFurnace); break; + case E_BLOCK_CAKE: a_Player.AwardAchievement(CustomStatistic::AchBakeCake); break; + case E_BLOCK_ENCHANTMENT_TABLE: a_Player.AwardAchievement(CustomStatistic::AchEnchantments); break; + case E_BLOCK_BOOKCASE: a_Player.AwardAchievement(CustomStatistic::AchBookcase); break; + case E_ITEM_WOODEN_PICKAXE: a_Player.AwardAchievement(CustomStatistic::AchBuildPickaxe); break; + case E_ITEM_WOODEN_SWORD: a_Player.AwardAchievement(CustomStatistic::AchBuildSword); break; + case E_ITEM_STONE_PICKAXE: a_Player.AwardAchievement(CustomStatistic::AchBuildBetterPickaxe); break; + case E_ITEM_WOODEN_HOE: a_Player.AwardAchievement(CustomStatistic::AchBuildHoe); break; + case E_ITEM_BREAD: a_Player.AwardAchievement(CustomStatistic::AchMakeBread); break; default: break; } } @@ -2105,8 +2105,8 @@ void cSlotAreaFurnace::HandleSmeltItem(const cItem & a_Result, cPlayer & a_Playe /** TODO 2014-05-12 xdot: Figure out when to call this method. */ switch (a_Result.m_ItemType) { - case E_ITEM_IRON: a_Player.AwardAchievement(Statistic::AchAcquireIron); break; - case E_ITEM_COOKED_FISH: a_Player.AwardAchievement(Statistic::AchCookFish); break; + case E_ITEM_IRON: a_Player.AwardAchievement(CustomStatistic::AchAcquireIron); break; + case E_ITEM_COOKED_FISH: a_Player.AwardAchievement(CustomStatistic::AchCookFish); break; default: break; } } @@ -2255,7 +2255,7 @@ void cSlotAreaBrewingstand::HandleBrewedItem(cPlayer & a_Player, const cItem & a // Award an achievement if the item is not a water bottle (is a real brewed potion) if (a_ClickedItem.m_ItemDamage > 0) { - a_Player.AwardAchievement(Statistic::AchPotion); + a_Player.AwardAchievement(CustomStatistic::AchPotion); } } diff --git a/src/WorldStorage/NamespaceSerializer.cpp b/src/WorldStorage/NamespaceSerializer.cpp index 8a4c9ea9b..2e2e9302e 100644 --- a/src/WorldStorage/NamespaceSerializer.cpp +++ b/src/WorldStorage/NamespaceSerializer.cpp @@ -15,123 +15,123 @@ unsigned NamespaceSerializer::DataVersion() -std::string_view NamespaceSerializer::From(const Statistic a_ID) +std::string_view NamespaceSerializer::From(const CustomStatistic a_ID) { switch (a_ID) { - case Statistic::AnimalsBred: return "animals_bred"; - case Statistic::AviateOneCm: return "aviate_one_cm"; - case Statistic::BellRing: return "bell_ring"; - case Statistic::BoatOneCm: return "boat_one_cm"; - case Statistic::CleanArmor: return "clean_armor"; - case Statistic::CleanBanner: return "clean_banner"; - case Statistic::CleanShulkerBox: return "clean_shulker_box"; - case Statistic::ClimbOneCm: return "climb_one_cm"; - case Statistic::CrouchOneCm: return "crouch_one_cm"; - case Statistic::DamageAbsorbed: return "damage_absorbed"; - case Statistic::DamageBlockedByShield: return "damage_blocked_by_shield"; - case Statistic::DamageDealt: return "damage_dealt"; - case Statistic::DamageDealtAbsorbed: return "damage_dealt_absorbed"; - case Statistic::DamageDealtResisted: return "damage_dealt_resisted"; - case Statistic::DamageResisted: return "damage_resisted"; - case Statistic::DamageTaken: return "damage_taken"; - case Statistic::Deaths: return "deaths"; - case Statistic::Drop: return "drop"; - case Statistic::EatCakeSlice: return "eat_cake_slice"; - case Statistic::EnchantItem: return "enchant_item"; - case Statistic::FallOneCm: return "fall_one_cm"; - case Statistic::FillCauldron: return "fill_cauldron"; - case Statistic::FishCaught: return "fish_caught"; - case Statistic::FlyOneCm: return "fly_one_cm"; - case Statistic::HorseOneCm: return "horse_one_cm"; - case Statistic::InspectDispenser: return "inspect_dispenser"; - case Statistic::InspectDropper: return "inspect_dropper"; - case Statistic::InspectHopper: return "inspect_hopper"; - case Statistic::InteractWithAnvil: return "interact_with_anvil"; - case Statistic::InteractWithBeacon: return "interact_with_beacon"; - case Statistic::InteractWithBlastFurnace: return "interact_with_blast_furnace"; - case Statistic::InteractWithBrewingstand: return "interact_with_brewingstand"; - case Statistic::InteractWithCampfire: return "interact_with_campfire"; - case Statistic::InteractWithCartographyTable: return "interact_with_cartography_table"; - case Statistic::InteractWithCraftingTable: return "interact_with_crafting_table"; - case Statistic::InteractWithFurnace: return "interact_with_furnace"; - case Statistic::InteractWithGrindstone: return "interact_with_grindstone"; - case Statistic::InteractWithLectern: return "interact_with_lectern"; - case Statistic::InteractWithLoom: return "interact_with_loom"; - case Statistic::InteractWithSmithingTable: return "interact_with_smithing_table"; - case Statistic::InteractWithSmoker: return "interact_with_smoker"; - case Statistic::InteractWithStonecutter: return "interact_with_stonecutter"; - case Statistic::Jump: return "jump"; - case Statistic::LeaveGame: return "leave_game"; - case Statistic::MinecartOneCm: return "minecart_one_cm"; - case Statistic::MobKills: return "mob_kills"; - case Statistic::OpenBarrel: return "open_barrel"; - case Statistic::OpenChest: return "open_chest"; - case Statistic::OpenEnderchest: return "open_enderchest"; - case Statistic::OpenShulkerBox: return "open_shulker_box"; - case Statistic::PigOneCm: return "pig_one_cm"; - case Statistic::PlayNoteblock: return "play_noteblock"; - case Statistic::PlayOneMinute: return "play_one_minute"; - case Statistic::PlayRecord: return "play_record"; - case Statistic::PlayerKills: return "player_kills"; - case Statistic::PotFlower: return "pot_flower"; - case Statistic::RaidTrigger: return "raid_trigger"; - case Statistic::RaidWin: return "raid_win"; - case Statistic::SleepInBed: return "sleep_in_bed"; - case Statistic::SneakTime: return "sneak_time"; - case Statistic::SprintOneCm: return "sprint_one_cm"; - case Statistic::StriderOneCm: return "strider_one_cm"; - case Statistic::SwimOneCm: return "swim_one_cm"; - case Statistic::TalkedToVillager: return "talked_to_villager"; - case Statistic::TargetHit: return "target_hit"; - case Statistic::TimeSinceDeath: return "time_since_death"; - case Statistic::TimeSinceRest: return "time_since_rest"; - case Statistic::TradedWithVillager: return "traded_with_villager"; - case Statistic::TriggerTrappedChest: return "trigger_trapped_chest"; - case Statistic::TuneNoteblock: return "tune_noteblock"; - case Statistic::UseCauldron: return "use_cauldron"; - case Statistic::WalkOnWaterOneCm: return "walk_on_water_one_cm"; - case Statistic::WalkOneCm: return "walk_one_cm"; - case Statistic::WalkUnderWaterOneCm: return "walk_under_water_one_cm"; + case CustomStatistic::AnimalsBred: return "animals_bred"; + case CustomStatistic::AviateOneCm: return "aviate_one_cm"; + case CustomStatistic::BellRing: return "bell_ring"; + case CustomStatistic::BoatOneCm: return "boat_one_cm"; + case CustomStatistic::CleanArmor: return "clean_armor"; + case CustomStatistic::CleanBanner: return "clean_banner"; + case CustomStatistic::CleanShulkerBox: return "clean_shulker_box"; + case CustomStatistic::ClimbOneCm: return "climb_one_cm"; + case CustomStatistic::CrouchOneCm: return "crouch_one_cm"; + case CustomStatistic::DamageAbsorbed: return "damage_absorbed"; + case CustomStatistic::DamageBlockedByShield: return "damage_blocked_by_shield"; + case CustomStatistic::DamageDealt: return "damage_dealt"; + case CustomStatistic::DamageDealtAbsorbed: return "damage_dealt_absorbed"; + case CustomStatistic::DamageDealtResisted: return "damage_dealt_resisted"; + case CustomStatistic::DamageResisted: return "damage_resisted"; + case CustomStatistic::DamageTaken: return "damage_taken"; + case CustomStatistic::Deaths: return "deaths"; + case CustomStatistic::Drop: return "drop"; + case CustomStatistic::EatCakeSlice: return "eat_cake_slice"; + case CustomStatistic::EnchantItem: return "enchant_item"; + case CustomStatistic::FallOneCm: return "fall_one_cm"; + case CustomStatistic::FillCauldron: return "fill_cauldron"; + case CustomStatistic::FishCaught: return "fish_caught"; + case CustomStatistic::FlyOneCm: return "fly_one_cm"; + case CustomStatistic::HorseOneCm: return "horse_one_cm"; + case CustomStatistic::InspectDispenser: return "inspect_dispenser"; + case CustomStatistic::InspectDropper: return "inspect_dropper"; + case CustomStatistic::InspectHopper: return "inspect_hopper"; + case CustomStatistic::InteractWithAnvil: return "interact_with_anvil"; + case CustomStatistic::InteractWithBeacon: return "interact_with_beacon"; + case CustomStatistic::InteractWithBlastFurnace: return "interact_with_blast_furnace"; + case CustomStatistic::InteractWithBrewingstand: return "interact_with_brewingstand"; + case CustomStatistic::InteractWithCampfire: return "interact_with_campfire"; + case CustomStatistic::InteractWithCartographyTable: return "interact_with_cartography_table"; + case CustomStatistic::InteractWithCraftingTable: return "interact_with_crafting_table"; + case CustomStatistic::InteractWithFurnace: return "interact_with_furnace"; + case CustomStatistic::InteractWithGrindstone: return "interact_with_grindstone"; + case CustomStatistic::InteractWithLectern: return "interact_with_lectern"; + case CustomStatistic::InteractWithLoom: return "interact_with_loom"; + case CustomStatistic::InteractWithSmithingTable: return "interact_with_smithing_table"; + case CustomStatistic::InteractWithSmoker: return "interact_with_smoker"; + case CustomStatistic::InteractWithStonecutter: return "interact_with_stonecutter"; + case CustomStatistic::Jump: return "jump"; + case CustomStatistic::LeaveGame: return "leave_game"; + case CustomStatistic::MinecartOneCm: return "minecart_one_cm"; + case CustomStatistic::MobKills: return "mob_kills"; + case CustomStatistic::OpenBarrel: return "open_barrel"; + case CustomStatistic::OpenChest: return "open_chest"; + case CustomStatistic::OpenEnderchest: return "open_enderchest"; + case CustomStatistic::OpenShulkerBox: return "open_shulker_box"; + case CustomStatistic::PigOneCm: return "pig_one_cm"; + case CustomStatistic::PlayNoteblock: return "play_noteblock"; + case CustomStatistic::PlayOneMinute: return "play_one_minute"; + case CustomStatistic::PlayRecord: return "play_record"; + case CustomStatistic::PlayerKills: return "player_kills"; + case CustomStatistic::PotFlower: return "pot_flower"; + case CustomStatistic::RaidTrigger: return "raid_trigger"; + case CustomStatistic::RaidWin: return "raid_win"; + case CustomStatistic::SleepInBed: return "sleep_in_bed"; + case CustomStatistic::SneakTime: return "sneak_time"; + case CustomStatistic::SprintOneCm: return "sprint_one_cm"; + case CustomStatistic::StriderOneCm: return "strider_one_cm"; + case CustomStatistic::SwimOneCm: return "swim_one_cm"; + case CustomStatistic::TalkedToVillager: return "talked_to_villager"; + case CustomStatistic::TargetHit: return "target_hit"; + case CustomStatistic::TimeSinceDeath: return "time_since_death"; + case CustomStatistic::TimeSinceRest: return "time_since_rest"; + case CustomStatistic::TradedWithVillager: return "traded_with_villager"; + case CustomStatistic::TriggerTrappedChest: return "trigger_trapped_chest"; + case CustomStatistic::TuneNoteblock: return "tune_noteblock"; + case CustomStatistic::UseCauldron: return "use_cauldron"; + case CustomStatistic::WalkOnWaterOneCm: return "walk_on_water_one_cm"; + case CustomStatistic::WalkOneCm: return "walk_one_cm"; + case CustomStatistic::WalkUnderWaterOneCm: return "walk_under_water_one_cm"; // Old ones just for compatibility - case Statistic::JunkFished: return "junk_fished"; - case Statistic::TreasureFished: return "treasure_fished"; + case CustomStatistic::JunkFished: return "junk_fished"; + case CustomStatistic::TreasureFished: return "treasure_fished"; // The old advancements - case Statistic::AchOpenInventory: return "cuberite:achievement.openInventory"; - case Statistic::AchMineWood: return "cuberite:achievement.mineWood"; - case Statistic::AchBuildWorkBench: return "cuberite:achievement.buildWorkBench"; - case Statistic::AchBuildPickaxe: return "cuberite:achievement.buildPickaxe"; - case Statistic::AchBuildFurnace: return "cuberite:achievement.buildFurnace"; - case Statistic::AchAcquireIron: return "cuberite:achievement.acquireIron"; - case Statistic::AchBuildHoe: return "cuberite:achievement.buildHoe"; - case Statistic::AchMakeBread: return "cuberite:achievement.makeBread"; - case Statistic::AchBakeCake: return "cuberite:achievement.bakeCake"; - case Statistic::AchBuildBetterPickaxe: return "cuberite:achievement.buildBetterPickaxe"; - case Statistic::AchCookFish: return "cuberite:achievement.cookFish"; - case Statistic::AchOnARail: return "cuberite:achievement.onARail"; - case Statistic::AchBuildSword: return "cuberite:achievement.buildSword"; - case Statistic::AchKillEnemy: return "cuberite:achievement.killEnemy"; - case Statistic::AchKillCow: return "cuberite:achievement.killCow"; - case Statistic::AchFlyPig: return "cuberite:achievement.flyPig"; - case Statistic::AchSnipeSkeleton: return "cuberite:achievement.snipeSkeleton"; - case Statistic::AchDiamonds: return "cuberite:achievement.diamonds"; - case Statistic::AchPortal: return "cuberite:achievement.portal"; - case Statistic::AchGhast: return "cuberite:achievement.ghast"; - case Statistic::AchBlazeRod: return "cuberite:achievement.blazeRod"; - case Statistic::AchPotion: return "cuberite:achievement.potion"; - case Statistic::AchTheEnd: return "cuberite:achievement.theEnd"; - case Statistic::AchTheEnd2: return "cuberite:achievement.theEnd2"; - case Statistic::AchEnchantments: return "cuberite:achievement.enchantments"; - case Statistic::AchOverkill: return "cuberite:achievement.overkill"; - case Statistic::AchBookcase: return "cuberite:achievement.bookcase"; - case Statistic::AchExploreAllBiomes: return "cuberite:achievement.exploreAllBiomes"; - case Statistic::AchSpawnWither: return "cuberite:achievement.spawnWither"; - case Statistic::AchKillWither: return "cuberite:achievement.killWither"; - case Statistic::AchFullBeacon: return "cuberite:achievement.fullBeacon"; - case Statistic::AchBreedCow: return "cuberite:achievement.breedCow"; - case Statistic::AchDiamondsToYou: return "cuberite:achievement.diamondsToYou"; + case CustomStatistic::AchOpenInventory: return "cuberite:achievement.openInventory"; + case CustomStatistic::AchMineWood: return "cuberite:achievement.mineWood"; + case CustomStatistic::AchBuildWorkBench: return "cuberite:achievement.buildWorkBench"; + case CustomStatistic::AchBuildPickaxe: return "cuberite:achievement.buildPickaxe"; + case CustomStatistic::AchBuildFurnace: return "cuberite:achievement.buildFurnace"; + case CustomStatistic::AchAcquireIron: return "cuberite:achievement.acquireIron"; + case CustomStatistic::AchBuildHoe: return "cuberite:achievement.buildHoe"; + case CustomStatistic::AchMakeBread: return "cuberite:achievement.makeBread"; + case CustomStatistic::AchBakeCake: return "cuberite:achievement.bakeCake"; + case CustomStatistic::AchBuildBetterPickaxe: return "cuberite:achievement.buildBetterPickaxe"; + case CustomStatistic::AchCookFish: return "cuberite:achievement.cookFish"; + case CustomStatistic::AchOnARail: return "cuberite:achievement.onARail"; + case CustomStatistic::AchBuildSword: return "cuberite:achievement.buildSword"; + case CustomStatistic::AchKillEnemy: return "cuberite:achievement.killEnemy"; + case CustomStatistic::AchKillCow: return "cuberite:achievement.killCow"; + case CustomStatistic::AchFlyPig: return "cuberite:achievement.flyPig"; + case CustomStatistic::AchSnipeSkeleton: return "cuberite:achievement.snipeSkeleton"; + case CustomStatistic::AchDiamonds: return "cuberite:achievement.diamonds"; + case CustomStatistic::AchPortal: return "cuberite:achievement.portal"; + case CustomStatistic::AchGhast: return "cuberite:achievement.ghast"; + case CustomStatistic::AchBlazeRod: return "cuberite:achievement.blazeRod"; + case CustomStatistic::AchPotion: return "cuberite:achievement.potion"; + case CustomStatistic::AchTheEnd: return "cuberite:achievement.theEnd"; + case CustomStatistic::AchTheEnd2: return "cuberite:achievement.theEnd2"; + case CustomStatistic::AchEnchantments: return "cuberite:achievement.enchantments"; + case CustomStatistic::AchOverkill: return "cuberite:achievement.overkill"; + case CustomStatistic::AchBookcase: return "cuberite:achievement.bookcase"; + case CustomStatistic::AchExploreAllBiomes: return "cuberite:achievement.exploreAllBiomes"; + case CustomStatistic::AchSpawnWither: return "cuberite:achievement.spawnWither"; + case CustomStatistic::AchKillWither: return "cuberite:achievement.killWither"; + case CustomStatistic::AchFullBeacon: return "cuberite:achievement.fullBeacon"; + case CustomStatistic::AchBreedCow: return "cuberite:achievement.breedCow"; + case CustomStatistic::AchDiamondsToYou: return "cuberite:achievement.diamondsToYou"; } UNREACHABLE("Tried to save unhandled statistic"); } @@ -274,123 +274,123 @@ std::string_view NamespaceSerializer::From(const BannerPattern a_Pattern) -Statistic NamespaceSerializer::ToCustomStatistic(const std::string_view ID) +CustomStatistic NamespaceSerializer::ToCustomStatistic(const std::string_view ID) { - static const std::unordered_map CustomStatistics + static const std::unordered_map CustomStatistics { - { "animals_bred", Statistic::AnimalsBred }, - { "aviate_one_cm", Statistic::AviateOneCm }, - { "bell_ring", Statistic::BellRing }, - { "boat_one_cm", Statistic::BoatOneCm }, - { "clean_armor", Statistic::CleanArmor }, - { "clean_banner", Statistic::CleanBanner }, - { "clean_shulker_box", Statistic::CleanShulkerBox }, - { "climb_one_cm", Statistic::ClimbOneCm }, - { "crouch_one_cm", Statistic::CrouchOneCm }, - { "damage_absorbed", Statistic::DamageAbsorbed }, - { "damage_blocked_by_shield", Statistic::DamageBlockedByShield }, - { "damage_dealt", Statistic::DamageDealt }, - { "damage_dealt_absorbed", Statistic::DamageDealtAbsorbed }, - { "damage_dealt_resisted", Statistic::DamageDealtResisted }, - { "damage_resisted", Statistic::DamageResisted }, - { "damage_taken", Statistic::DamageTaken }, - { "deaths", Statistic::Deaths }, - { "drop", Statistic::Drop }, - { "eat_cake_slice", Statistic::EatCakeSlice }, - { "enchant_item", Statistic::EnchantItem }, - { "fall_one_cm", Statistic::FallOneCm }, - { "fill_cauldron", Statistic::FillCauldron }, - { "fish_caught", Statistic::FishCaught }, - { "fly_one_cm", Statistic::FlyOneCm }, - { "horse_one_cm", Statistic::HorseOneCm }, - { "inspect_dispenser", Statistic::InspectDispenser }, - { "inspect_dropper", Statistic::InspectDropper }, - { "inspect_hopper", Statistic::InspectHopper }, - { "interact_with_anvil", Statistic::InteractWithAnvil }, - { "interact_with_beacon", Statistic::InteractWithBeacon }, - { "interact_with_blast_furnace", Statistic::InteractWithBlastFurnace }, - { "interact_with_brewingstand", Statistic::InteractWithBrewingstand }, - { "interact_with_campfire", Statistic::InteractWithCampfire }, - { "interact_with_cartography_table", Statistic::InteractWithCartographyTable }, - { "interact_with_crafting_table", Statistic::InteractWithCraftingTable }, - { "interact_with_furnace", Statistic::InteractWithFurnace }, - { "interact_with_grindstone", Statistic::InteractWithGrindstone }, - { "interact_with_lectern", Statistic::InteractWithLectern }, - { "interact_with_loom", Statistic::InteractWithLoom }, - { "interact_with_smithing_table", Statistic::InteractWithSmithingTable }, - { "interact_with_smoker", Statistic::InteractWithSmoker }, - { "interact_with_stonecutter", Statistic::InteractWithStonecutter }, - { "jump", Statistic::Jump }, - { "leave_game", Statistic::LeaveGame }, - { "minecart_one_cm", Statistic::MinecartOneCm }, - { "mob_kills", Statistic::MobKills }, - { "open_barrel", Statistic::OpenBarrel }, - { "open_chest", Statistic::OpenChest }, - { "open_enderchest", Statistic::OpenEnderchest }, - { "open_shulker_box", Statistic::OpenShulkerBox }, - { "pig_one_cm", Statistic::PigOneCm }, - { "play_noteblock", Statistic::PlayNoteblock }, - { "play_one_minute", Statistic::PlayOneMinute }, - { "play_record", Statistic::PlayRecord }, - { "player_kills", Statistic::PlayerKills }, - { "pot_flower", Statistic::PotFlower }, - { "raid_trigger", Statistic::RaidTrigger }, - { "raid_win", Statistic::RaidWin }, - { "sleep_in_bed", Statistic::SleepInBed }, - { "sneak_time", Statistic::SneakTime }, - { "sprint_one_cm", Statistic::SprintOneCm }, - { "strider_one_cm", Statistic::StriderOneCm }, - { "swim_one_cm", Statistic::SwimOneCm }, - { "talked_to_villager", Statistic::TalkedToVillager }, - { "target_hit", Statistic::TargetHit }, - { "time_since_death", Statistic::TimeSinceDeath }, - { "time_since_rest", Statistic::TimeSinceRest }, - { "traded_with_villager", Statistic::TradedWithVillager }, - { "trigger_trapped_chest", Statistic::TriggerTrappedChest }, - { "tune_noteblock", Statistic::TuneNoteblock }, - { "use_cauldron", Statistic::UseCauldron }, - { "walk_on_water_one_cm", Statistic::WalkOnWaterOneCm }, - { "walk_one_cm", Statistic::WalkOneCm }, - { "walk_under_water_one_cm", Statistic::WalkUnderWaterOneCm }, + { "animals_bred", CustomStatistic::AnimalsBred }, + { "aviate_one_cm", CustomStatistic::AviateOneCm }, + { "bell_ring", CustomStatistic::BellRing }, + { "boat_one_cm", CustomStatistic::BoatOneCm }, + { "clean_armor", CustomStatistic::CleanArmor }, + { "clean_banner", CustomStatistic::CleanBanner }, + { "clean_shulker_box", CustomStatistic::CleanShulkerBox }, + { "climb_one_cm", CustomStatistic::ClimbOneCm }, + { "crouch_one_cm", CustomStatistic::CrouchOneCm }, + { "damage_absorbed", CustomStatistic::DamageAbsorbed }, + { "damage_blocked_by_shield", CustomStatistic::DamageBlockedByShield }, + { "damage_dealt", CustomStatistic::DamageDealt }, + { "damage_dealt_absorbed", CustomStatistic::DamageDealtAbsorbed }, + { "damage_dealt_resisted", CustomStatistic::DamageDealtResisted }, + { "damage_resisted", CustomStatistic::DamageResisted }, + { "damage_taken", CustomStatistic::DamageTaken }, + { "deaths", CustomStatistic::Deaths }, + { "drop", CustomStatistic::Drop }, + { "eat_cake_slice", CustomStatistic::EatCakeSlice }, + { "enchant_item", CustomStatistic::EnchantItem }, + { "fall_one_cm", CustomStatistic::FallOneCm }, + { "fill_cauldron", CustomStatistic::FillCauldron }, + { "fish_caught", CustomStatistic::FishCaught }, + { "fly_one_cm", CustomStatistic::FlyOneCm }, + { "horse_one_cm", CustomStatistic::HorseOneCm }, + { "inspect_dispenser", CustomStatistic::InspectDispenser }, + { "inspect_dropper", CustomStatistic::InspectDropper }, + { "inspect_hopper", CustomStatistic::InspectHopper }, + { "interact_with_anvil", CustomStatistic::InteractWithAnvil }, + { "interact_with_beacon", CustomStatistic::InteractWithBeacon }, + { "interact_with_blast_furnace", CustomStatistic::InteractWithBlastFurnace }, + { "interact_with_brewingstand", CustomStatistic::InteractWithBrewingstand }, + { "interact_with_campfire", CustomStatistic::InteractWithCampfire }, + { "interact_with_cartography_table", CustomStatistic::InteractWithCartographyTable }, + { "interact_with_crafting_table", CustomStatistic::InteractWithCraftingTable }, + { "interact_with_furnace", CustomStatistic::InteractWithFurnace }, + { "interact_with_grindstone", CustomStatistic::InteractWithGrindstone }, + { "interact_with_lectern", CustomStatistic::InteractWithLectern }, + { "interact_with_loom", CustomStatistic::InteractWithLoom }, + { "interact_with_smithing_table", CustomStatistic::InteractWithSmithingTable }, + { "interact_with_smoker", CustomStatistic::InteractWithSmoker }, + { "interact_with_stonecutter", CustomStatistic::InteractWithStonecutter }, + { "jump", CustomStatistic::Jump }, + { "leave_game", CustomStatistic::LeaveGame }, + { "minecart_one_cm", CustomStatistic::MinecartOneCm }, + { "mob_kills", CustomStatistic::MobKills }, + { "open_barrel", CustomStatistic::OpenBarrel }, + { "open_chest", CustomStatistic::OpenChest }, + { "open_enderchest", CustomStatistic::OpenEnderchest }, + { "open_shulker_box", CustomStatistic::OpenShulkerBox }, + { "pig_one_cm", CustomStatistic::PigOneCm }, + { "play_noteblock", CustomStatistic::PlayNoteblock }, + { "play_one_minute", CustomStatistic::PlayOneMinute }, + { "play_record", CustomStatistic::PlayRecord }, + { "player_kills", CustomStatistic::PlayerKills }, + { "pot_flower", CustomStatistic::PotFlower }, + { "raid_trigger", CustomStatistic::RaidTrigger }, + { "raid_win", CustomStatistic::RaidWin }, + { "sleep_in_bed", CustomStatistic::SleepInBed }, + { "sneak_time", CustomStatistic::SneakTime }, + { "sprint_one_cm", CustomStatistic::SprintOneCm }, + { "strider_one_cm", CustomStatistic::StriderOneCm }, + { "swim_one_cm", CustomStatistic::SwimOneCm }, + { "talked_to_villager", CustomStatistic::TalkedToVillager }, + { "target_hit", CustomStatistic::TargetHit }, + { "time_since_death", CustomStatistic::TimeSinceDeath }, + { "time_since_rest", CustomStatistic::TimeSinceRest }, + { "traded_with_villager", CustomStatistic::TradedWithVillager }, + { "trigger_trapped_chest", CustomStatistic::TriggerTrappedChest }, + { "tune_noteblock", CustomStatistic::TuneNoteblock }, + { "use_cauldron", CustomStatistic::UseCauldron }, + { "walk_on_water_one_cm", CustomStatistic::WalkOnWaterOneCm }, + { "walk_one_cm", CustomStatistic::WalkOneCm }, + { "walk_under_water_one_cm", CustomStatistic::WalkUnderWaterOneCm }, // Old ones just for compatibility - { "junk_fished", Statistic::JunkFished }, - { "treasure_fished", Statistic::TreasureFished }, + { "junk_fished", CustomStatistic::JunkFished }, + { "treasure_fished", CustomStatistic::TreasureFished }, // The old advancements - { "cuberite:achievement.openInventory", Statistic::AchOpenInventory }, - { "cuberite:achievement.mineWood", Statistic::AchMineWood }, - { "cuberite:achievement.buildWorkBench", Statistic::AchBuildWorkBench }, - { "cuberite:achievement.buildPickaxe", Statistic::AchBuildPickaxe }, - { "cuberite:achievement.buildFurnace", Statistic::AchBuildFurnace }, - { "cuberite:achievement.acquireIron", Statistic::AchAcquireIron }, - { "cuberite:achievement.buildHoe", Statistic::AchBuildHoe }, - { "cuberite:achievement.makeBread", Statistic::AchMakeBread }, - { "cuberite:achievement.bakeCake", Statistic::AchBakeCake }, - { "cuberite:achievement.buildBetterPickaxe", Statistic::AchBuildBetterPickaxe }, - { "cuberite:achievement.cookFish", Statistic::AchCookFish }, - { "cuberite:achievement.onARail", Statistic::AchOnARail }, - { "cuberite:achievement.buildSword", Statistic::AchBuildSword }, - { "cuberite:achievement.killEnemy", Statistic::AchKillEnemy }, - { "cuberite:achievement.killCow", Statistic::AchKillCow }, - { "cuberite:achievement.flyPig", Statistic::AchFlyPig }, - { "cuberite:achievement.snipeSkeleton", Statistic::AchSnipeSkeleton }, - { "cuberite:achievement.diamonds", Statistic::AchDiamonds }, - { "cuberite:achievement.portal", Statistic::AchPortal }, - { "cuberite:achievement.ghast", Statistic::AchGhast }, - { "cuberite:achievement.blazeRod", Statistic::AchBlazeRod }, - { "cuberite:achievement.potion", Statistic::AchPotion }, - { "cuberite:achievement.theEnd", Statistic::AchTheEnd }, - { "cuberite:achievement.theEnd2", Statistic::AchTheEnd2 }, - { "cuberite:achievement.enchantments", Statistic::AchEnchantments }, - { "cuberite:achievement.overkill", Statistic::AchOverkill }, - { "cuberite:achievement.bookcase", Statistic::AchBookcase }, - { "cuberite:achievement.exploreAllBiomes", Statistic::AchExploreAllBiomes }, - { "cuberite:achievement.spawnWither", Statistic::AchSpawnWither }, - { "cuberite:achievement.killWither", Statistic::AchKillWither }, - { "cuberite:achievement.fullBeacon", Statistic::AchFullBeacon }, - { "cuberite:achievement.breedCow", Statistic::AchBreedCow }, - { "cuberite:achievement.diamondsToYou", Statistic::AchDiamondsToYou} + { "cuberite:achievement.openInventory", CustomStatistic::AchOpenInventory }, + { "cuberite:achievement.mineWood", CustomStatistic::AchMineWood }, + { "cuberite:achievement.buildWorkBench", CustomStatistic::AchBuildWorkBench }, + { "cuberite:achievement.buildPickaxe", CustomStatistic::AchBuildPickaxe }, + { "cuberite:achievement.buildFurnace", CustomStatistic::AchBuildFurnace }, + { "cuberite:achievement.acquireIron", CustomStatistic::AchAcquireIron }, + { "cuberite:achievement.buildHoe", CustomStatistic::AchBuildHoe }, + { "cuberite:achievement.makeBread", CustomStatistic::AchMakeBread }, + { "cuberite:achievement.bakeCake", CustomStatistic::AchBakeCake }, + { "cuberite:achievement.buildBetterPickaxe", CustomStatistic::AchBuildBetterPickaxe }, + { "cuberite:achievement.cookFish", CustomStatistic::AchCookFish }, + { "cuberite:achievement.onARail", CustomStatistic::AchOnARail }, + { "cuberite:achievement.buildSword", CustomStatistic::AchBuildSword }, + { "cuberite:achievement.killEnemy", CustomStatistic::AchKillEnemy }, + { "cuberite:achievement.killCow", CustomStatistic::AchKillCow }, + { "cuberite:achievement.flyPig", CustomStatistic::AchFlyPig }, + { "cuberite:achievement.snipeSkeleton", CustomStatistic::AchSnipeSkeleton }, + { "cuberite:achievement.diamonds", CustomStatistic::AchDiamonds }, + { "cuberite:achievement.portal", CustomStatistic::AchPortal }, + { "cuberite:achievement.ghast", CustomStatistic::AchGhast }, + { "cuberite:achievement.blazeRod", CustomStatistic::AchBlazeRod }, + { "cuberite:achievement.potion", CustomStatistic::AchPotion }, + { "cuberite:achievement.theEnd", CustomStatistic::AchTheEnd }, + { "cuberite:achievement.theEnd2", CustomStatistic::AchTheEnd2 }, + { "cuberite:achievement.enchantments", CustomStatistic::AchEnchantments }, + { "cuberite:achievement.overkill", CustomStatistic::AchOverkill }, + { "cuberite:achievement.bookcase", CustomStatistic::AchBookcase }, + { "cuberite:achievement.exploreAllBiomes", CustomStatistic::AchExploreAllBiomes }, + { "cuberite:achievement.spawnWither", CustomStatistic::AchSpawnWither }, + { "cuberite:achievement.killWither", CustomStatistic::AchKillWither }, + { "cuberite:achievement.fullBeacon", CustomStatistic::AchFullBeacon }, + { "cuberite:achievement.breedCow", CustomStatistic::AchBreedCow }, + { "cuberite:achievement.diamondsToYou", CustomStatistic::AchDiamondsToYou} }; return CustomStatistics.at(ID); diff --git a/src/WorldStorage/NamespaceSerializer.h b/src/WorldStorage/NamespaceSerializer.h index 876db740f..c521db201 100644 --- a/src/WorldStorage/NamespaceSerializer.h +++ b/src/WorldStorage/NamespaceSerializer.h @@ -15,11 +15,11 @@ namespace NamespaceSerializer unsigned DataVersion(); - std::string_view From(Statistic a_ID); + std::string_view From(CustomStatistic a_ID); std::string_view From(eMonsterType a_ID); std::string_view From(BannerPattern a_ID); - Statistic ToCustomStatistic(std::string_view a_ID); + CustomStatistic ToCustomStatistic(std::string_view a_ID); eMonsterType ToMonsterType(std::string_view a_ID); std::pair SplitNamespacedID(std::string_view ID); diff --git a/src/WorldStorage/StatSerializer.cpp b/src/WorldStorage/StatSerializer.cpp index 4721d7022..5432f6ab9 100644 --- a/src/WorldStorage/StatSerializer.cpp +++ b/src/WorldStorage/StatSerializer.cpp @@ -33,115 +33,112 @@ namespace StatSerializer - static void SaveStatToJSON(const cStatManager & Manager, Json::Value & a_Out) + static void SaveStatToJSON(const StatisticsManager & Manager, Json::Value & a_Out) { - Manager.ForEachStatisticType([&a_Out](const cStatManager::CustomStore & Store) + if (Manager.Custom.empty()) { - if (Store.empty()) - { - // Avoid saving "custom": null to disk: - return; - } + // Avoid saving "custom": null to disk: + return; + } - auto & Custom = a_Out["custom"]; - for (const auto & Item : Store) - { - Custom[NamespaceSerializer::From(Item.first).data()] = Item.second; - } - }); + auto & Custom = a_Out["custom"]; + for (const auto & [Statistic, Value] : Manager.Custom) + { + Custom[NamespaceSerializer::From(Statistic).data()] = Value; + } } - static void LoadLegacyFromJSON(cStatManager & Manager, const Json::Value & In) + static void LoadLegacyFromJSON(StatisticsManager & Manager, const Json::Value & In) { // Upgrade mapping from pre-1.13 names. TODO: remove on 2020-09-18 - static const std::unordered_map LegacyMapping + static const std::unordered_map LegacyMapping { - { "achievement.openInventory", Statistic::AchOpenInventory }, - { "achievement.mineWood", Statistic::AchMineWood }, - { "achievement.buildWorkBench", Statistic::AchBuildWorkBench }, - { "achievement.buildPickaxe", Statistic::AchBuildPickaxe }, - { "achievement.buildFurnace", Statistic::AchBuildFurnace }, - { "achievement.acquireIron", Statistic::AchAcquireIron }, - { "achievement.buildHoe", Statistic::AchBuildHoe }, - { "achievement.makeBread", Statistic::AchMakeBread }, - { "achievement.bakeCake", Statistic::AchBakeCake }, - { "achievement.buildBetterPickaxe", Statistic::AchBuildBetterPickaxe }, - { "achievement.cookFish", Statistic::AchCookFish }, - { "achievement.onARail", Statistic::AchOnARail }, - { "achievement.buildSword", Statistic::AchBuildSword }, - { "achievement.killEnemy", Statistic::AchKillEnemy }, - { "achievement.killCow", Statistic::AchKillCow }, - { "achievement.flyPig", Statistic::AchFlyPig }, - { "achievement.snipeSkeleton", Statistic::AchSnipeSkeleton }, - { "achievement.diamonds", Statistic::AchDiamonds }, - { "achievement.portal", Statistic::AchPortal }, - { "achievement.ghast", Statistic::AchGhast }, - { "achievement.blazeRod", Statistic::AchBlazeRod }, - { "achievement.potion", Statistic::AchPotion }, - { "achievement.theEnd", Statistic::AchTheEnd }, - { "achievement.theEnd2", Statistic::AchTheEnd2 }, - { "achievement.enchantments", Statistic::AchEnchantments }, - { "achievement.overkill", Statistic::AchOverkill }, - { "achievement.bookcase", Statistic::AchBookcase }, - { "achievement.exploreAllBiomes", Statistic::AchExploreAllBiomes }, - { "achievement.spawnWither", Statistic::AchSpawnWither }, - { "achievement.killWither", Statistic::AchKillWither }, - { "achievement.fullBeacon", Statistic::AchFullBeacon }, - { "achievement.breedCow", Statistic::AchBreedCow }, - { "achievement.diamondsToYou", Statistic::AchDiamondsToYou }, - { "stat.animalsBred", Statistic::AnimalsBred }, - { "stat.boatOneCm", Statistic::BoatOneCm }, - { "stat.climbOneCm", Statistic::ClimbOneCm }, - { "stat.crouchOneCm", Statistic::CrouchOneCm }, - { "stat.damageDealt", Statistic::DamageDealt }, - { "stat.damageTaken", Statistic::DamageTaken }, - { "stat.deaths", Statistic::Deaths }, - { "stat.drop", Statistic::Drop }, - { "stat.fallOneCm", Statistic::FallOneCm }, - { "stat.fishCaught", Statistic::FishCaught }, - { "stat.flyOneCm", Statistic::FlyOneCm }, - { "stat.horseOneCm", Statistic::HorseOneCm }, - { "stat.jump", Statistic::Jump }, - { "stat.leaveGame", Statistic::LeaveGame }, - { "stat.minecartOneCm", Statistic::MinecartOneCm }, - { "stat.mobKills", Statistic::MobKills }, - { "stat.pigOneCm", Statistic::PigOneCm }, - { "stat.playerKills", Statistic::PlayerKills }, - { "stat.playOneMinute", Statistic::PlayOneMinute }, - { "stat.sprintOneCm", Statistic::SprintOneCm }, - { "stat.swimOneCm", Statistic::SwimOneCm }, - { "stat.talkedToVillager", Statistic::TalkedToVillager }, - { "stat.timeSinceDeath", Statistic::TimeSinceDeath }, - { "stat.tradedWithVillager", Statistic::TradedWithVillager }, - { "stat.walkOneCm", Statistic::WalkOneCm }, - { "stat.diveOneCm", Statistic::WalkUnderWaterOneCm }, - { "stat.armorCleaned", Statistic::CleanArmor }, - { "stat.bannerCleaned", Statistic::CleanBanner }, - { "stat.cakeSlicesEaten", Statistic::EatCakeSlice }, - { "stat.itemEnchanted", Statistic::EnchantItem }, - { "stat.cauldronFilled", Statistic::FillCauldron }, - { "stat.dispenserInspected", Statistic::InspectDispenser }, - { "stat.dropperInspected", Statistic::InspectDropper }, - { "stat.hopperInspected", Statistic::InspectHopper }, - { "stat.beaconInteraction", Statistic::InteractWithBeacon }, - { "stat.brewingstandInteraction", Statistic::InteractWithBrewingstand }, - { "stat.craftingTableInteraction", Statistic::InteractWithCraftingTable }, - { "stat.furnaceInteraction", Statistic::InteractWithFurnace }, - { "stat.chestOpened", Statistic::OpenChest }, - { "stat.enderchestOpened", Statistic::OpenEnderchest }, - { "stat.noteblockPlayed", Statistic::PlayNoteblock }, - { "stat.recordPlayed", Statistic::PlayRecord }, - { "stat.flowerPotted", Statistic::PotFlower }, - { "stat.trappedChestTriggered", Statistic::TriggerTrappedChest }, - { "stat.noteblockTuned", Statistic::TuneNoteblock }, - { "stat.cauldronUsed", Statistic::UseCauldron }, - { "stat.aviateOneCm", Statistic::AviateOneCm }, - { "stat.sleepInBed", Statistic::SleepInBed }, - { "stat.sneakTime", Statistic::SneakTime } + { "achievement.openInventory", CustomStatistic::AchOpenInventory }, + { "achievement.mineWood", CustomStatistic::AchMineWood }, + { "achievement.buildWorkBench", CustomStatistic::AchBuildWorkBench }, + { "achievement.buildPickaxe", CustomStatistic::AchBuildPickaxe }, + { "achievement.buildFurnace", CustomStatistic::AchBuildFurnace }, + { "achievement.acquireIron", CustomStatistic::AchAcquireIron }, + { "achievement.buildHoe", CustomStatistic::AchBuildHoe }, + { "achievement.makeBread", CustomStatistic::AchMakeBread }, + { "achievement.bakeCake", CustomStatistic::AchBakeCake }, + { "achievement.buildBetterPickaxe", CustomStatistic::AchBuildBetterPickaxe }, + { "achievement.cookFish", CustomStatistic::AchCookFish }, + { "achievement.onARail", CustomStatistic::AchOnARail }, + { "achievement.buildSword", CustomStatistic::AchBuildSword }, + { "achievement.killEnemy", CustomStatistic::AchKillEnemy }, + { "achievement.killCow", CustomStatistic::AchKillCow }, + { "achievement.flyPig", CustomStatistic::AchFlyPig }, + { "achievement.snipeSkeleton", CustomStatistic::AchSnipeSkeleton }, + { "achievement.diamonds", CustomStatistic::AchDiamonds }, + { "achievement.portal", CustomStatistic::AchPortal }, + { "achievement.ghast", CustomStatistic::AchGhast }, + { "achievement.blazeRod", CustomStatistic::AchBlazeRod }, + { "achievement.potion", CustomStatistic::AchPotion }, + { "achievement.theEnd", CustomStatistic::AchTheEnd }, + { "achievement.theEnd2", CustomStatistic::AchTheEnd2 }, + { "achievement.enchantments", CustomStatistic::AchEnchantments }, + { "achievement.overkill", CustomStatistic::AchOverkill }, + { "achievement.bookcase", CustomStatistic::AchBookcase }, + { "achievement.exploreAllBiomes", CustomStatistic::AchExploreAllBiomes }, + { "achievement.spawnWither", CustomStatistic::AchSpawnWither }, + { "achievement.killWither", CustomStatistic::AchKillWither }, + { "achievement.fullBeacon", CustomStatistic::AchFullBeacon }, + { "achievement.breedCow", CustomStatistic::AchBreedCow }, + { "achievement.diamondsToYou", CustomStatistic::AchDiamondsToYou }, + { "stat.animalsBred", CustomStatistic::AnimalsBred }, + { "stat.boatOneCm", CustomStatistic::BoatOneCm }, + { "stat.climbOneCm", CustomStatistic::ClimbOneCm }, + { "stat.crouchOneCm", CustomStatistic::CrouchOneCm }, + { "stat.damageDealt", CustomStatistic::DamageDealt }, + { "stat.damageTaken", CustomStatistic::DamageTaken }, + { "stat.deaths", CustomStatistic::Deaths }, + { "stat.drop", CustomStatistic::Drop }, + { "stat.fallOneCm", CustomStatistic::FallOneCm }, + { "stat.fishCaught", CustomStatistic::FishCaught }, + { "stat.flyOneCm", CustomStatistic::FlyOneCm }, + { "stat.horseOneCm", CustomStatistic::HorseOneCm }, + { "stat.jump", CustomStatistic::Jump }, + { "stat.leaveGame", CustomStatistic::LeaveGame }, + { "stat.minecartOneCm", CustomStatistic::MinecartOneCm }, + { "stat.mobKills", CustomStatistic::MobKills }, + { "stat.pigOneCm", CustomStatistic::PigOneCm }, + { "stat.playerKills", CustomStatistic::PlayerKills }, + { "stat.playOneMinute", CustomStatistic::PlayOneMinute }, + { "stat.sprintOneCm", CustomStatistic::SprintOneCm }, + { "stat.swimOneCm", CustomStatistic::SwimOneCm }, + { "stat.talkedToVillager", CustomStatistic::TalkedToVillager }, + { "stat.timeSinceDeath", CustomStatistic::TimeSinceDeath }, + { "stat.tradedWithVillager", CustomStatistic::TradedWithVillager }, + { "stat.walkOneCm", CustomStatistic::WalkOneCm }, + { "stat.diveOneCm", CustomStatistic::WalkUnderWaterOneCm }, + { "stat.armorCleaned", CustomStatistic::CleanArmor }, + { "stat.bannerCleaned", CustomStatistic::CleanBanner }, + { "stat.cakeSlicesEaten", CustomStatistic::EatCakeSlice }, + { "stat.itemEnchanted", CustomStatistic::EnchantItem }, + { "stat.cauldronFilled", CustomStatistic::FillCauldron }, + { "stat.dispenserInspected", CustomStatistic::InspectDispenser }, + { "stat.dropperInspected", CustomStatistic::InspectDropper }, + { "stat.hopperInspected", CustomStatistic::InspectHopper }, + { "stat.beaconInteraction", CustomStatistic::InteractWithBeacon }, + { "stat.brewingstandInteraction", CustomStatistic::InteractWithBrewingstand }, + { "stat.craftingTableInteraction", CustomStatistic::InteractWithCraftingTable }, + { "stat.furnaceInteraction", CustomStatistic::InteractWithFurnace }, + { "stat.chestOpened", CustomStatistic::OpenChest }, + { "stat.enderchestOpened", CustomStatistic::OpenEnderchest }, + { "stat.noteblockPlayed", CustomStatistic::PlayNoteblock }, + { "stat.recordPlayed", CustomStatistic::PlayRecord }, + { "stat.flowerPotted", CustomStatistic::PotFlower }, + { "stat.trappedChestTriggered", CustomStatistic::TriggerTrappedChest }, + { "stat.noteblockTuned", CustomStatistic::TuneNoteblock }, + { "stat.cauldronUsed", CustomStatistic::UseCauldron }, + { "stat.aviateOneCm", CustomStatistic::AviateOneCm }, + { "stat.sleepInBed", CustomStatistic::SleepInBed }, + { "stat.sneakTime", CustomStatistic::SneakTime } }; for (auto Entry = In.begin(); Entry != In.end(); ++Entry) @@ -151,7 +148,7 @@ namespace StatSerializer if ((FindResult != LegacyMapping.end()) && Entry->isInt()) { - Manager.SetValue(FindResult->second, Entry->asUInt()); + Manager.Custom[FindResult->second] = Entry->asUInt(); } } } @@ -160,7 +157,7 @@ namespace StatSerializer - static void LoadCustomStatFromJSON(cStatManager & Manager, const Json::Value & a_In) + static void LoadCustomStatFromJSON(StatisticsManager & Manager, const Json::Value & a_In) { for (auto it = a_In.begin(); it != a_In.end(); ++it) { @@ -175,7 +172,7 @@ namespace StatSerializer const auto & StatName = StatInfo.second; try { - Manager.SetValue(NamespaceSerializer::ToCustomStatistic(StatName), it->asUInt()); + Manager.Custom[NamespaceSerializer::ToCustomStatistic(StatName)] = it->asUInt(); } catch (const std::out_of_range &) { @@ -192,7 +189,7 @@ namespace StatSerializer - void Load(cStatManager & Manager, const std::string & WorldPath, std::string && FileName) + void Load(StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName) { Json::Value Root; InputFileStream(MakeStatisticsDirectory(WorldPath, std::move(FileName))) >> Root; @@ -205,7 +202,7 @@ namespace StatSerializer - void Save(const cStatManager & Manager, const std::string & WorldPath, std::string && FileName) + void Save(const StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName) { Json::Value Root; diff --git a/src/WorldStorage/StatSerializer.h b/src/WorldStorage/StatSerializer.h index 1a52b55b7..a178db79c 100644 --- a/src/WorldStorage/StatSerializer.h +++ b/src/WorldStorage/StatSerializer.h @@ -13,8 +13,7 @@ -// fwd: -class cStatManager; +struct StatisticsManager; namespace Json { class Value; } @@ -24,8 +23,8 @@ namespace Json { class Value; } namespace StatSerializer { /* Try to load the player statistics. */ - void Load(cStatManager & Manager, const std::string & WorldPath, std::string && FileName); + void Load(StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName); /* Try to save the player statistics. */ - void Save(const cStatManager & Manager, const std::string & WorldPath, std::string && FileName); + void Save(const StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName); }