summaryrefslogtreecommitdiffstats
path: root/src/WorldStorage
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2014-01-22 15:05:17 +0100
committerMattes D <github@xoft.cz>2014-01-22 15:05:17 +0100
commit26586fdb92c7924e47debf6946fbdbe06775ae19 (patch)
tree093a0fa1ad5de0cc2e7dd90f49a3a3ab6429ac5b /src/WorldStorage
parentInfoDump: Can dump a single plugin without LFS. (diff)
parentcWorld now saves/loads the scoreboard (diff)
downloadcuberite-26586fdb92c7924e47debf6946fbdbe06775ae19.tar
cuberite-26586fdb92c7924e47debf6946fbdbe06775ae19.tar.gz
cuberite-26586fdb92c7924e47debf6946fbdbe06775ae19.tar.bz2
cuberite-26586fdb92c7924e47debf6946fbdbe06775ae19.tar.lz
cuberite-26586fdb92c7924e47debf6946fbdbe06775ae19.tar.xz
cuberite-26586fdb92c7924e47debf6946fbdbe06775ae19.tar.zst
cuberite-26586fdb92c7924e47debf6946fbdbe06775ae19.zip
Diffstat (limited to '')
-rw-r--r--src/WorldStorage/ScoreboardSerializer.cpp389
-rw-r--r--src/WorldStorage/ScoreboardSerializer.h52
-rw-r--r--src/WorldStorage/WSSAnvil.cpp2
3 files changed, 442 insertions, 1 deletions
diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp
new file mode 100644
index 000000000..dabc5e2e1
--- /dev/null
+++ b/src/WorldStorage/ScoreboardSerializer.cpp
@@ -0,0 +1,389 @@
+
+// ScoreboardSerializer.cpp
+
+
+#include "Globals.h"
+#include "ScoreboardSerializer.h"
+#include "../StringCompression.h"
+#include "zlib/zlib.h"
+#include "FastNBT.h"
+
+#include "../Scoreboard.h"
+
+
+
+
+#define SCOREBOARD_INFLATE_MAX 16 KiB
+
+
+
+
+
+cScoreboardSerializer::cScoreboardSerializer(const AString & a_WorldName, cScoreboard* a_ScoreBoard)
+ : m_ScoreBoard(a_ScoreBoard)
+{
+ AString DataPath;
+ Printf(DataPath, "%s/data", a_WorldName.c_str());
+
+ m_Path = DataPath + "/scoreboard.dat";
+
+ cFile::CreateFolder(FILE_IO_PREFIX + DataPath);
+}
+
+
+
+
+
+bool cScoreboardSerializer::Load(void)
+{
+ cFile File;
+
+ if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmReadWrite))
+ {
+ return false;
+ }
+
+ AString Data;
+
+ File.ReadRestOfFile(Data);
+
+ File.Close();
+
+ char Uncompressed[SCOREBOARD_INFLATE_MAX];
+ z_stream strm;
+ strm.zalloc = (alloc_func)NULL;
+ strm.zfree = (free_func)NULL;
+ strm.opaque = NULL;
+ inflateInit(&strm);
+ strm.next_out = (Bytef *)Uncompressed;
+ strm.avail_out = sizeof(Uncompressed);
+ strm.next_in = (Bytef *)Data.data();
+ strm.avail_in = Data.size();
+ int res = inflate(&strm, Z_FINISH);
+ inflateEnd(&strm);
+ if (res != Z_STREAM_END)
+ {
+ return false;
+ }
+
+ // Parse the NBT data:
+ cParsedNBT NBT(Uncompressed, strm.total_out);
+ if (!NBT.IsValid())
+ {
+ // NBT Parsing failed
+ return false;
+ }
+
+ return LoadScoreboardFromNBT(NBT);
+}
+
+
+
+
+
+bool cScoreboardSerializer::Save(void)
+{
+ cFastNBTWriter Writer;
+
+ Writer.BeginCompound("");
+ m_ScoreBoard->RegisterObjective("test","test",cObjective::E_TYPE_DUMMY)->AddScore("dot", 2);
+ SaveScoreboardToNBT(Writer);
+
+ Writer.EndCompound();
+ Writer.Finish();
+
+ #ifdef _DEBUG
+ cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size());
+ ASSERT(TestParse.IsValid());
+ #endif // _DEBUG
+
+ gzFile gz = gzopen((FILE_IO_PREFIX + m_Path).c_str(), "wb");
+ if (gz != NULL)
+ {
+ gzwrite(gz, Writer.GetResult().data(), Writer.GetResult().size());
+ }
+ gzclose(gz);
+
+ return true;
+}
+
+
+
+
+
+void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
+{
+ a_Writer.BeginCompound("Data");
+ a_Writer.BeginList("Objectives", TAG_Compound);
+
+ for (cScoreboard::cObjectiveMap::const_iterator it = m_ScoreBoard->m_Objectives.begin(); it != m_ScoreBoard->m_Objectives.end(); ++it)
+ {
+ const cObjective & Objective = it->second;
+
+ a_Writer.BeginCompound("");
+
+ a_Writer.AddString("CriteriaName", cObjective::TypeToString(Objective.GetType()));
+
+ a_Writer.AddString("DisplayName", Objective.GetDisplayName());
+ a_Writer.AddString("Name", it->first);
+
+ a_Writer.EndCompound();
+ }
+
+ a_Writer.EndList();
+
+ a_Writer.BeginList("PlayerScores", TAG_Compound);
+
+ for (cScoreboard::cObjectiveMap::const_iterator it = m_ScoreBoard->m_Objectives.begin(); it != m_ScoreBoard->m_Objectives.end(); ++it)
+ {
+ const cObjective & Objective = it->second;
+
+ for (cObjective::cScoreMap::const_iterator it2 = Objective.m_Scores.begin(); it2 != Objective.m_Scores.end(); ++it2)
+ {
+ a_Writer.BeginCompound("");
+
+ a_Writer.AddInt("Score", it2->second);
+
+ a_Writer.AddString("Name", it2->first);
+ a_Writer.AddString("Objective", it->first);
+
+ a_Writer.EndCompound();
+ }
+ }
+
+ a_Writer.EndList();
+
+ a_Writer.BeginList("Teams", TAG_Compound);
+
+ for (cScoreboard::cTeamMap::const_iterator it = m_ScoreBoard->m_Teams.begin(); it != m_ScoreBoard->m_Teams.end(); ++it)
+ {
+ const cTeam & Team = it->second;
+
+ a_Writer.BeginCompound("");
+
+ a_Writer.AddByte("AllowFriendlyFire", Team.AllowsFriendlyFire() ? 1 : 0);
+ a_Writer.AddByte("SeeFriendlyInvisibles", Team.CanSeeFriendlyInvisible() ? 1 : 0);
+
+ a_Writer.AddString("DisplayName", Team.GetDisplayName());
+ a_Writer.AddString("Name", it->first);
+
+ a_Writer.AddString("Prefix", Team.GetPrefix());
+ a_Writer.AddString("Suffix", Team.GetSuffix());
+
+ a_Writer.BeginList("Players", TAG_String);
+
+ for (cTeam::cPlayerNameSet::const_iterator it2 = Team.m_Players.begin(); it2 != Team.m_Players.end(); ++it2)
+ {
+ a_Writer.AddString("", *it2);
+ }
+
+ a_Writer.EndList();
+
+ a_Writer.EndCompound();
+ }
+
+ a_Writer.EndList();
+ a_Writer.EndCompound();
+
+ a_Writer.BeginCompound("DisplaySlots");
+
+ cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_LIST);
+ a_Writer.AddString("slot_0", (Objective == NULL) ? "" : Objective->GetName());
+
+ Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_SIDEBAR);
+ a_Writer.AddString("slot_1", (Objective == NULL) ? "" : Objective->GetName());
+
+ Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_NAME);
+ a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName());
+
+ a_Writer.EndCompound();
+}
+
+
+
+
+
+bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT)
+{
+ int Data = a_NBT.FindChildByName(0, "Data");
+ if (Data < 0)
+ {
+ return false;
+ }
+
+ int Objectives = a_NBT.FindChildByName(Data, "Objectives");
+ if (Objectives < 0)
+ {
+ return false;
+ }
+
+ for (int Child = a_NBT.GetFirstChild(Objectives); Child >= 0; Child = a_NBT.GetNextSibling(Child))
+ {
+ AString CriteriaName, DisplayName, Name;
+
+ int CurrLine = a_NBT.FindChildByName(Child, "CriteriaName");
+ if (CurrLine >= 0)
+ {
+ CriteriaName = a_NBT.GetString(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "DisplayName");
+ if (CurrLine >= 0)
+ {
+ DisplayName = a_NBT.GetString(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "Name");
+ if (CurrLine >= 0)
+ {
+ Name = a_NBT.GetString(CurrLine);
+ }
+
+ cObjective::eType Type = cObjective::StringToType(CriteriaName);
+
+ m_ScoreBoard->RegisterObjective(Name, DisplayName, Type);
+ }
+
+ int PlayerScores = a_NBT.FindChildByName(Data, "PlayerScores");
+ if (PlayerScores < 0)
+ {
+ return false;
+ }
+
+ for (int Child = a_NBT.GetFirstChild(PlayerScores); Child >= 0; Child = a_NBT.GetNextSibling(Child))
+ {
+ AString Name, ObjectiveName;
+
+ cObjective::Score Score;
+
+ int CurrLine = a_NBT.FindChildByName(Child, "Score");
+ if (CurrLine >= 0)
+ {
+ Score = a_NBT.GetInt(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "Name");
+ if (CurrLine >= 0)
+ {
+ Name = a_NBT.GetString(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "Objective");
+ if (CurrLine >= 0)
+ {
+ ObjectiveName = a_NBT.GetString(CurrLine);
+ }
+
+ cObjective * Objective = m_ScoreBoard->GetObjective(ObjectiveName);
+
+ if (Objective)
+ {
+ Objective->SetScore(Name, Score);
+ }
+ }
+
+ int Teams = a_NBT.FindChildByName(Data, "Teams");
+ if (Teams < 0)
+ {
+ return false;
+ }
+
+ for (int Child = a_NBT.GetFirstChild(Teams); Child >= 0; Child = a_NBT.GetNextSibling(Child))
+ {
+ AString Name, DisplayName, Prefix, Suffix;
+
+ bool AllowsFriendlyFire, CanSeeFriendlyInvisible;
+
+ int CurrLine = a_NBT.FindChildByName(Child, "Name");
+ if (CurrLine >= 0)
+ {
+ Name = a_NBT.GetInt(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "DisplayName");
+ if (CurrLine >= 0)
+ {
+ DisplayName = a_NBT.GetInt(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "Prefix");
+ if (CurrLine >= 0)
+ {
+ Prefix = a_NBT.GetInt(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "Suffix");
+ if (CurrLine >= 0)
+ {
+ Suffix = a_NBT.GetInt(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "AllowFriendlyFire");
+ if (CurrLine >= 0)
+ {
+ AllowsFriendlyFire = a_NBT.GetInt(CurrLine);
+ }
+
+ CurrLine = a_NBT.FindChildByName(Child, "SeeFriendlyInvisibles");
+ if (CurrLine >= 0)
+ {
+ CanSeeFriendlyInvisible = a_NBT.GetInt(CurrLine);
+ }
+
+ cTeam * Team = m_ScoreBoard->RegisterTeam(Name, DisplayName, Prefix, Suffix);
+
+ Team->SetFriendlyFire(AllowsFriendlyFire);
+ Team->SetCanSeeFriendlyInvisible(CanSeeFriendlyInvisible);
+
+ int Players = a_NBT.FindChildByName(Child, "Players");
+ if (Players < 0)
+ {
+ continue;
+ }
+
+ for (int ChildB = a_NBT.GetFirstChild(Players); ChildB >= 0; ChildB = a_NBT.GetNextSibling(ChildB))
+ {
+ Team->AddPlayer(a_NBT.GetString(ChildB));
+ }
+ }
+
+ int DisplaySlots = a_NBT.FindChildByName(0, "DisplaySlots");
+ if (DisplaySlots < 0)
+ {
+ return false;
+ }
+
+ int CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_0");
+ if (CurrLine >= 0)
+ {
+ AString Name = a_NBT.GetString(CurrLine);
+
+ m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_LIST);
+ }
+
+ CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_1");
+ if (CurrLine >= 0)
+ {
+ AString Name = a_NBT.GetString(CurrLine);
+
+ m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_SIDEBAR);
+ }
+
+ CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_2");
+ if (CurrLine >= 0)
+ {
+ AString Name = a_NBT.GetString(CurrLine);
+
+ m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_NAME);
+ }
+
+ return true;
+}
+
+
+
+
+
+
+
+
diff --git a/src/WorldStorage/ScoreboardSerializer.h b/src/WorldStorage/ScoreboardSerializer.h
new file mode 100644
index 000000000..048fa3ab4
--- /dev/null
+++ b/src/WorldStorage/ScoreboardSerializer.h
@@ -0,0 +1,52 @@
+
+// ScoreboardSerializer.h
+
+// Declares the cScoreboardSerializer class that is used for saving scoreboards into NBT format used by Anvil
+
+
+
+
+
+#pragma once
+
+
+
+
+
+// fwd:
+class cFastNBTWriter;
+class cParsedNBT;
+class cScoreboard;
+
+
+
+
+class cScoreboardSerializer
+{
+public:
+
+ cScoreboardSerializer(const AString & a_WorldName, cScoreboard* a_ScoreBoard);
+
+ /// Try to load the scoreboard
+ bool Load(void);
+
+ /// Try to save the scoreboard
+ bool Save(void);
+
+
+private:
+
+ void SaveScoreboardToNBT(cFastNBTWriter & a_Writer);
+
+ bool LoadScoreboardFromNBT(const cParsedNBT & a_NBT);
+
+ cScoreboard* m_ScoreBoard;
+
+ AString m_Path;
+
+
+} ;
+
+
+
+
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index 8983f25ba..8be6372e2 100644
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -1936,7 +1936,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
return false;
}
a_Entity.SetYaw(Rotation[0]);
- a_Entity.SetRoll (Rotation[1]);
+ a_Entity.SetRoll(Rotation[1]);
return true;
}