summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/WorldStorage/StatSerializer.cpp129
-rw-r--r--src/WorldStorage/StatSerializer.h6
2 files changed, 122 insertions, 13 deletions
diff --git a/src/WorldStorage/StatSerializer.cpp b/src/WorldStorage/StatSerializer.cpp
index de8a1d277..50767ae94 100644
--- a/src/WorldStorage/StatSerializer.cpp
+++ b/src/WorldStorage/StatSerializer.cpp
@@ -7,26 +7,114 @@
#include "../Statistics.h"
#include "NamespaceSerializer.h"
-#include <fstream>
#include <json/json.h>
-cStatSerializer::cStatSerializer(cStatManager & a_Manager, const AString & a_WorldName, const AString & a_FileName)
- : m_Manager(a_Manager)
+// Upgrade mapping from pre-1.13 names. TODO: remove on 2020-09-18
+static const std::unordered_map<std::string_view, Statistic> 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 }
+};
+
+
+
+
+
+cStatSerializer::cStatSerializer(cStatManager & Manager, const std::string & WorldPath, std::string FileName) :
+ m_Manager(Manager),
+ m_Path(WorldPath + cFile::GetPathSeparator() + "stats")
{
// Even though stats are shared between worlds, they are (usually) saved
// inside the folder of the default world.
- AString StatsPath;
- Printf(StatsPath, "%s%cstats", a_WorldName.c_str(), cFile::PathSeparator());
-
- m_Path = StatsPath + cFile::PathSeparator() + a_FileName + ".json";
-
// Ensure that the directory exists.
- cFile::CreateFolder(StatsPath);
+ cFile::CreateFolder(m_Path);
+
+ m_Path += cFile::GetPathSeparator() + std::move(FileName) + ".json";
}
@@ -36,8 +124,9 @@ cStatSerializer::cStatSerializer(cStatManager & a_Manager, const AString & a_Wor
void cStatSerializer::Load(void)
{
Json::Value Root;
- std::ifstream(m_Path) >> Root;
+ InputFileStream(m_Path) >> Root;
+ LoadLegacyFromJSON(Root);
LoadCustomStatFromJSON(Root["stats"]["custom"]);
}
@@ -52,7 +141,7 @@ void cStatSerializer::Save(void)
SaveStatToJSON(Root["stats"]);
Root["DataVersion"] = NamespaceSerializer::DataVersion();
- std::ofstream(m_Path) << Root;
+ OutputFileStream(m_Path) << Root;
}
@@ -81,6 +170,24 @@ void cStatSerializer::SaveStatToJSON(Json::Value & a_Out)
+void cStatSerializer::LoadLegacyFromJSON(const Json::Value & In)
+{
+ for (auto Entry = In.begin(); Entry != In.end(); ++Entry)
+ {
+ const auto & Key = Entry.key().asString();
+ const auto FindResult = LegacyMapping.find(Key);
+
+ if ((FindResult != LegacyMapping.end()) && Entry->isInt())
+ {
+ m_Manager.SetValue(FindResult->second, Entry->asInt());
+ }
+ }
+}
+
+
+
+
+
void cStatSerializer::LoadCustomStatFromJSON(const Json::Value & a_In)
{
for (auto it = a_In.begin() ; it != a_In.end() ; ++it)
diff --git a/src/WorldStorage/StatSerializer.h b/src/WorldStorage/StatSerializer.h
index e6a5bd325..efbdbe4e5 100644
--- a/src/WorldStorage/StatSerializer.h
+++ b/src/WorldStorage/StatSerializer.h
@@ -25,7 +25,7 @@ class cStatSerializer
{
public:
- cStatSerializer(cStatManager & a_Manager, const AString & a_WorldName, const AString & a_FileName);
+ cStatSerializer(cStatManager & Manager, const std::string & WorldPath, std::string FileName);
/* Try to load the player statistics. */
void Load(void);
@@ -37,9 +37,11 @@ private:
void SaveStatToJSON(Json::Value & a_Out);
+ void LoadLegacyFromJSON(const Json::Value & In);
+
void LoadCustomStatFromJSON(const Json::Value & a_In);
cStatManager & m_Manager;
- AString m_Path;
+ std::string m_Path;
} ;