#include "Contents/Store/MCStoreInfoBackup.h" #include "Client/Session/Session.h" #include "Network/TextEncoding.h" #include "UI/Shop/UIMerchantShopMakeWnd.h" #include "UI/Window/UIWindowMgr.h" #include #include #include #include // INLINED template static __forceinline void StoreField(unsigned char* field, T value) { std::memcpy(field, &value, sizeof(value)); } // INLINED template static __forceinline T LoadField(const unsigned char* field) { T value; std::memcpy(&value, field, sizeof(value)); return value; } // OFFSET: 0x00606190 // FUNCTION: fn_04233 void CMCStoreInfoBackup::ImportData(Json::Value& data) { this->items.clear(); this->title = static_cast(FromUtf8(data.get("Title", "").asString(), g_textCodePage)); Json::Value values = data["Item"]; const std::string styledText = values.toStyledString(); if (values.isNull() && this->title.empty()) { return; } for (auto entry = values.begin(); entry != values.end(); ++entry) { if (!(*entry).isObject()) { continue; } ITEM_INFO item; item.SetItemId((*entry).get("ID", 0).asInt()); item.quantity = (*entry).get("Count", 0).asInt(); item.identified = (*entry).get("Identified", 0).asBool(); item.refiningLevel = (*entry).get("RefiningLevel", 0).asInt(); item.grade = static_cast((*entry).get("GradeLevel", 0).asInt()); StoreField(item.cards + 0, (*entry).get("Slot_1", 0).asInt()); StoreField(item.cards + 4, (*entry).get("Slot_2", 0).asInt()); StoreField(item.cards + 8, (*entry).get("Slot_3", 0).asInt()); StoreField(item.cards + 12, (*entry).get("Slot_4", 0).asInt()); item.optionCount = (*entry).get("RandomOptionCount", 0).asInt(); Json::Value options = (*entry)["RandomOptionList"]; int index = 0; unsigned char* record = item.options; for (auto option = options.begin(); option != options.end() && index <= 5; ++option, ++index, record += 5) { StoreField(record, (*option).get("OptIndex", 0).asInt()); StoreField(record + 2, (*option).get("Value", 0).asInt()); record[4] = static_cast((*option).get("Parm1", 0).asInt()); } item.prices[0] = static_cast((*entry).get("Price", 0).asInt()); this->items.push_back(item); } UIWindow* window = g_windowMgr.merchantShopMakeWnd ? g_windowMgr.merchantShopMakeWnd : g_windowMgr.buyingShopMakeWnd; if (window) { static_cast(window)->Refresh(); } } // OFFSET: 0x00607240 // FUNCTION: fn_04238 void CMCStoreInfoBackup::ExportData(Json::Value& data) const { data["Title"] = ToUtf8(this->title, g_textCodePage); Json::Value values; const int itemCount = g_session.GetList9Size(); for (int itemIndex = 0; itemIndex < itemCount; ++itemIndex) { const ITEM_INFO item = g_session.GetItem1758At(itemIndex); Json::Value value; value["ID"] = std::atoi(item.itemId.c_str()); value["Count"] = item.quantity; value["Identified"] = item.identified != 0; value["RefiningLevel"] = item.refiningLevel; value["GradeLevel"] = item.grade; value["Slot_1"] = LoadField(item.cards + 0); value["Slot_2"] = LoadField(item.cards + 4); value["Slot_3"] = LoadField(item.cards + 8); value["Slot_4"] = LoadField(item.cards + 12); const int count = item.optionCount; value["RandomOptionCount"] = count; Json::Value options; for (int index = 0; index < count; ++index) { const auto* record = reinterpret_cast(&item) + offsetof(ITEM_INFO, options) + index * 5; std::int16_t id, amount; std::memcpy(&id, record, sizeof(id)); std::memcpy(&amount, record + 2, sizeof(amount)); Json::Value option; option["OptIndex"] = id; option["Value"] = amount; option["Parm1"] = record[4]; options.append(option); } value["RandomOptionList"] = options; value["Price"] = static_cast(item.prices[0]); values.append(value); } data["Item"] = values; }