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 BiomeGate v1.0.7
BiomeGate.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using ConditionalConfigSync; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Biome Gate")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Biome Gate")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b8f1a3c4-5dcf-4df6-899e-73f354a55c84")] [assembly: AssemblyFileVersion("1.0.7")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.7.0")] [module: UnverifiableCode] namespace BiomeGate; [BepInPlugin("shudnal.BiomeGate", "Biome Gate", "1.0.7")] [BepInDependency("_shudnal.ConditionalConfigSync", "1.0.5")] public class BiomeGate : BaseUnityPlugin { [HarmonyPatch] public static class PreventInteractions { private static IEnumerable<MethodBase> TargetMethods() { return (from p in typeof(Player).Assembly.GetTypes() where typeof(Interactable).IsAssignableFrom(p) where p.Name != "Interactable" where p.Name != "Ladder" where p.Name != "ShipControlls" where p.Name != "Sadle" where p.Name != "Chair" where p.Name != "TombStone" select p).SelectMany((Type t) => new List<MethodBase> { AccessTools.Method(t, "Interact", (Type[])null, (Type[])null), AccessTools.Method(t, "UseItem", (Type[])null, (Type[])null) }); } private static bool Prefix(Humanoid __0) { if (!preventInteraction.Value) { return true; } if ((Object)(object)__0 != (Object)null && IsGated(__0)) { ((Character)__0).Message((MessageType)2, "$msg_nobuildzone", 0, (Sprite)null, false); return false; } return true; } } [HarmonyPatch(typeof(Player), "SetPlaceMode")] public static class Player_SetPlaceMode_PreventBuilding { private static void Prefix(Player __instance, ref PieceTable buildPieces, ref PieceTable __state) { if (preventBuilding.Value && IsGated((Humanoid)(object)__instance)) { __state = buildPieces; buildPieces = null; } } private static void Postfix(ref PieceTable buildPieces, ref PieceTable __state) { if (!((Object)(object)__state == (Object)null)) { buildPieces = __state; } } } [HarmonyPatch(typeof(Player), "InPlaceMode")] public static class Player_InPlaceMode_PreventBuilding { private static bool Prefix(Player __instance, ref bool __result) { if (!preventBuilding.Value) { return true; } if (!IsGated((Humanoid)(object)__instance)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Minimap), "UpdateExplore")] public static class Minimap_UpdateExplore_PreventExplore { private static void Prefix(Minimap __instance, Player player) { if (preventExploring.Value && IsGated((Humanoid)(object)player)) { __instance.m_exploreTimer = 0f; } } } public const string pluginID = "shudnal.BiomeGate"; public const string pluginName = "Biome Gate"; public const string pluginVersion = "1.0.7"; private readonly Harmony harmony = new Harmony("shudnal.BiomeGate"); internal static readonly ConfigSync configSync = new ConfigSync("shudnal.BiomeGate") { DisplayName = "Biome Gate", CurrentVersion = "1.0.7", MinimumRequiredVersion = "1.0.7" }; public static BiomeGate instance; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> configLocked; public static ConfigEntry<bool> loggingEnabled; public static ConfigEntry<Biome> gatedBiomes; public static ConfigEntry<bool> adminPermitted; public static ConfigEntry<DamageModifier> damageReceivedModifier; public static ConfigEntry<float> damageDoneModifier; public static ConfigEntry<float> noiseModifier; public static ConfigEntry<float> sneakModifier; public static ConfigEntry<float> raiseSkillModifier; public static ConfigEntry<bool> showRepeatMessage; public static ConfigEntry<bool> showStartMessage; public static ConfigEntry<bool> preventBuilding; public static ConfigEntry<bool> preventExploring; public static ConfigEntry<bool> preventInteraction; public static ConfigEntry<bool> showStatusEffectIcon; public static ConfigEntry<bool> globalKeyPermitted; public static ConfigEntry<string> globalKeyAvailability; public static ConfigEntry<bool> playerKeyPermitted; public static ConfigEntry<string> playerKeyAvailability; public static ConfigEntry<bool> playerItemPermitted; public static ConfigEntry<string> playerItemAvailability; private static readonly Dictionary<string, string> biomeGlobalKeys = new Dictionary<string, string>(); private static readonly Dictionary<string, string> biomePlayerKeys = new Dictionary<string, string>(); private static readonly Dictionary<string, string> biomePlayerItems = new Dictionary<string, string>(); private void Awake() { harmony.PatchAll(); instance = this; ConfigInit(); ((ConditionalConfigSync)configSync).AddLockingConfigEntry<bool>(configLocked); Game.isModded = true; } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static void LogInfo(object data) { if (loggingEnabled.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo(data); } } private void ConfigInit() { modEnabled = config("General", "Enabled", defaultValue: true, "Enable the mod."); configLocked = config("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only."); loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false); gatedBiomes = config<Biome>("Gating", "Biomes", (Biome)0, "Biome list."); adminPermitted = config("Gating", "Ignore admins", defaultValue: true, "Admins and host will not be affected"); preventBuilding = config("Gating", "Prevent building", defaultValue: true, "Prevent usage of hammers, hoe, cultivator"); preventExploring = config("Gating", "Prevent exploring", defaultValue: true, "Prevent minimap from exploring"); preventInteraction = config("Gating", "Prevent interactions", defaultValue: true, "Prevent interaction with any interactable object"); damageReceivedModifier = config<DamageModifier>("Gating", "Damage received modifier", (DamageModifier)6, "Damage modifier for incoming damage"); damageDoneModifier = config("Gating", "Damage dealt modifier", 0f, "Damage modifier for damage done by affected players"); noiseModifier = config("Gating", "Noise modifier", 10f, "Noise modifier. How far away player will be heared."); sneakModifier = config("Gating", "Sneak modifier", -1f, "Sneak efficacy modifier"); raiseSkillModifier = config("Gating", "Raise skill modifier", -100f, "Modifier for skill raise. 0 is normal skill raise. Other status effects can also modify skill raise."); showRepeatMessage = config("Gating", "Show repeat message", defaultValue: true, "Show repeated message every 20 seconds"); showStartMessage = config("Gating", "Show start message", defaultValue: true, "Show message when debuff is applied"); showStatusEffectIcon = config("Gating", "Show status effect icon", defaultValue: true, "Show status effect in list when debuff is applied."); damageReceivedModifier.SettingChanged += delegate { SE_BiomeGate.UpdateBiomeGateProperties(); }; damageDoneModifier.SettingChanged += delegate { SE_BiomeGate.UpdateBiomeGateProperties(); }; noiseModifier.SettingChanged += delegate { SE_BiomeGate.UpdateBiomeGateProperties(); }; sneakModifier.SettingChanged += delegate { SE_BiomeGate.UpdateBiomeGateProperties(); }; raiseSkillModifier.SettingChanged += delegate { SE_BiomeGate.UpdateBiomeGateProperties(); }; showRepeatMessage.SettingChanged += delegate { SE_BiomeGate.UpdateBiomeGateProperties(); }; showStartMessage.SettingChanged += delegate { SE_BiomeGate.UpdateBiomeGateProperties(); }; showStatusEffectIcon.SettingChanged += delegate { SE_BiomeGate.UpdateBiomeGateProperties(); }; globalKeyPermitted = config("Gating - Global keys", "Disable gating if global key is set", defaultValue: false, "If enabled - corresponding global key should be set to disable biome gating"); globalKeyAvailability = config("Gating - Global keys", "Biome global keys", "Swamp:defeated_gdking,Mountain:defeated_bonemass,Plains:defeated_dragon,Mistlands:defeated_goblinking,AshLands:defeated_queen,DeepNorth:defeated_fader", "Comma-separated list of biome-globalkey pairs. If globalkey is set biome will not be gated."); globalKeyAvailability.SettingChanged += delegate { UpdateGlobalKeysList(); }; UpdateGlobalKeysList(); playerKeyPermitted = config("Gating - Player keys", "Disable gating if player key is set", defaultValue: false, "If enabled - corresponding player key should be set to disable biome gating"); playerKeyAvailability = config("Gating - Player keys", "Biome player keys", "Swamp:GP_TheElder,Mountain:GP_Bonemass,Plains:GP_Moder,Mistlands:GP_Yagluth,AshLands:GP_Queen,DeepNorth:GP_Fader", "Comma-separated list of biome-playerkey pairs. If playerkey is set biome will not be gated."); playerKeyAvailability.SettingChanged += delegate { UpdatePlayerKeysList(); }; UpdatePlayerKeysList(); playerItemPermitted = config("Gating - Player items", "Disable gating if player has item known", defaultValue: false, "If enabled - corresponding item should be known by player to disable biome gating"); playerItemAvailability = config("Gating - Player items", "Biome player items", "Swamp:$item_cryptkey,Mountain:$item_wishbone,Plains:$item_dragontear,Mistlands:$item_yagluththing,AshLands:$item_seekerqueen_drop,DeepNorth:$item_fader_drop", "Comma-separated list of biome-item pairs. If item is known by player biome will not be gated."); playerItemAvailability.SettingChanged += delegate { UpdatePlayerItemsList(); }; UpdatePlayerItemsList(); } private static void UpdateGlobalKeysList() { biomeGlobalKeys.Clear(); string[] array = globalKeyAvailability.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 2) { biomeGlobalKeys[array2[0].Trim()] = array2[1].Trim(); } } } private static void UpdatePlayerKeysList() { biomePlayerKeys.Clear(); string[] array = playerKeyAvailability.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 2) { biomePlayerKeys[array2[0].Trim()] = array2[1].Trim(); } } } private static void UpdatePlayerItemsList() { biomePlayerItems.Clear(); string[] array = playerItemAvailability.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 2) { biomePlayerItems[array2[0].Trim()] = array2[1].Trim(); } } } private static bool IsAdmin() { if (!adminPermitted.Value) { return false; } if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return true; } return ZNet.instance.LocalPlayerIsAdminOrHost(); } private ConfigEntry<T> config<T>(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultValue, description); ((ConditionalConfigSync)configSync).AddConfigEntry<T>(val, (ConfigSyncMode)1, synchronizedSetting); return val; } private ConfigEntry<T> config<T>(string group, string name, T defaultValue, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } public void FixedUpdate() { Player localPlayer = Player.m_localPlayer; if (localPlayer == null) { return; } SEMan sEMan = ((Character)localPlayer).GetSEMan(); if (sEMan == null || !((Character)localPlayer).IsOwner()) { return; } if (sEMan.HaveStatusEffect(SE_BiomeGate.statusEffectBiomeGateHash)) { if (RemoveStatusEffect(localPlayer)) { sEMan.RemoveStatusEffect(SE_BiomeGate.statusEffectBiomeGateHash, false); } } else if (modEnabled.Value && AddStatusEffect(localPlayer)) { sEMan.AddStatusEffect(SE_BiomeGate.statusEffectBiomeGateHash, false, 0, 0f, (short)(-1)); } } public static bool RemoveStatusEffect(Player player) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) return !modEnabled.Value || (int)gatedBiomes.Value == 0 || (int)player.m_currentBiome == 0 || !((Enum)gatedBiomes.Value).HasFlag((Enum)(object)player.m_currentBiome) || IsAdmin() || IsGatingDisabledByProgression(player); } public static bool AddStatusEffect(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return (int)gatedBiomes.Value != 0 && (int)player.m_currentBiome != 0 && ((Enum)gatedBiomes.Value).HasFlag((Enum)(object)player.m_currentBiome) && !((Character)player).InCutscene() && !((Character)player).IsTeleporting() && !player.m_isLoading && !((Character)player).IsDead() && !IsAdmin() && !IsGatingDisabledByProgression(player); } public static bool IsGatingDisabledByProgression(Player player) { return IsBiomeGlobalKeyEnabled(player) || IsBiomePlayerKeyEnabled(player) || IsBiomePlayerItemEnabled(player); } private static bool IsBiomeGlobalKeyEnabled(Player player) { int result; if (globalKeyPermitted.Value && biomeGlobalKeys.TryGetValue(((object)Unsafe.As<Biome, Biome>(ref player.m_currentBiome)/*cast due to .constrained prefix*/).ToString(), out var value)) { ZoneSystem obj = ZoneSystem.instance; result = ((obj != null && obj.GetGlobalKey(value)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } private static bool IsBiomePlayerKeyEnabled(Player player) { string value; return playerKeyPermitted.Value && biomePlayerKeys.TryGetValue(((object)Unsafe.As<Biome, Biome>(ref player.m_currentBiome)/*cast due to .constrained prefix*/).ToString(), out value) && ((Humanoid)player).HaveUniqueKey(value); } private static bool IsBiomePlayerItemEnabled(Player player) { string value; return playerItemPermitted.Value && biomePlayerItems.TryGetValue(((object)Unsafe.As<Biome, Biome>(ref player.m_currentBiome)/*cast due to .constrained prefix*/).ToString(), out value) && player.IsKnownMaterial(value); } private static bool IsGated(Humanoid human) { Player val = (Player)(object)((human is Player) ? human : null); int result; if (val != null) { SEMan sEMan = ((Character)val).GetSEMan(); if (sEMan != null && sEMan.HaveStatusEffect(SE_BiomeGate.statusEffectBiomeGateHash)) { result = (((Object)(object)Ship.GetLocalShip() == (Object)null) ? 1 : 0); goto IL_0031; } } result = 0; goto IL_0031; IL_0031: return (byte)result != 0; } } public class SE_BiomeGate : SE_Stats { [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_AddStatusEffects { public static void AddCustomStatusEffects(ObjectDB odb) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if (odb.m_StatusEffects.Count > 0 && !odb.m_StatusEffects.Any((StatusEffect se) => ((Object)se).name == "BiomeGate")) { SE_BiomeGate sE_BiomeGate = ScriptableObject.CreateInstance<SE_BiomeGate>(); ((Object)sE_BiomeGate).name = "BiomeGate"; ((StatusEffect)sE_BiomeGate).m_nameHash = statusEffectBiomeGateHash; ((StatusEffect)sE_BiomeGate).m_icon = odb.m_StatusEffects.Find((StatusEffect se) => (Object)(object)se.m_icon != (Object)null && ((Object)se.m_icon).name.IndexOf("immobilized") != -1)?.m_icon; ((StatusEffect)sE_BiomeGate).m_flashIcon = true; ((SE_Stats)sE_BiomeGate).m_modifyAttackSkill = (SkillType)999; ((SE_Stats)sE_BiomeGate).m_raiseSkill = (SkillType)999; ((StatusEffect)sE_BiomeGate).m_startMessageType = (MessageType)2; ((StatusEffect)sE_BiomeGate).m_repeatMessageType = (MessageType)2; ((StatusEffect)sE_BiomeGate).m_repeatInterval = 20f; ((StatusEffect)sE_BiomeGate).m_name = "$menu_server_warning"; ((StatusEffect)sE_BiomeGate).m_tooltip = "$tutorial_blackforest_topic"; UpdateStatusEffectProperties(sE_BiomeGate); odb.m_StatusEffects.Add((StatusEffect)(object)sE_BiomeGate); } } private static void Postfix(ObjectDB __instance) { AddCustomStatusEffects(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDB_CopyOtherDB_AddStatusEffects { private static void Postfix(ObjectDB __instance) { ObjectDB_Awake_AddStatusEffects.AddCustomStatusEffects(__instance); } } public const string statusEffectBiomeGateName = "BiomeGate"; public static readonly int statusEffectBiomeGateHash = StringExtensionMethods.GetStableHashCode("BiomeGate"); public const string statusEffectName = "$menu_server_warning"; public const string statusEffectTooltip = "$tutorial_blackforest_topic"; public override string GetIconText() { return Localization.instance.Localize("$tutorial_blackforest_topic"); } public static void UpdateBiomeGateProperties() { if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { UpdateStatusEffectProperties(ObjectDB.instance.GetStatusEffect(statusEffectBiomeGateHash) as SE_BiomeGate); } if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(statusEffectBiomeGateHash)) { UpdateStatusEffectProperties(((Character)Player.m_localPlayer).GetSEMan().GetStatusEffect(statusEffectBiomeGateHash) as SE_BiomeGate); } } private static void UpdateStatusEffectProperties(SE_BiomeGate statusEffect) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Invalid comparison between Unknown and I4 //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Invalid comparison between Unknown and I4 //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Invalid comparison between Unknown and I4 //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)statusEffect == (Object)null) { return; } ((StatusEffect)statusEffect).m_icon = ((!BiomeGate.showStatusEffectIcon.Value) ? null : ObjectDB.instance.m_StatusEffects.Find((StatusEffect se) => (Object)(object)se.m_icon != (Object)null && ((Object)se.m_icon).name.IndexOf("immobilized") != -1)?.m_icon); ((SE_Stats)statusEffect).m_noiseModifier = BiomeGate.noiseModifier.Value; ((SE_Stats)statusEffect).m_stealthModifier = BiomeGate.sneakModifier.Value; ((SE_Stats)statusEffect).m_damageModifier = BiomeGate.damageDoneModifier.Value; ((SE_Stats)statusEffect).m_raiseSkillModifier = BiomeGate.raiseSkillModifier.Value; ((StatusEffect)statusEffect).m_repeatMessage = (BiomeGate.showRepeatMessage.Value ? "$npc_dvergrrogue_random_private_area_alarm8" : ""); ((StatusEffect)statusEffect).m_startMessage = (BiomeGate.showStartMessage.Value ? "$npc_dvergr_ashlands_random_private_area_alarm5" : ""); ((SE_Stats)statusEffect).m_mods.Clear(); foreach (DamageType value in Enum.GetValues(typeof(DamageType))) { if ((int)value != 1024 && (int)value != 31 && (int)value != 224) { ((SE_Stats)statusEffect).m_mods.Add(new DamageModPair { m_modifier = BiomeGate.damageReceivedModifier.Value, m_type = value }); } } } }