Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SoberShip v1.3.0
sobership.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using SoberShip.Config; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("essiefir.sobership")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.0.0")] [assembly: AssemblyInformationalVersion("1.3.0+e00a77cccca62ba3cb14b8c1d7279d1feda1080e")] [assembly: AssemblyProduct("SoberShip")] [assembly: AssemblyTitle("essiefir.sobership")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SoberShip { [BepInPlugin("essiefir.sobership", "SoberShip", "1.3.0")] public class SoberShip : BaseUnityPlugin { internal static bool forceSpawnShrouds; public static SoberShip Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony? Harmony { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; ConfigOptions.Init(((BaseUnityPlugin)this).Config); Patch(); Logger.LogInfo((object)"SoberShip v1.3.0 has loaded!"); } internal static void Patch() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("essiefir.sobership"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "essiefir.sobership"; public const string PLUGIN_NAME = "SoberShip"; public const string PLUGIN_VERSION = "1.3.0"; } } namespace SoberShip.Patches { [HarmonyPatch(typeof(MoldSpreadManager), "GenerateMold")] public class MoldSpreadManagerPatches { public static bool ClearedNearbyMold; public static bool ClearedExcessiveMold; [HarmonyPostfix] private static void GenerateMoldPostfix(MoldSpreadManager __instance) { if ((Object)(object)GameNetworkManager.Instance == (Object)null || !GameNetworkManager.Instance.isHostingGame) { SoberShip.Logger.LogDebug((object)"GenerateMoldPostFix() called on a non-host client, skipping..."); } else { if (ConfigOptions.DisableVainShroudsCompletely.Value || (ConfigOptions.RemoveExcessiveVainShrouds.Value && ConfigOptions.MaximumVainShrouds.Value <= 0)) { return; } if (ConfigOptions.FixFalseVainShroudRemoval.Value && RoundManagerPatches.moldIterations > 0 && RoundManagerPatches.moldStartPosition > 0) { SoberShip.Logger.LogDebug((object)$"Loading Vain Shroud state... : iterations = {RoundManagerPatches.moldIterations}; startPosition = {RoundManagerPatches.moldStartPosition}"); StartOfRound.Instance.currentLevel.moldSpreadIterations = RoundManagerPatches.moldIterations; StartOfRound.Instance.currentLevel.moldStartPosition = RoundManagerPatches.moldStartPosition; } if (StartOfRound.Instance.currentLevel.moldSpreadIterations >= 1 && ConfigOptions.RemoveNearbyVainShrouds.Value) { if (ConfigOptions.VainShroudRemovalMethod.Value == ConfigOptions.RemovalMethod.DELETION) { DestroyNearbyMold(__instance); } else { DestroyNearbyMold(__instance, permanently: true); } } } } private static void DestroyNearbyMold(MoldSpreadManager __instance, bool permanently = false) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (ClearedNearbyMold || __instance.moldContainer.childCount <= 0) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return; } SoberShip.Logger.LogInfo((object)"Scanning Vain Shrouds..."); int num = 0; for (int i = 0; i < __instance.moldContainer.childCount; i++) { GameObject gameObject = ((Component)__instance.moldContainer.GetChild(i)).gameObject; if (Vector3.Distance(gameObject.transform.position, instance.elevatorTransform.position) <= ConfigOptions.MinimumVainShroudDistanceFromShip.Value) { DestroyMold(permanently, __instance, gameObject); num++; } SoberShip.Logger.LogDebug((object)$"Removed : {num} of {__instance.moldContainer.childCount} Shrouds"); } ClearedNearbyMold = true; SoberShip.Logger.LogInfo((object)"Scanned all Vain Shrouds!"); } private static void DestroyMold(bool permanently, MoldSpreadManager manager, GameObject mold) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Vector3 position = mold.transform.position; if (permanently) { manager.DestroyMoldAtPosition(mold.transform.position, false); } new SprayPaintItem().KillWeedServerRpc(mold.transform.position); if (manager.generatedMold.Contains(mold)) { manager.generatedMold.Remove(mold); } Object.Destroy((Object)(object)mold); ManualLogSource logger = SoberShip.Logger; Vector3 val = position; logger.LogDebug((object)("Destroying Vain Shroud at : " + ((object)(Vector3)(ref val)).ToString())); } } [HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")] public class RoundManagerPatches { public static int moldIterations = 0; public static int moldStartPosition = -1; [HarmonyPrefix] private static void GenerateNewLevelClientRpcPrefix(RoundManager __instance, ref int moldIterations, ref int moldStartPosition) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) SoberShip.Logger.LogDebug((object)$"GenerateNewClientLevelRpcPreFix() moldIterations : {moldIterations}; moldStartPosition : {moldStartPosition}"); if ((Object)(object)GameNetworkManager.Instance == (Object)null || !GameNetworkManager.Instance.isHostingGame) { SoberShip.Logger.LogDebug((object)"GenerateNewClientLevelRpcPreFix() called on a non-host client, skipping..."); return; } if (ConfigOptions.DisableVainShroudsCompletely.Value || (ConfigOptions.RemoveExcessiveVainShrouds.Value && ConfigOptions.MaximumVainShrouds.Value <= 0)) { moldIterations = 0; moldStartPosition = -1; SoberShip.Logger.LogDebug((object)"Vain Shrouds disabled."); return; } if (SoberShip.forceSpawnShrouds) { moldIterations = 17; moldStartPosition = 10; } if (moldIterations <= 0) { return; } if (ConfigOptions.RemoveExcessiveVainShrouds.Value && moldIterations > ConfigOptions.MaximumVainShrouds.Value) { SoberShip.Logger.LogInfo((object)$"Capping moldIterations to the specified maximum of {ConfigOptions.MaximumVainShrouds.Value}"); moldIterations = ConfigOptions.MaximumVainShrouds.Value; } if (ConfigOptions.RelocateVainShroudSpawnPosition.Value) { float value = ConfigOptions.MinimumVainShroudStartDistanceFromShip.Value; Vector3 position = StartOfRound.Instance.elevatorTransform.position; if (moldStartPosition <= 0 || (__instance.outsideAINodes.Length > moldStartPosition && Vector3.Distance(__instance.outsideAINodes[moldStartPosition].transform.position, position) < value)) { SoberShip.Logger.LogInfo((object)$"Vain Shroud starting position is {moldStartPosition}, which is too close to the ship, looking for a new location..."); Random random = new Random(StartOfRound.Instance.randomMapSeed + 2017); int num = 0; int num2 = random.Next(num, __instance.outsideAINodes.Length); while (Vector3.Distance(__instance.outsideAINodes[num2].transform.position, position) < value) { num2 = random.Next(++num, __instance.outsideAINodes.Length); if (num >= __instance.outsideAINodes.Length) { break; } } if (Vector3.Distance(__instance.outsideAINodes[num2].transform.position, position) >= value) { moldStartPosition = num2; SoberShip.Logger.LogInfo((object)$"Found a new Vain Shroud starting position ({num2}) using the specified minimum distance : {value}"); } else { moldStartPosition = random.Next(20, __instance.outsideAINodes.Length); SoberShip.Logger.LogWarning((object)$"Randomly chose a new Vain Shroud starting point ({moldStartPosition})."); SoberShip.Logger.LogError((object)$"Couldn't find a new position that's further than the specified minimum ({value}), is it too high?"); } } } if (ConfigOptions.FixFalseVainShroudRemoval.Value) { SoberShip.Logger.LogDebug((object)$"Saving Vain Shroud state... : iterations = {moldIterations}; startPosition = {moldStartPosition}"); RoundManagerPatches.moldIterations = moldIterations; RoundManagerPatches.moldStartPosition = moldStartPosition; } } } [HarmonyPatch(typeof(StartOfRound), "EndOfGame")] public class EndOfGamePatch { [HarmonyPostfix] private static void EndOfGamePostfix(StartOfRound __instance) { if (!((Object)(object)GameNetworkManager.Instance == (Object)null) && GameNetworkManager.Instance.isHostingGame) { MoldSpreadManagerPatches.ClearedNearbyMold = false; MoldSpreadManagerPatches.ClearedExcessiveMold = false; } } } [HarmonyPatch(typeof(StartOfRound), "SetPlanetsMold")] public class SetPlanetsMoldPatch { public static bool patchSetPlanetsMoldTranspilerSuccess; [HarmonyPrefix] private static bool SetPlanetsMoldPrefix(StartOfRound __instance) { if (patchSetPlanetsMoldTranspilerSuccess) { SoberShip.Logger.LogDebug((object)"SetPlanetsMoldPrefix() called."); if (!ConfigOptions.BringBackVainShrouds.Value) { return false; } if ((Object)(object)GameNetworkManager.Instance == (Object)null || !GameNetworkManager.Instance.isHostingGame) { SoberShip.Logger.LogDebug((object)"SetPlanetsMoldPrefix() called on a non-host client, skipping..."); return false; } } return true; } [HarmonyTranspiler] private static IEnumerable<CodeInstruction> SetPlanetsMoldTranspiler(IEnumerable<CodeInstruction> instructions) { if (!ConfigOptions.BringBackVainShrouds.Value) { return instructions; } bool flag = false; int num = -1; int num2 = -1; List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (!(list[i].opcode == OpCodes.Ret)) { continue; } num = i + 1; SoberShip.Logger.LogDebug((object)$"SetPlanetsMoldTranspiler() : Start = {num}"); for (int j = num; j < list.Count; j++) { if (list[j].opcode == OpCodes.Ret) { num2 = j; flag = true; SoberShip.Logger.LogDebug((object)$"SetPlanetsMoldTranspiler() : End = {num2}"); break; } } break; } int num3 = num2 - num; if (flag && num3 < 4 && num3 > 0) { if (list[num2 + 1].labels.Count < 0) { return instructions; } list[num].opcode = OpCodes.Br_S; list[num].operand = list[num2 + 1].labels[0]; list.RemoveRange(num + 1, num3 - 1); patchSetPlanetsMoldTranspilerSuccess = true; } return list.AsEnumerable(); } } } namespace SoberShip.Config { internal class ConfigOptions { public enum RemovalMethod { DELETION, DELETION_PERMANENT } public static ConfigEntry<bool> BringBackVainShrouds; public static ConfigEntry<bool> FixFalseVainShroudRemoval; public static ConfigEntry<bool> DisableVainShroudsCompletely; public static ConfigEntry<bool> RemoveExcessiveVainShrouds; public static ConfigEntry<int> MaximumVainShrouds; public static ConfigEntry<bool> RemoveNearbyVainShrouds; public static ConfigEntry<float> MinimumVainShroudDistanceFromShip; public static ConfigEntry<RemovalMethod> VainShroudRemovalMethod; public static ConfigEntry<bool> RelocateVainShroudSpawnPosition; public static ConfigEntry<float> MinimumVainShroudStartDistanceFromShip; public static void Init(ConfigFile config) { string text = "v60 Settings"; BringBackVainShrouds = config.Bind<bool>(text, "BringBackVainShrouds", true, "Bring back Vain Shrouds (including the fox) again in v60.\nDisable this if you're having issues with other mods."); FixFalseVainShroudRemoval = config.Bind<bool>(text, "FixFalseVainShroudRemoval", true, "In v60, if the Vain Shrouds fail to spawn they are reset completely,\nthis setting makes sure they aren't reset if they fail to spawn."); text = "Relocation"; RelocateVainShroudSpawnPosition = config.Bind<bool>(text, "AllowStartRelocation", true, "Relocate the starting position of the Vain Shrouds when they're too close to the ship.\nIn v60 this setting is only useful if you're loading a save that already has Vain Shrouds on the ship."); MinimumVainShroudStartDistanceFromShip = config.Bind<float>(text, "MinStartDistance", 35f, "The minimum distance the Vain Shroud starting position is required to be from the ship."); text = "Removal"; RemoveNearbyVainShrouds = config.Bind<bool>(text, "AllowRemoval", true, "Remove existing Vain Shrouds that are too close to the ship.\nEnable this to prevent Vain Shrouds from spreading to the ship."); MinimumVainShroudDistanceFromShip = config.Bind<float>(text, "MinDistance", 35f, "The minimum distance Vain Shrouds are required to be from the ship, otherwise they're deleted."); VainShroudRemovalMethod = config.Bind<RemovalMethod>(text, "RemovalMethod", RemovalMethod.DELETION, "The method used to remove Vain Shrouds that are near the ship."); text = "Disable Vain Shrouds"; DisableVainShroudsCompletely = config.Bind<bool>(text, "DisableCompletely", false, "Makes the mod just disable the spawning of Vain Shrouds entirely.\nIn v60, you can turn this on to remove any Vain Shrouds that spawned before the update."); text = "Vain Shroud Limiter"; RemoveExcessiveVainShrouds = config.Bind<bool>(text, "CapVainShroudIterations", false, "Makes the mod cap the amount of Vain Shrouds iterations that are allowed to be generated."); MaximumVainShrouds = config.Bind<int>(text, "MaximumVainShroudIterations", 20, "The maximum amount of Vain Shroud iterations that are allowed to be generated."); } } }