From f78f311b6f49e9ac62426a84459d363161fe6bc9 Mon Sep 17 00:00:00 2001 From: Conqu3red Date: Sat, 6 Mar 2021 11:04:07 +0000 Subject: [PATCH 1/2] added ability for mods to save custom byte data to layouts --- PolyTechMain.cs | 68 ++++++++++++++++++++++++++++++++++++++++++++----- PolyTechMod.cs | 8 ++++++ 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/PolyTechMain.cs b/PolyTechMain.cs index a21ac4b..4c43cf5 100644 --- a/PolyTechMain.cs +++ b/PolyTechMain.cs @@ -24,7 +24,7 @@ public class PolyTechMain : PolyTechMod public new const string PluginGuid = "polytech.polytechframework", PluginName = "PolyTech Framework", - PluginVersion = "0.9.3"; + PluginVersion = "0.9.4"; private static BindingList noncheatMods = new BindingList { }, cheatMods = new BindingList { }; @@ -707,7 +707,7 @@ static void patchSerializerOne(SandboxLayoutData __instance, List bytes) { ptfInstance.ptfLogger.LogMessage($"Layout pre version: {__instance.m_Version}"); if (GameStateManager.GetState() != GameState.BUILD && GameStateManager.GetState() != GameState.SANDBOX) return; - if (cheatMods.Where(x => x.isEnabled).Count() == 0) return; + if (noncheatMods.Where(x => x.shouldSaveData).Count() + cheatMods.Where(x => x.shouldSaveData).Count() == 0) return; __instance.m_Version *= -1; //PopUpMessage.Display("You have cheat mods enabled, do you want to store them?\n(This will make the layout incompatible with vanilla PB2)", yes, no); ptfInstance.ptfLogger.LogMessage($"Version after cheat question: {__instance.m_Version.ToString()}"); @@ -718,10 +718,41 @@ static void patchSerializerOne(SandboxLayoutData __instance, List bytes) private static void patchSerializerTwo(SandboxLayoutData __instance, List bytes) { ptfInstance.ptfLogger.LogMessage($"Layout post version: {__instance.m_Version}"); + + // add number of mods stored + //bytes.AddRange(ByteSerializer.SerializeInt(noncheatMods.Where(x => x.shouldSaveData).Count() + cheatMods.Where(x => x.shouldSaveData).Count())); - string[] mods = cheatMods.Where(x => x.isEnabled).Select(x => $"{x.Info.Metadata.Name}\u058D{x.Info.Metadata.Version}\u058D{x.getSettings()}").ToArray(); + // add mod data for each mod + + // make sure to be backwards compatible! + List modData = cheatMods.Where(x => x.isEnabled).Select(x => $"{x.Info.Metadata.Name}\u058D{x.Info.Metadata.Version}\u058D{x.getSettings()}").ToList(); + modData.AddRange(noncheatMods.Where(x => x.shouldSaveData).Select(x => $"{x.Info.Metadata.Name}\u058D{x.Info.Metadata.Version}\u058D{x.getSettings()}").ToList()); + string[] mods = modData.ToArray(); + if (__instance.m_Version >= 0) return; bytes.AddRange(ByteSerializer.SerializeStrings(mods)); + + bytes.AddRange(ByteSerializer.SerializeInt(modData.Count)); + foreach (var mod in noncheatMods){ + if (mod.isEnabled && mod.shouldSaveData){ + bytes.AddRange(ByteSerializer.SerializeString( + $"{mod.Info.Metadata.Name}\u058D{mod.Info.Metadata.Version}" + )); + bytes.AddRange(ByteSerializer.SerializeByteArray( + mod.saveData() + )); + } + } + foreach (var mod in cheatMods){ + if (mod.isEnabled && mod.shouldSaveData){ + bytes.AddRange(ByteSerializer.SerializeString( + $"{mod.Info.Metadata.Name}\u058D{mod.Info.Metadata.Version}" + )); + bytes.AddRange(ByteSerializer.SerializeByteArray( + mod.saveData() + )); + } + } ptfInstance.ptfLogger.LogMessage($"Serialized {mods.Length.ToString()} Mod Names"); } @@ -762,16 +793,41 @@ public static void patchDeserializerPostfix(SandboxLayoutData __instance, byte[] ptfInstance.ptfLogger.LogInfo($" -- {str.Replace("\u058D", " - v")}"); - var currMod = cheatMods.Where(p => p.Info.Metadata.Name == name).First(); + var currMod = cheatMods.Where(p => p.Info.Metadata.Name == name).FirstOrDefault(); + if (currMod == null) currMod = noncheatMods.Where(p => p.Info.Metadata.Name == name).FirstOrDefault(); ptfInstance.checkMods(0, name, version, settings, currMod); } + if (offset == bytes.Length) return; + int extraSaveDataCount = ByteSerializer.DeserializeInt(bytes, ref offset); + if (extraSaveDataCount == 0) return; + + ptfInstance.Logger.LogInfo($"Layout created with custom data from mods: "); + + for (int i = 0; i < extraSaveDataCount; i++){ + string modIdentifier = ByteSerializer.DeserializeString(bytes, ref offset); + byte[] customModSaveData = ByteSerializer.DeserializeByteArray(bytes, ref offset); + + string[] partsOfMod = modIdentifier.Split('\u058D'); + string name = partsOfMod.Length >= 1 ? partsOfMod[0] : null; + string version = partsOfMod.Length >= 2 ? partsOfMod[1] : null; + + ptfInstance.Logger.LogInfo($" -- {name} - v{version}"); + + var currMod = cheatMods.Where(p => p.Info.Metadata.Name == name).FirstOrDefault(); + if (currMod == null) currMod = noncheatMods.Where(p => p.Info.Metadata.Name == name).FirstOrDefault(); + + if (currMod == null) return; + if (currMod.Info.Metadata.Version.ToString() != version) return; + + currMod.loadData(customModSaveData); + } } void checkMods(int step, string name, string version, string settings, PolyTechMod currMod) { - if (step <= 0 && currMod.Info.Metadata.Name != name) missingMod(name, version, settings, currMod); + if (currMod == null || (step <= 0 && currMod.Info.Metadata.Name != name)) missingMod(name, version, settings, currMod); else if (step <= 1 && currMod.Info.Metadata.Version.ToString() != version) wrongVersion(name, version, settings, currMod); else if (step <= 2 && !currMod.isEnabled) notEnabled(name, version, settings, currMod); else if (step <= 3 && currMod.getSettings() != settings) wrongSettings(name, version, settings, currMod); @@ -782,7 +838,7 @@ void missingMod(string name, string version, string settings, PolyTechMod currMo ptfInstance.ptfLogger.LogWarning("Mod in layout not present."); PopUpMessage.Display( $"Mod ({name}) in layout not present.", - () => checkMods(1, name, version, settings, currMod) + () => {} ); } diff --git a/PolyTechMod.cs b/PolyTechMod.cs index 6526408..cf1a31d 100644 --- a/PolyTechMod.cs +++ b/PolyTechMod.cs @@ -38,9 +38,17 @@ public virtual void setSettings(string settings) PopUpWarning.Display("Something tried to automatically set the settings for a mod, but the mod doesn't support this feature. Try setting them manually.", PopUpWarningCategory.OLDER_PHYSICS_ENGINE); } + public virtual byte[] saveData(){ + return new byte[] {}; + } + + public virtual void loadData(byte[] bytes){ + return; + } public bool isEnabled; public bool isCheat; public string repositoryUrl; public string[] authors; + public bool shouldSaveData; } } From c3f2967ba0e163e1b7b71fbeced3bbc3edf0673c Mon Sep 17 00:00:00 2001 From: Conqu3red Date: Sat, 6 Mar 2021 11:08:11 +0000 Subject: [PATCH 2/2] backwards compatibility --- PolyTechMain.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PolyTechMain.cs b/PolyTechMain.cs index 4c43cf5..aa5379b 100644 --- a/PolyTechMain.cs +++ b/PolyTechMain.cs @@ -726,7 +726,7 @@ private static void patchSerializerTwo(SandboxLayoutData __instance, List // make sure to be backwards compatible! List modData = cheatMods.Where(x => x.isEnabled).Select(x => $"{x.Info.Metadata.Name}\u058D{x.Info.Metadata.Version}\u058D{x.getSettings()}").ToList(); - modData.AddRange(noncheatMods.Where(x => x.shouldSaveData).Select(x => $"{x.Info.Metadata.Name}\u058D{x.Info.Metadata.Version}\u058D{x.getSettings()}").ToList()); + modData.AddRange(noncheatMods.Where(x => x.shouldSaveData && x.isEnabled).Select(x => $"{x.Info.Metadata.Name}\u058D{x.Info.Metadata.Version}\u058D{x.getSettings()}").ToList()); string[] mods = modData.ToArray(); if (__instance.m_Version >= 0) return;