diff --git a/include/OutfitSystem.h b/include/OutfitSystem.h index 74682e3..a8b2b22 100644 --- a/include/OutfitSystem.h +++ b/include/OutfitSystem.h @@ -4,4 +4,4 @@ namespace OutfitSystem { bool RegisterPapyrus(VMClassRegistry* registry); -} \ No newline at end of file +} diff --git a/mod_files/interface/translations/skyrimoutfitsystem_english.txt b/mod_files/interface/translations/skyrimoutfitsystem_english.txt index f2e7f71..4bd98a6 100644 Binary files a/mod_files/interface/translations/skyrimoutfitsystem_english.txt and b/mod_files/interface/translations/skyrimoutfitsystem_english.txt differ diff --git a/src/OutfitSystem.cpp b/src/OutfitSystem.cpp index 54d6076..decd584 100644 --- a/src/OutfitSystem.cpp +++ b/src/OutfitSystem.cpp @@ -35,6 +35,10 @@ #include +#include "google/protobuf/util/json_util.h" + +// Needed for save and load of config JSON +extern SKSESerializationInterface* g_Serialization; namespace OutfitSystem { SInt32 GetOutfitNameMaxLength(VMClassRegistry* registry, UInt32 stackId, StaticFunctionTag*) { @@ -651,6 +655,55 @@ return BSFixedString(""); } } + bool ExportSettings(VMClassRegistry* registry, UInt32 stackId, StaticFunctionTag*) { + std::string outputFile = GetRuntimeDirectory() + "Data\\SKSE\\Plugins\\OutfitSystemData.json"; + auto& service = ArmorAddonOverrideService::GetInstance(); + proto::OutfitSystem data = service.save(g_Serialization); + std::string output; + google::protobuf::util::JsonPrintOptions options; + options.add_whitespace = true; + google::protobuf::util::MessageToJsonString(data, &output, options); + std::ofstream file(outputFile); + if (file) { + file << output; + } else { + RE::DebugNotification("Failed to open config for writing", nullptr, false); + return false; + } + if (file.good()) { + std::string message = "Wrote JSON config to " + outputFile; + RE::DebugNotification(message.c_str(), nullptr, false); + return true; + } else { + RE::DebugNotification("Failed to write config", nullptr, false); + return false; + } + } + bool ImportSettings(VMClassRegistry* registry, UInt32 stackId, StaticFunctionTag*) { + std::string inputFile = GetRuntimeDirectory() + "Data\\SKSE\\Plugins\\OutfitSystemData.json"; + std::ifstream file(inputFile); + if (!file) { + RE::DebugNotification("Failed to open config for reading", nullptr, false); + return false; + } + std::stringstream input; + input << file.rdbuf(); + if (!file.good()) { + RE::DebugNotification("Failed to read config data", nullptr, false); + return false; + } + proto::OutfitSystem data; + auto status = google::protobuf::util::JsonStringToMessage(input.str(), &data); + if (!status.ok()) { + RE::DebugNotification("Failed to parse config data. Invalid syntax.", nullptr, false); + return false; + } + auto& service = ArmorAddonOverrideService::GetInstance(); + service.load(g_Serialization, data); + std::string message = "Read JSON config from " + inputFile; + RE::DebugNotification(message.c_str(), nullptr, false); + return true; + } } @@ -922,5 +975,18 @@ bool OutfitSystem::RegisterPapyrus(VMClassRegistry* registry) { GetLocationOutfit, registry )); + registry->RegisterFunction(new NativeFunction0( + "ExportSettings", + "SkyrimOutfitSystemNativeFuncs", + ExportSettings, + registry + )); + registry->RegisterFunction(new NativeFunction0( + "ImportSettings", + "SkyrimOutfitSystemNativeFuncs", + ImportSettings, + registry + )); + return true; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2048e97..444a08c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,12 +12,12 @@ #define DllExport __declspec( dllexport ) -static PluginHandle g_pluginHandle = kPluginHandle_Invalid; -static SKSEPapyrusInterface* g_Papyrus = nullptr; -static SKSEMessagingInterface* g_Messaging = nullptr; -static SKSESerializationInterface* g_Serialization = nullptr; +PluginHandle g_pluginHandle = kPluginHandle_Invalid; +SKSEPapyrusInterface* g_Papyrus = nullptr; +SKSEMessagingInterface* g_Messaging = nullptr; +SKSESerializationInterface* g_Serialization = nullptr; -static UInt32 g_pluginSerializationSignature = 'cOft'; +UInt32 g_pluginSerializationSignature = 'cOft'; void Callback_Messaging_SKSE(SKSEMessagingInterface::Message* message); void Callback_Serialization_Save(SKSESerializationInterface* intfc); diff --git a/src/papyrus/skyoutsysmcm.psc b/src/papyrus/skyoutsysmcm.psc index 7077b78..7cc67a8 100644 --- a/src/papyrus/skyoutsysmcm.psc +++ b/src/papyrus/skyoutsysmcm.psc @@ -234,6 +234,13 @@ EndFunction SkyOutSysQuickslotManager kQM = GetQuickslotManager() AddHeaderOption("$SkyOutSys_MCMHeader_Quickslots") AddToggleOptionST("OPT_QuickslotsEnabled", "$SkyOutSys_Text_EnableQuickslots", kQM.GetEnabled()) + AddEmptyOption() + ; + ; Setting import/export + ; + AddHeaderOption("$SkyOutSys_Text_SettingExportImport") + AddTextOptionST ("OPT_ExportSettings", "$SkyOutSys_Text_Export", "") + AddTextOptionST ("OPT_ImportSettings", "$SkyOutSys_Text_Import", "") ;/EndBlock/; ;/Block/; ; Right column SetCursorPosition(1) @@ -282,6 +289,24 @@ EndFunction SetInfoText("$SkyOutSys_Desc_EnableAutoswitch") EndEvent EndState + State OPT_ImportSettings + Event OnSelectST() + SkyrimOutfitSystemNativeFuncs.ImportSettings() + ForcePageReset() + EndEvent + Event OnHighlightST() + SetInfoText("$SkyOutSys_Desc_Import") + EndEvent + EndState + State OPT_ExportSettings + Event OnSelectST() + SkyrimOutfitSystemNativeFuncs.ExportSettings() + ForcePageReset() + EndEvent + Event OnHighlightST() + SetInfoText("$SkyOutSys_Desc_Export") + EndEvent + EndState ;/EndBlock/; ;/Block/; ; Outfit editing diff --git a/src/papyrus/skyrimoutfitsystemnativefuncs.psc b/src/papyrus/skyrimoutfitsystemnativefuncs.psc index 132c9d1..9886ed2 100644 --- a/src/papyrus/skyrimoutfitsystemnativefuncs.psc +++ b/src/papyrus/skyrimoutfitsystemnativefuncs.psc @@ -85,3 +85,5 @@ Int Function IdentifyLocationType (Location alLocation) Global Native Function SetLocationOutfit (Int aiLocationType, String asOutfitName) Global Native Function UnsetLocationOutfit (Int aiLocationType) Global Native String Function GetLocationOutfit (Int aiLocationType) Global Native +Bool Function ExportSettings () Global Native +Bool Function ImportSettings () Global Native