From 843df24384b6609e85da952b74f6e26d7b723e31 Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Mon, 5 Dec 2022 21:19:08 +0800 Subject: [PATCH] Dustbin: Save dustbin state using DSPModSave --- Dustbin/Dustbin.cs | 66 +++++++++++++++++++++++++++-------- Dustbin/Dustbin.csproj | 3 +- Dustbin/StoragePatch.cs | 63 ++++++++++++++++++++------------- Dustbin/TankPatch.cs | 62 ++++++++++++++++++-------------- Dustbin/package/manifest.json | 3 +- 5 files changed, 129 insertions(+), 68 deletions(-) diff --git a/Dustbin/Dustbin.cs b/Dustbin/Dustbin.cs index d571d60..ca8dc75 100644 --- a/Dustbin/Dustbin.cs +++ b/Dustbin/Dustbin.cs @@ -1,47 +1,62 @@ using System; -using System.Collections.Generic; +using System.Collections; +using System.IO; using System.Linq; -using System.Reflection.Emit; using BepInEx; +using crecheng.DSPModSave; using HarmonyLib; -using UnityEngine; namespace Dustbin; -class IsDusbinIndexer +public class IsDusbinIndexer { - private bool[] store = new bool[256]; + private bool[] _store = new bool[256]; public bool this[int index] { get { - if (index < 0 || index >= store.Length) return false; - return store[index]; + if (index < 0 || index >= _store.Length) return false; + return _store[index]; } set { - if (index >= store.Length) + if (index >= _store.Length) { - var oldLen = store.Length; + var oldLen = _store.Length; var newLen = oldLen * 2; - var oldArr = store; - store = new bool[newLen]; - Array.Copy(oldArr, store, oldLen); + var oldArr = _store; + _store = new bool[newLen]; + Array.Copy(oldArr, _store, oldLen); } - store[index] = value; + _store[index] = value; } } public void Reset() { - store = new bool[256]; + _store = new bool[256]; + } + + public delegate void ForEachFunc(int id); + public void ForEachIsDustbin(ForEachFunc func) + { + var len = _store.Length; + for (var i = 0; i < len; i++) + { + if (_store[i]) + { + func(i); + } + } } } [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] -public class Dustbin : BaseUnityPlugin +[BepInDependency(DSPModSavePlugin.MODGUID)] +public class Dustbin : BaseUnityPlugin, IModCanSave { + private const ushort ModSaveVersion = 1; private new static readonly BepInEx.Logging.ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME); @@ -79,4 +94,25 @@ public class Dustbin : BaseUnityPlugin foreach (var id in ItemProto.fluids) IsFluid[id] = true; } + + public void Export(BinaryWriter w) + { + w.Write(ModSaveVersion); + StoragePatch.Export(w); + TankPatch.Export(w); + } + + public void Import(BinaryReader r) + { + var version = r.ReadUInt16(); + if (version > 0) + { + StoragePatch.Import(r); + TankPatch.Import(r); + } + } + + public void IntoOtherSave() + { + } } diff --git a/Dustbin/Dustbin.csproj b/Dustbin/Dustbin.csproj index c0ac1e2..843af12 100644 --- a/Dustbin/Dustbin.csproj +++ b/Dustbin/Dustbin.csproj @@ -15,11 +15,12 @@ + - + diff --git a/Dustbin/StoragePatch.cs b/Dustbin/StoragePatch.cs index 3ba57b0..3267d18 100644 --- a/Dustbin/StoragePatch.cs +++ b/Dustbin/StoragePatch.cs @@ -1,4 +1,5 @@ -using HarmonyLib; +using System.IO; +using HarmonyLib; using UnityEngine; namespace Dustbin; @@ -16,6 +17,32 @@ public static class StoragePatch lastStorageId = 0; } + public static void Export(BinaryWriter w) + { + var tempStream = new MemoryStream(); + var tempWriter = new BinaryWriter(tempStream); + int count = 0; + storageIsDustbin.ForEachIsDustbin(i => + { + tempWriter.Write(i); + count++; + }); + w.Write(count); + tempStream.Position = 0; + /* FixMe: May BinaryWriter not sync with its BaseStream while subclass overrides Write()? */ + tempStream.CopyTo(w.BaseStream); + tempWriter.Dispose(); + tempStream.Dispose(); + } + + public static void Import(BinaryReader r) + { + for (var count = r.ReadInt32(); count > 0; count--) + { + storageIsDustbin[r.ReadInt32()] = true; + } + } + [HarmonyPostfix] [HarmonyPatch(typeof(UIStorageWindow), "_OnCreate")] private static void UIStorageWindow__OnCreate_Postfix(UIStorageWindow __instance) @@ -81,38 +108,24 @@ public static class StoragePatch } [HarmonyPrefix] - [HarmonyPatch(typeof(StorageComponent), "Export")] - private static void StorageComponent_Export_Prefix(StorageComponent __instance, out int __state) + [HarmonyPatch(typeof(FactoryStorage), "RemoveStorageComponent")] + private static void FactoryStorage_RemoveStorageComponent_Prefix(FactoryStorage __instance, int id) { - if (storageIsDustbin[__instance.id]) + var storage = __instance.storagePool[id]; + if (storage != null && storage.id != 0) { - __state = __instance.bans; - __instance.bans = -__instance.bans - 1; - } - else - { - __state = -1; + storageIsDustbin[id] = false; } } - [HarmonyPostfix] - [HarmonyPatch(typeof(StorageComponent), "Export")] - private static void StorageComponent_Export_Postfix(StorageComponent __instance, int __state) - { - if (__state < 0) return; - __instance.bans = __state; - } - + /* We keep this to make MOD compatible with older version */ [HarmonyPostfix] [HarmonyPatch(typeof(StorageComponent), "Import")] private static void StorageComponent_Import_Postfix(StorageComponent __instance) { - if ((__instance.bans & 0x8000) == 0) - storageIsDustbin[__instance.id] = false; - else - { - storageIsDustbin[__instance.id] = true; - __instance.bans ^= 0x8000; - } + if (__instance.bans >= 0) + return; + storageIsDustbin[__instance.id] = true; + __instance.bans = -__instance.bans - 1; } } diff --git a/Dustbin/TankPatch.cs b/Dustbin/TankPatch.cs index 705e938..ea053a5 100644 --- a/Dustbin/TankPatch.cs +++ b/Dustbin/TankPatch.cs @@ -1,5 +1,5 @@ -using HarmonyLib; -using UnityEngine; +using System.IO; +using HarmonyLib; namespace Dustbin; @@ -16,6 +16,32 @@ public static class TankPatch lastTankId = 0; } + public static void Export(BinaryWriter w) + { + var tempStream = new MemoryStream(); + var tempWriter = new BinaryWriter(tempStream); + int count = 0; + tankIsDustbin.ForEachIsDustbin(i => + { + tempWriter.Write(i); + count++; + }); + w.Write(count); + tempStream.Position = 0; + /* FixMe: May BinaryWriter not sync with its BaseStream while subclass overrides Write()? */ + tempStream.CopyTo(w.BaseStream); + tempWriter.Dispose(); + tempStream.Dispose(); + } + + public static void Import(BinaryReader r) + { + for (var count = r.ReadInt32(); count > 0; count--) + { + tankIsDustbin[r.ReadInt32()] = true; + } + } + [HarmonyPostfix] [HarmonyPatch(typeof(UITankWindow), "_OnCreate")] private static void UITankWindow__OnCreate_Postfix(UITankWindow __instance) @@ -69,38 +95,22 @@ public static class TankPatch } [HarmonyPrefix] - [HarmonyPatch(typeof(TankComponent), "Export")] - private static void TankComponent_Export_Prefix(ref TankComponent __instance, out int __state) + [HarmonyPatch(typeof(FactoryStorage), "RemoveTankComponent")] + private static void FactoryStorage_RemoveTankComponent_Prefix(FactoryStorage __instance, int id) { - if (tankIsDustbin[__instance.id]) + if (__instance.tankPool[id].id != 0) { - __state = __instance.fluidInc; - __instance.fluidInc = -__instance.fluidInc - 1; + tankIsDustbin[id] = false; } - else - { - __state = -1; - } - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(TankComponent), "Export")] - private static void TankComponent_Export_Postfix(ref TankComponent __instance, int __state) - { - if (__state < 0) return; - __instance.fluidInc = __state; } + /* We keep this to make MOD compatible with older version */ [HarmonyPostfix] [HarmonyPatch(typeof(TankComponent), "Import")] private static void TankComponent_Import_Postfix(TankComponent __instance) { - if (__instance.fluidInc >= 0) - tankIsDustbin[__instance.id] = false; - else - { - tankIsDustbin[__instance.id] = true; - __instance.fluidInc = -__instance.fluidInc - 1; - } + if (__instance.fluidInc >= 0) return; + tankIsDustbin[__instance.id] = true; + __instance.fluidInc = -__instance.fluidInc - 1; } } diff --git a/Dustbin/package/manifest.json b/Dustbin/package/manifest.json index 6e5d448..d97d5db 100644 --- a/Dustbin/package/manifest.json +++ b/Dustbin/package/manifest.json @@ -4,6 +4,7 @@ "website_url": "https://github.com/soarqin/DSP_Mods/tree/master/Dustbin", "description": "Can turn Storages and Tanks into Dustbin(Destroy incoming items) / 储物仓和储液罐可以转变为垃圾桶(销毁送进的物品)", "dependencies": [ - "xiaoye97-BepInEx-5.4.17" + "xiaoye97-BepInEx-5.4.17", + "CommonAPI-DSPModSave-1.1.4" ] }