rodecomp/Source/Utility/JsonCppLoader.cpp
ragnarok-clanker f8d3e8622d Maintenance: Rename placeholder sub_XXXXXX functions to evidence-based names (Lua registration strings, log/error strings, packet ids
Batch #13412 by ragnarok-clanker: no function's compiled code changes; checked with 592 compiled unit(s), including every includer of Source/Client/Mode/CGameMode.h, Source/Client/Session.h, Source/Contents/Actors/GameActor.h, Source/Contents/CashEmotionMgr.h, Source/Contents/ClientItemLists.h, Source/Contents/ClientState.h, Source/Contents/Configuration/GameSettingsMgr.h, Source/Contents/Items/ItemInfo.h, Source/Contents/NavigationManager.h, Source/Contents/RenewQuestMgr.h, Source/Contents/ReputeMgr.h, Source/Contents/Schedule/TimeScheduler.h, Source/Contents/WorldView/WorldViewData.h, Source/UI/Buttons/UIDescriptRace.h, Source/UI/CashEmotion/UICashEmotionListWnd.h, Source/UI/Dialogs/UIPasswordWnd.h, Source/UI/Edit/UIEditCtrl.h, Source/UI/Edit/UIItemTagCtrl.h, Source/UI/GameSettings/GameSettingsUI.h, Source/UI/Item/UIItemStoreSubWnd.h, Source/UI/Items/UISwapEquipmentWnd.h, Source/UI/Lists/UIChatHisBox.h, Source/UI/Lists/UITagListBox.h, Source/UI/Quest/UIOngoingQuestInfo.h, Source/UI/Quest/UIRenewQuestUI.h, Source/UI/Rodex/UIRodexComposeWnd.h, Source/UI/Text/UIAchWnd.h, Source/UI/UIGradeEnchantWnd.h, Source/UI/UIIngredientInfoWnd.h, Source/UI/UIMacroUserInfoWnd.h, Source/UI/Window/UINewSkillListWnd.h, Source/UI/Window/UIRegisterMgr.h, Source/UI/Window/UIWindow.h, Source/UI/Window/UIWindowMgr.h, Source/Utility/JsonCppLoader.h.
2026-11-06 16:30:12 +00:00

397 lines
13 KiB
C++

#include "Utility/JsonCppLoader.h"
#include <cstdarg>
#include <cstdio>
#include <cstring>
// OFFSET: 0x00509940
// FUNCTION: fn_00891
bool JsonCppLoader::GetMapStringBoolValue(const JsonValue& node, const std::string& key, std::map<std::string, bool>* out) {
JsonValue value;
this->GetValue(value, key, node, JsonValue::OBJECT_VALUE);
if (value.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", key.c_str());
return false;
}
const JsonObject& members = value.GetObject();
for (JsonObject::const_iterator member = members.begin(); member != members.end(); ++member) {
std::string name = member->first;
JsonValue element = member->second;
if (element.GetType() != JsonValue::BOOL_VALUE) {
this->Fail("잘못된 데이터가 입력되었습니다. boolValue 가 입력되어야 합니다. (keyName : %s)", key.c_str());
return false;
}
if (!out->insert(std::make_pair(name, element.AsBool())).second) {
this->Fail("중복키가 입력되었습니다. (keyName : %s)", key.c_str());
return false;
}
}
return true;
}
// OFFSET: 0x005086D0
// FUNCTION: fn_00887
bool JsonCppLoader::GetStringValue(const JsonValue& node, const std::string& key, std::string* out) {
JsonValue value;
this->GetValue(value, key, node, JsonValue::STRING_VALUE);
if (value.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", key.c_str());
return false;
}
*out = value.AsString();
return true;
}
#include <fstream>
struct JsonCppLoaderBsonOptions {
void* storage[4];
};
struct JsonCppLoaderJsonOptions {
unsigned char storage[248];
};
extern "C" void fn_00198();
struct JsonCppLoaderJsonHandler {
unsigned char storage[40];
// INLINED
JsonCppLoaderJsonHandler() {
reinterpret_cast<void(__thiscall*)(JsonCppLoaderJsonHandler*, JsonCppLoaderJsonHandler*)>(fn_00198)(this, this);
}
JsonCppLoaderJsonHandler(const JsonCppLoaderJsonHandler&) = delete;
// INLINED
~JsonCppLoaderJsonHandler() {
}
};
extern "C" {
void fn_00349();
void fn_00321();
void fn_00368();
void fn_00198();
void* __cdecl fn_00272(JsonValue* out, std::ifstream* file, JsonCppLoaderBsonOptions* options);
void* __cdecl fn_00273(JsonValue* out, const std::vector<unsigned char>* buffer, JsonCppLoaderBsonOptions* options);
void* __cdecl fn_00733(JsonValue* out, std::ifstream* file, JsonCppLoaderJsonOptions* options, JsonCppLoaderJsonHandler handler);
void* __cdecl fn_00734(JsonValue* out, const unsigned char* data, JsonCppLoaderJsonOptions* options, JsonCppLoaderJsonHandler handler);
void fn_00769();
void fn_00367();
}
struct JsonCppLoaderParsedValue {
JsonValue value;
// INLINED
~JsonCppLoaderParsedValue() {
reinterpret_cast<void(__thiscall*)(JsonValue*)>(fn_00367)(&this->value);
}
};
struct JsonCppLoaderJsonOptionsGuard {
JsonCppLoaderJsonOptions* options;
// INLINED
~JsonCppLoaderJsonOptionsGuard() {
reinterpret_cast<void(__thiscall*)(JsonCppLoaderJsonOptions*)>(fn_00368)(reinterpret_cast<JsonCppLoaderJsonOptions*>(reinterpret_cast<unsigned char*>(this->options) + 8));
}
};
// OFFSET: 0x004F3CC0
// FUNCTION: fn_00487
bool JsonCppLoader::LoadBson(const std::string& path) {
try {
std::ifstream file(path.c_str(), std::ios::binary);
if (!file.is_open()) {
return false;
}
JsonCppLoaderBsonOptions optionStorage;
JsonCppLoaderBsonOptions* options = reinterpret_cast<JsonCppLoaderBsonOptions*(__thiscall*)(JsonCppLoaderBsonOptions*, int)>(fn_00349)(&optionStorage, 1);
{
JsonCppLoaderParsedValue parsed;
JsonValue* result = static_cast<JsonValue*>(fn_00272(&parsed.value, &file, options));
if (&this->document != result) {
reinterpret_cast<void(__thiscall*)(JsonValue*, JsonValue*)>(fn_00769)(&this->document, result);
}
}
file.close();
} catch (const std::exception& exception) {
this->Fail("error : JsonCppLoader::LoadBson failed (reason : %s)", exception.what());
return false;
}
return true;
}
// OFFSET: 0x004F3ED0
// FUNCTION: fn_00489
bool JsonCppLoader::LoadJson(const std::string& path) {
try {
std::ifstream file(path.c_str());
if (!file.is_open()) {
return false;
}
JsonCppLoaderJsonOptions optionStorage;
JsonCppLoaderJsonOptionsGuard options{reinterpret_cast<JsonCppLoaderJsonOptions*(__thiscall*)(JsonCppLoaderJsonOptions*, int)>(fn_00321)(&optionStorage, 1)};
{
JsonCppLoaderParsedValue parsed;
JsonValue* result = static_cast<JsonValue*>(fn_00733(&parsed.value, &file, options.options, JsonCppLoaderJsonHandler{}));
if (&this->document != result) {
reinterpret_cast<void(__thiscall*)(JsonValue*, JsonValue*)>(fn_00769)(&this->document, result);
}
}
file.close();
} catch (const std::exception& exception) {
this->Fail("error : JsonCppLoader::LoadJson failed (reason : %s)", exception.what());
return false;
}
return true;
}
// OFFSET: 0x004F3C70
// FUNCTION: fn_00486
bool JsonCppLoader::Load(std::vector<unsigned char>& buffer, bool bson) {
if (buffer.empty()) {
this->Fail("error : JsonCppLoader::Load failed (reason : 비어있는 버퍼가 전달되었습니다.)");
return false;
}
bool parsed;
if (bson == true) {
parsed = this->LoadBson(buffer);
} else {
parsed = this->LoadJson(buffer);
}
if (parsed) {
this->loaded = true;
return true;
}
return false;
}
// OFFSET: 0x004F3DF0
// FUNCTION: fn_00488
__declspec(noinline) bool JsonCppLoader::LoadBson(std::vector<unsigned char>& buffer) {
if (buffer.empty()) {
this->Fail("비어있는 버퍼가 전달되었습니다.");
return false;
}
try {
JsonCppLoaderBsonOptions optionStorage;
JsonCppLoaderBsonOptions* options = reinterpret_cast<JsonCppLoaderBsonOptions*(__thiscall*)(JsonCppLoaderBsonOptions*, int)>(fn_00349)(&optionStorage, 1);
JsonCppLoaderParsedValue parsed;
JsonValue* result = static_cast<JsonValue*>(fn_00273(&parsed.value, &buffer, options));
if (&this->document != result) {
reinterpret_cast<void(__thiscall*)(JsonValue*, JsonValue*)>(fn_00769)(&this->document, result);
}
} catch (const std::exception& exception) {
this->Fail("error : JsonCppLoader::LoadBson failed (reason : %s)", exception.what());
return false;
}
return true;
}
// OFFSET: 0x004F4040
// FUNCTION: fn_00490
__declspec(noinline) bool JsonCppLoader::LoadJson(std::vector<unsigned char>& buffer) {
if (buffer.empty()) {
this->Fail("비어있는 버퍼가 전달되었습니다.");
return false;
}
if (buffer.back() != '\0') {
this->Fail("문자열 끝이 존재하지 않습니다.");
return false;
}
try {
JsonCppLoaderJsonOptions optionStorage;
JsonCppLoaderJsonOptionsGuard options{reinterpret_cast<JsonCppLoaderJsonOptions*(__thiscall*)(JsonCppLoaderJsonOptions*, int)>(fn_00321)(&optionStorage, 1)};
JsonCppLoaderParsedValue parsed;
JsonValue* result = static_cast<JsonValue*>(fn_00734(&parsed.value, buffer.data(), options.options, JsonCppLoaderJsonHandler{}));
if (&this->document != result) {
reinterpret_cast<void(__thiscall*)(JsonValue*, JsonValue*)>(fn_00769)(&this->document, result);
}
} catch (const std::exception& exception) {
this->Fail("error : JsonCppLoader::LoadJson failed (reason : %s)", exception.what());
return false;
}
return true;
}
// OFFSET: 0x004F4180
// FUNCTION: fn_00491
void JsonCppLoader::Fail(const char* format, ...) {
char buffer[0x800];
std::memset(buffer, 0, sizeof(buffer));
va_list arguments;
va_start(arguments, format);
vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, format, arguments);
va_end(arguments);
this->error.assign(buffer, std::strlen(buffer));
this->succeeded = false;
}
// OFFSET: 0x00508570
// FUNCTION: fn_00886
bool JsonCppLoader::GetIntValue(const JsonValue& node, const std::string& key, int* out) {
JsonValue value;
this->GetValue(value, key, node, JsonValue::INT64_VALUE);
if (value.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", key.c_str());
return false;
}
*out = value.AsInt();
return true;
}
// OFFSET: 0x005087D0
// FUNCTION: fn_00888
bool JsonCppLoader::GetMapStringIntValue(const JsonValue& node, const std::string& key, std::map<std::string, int>* out) {
JsonValue value;
this->GetValue(value, key, node, JsonValue::OBJECT_VALUE);
if (value.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", key.c_str());
return false;
}
const JsonObject& members = value.GetObject();
for (JsonObject::const_iterator member = members.begin(); member != members.end(); ++member) {
std::string name = member->first;
JsonValue element = member->second;
if (element.GetType() != JsonValue::INT64_VALUE) {
this->Fail("잘못된 데이터가 입력되었습니다. intValue 가 입력되어야 합니다. (keyName : %s)", key.c_str());
return false;
}
if (!out->insert(std::make_pair(name, element.AsInt())).second) {
this->Fail("중복키가 입력되었습니다. (keyName : %s)", key.c_str());
return false;
}
}
return true;
}
// OFFSET: 0x00508BD0
// FUNCTION: fn_00889
bool JsonCppLoader::GetMapStringStringValue(const JsonValue& node, const std::string& key, std::map<std::string, std::string>* out) {
JsonValue value;
this->GetValue(value, key, node, JsonValue::OBJECT_VALUE);
if (value.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", key.c_str());
return false;
}
const JsonObject& members = value.GetObject();
for (JsonObject::const_iterator member = members.begin(); member != members.end(); ++member) {
std::string name = member->first;
JsonValue element = member->second;
if (element.GetType() != JsonValue::STRING_VALUE) {
this->Fail("잘못된 데이터가 입력되었습니다. stringValue 가 입력되어야 합니다. (keyName : %s)", key.c_str());
return false;
}
if (!out->insert(std::make_pair(name, element.AsString())).second) {
this->Fail("중복키가 입력되었습니다. (keyName : %s)", key.c_str());
return false;
}
}
return true;
}
// OFFSET: 0x00509130
// FUNCTION: fn_00890
bool JsonCppLoader::GetMapStringIntVectorValue(const JsonValue& node, const std::string& key, std::map<std::string, std::vector<int> >* out) {
JsonValue value;
this->GetValue(value, key, node, JsonValue::OBJECT_VALUE);
if (value.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", key.c_str());
return false;
}
const JsonObject& members = value.GetObject();
for (JsonObject::const_iterator member = members.begin(); member != members.end(); ++member) {
std::string name = member->first;
JsonValue element = member->second;
if (element.GetType() != JsonValue::ARRAY_VALUE) {
this->Fail("잘못된 데이터가 입력되었습니다. arrayValue 가 입력되어야 합니다. (keyName : %s)", key.c_str());
return false;
}
std::vector<int> values;
const JsonArray& items = element.ArrayRange();
for (JsonArray::const_iterator item = items.begin(); item != items.end(); ++item) {
if (item->GetType() != JsonValue::INT64_VALUE) {
this->Fail("잘못된 데이터가 입력되었습니다. intValue 가 입력되어야 합니다. (keyName : %s)", key.c_str());
return false;
}
values.push_back(item->AsInt());
}
if (!out->insert(std::make_pair(name, values)).second) {
this->Fail("중복키가 입력되었습니다. (keyName : %s)", key.c_str());
return false;
}
}
return true;
}
// OFFSET: 0x00509D40
// FUNCTION: fn_00892
bool JsonCppLoader::GetIntVectorValue(const JsonValue& node, const std::string& key, std::vector<int>* out) {
JsonValue value;
this->GetValue(value, key, node, JsonValue::ARRAY_VALUE);
if (value.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", key.c_str());
return false;
}
const JsonArray& items = value.ArrayRange();
for (JsonArray::const_iterator item = items.begin(); item != items.end(); ++item) {
if (item->GetType() != JsonValue::INT64_VALUE) {
this->Fail("잘못된 데이터가 입력되었습니다. intValue 가 입력되어야 합니다. (keyName : %s)", key.c_str());
return false;
}
out->push_back(item->AsInt());
}
return true;
}
// OFFSET: 0x00509F70
// FUNCTION: fn_00893
bool JsonCppLoader::GetBoolValue(const JsonValue& node, const std::string& key, bool* out) {
JsonValue value;
this->GetValue(value, key, node, JsonValue::BOOL_VALUE);
if (value.IsNull()) {
this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", key.c_str());
return false;
}
*out = value.AsBool();
return true;
}