24#include <rapidjson/pointer.h>
25#include <rapidjson/stringbuffer.h>
26#include <rapidjson/writer.h>
27#include <rapidjson/error/en.h>
31 std::string
const HeadersKey =
"Header";
33 std::string
const BossStatesSaveDataKey =
"BossStates";
35 std::string
const MoreSaveDataKey =
"AdditionalData";
52 if (
_doc.Parse(data).HasParseError())
54 TC_LOG_ERROR(
"scripts.data.load",
"JSON parser error {} at {} while loading data for instance {} [{}-{} | {}-{}]",
55 rapidjson::GetParseError_En(
_doc.GetParseError()),
_doc.GetErrorOffset(),
62 TC_LOG_ERROR(
"scripts.data.load",
"Root JSON value is not an object for instance {} [{}-{} | {}-{}]",
84 auto headerItr =
_doc.FindMember(HeadersKey);
85 if (headerItr ==
_doc.MemberEnd())
87 TC_LOG_ERROR(
"scripts.data.load",
"Missing data header for instance {} [{}-{} | {}-{}]",
94 TC_LOG_ERROR(
"scripts.data.load",
"Incorrect data header for instance {} [{}-{} | {}-{}], expected \"{}\" got \"{}\"",
96 _instance.
GetHeader(), headerItr->value.IsString() ? headerItr->value.GetString() :
"");
105 auto bossStatesItr =
_doc.FindMember(BossStatesSaveDataKey);
106 if (bossStatesItr ==
_doc.MemberEnd())
108 TC_LOG_ERROR(
"scripts.data.load",
"Missing boss states for instance {} [{}-{} | {}-{}]",
113 if (!bossStatesItr->value.IsArray())
115 TC_LOG_ERROR(
"scripts.data.load",
"Boss states is not an array for instance {} [{}-{} | {}-{}]",
120 for (
uint32 bossId = 0; bossId < bossStatesItr->value.Size(); ++bossId)
124 TC_LOG_ERROR(
"scripts.data.load",
"Boss states has entry for boss with higher id ({}) than number of bosses ({}) for instance {} [{}-{} | {}-{}]",
129 auto& bossState = bossStatesItr->value[bossId];
130 if (!bossState.IsNumber())
132 TC_LOG_ERROR(
"scripts.data.load",
"Boss state for boss ({}) is not a number for instance {} [{}-{} | {}-{}]",
150 auto moreDataItr =
_doc.FindMember(MoreSaveDataKey);
151 if (moreDataItr ==
_doc.MemberEnd())
154 if (!moreDataItr->value.IsObject())
156 TC_LOG_ERROR(
"scripts.data.load",
"Additional data is not an object for instance {} [{}-{} | {}-{}]",
163 auto valueItr = moreDataItr->value.FindMember(value->GetName());
164 if (valueItr != moreDataItr->value.MemberEnd() && !valueItr->value.IsNull())
166 if (!valueItr->value.IsNumber())
168 TC_LOG_ERROR(
"scripts.data.load",
"Additional data value for key {} is not a number for instance {} [{}-{} | {}-{}]",
173 if (valueItr->value.IsDouble())
174 value->LoadValue(valueItr->value.GetDouble());
176 value->LoadValue(valueItr->value.GetInt64());
191 rapidjson::StringBuffer buffer;
192 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
195 return std::string(buffer.GetString(), buffer.GetSize());
203 rapidjson::Value bossStates(rapidjson::kArrayType);
206 rapidjson::Value bossStateValue(rapidjson::kNumberType);
208 bossStates.PushBack(bossStateValue.Move(),
_doc.GetAllocator());
210 _doc.AddMember(rapidjson::StringRef(BossStatesSaveDataKey), bossStates.Move(),
_doc.GetAllocator());
214 rapidjson::Value moreData(rapidjson::kObjectType);
220 std::visit([&](
auto v)
222 moreData.AddMember(rapidjson::StringRef(data.
Key), rapidjson::Value(v),
_doc.GetAllocator());
226 moreData.AddMember(rapidjson::StringRef(additionalValue->GetName()), rapidjson::Value(),
_doc.GetAllocator());
229 _doc.AddMember(rapidjson::StringRef(MoreSaveDataKey), moreData.Move(),
_doc.GetAllocator());
235 if (
_doc.Parse(data).HasParseError())
243 rapidjson::Pointer::Token tokens[] =
245 { BossStatesSaveDataKey.c_str(),
uint32(BossStatesSaveDataKey.length()), rapidjson::kPointerInvalidIndex },
246 { bossIdKey.c_str(),
uint32(bossIdKey.length()), rapidjson::kPointerInvalidIndex }
248 rapidjson::Pointer ptr(tokens,
std::size(tokens));
251 rapidjson::Value stateValue(rapidjson::kNumberType);
253 rapidjson::SetValueByPointer(
_doc, ptr, stateValue.Move());
258 rapidjson::Pointer::Token tokens[] =
260 { MoreSaveDataKey.c_str(),
uint32(MoreSaveDataKey.length()), rapidjson::kPointerInvalidIndex },
261 { data.
Key,
uint32(strlen(data.
Key)), rapidjson::kPointerInvalidIndex }
263 rapidjson::Pointer ptr(tokens,
std::size(tokens));
266 std::visit([&](
auto v)
268 rapidjson::SetValueByPointer(
_doc, ptr, v);
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
#define TC_LOG_ERROR(filterType__,...)
@ BossStatesIsNotAnObject
@ AdditionalDataIsNotAnObject
@ AdditionalDataUnexpectedValueType
InstanceScript & _instance
char const * GetDifficultyName() const
Result Load(char const *data)
uint32 GetInstanceId() const
char const * GetMapName() const
uint32 GetDifficultyId() const
Result ParseAdditionalData()
InstanceScript & _instance
void SetAdditionalData(UpdateAdditionalSaveDataEvent const &data)
void FillDataFrom(std::string const &data)
void FillData(bool withValues=true)
void SetBossState(UpdateBossStateSaveDataEvent const &data)
virtual bool SetBossState(uint32 id, EncounterState state)
std::vector< PersistentInstanceScriptValueBase * > & GetPersistentScriptValues()
std::string const & GetHeader() const
EncounterState GetBossState(uint32 id) const
uint32 GetEncounterCount() const
Difficulty GetDifficultyID() const
char const * GetMapName() const
uint32 GetInstanceId() const
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.
constexpr std::size_t size()
std::variant< int64, double > Value