using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using crecheng.DSPModSave; using NebulaAPI; using NebulaAPI.Interfaces; namespace Dustbin; [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] [BepInDependency(DSPModSavePlugin.MODGUID)] [BepInDependency(NebulaModAPI.API_GUID, BepInDependency.DependencyFlags.SoftDependency)] public class Dustbin : BaseUnityPlugin, IModCanSave, IMultiplayerMod { public string Version => PluginInfo.PLUGIN_VERSION; public new static readonly BepInEx.Logging.ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME); private static readonly int[] SandsFactors = new int[12001]; public bool CheckVersion(string hostVersion, string clientVersion) { return hostVersion.Equals(clientVersion); } private void Awake() { var storageDustbin = Config.Bind("General", "StorageDustbin", true, "Can turn storages into dustbins").Value; var tankDustbin = Config.Bind("General", "TankDustbin", true, "Can turn tanks into dustbins").Value; var belgSignalDustbin = Config.Bind("General", "BeltSignalDustbin", true, "Add belt signal as dustbin").Value; var sandsFactorsStr = Config.Bind("General", "SandsFactors", "", "Soil piles get from different items\nFormat: id1:value1|id2:value2|...").Value; foreach (var s in sandsFactorsStr.Split('|')) { var sp = s.Split(':'); if (sp.Length < 2) continue; if (!int.TryParse(sp[0], out var id) || id > 12000) continue; if (!int.TryParse(sp[1], out var factor)) continue; SandsFactors[id] = factor; } if (storageDustbin) StoragePatch.Enable(true); if (tankDustbin) TankPatch.Enable(true); if (belgSignalDustbin) BeltSignal.Enable(true); if (!BepInEx.Bootstrap.Chainloader.PluginInfos.ContainsKey("dsp.nebula-multiplayer") || (!storageDustbin && !tankDustbin)) return; NebulaModAPI.RegisterPackets(Assembly.GetExecutingAssembly()); NebulaModAPI.OnPlanetLoadFinished += RequestPlanetDustbinData; } private void OnDestroy() { TankPatch.Enable(false); StoragePatch.Enable(false); BeltSignal.Enable(false); NebulaModAPI.OnPlanetLoadFinished -= RequestPlanetDustbinData; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CalcGetSands(int itemId, int count) { var sandsPerItem = itemId <= 12000 ? Dustbin.SandsFactors[itemId] : 0; if (sandsPerItem <= 0) return count; var player = GameMain.mainPlayer; var addCount = count * sandsPerItem; player.sandCount += addCount; return count; } #region IModCanSave private const ushort ModSaveVersion = 1; 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) return; StoragePatch.Import(r); TankPatch.Import(r); } public void IntoOtherSave() { } #endregion #region IMultiplayerMod public static byte[] ExportData(PlanetFactory factory) { var planetId = factory.planetId; var storageIds = new List(); var tankIds = new List(); var factoryStorage = factory.factoryStorage; var storagePool = factoryStorage.storagePool; for (var i = 1; i < factoryStorage.storageCursor; i++) { var storage = storagePool[i]; if (storage == null || storage.id != i) continue; if (storage.IsDustbin) storageIds.Add(i); } var tankPool = factoryStorage.tankPool; for (var i = 1; i < factoryStorage.tankCursor; i++) { ref var tank = ref tankPool[i]; if (tank.id != i) continue; if (tank.IsDustbin) tankIds.Add(i); } using var p = NebulaModAPI.GetBinaryWriter(); using var w = p.BinaryWriter; w.Write(planetId); w.Write(storageIds.Count); foreach (var storageId in storageIds) w.Write(storageId); w.Write(tankIds.Count); foreach (var tankId in tankIds) w.Write(tankId); return p.CloseAndGetBytes(); } public static void ImportData(byte[] bytes) { using var p = NebulaModAPI.GetBinaryReader(bytes); using var r = p.BinaryReader; var planetId = r.ReadInt32(); var factory = GameMain.galaxy.PlanetById(planetId)?.factory; if (factory == null) return; var factoryStorage = factory.factoryStorage; var count = r.ReadInt32(); var storagePool = factoryStorage.storagePool; var cursor = factoryStorage.storageCursor; for (var i = 1; i < cursor; i++) { var storage = storagePool[i]; if (storage == null || storage.id != i) continue; storage.IsDustbin = false; } for (var i = 0; i < count; i++) { var id = r.ReadInt32(); storagePool[id].IsDustbin = true; } count = r.ReadInt32(); var tankPool = factoryStorage.tankPool; cursor = factoryStorage.tankCursor; for (var i = 1; i < cursor; i++) { ref var tank = ref tankPool[i]; if (tank.id != i) continue; tank.IsDustbin = false; } for (var i = 0; i < count; i++) { var id = r.ReadInt32(); if (id >= cursor) continue; ref var tank = ref tankPool[id]; if (tank.id != id) continue; tank.IsDustbin = true; } } public void RequestPlanetDustbinData(int planetId) { if (NebulaModAPI.IsMultiplayerActive && NebulaModAPI.MultiplayerSession.IsClient) NebulaModAPI.MultiplayerSession.Network.SendPacket(new NebulaSupport.Packet.ToggleEvent(planetId, 0, false)); } #endregion }