Cuberite
A lightweight, fast and extensible game server for Minecraft
StatisticsSerializer.cpp
Go to the documentation of this file.
1 
2 // StatisticsSerializer.cpp
3 
4 
5 #include "Globals.h"
6 #include "StatisticsManager.h"
7 #include "StatisticsSerializer.h"
8 #include "NamespaceSerializer.h"
9 
10 #include <json/json.h>
11 
12 
13 
14 
15 
16 static auto MakeStatisticsDirectory(const std::string & WorldPath, std::string && FileName)
17 {
18  // Even though stats are shared between worlds, they are (usually) saved
19  // inside the folder of the default world.
20 
21  // Path to the world's statistics folder.
22  const auto Path = WorldPath + cFile::GetPathSeparator() + "stats";
23 
24  // Ensure that the directory exists.
25  cFile::CreateFolder(Path);
26 
27  return Path + cFile::GetPathSeparator() + std::move(FileName) + ".json";
28 }
29 
30 
31 
32 
33 
34 static void SaveStatToJSON(const StatisticsManager & Manager, Json::Value & a_Out)
35 {
36  if (Manager.Custom.empty())
37  {
38  // Avoid saving "custom": null to disk:
39  return;
40  }
41 
42  auto & Custom = a_Out["custom"];
43  for (const auto & [Statistic, Value] : Manager.Custom)
44  {
45  Custom[NamespaceSerializer::From(Statistic).data()] = Value;
46  }
47 }
48 
49 
50 
51 
52 
53 static void LoadCustomStatFromJSON(StatisticsManager & Manager, const Json::Value & a_In)
54 {
55  for (auto it = a_In.begin(); it != a_In.end(); ++it)
56  {
57  const auto & Key = it.key().asString();
58  const auto & [Namespace, Name] = NamespaceSerializer::SplitNamespacedID(Key);
59 
61  {
62  // Ignore non-Vanilla, non-Cuberite namespaces for now:
63  continue;
64  }
65 
66  Manager.Custom[NamespaceSerializer::ToCustomStatistic(Name)] = it->asUInt();
67  }
68 }
69 
70 
71 
72 
73 
74 void StatisticsSerializer::Load(StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName)
75 {
76  Json::Value Root;
77  InputFileStream(MakeStatisticsDirectory(WorldPath, std::move(FileName))) >> Root;
78 
79  LoadCustomStatFromJSON(Manager, Root["stats"]["custom"]);
80 }
81 
82 
83 
84 
85 
86 void StatisticsSerializer::Save(const StatisticsManager & Manager, const std::string & WorldPath, std::string && FileName)
87 {
88  Json::Value Root;
89 
90  SaveStatToJSON(Manager, Root["stats"]);
91  Root["DataVersion"] = NamespaceSerializer::DataVersion();
92 
93  OutputFileStream(MakeStatisticsDirectory(WorldPath, std::move(FileName))) << Root;
94 }
FileStream< std::ofstream > OutputFileStream
Definition: File.h:197
FileStream< std::ifstream > InputFileStream
Definition: File.h:196
static auto MakeStatisticsDirectory(const std::string &WorldPath, std::string &&FileName)
static void LoadCustomStatFromJSON(StatisticsManager &Manager, const Json::Value &a_In)
static void SaveStatToJSON(const StatisticsManager &Manager, Json::Value &a_Out)
std::string_view From(CustomStatistic a_ID)
CustomStatistic ToCustomStatistic(std::string_view a_ID)
std::pair< Namespace, std::string_view > SplitNamespacedID(std::string_view ID)
void Save(const StatisticsManager &Manager, const std::string &WorldPath, std::string &&FileName)
void Load(StatisticsManager &Manager, const std::string &WorldPath, std::string &&FileName)
static bool CreateFolder(const AString &a_FolderPath)
Creates a new folder with the specified name.
Definition: File.cpp:454
static AString GetPathSeparator()
Returns the path separator used by the current platform.
Definition: File.cpp:669
Class that manages the statistics and achievements of a single player.
std::unordered_map< CustomStatistic, StatValue > Custom