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 BiomeLock v1.2.1
plugins/BiomeLock.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.PostProcessing; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: Guid("E74EB49A-461D-48EA-85BC-F462D60C98C4")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyProduct("BiomeLock")] [assembly: AssemblyCompany("Radamanto")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("BiomeLock")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyFileVersion("1.2.1")] [assembly: AssemblyConfiguration("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.1.0")] [module: UnverifiableCode] [module: <9cdc4a4c-fda5-4912-8859-9fa5d3036d01>RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<232928c7-3891-4d21-8865-cef381af162d>Embedded] internal sealed class <232928c7-3891-4d21-8865-cef381af162d>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<232928c7-3891-4d21-8865-cef381af162d>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <dbedd104-49d4-45b5-9930-e5d6d508bb9a>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <dbedd104-49d4-45b5-9930-e5d6d508bb9a>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <dbedd104-49d4-45b5-9930-e5d6d508bb9a>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [<232928c7-3891-4d21-8865-cef381af162d>Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContextAttribute : Attribute { public readonly byte Flag; public <5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [<232928c7-3891-4d21-8865-cef381af162d>Embedded] internal sealed class <9cdc4a4c-fda5-4912-8859-9fa5d3036d01>RefSafetyRulesAttribute : Attribute { public readonly int Version; public <9cdc4a4c-fda5-4912-8859-9fa5d3036d01>RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BiomeLock { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] public static class BiomeLockAPI { public static readonly string PrivatePrefix = "bl_"; public static bool IsReady => BiomeLockKeys.IsInMainScene(); [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(new byte[] { 2, 1 })] [method: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(new byte[] { 2, 1 })] [field: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(new byte[] { 2, 1 })] public static event Action<string> OnPrivateKeyAdded; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(new byte[] { 2, 1 })] [method: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(new byte[] { 2, 1 })] [field: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(new byte[] { 2, 1 })] public static event Action<string> OnPrivateKeyRemoved; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] [method: <5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(2)] [field: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] public static event Action OnPrivateKeysReset; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] [method: <5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(2)] [field: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] public static event Action OnPrivateKeysLoaded; public static bool HasPrivateKey(string globalOrPrivateKey) { return globalOrPrivateKey != null && BiomeLockKeys.HasLocalPrivateKey(globalOrPrivateKey); } public static bool HasProgressionKey(string globalOrPrivateKey) { return globalOrPrivateKey != null && BiomeLockKeys.HasProgressionKey(globalOrPrivateKey); } public static IReadOnlyList<string> GetPrivateKeys() { if (!IsReady) { return Array.Empty<string>(); } return BiomeLockPrivateKeys.PrivateKeys.OrderBy<string, string>([<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] (string k) => k, StringComparer.Ordinal).ToList(); } public static bool IsBiomeLocked(Biome biome) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return IsReady && BiomeLock_SE.NeedsRestriction(biome); } public static bool IsRestricted() { return IsReady && BiomeLock_SE.HasBiomeLockSE(Player.m_localPlayer); } public static string ToPrivateKey(string globalOrPrivateKey) { return BiomeLockKeys.ToPrivateKey(globalOrPrivateKey); } public static string ToGlobalKey(string globalOrPrivateKey) { return BiomeLockKeys.ToGlobalKey(globalOrPrivateKey); } public static void AddRestrictionBypass(Func<Vector3, bool> bypass) { BiomeLock_SE.AddBypass(bypass); } public static void RemoveRestrictionBypass(Func<Vector3, bool> bypass) { BiomeLock_SE.RemoveBypass(bypass); } internal static void RaisePrivateKeyAdded(string privateKey) { Raise(BiomeLockAPI.OnPrivateKeyAdded, privateKey); } internal static void RaisePrivateKeyRemoved(string privateKey) { Raise(BiomeLockAPI.OnPrivateKeyRemoved, privateKey); } internal static void RaisePrivateKeysReset() { Raise(BiomeLockAPI.OnPrivateKeysReset); } internal static void RaisePrivateKeysLoaded() { Raise(BiomeLockAPI.OnPrivateKeysLoaded); } private static void Raise([<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(new byte[] { 2, 1 })] Action<string> handler, string privateKey) { if (handler == null) { return; } privateKey = BiomeLockKeys.ToPrivateKey(privateKey); if (privateKey.Length == 0) { return; } Delegate[] invocationList = handler.GetInvocationList(); foreach (Delegate obj in invocationList) { try { ((Action<string>)obj)(privateKey); } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[BiomeLockAPI] " + ex)); } } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(2)] private static void Raise(Action handler) { if (handler == null) { return; } Delegate[] invocationList = handler.GetInvocationList(); foreach (Delegate obj in invocationList) { try { ((Action)obj)(); } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[BiomeLockAPI] " + ex)); } } } } [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] internal static class AssetLoader { private const string ResourceName = "BiomeLock.assets.rd_biome"; private static bool _loadAttempted; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private static AssetBundle _bundle; [return: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] internal static Sprite GetSprite(string name) { return Load<Sprite>(name); } [return: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] internal static GameObject GetPrefab(string name) { return Load<GameObject>(name); } [return: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private static T Load<[<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] T>(string name) where T : Object { if (string.IsNullOrWhiteSpace(name)) { return default(T); } AssetBundle bundle = GetBundle(); return ((Object)(object)bundle != (Object)null) ? bundle.LoadAsset<T>(name) : default(T); } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(2)] private static AssetBundle GetBundle() { if ((Object)(object)_bundle != (Object)null || _loadAttempted) { return _bundle; } _loadAttempted = true; try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BiomeLock.assets.rd_biome"); if (stream == null) { BiomeLockPlugin.Log.LogError((object)"[AssetLoader] Embedded resource not found: BiomeLock.assets.rd_biome"); return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); _bundle = AssetBundle.LoadFromMemory(memoryStream.ToArray()); } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[AssetLoader] " + ex)); _bundle = null; } return _bundle; } } [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [BepInPlugin("radamanto.BiomeLock", "BiomeLock", "1.2.1")] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] public class BiomeLockPlugin : BaseUnityPlugin { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private sealed class ConfigurationManagerAttributes { public bool? Browsable = false; } internal const string ModGUID = "radamanto.BiomeLock"; internal const string ModName = "BiomeLock"; internal const string ModVersion = "1.2.1"; internal static ManualLogSource Log; private Harmony _harmony = null; internal static ConfigEntry<bool> CE_SE_AdminBypass; internal static ConfigEntry<string> CE_SE_BlockedBiomes; internal static ConfigEntry<bool> CE_SE_Block_DungeonTeleport; internal static ConfigEntry<bool> CE_SE_Block_MapExplore; internal static ConfigEntry<bool> CE_SE_Block_AutoPickup; internal static ConfigEntry<bool> CE_SE_Block_Pickup; internal static ConfigEntry<bool> CE_SE_Block_ItemDropInteract; internal static ConfigEntry<bool> CE_SE_Block_PickableInteract; internal static ConfigEntry<bool> CE_SE_Block_AttackBlock; internal static ConfigEntry<bool> CE_SE_Block_Hammer; internal static ConfigEntry<bool> CE_SE_Block_TerrainHoe; internal static ConfigEntry<bool> CE_SE_Block_GenericInteract; internal static ConfigEntry<bool> CE_SE_Block_DoorInteract; internal static ConfigEntry<bool> CE_SE_Block_ContainerInteract; internal static ConfigEntry<bool> CE_SE_Broadcast_Enabled; internal static ConfigEntry<float> CE_SE_Broadcast_Interval; internal static ConfigEntry<bool> CE_SE_AttackBlock_BlacklistEnabled; internal static ConfigEntry<string> CE_SE_AttackBlock_BlacklistPrefabs; internal static ConfigEntry<bool> CE_GuardianPower_Enabled; internal static ConfigEntry<bool> CE_BossPrevKey_Enabled; internal static ConfigEntry<bool> CE_BossDay_Enabled; internal static ConfigEntry<int> CE_BossDay_Eikthyr; internal static ConfigEntry<int> CE_BossDay_Elder; internal static ConfigEntry<int> CE_BossDay_Bonemass; internal static ConfigEntry<int> CE_BossDay_Moder; internal static ConfigEntry<int> CE_BossDay_Yagluth; internal static ConfigEntry<int> CE_BossDay_Queen; internal static ConfigEntry<int> CE_BossDay_Fader; internal static ConfigEntry<int> CE_BossDay_Kall; internal static ConfigEntry<bool> CE_SE_Block_SpawnBlock; internal static ConfigEntry<bool> CE_SE_Block_MapPins; internal static ConfigEntry<bool> CE_GlobalKeys_PrivateKeys; internal static ConfigEntry<bool> CE_SE_Block_TraderInteract; internal static ConfigEntry<bool> CE_SE_Block_HildirMapTable; internal static ConfigEntry<bool> CE_SkillCap_Enabled; internal static ConfigEntry<int> CE_SkillCap_Eikthyr; internal static ConfigEntry<int> CE_SkillCap_Elder; internal static ConfigEntry<int> CE_SkillCap_Bonemass; internal static ConfigEntry<int> CE_SkillCap_Moder; internal static ConfigEntry<int> CE_SkillCap_Yagluth; internal static ConfigEntry<int> CE_SkillCap_Queen; internal static ConfigEntry<int> CE_SkillCap_Fader; internal static ConfigEntry<int> CE_SkillCap_Kall; internal static ConfigEntry<bool> CE_SE_RestrictedMist; internal static ConfigEntry<bool> CE_SE_RestrictedMistSfx; internal static ConfigEntry<bool> CE_SE_HealthDrain; internal static ConfigEntry<float> CE_SE_HealthDrainPerSecond; internal static ConfigEntry<float> CE_SE_HealthDrainMinHealth; private const float ConfigReloadQuietSeconds = 0.75f; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] internal static ConfigSync ConfigSync; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private static ConfigEntry<bool> _serverConfigLocked; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private FileSystemWatcher _configWatcher; private DateTime _lastCfgWriteUtc = DateTime.MinValue; private DateTime _ignoreEventsUntilUtc = DateTime.MinValue; private bool _reloadScheduled; internal static ConfigEntry<bool> CE_BossCooldown_Enabled; internal static ConfigEntry<int> CE_BossCooldown_Eikthyr; internal static ConfigEntry<int> CE_BossCooldown_Elder; internal static ConfigEntry<int> CE_BossCooldown_Bonemass; internal static ConfigEntry<int> CE_BossCooldown_Moder; internal static ConfigEntry<int> CE_BossCooldown_Yagluth; internal static ConfigEntry<int> CE_BossCooldown_Queen; internal static ConfigEntry<int> CE_BossCooldown_Fader; internal static ConfigEntry<int> CE_BossCooldown_Kall; private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Localizer.Load(); bool syncReady = BeginConfigSetup(); SetupBinds(); EndConfigSetup(syncReady); _harmony = new Harmony("radamanto.BiomeLock"); _harmony.PatchAll(); } private void OnDestroy() { BiomeLockBossCooldown.ClearPending(); BiomeLock_SE.RestoreRestrictedMistSky(); BiomeLock_SE.RestoreRestrictedYggdrasilFog(); DisposeConfigWatcher(); } public static bool IsLocalPlayerAdmin() { return ConfigSync != null && ConfigSync.IsAdmin; } internal static bool AdminBypassActive() { return CE_SE_AdminBypass.Value && IsLocalPlayerAdmin(); } private void SetupBinds() { CE_SE_AdminBypass = Cfg("01 - General", "AdminBypass", defaultValue: true, "If true, administrators bypass restrictions."); CE_GlobalKeys_PrivateKeys = Cfg("01 - General", "PrivateKeys", defaultValue: true, "If true, redirects content unlocks based on Global Keys to per-player Private Keys."); CE_SE_BlockedBiomes = Cfg("02 - BiomeLock", "02.1 - BlockedBiomes", "BlackForest,Swamp,Mountain,Plains,Mistlands,AshLands,DeepNorth", "The biomes listed here will be blocked for players who have not defeated the previous biome’s boss.\nAllowed values: BlackForest, Swamp, Mountain, Plains, Mistlands, AshLands, DeepNorth, Ocean"); CE_SE_Block_TraderInteract = Cfg("03 - Traders", "03.01 - TraderInteract", defaultValue: true, "If true, blocks interaction with the traders Haldor and the Bog Witch."); CE_SE_Block_HildirMapTable = Cfg("03 - Traders", "03.02 - HildirMapTable", defaultValue: true, "If true, blocks interaction on Hildir's map table."); CE_SE_Block_DungeonTeleport = Cfg("04 - SE Blocks", "04.01 - Dungeon", defaultValue: true, "If true, blocks dungeon teleport entrances/exits."); CE_SE_Block_MapExplore = Cfg("04 - SE Blocks", "04.02 - MapExplore", defaultValue: true, "If true, blocks map exploration."); CE_SE_Block_AutoPickup = Cfg("04 - SE Blocks", "04.03 - AutoPickup", defaultValue: true, "If true, blocks automatic pickup."); CE_SE_Block_Pickup = Cfg("04 - SE Blocks", "04.04 - Pickup", defaultValue: true, "If true, blocks manual pickup."); CE_SE_Block_GenericInteract = Cfg("04 - SE Blocks", "04.05 - Interact", defaultValue: true, "If true, blocks generic world interactions."); CE_SE_Block_DoorInteract = Cfg("04 - SE Blocks", "04.06 - DoorInteract", defaultValue: true, "If true, blocks door interactions."); CE_SE_Block_ItemDropInteract = Cfg("04 - SE Blocks", "04.07 - ItemDropInteract", defaultValue: true, "If true, blocks item drop interactions."); CE_SE_Block_PickableInteract = Cfg("04 - SE Blocks", "04.08 - PickableInteract", defaultValue: true, "If true, blocks pickable interactions."); CE_SE_Block_ContainerInteract = Cfg("04 - SE Blocks", "04.09 - ContainerInteract", defaultValue: true, "If true, blocks container interactions."); CE_SE_Block_Hammer = Cfg("04 - SE Blocks", "04.10 - Hammer", defaultValue: true, "If true, blocks hammer actions."); CE_SE_Block_TerrainHoe = Cfg("04 - SE Blocks", "04.11 - Hoe/Cultivator", defaultValue: true, "If true, blocks terrain modification by hoe/cultivator."); CE_SE_Block_MapPins = Cfg("04 - SE Blocks", "04.12 - MapPins", defaultValue: true, "If true, blocks placing pins on the map."); CE_SE_Block_SpawnBlock = Cfg("04 - SE Blocks", "04.13 - MobSpawn", defaultValue: true, "If true, blocks mob spawning."); CE_SE_Block_AttackBlock = Cfg("04 - SE Blocks", "04.14 - AttackBlock", defaultValue: true, "If true, blocks attacks with weapons, tools, bows, and shields. If BlacklistEnabled is true, only the prefabs listed in BlacklistPrefabs are blocked."); CE_SE_AttackBlock_BlacklistEnabled = Cfg("04 - SE Blocks", "04.14.1 - BlacklistEnabled", defaultValue: false, "If true, attacks are blocked only when using the prefabs listed in BlacklistPrefabs. If false, all attacks are blocked."); CE_SE_AttackBlock_BlacklistPrefabs = Cfg("04 - SE Blocks", "04.14.2 - BlacklistPrefabs", "", "Comma-separated prefab names whose attacks are blocked when BlacklistEnabled is true."); CE_SE_RestrictedMist = Cfg("04 - SE Blocks", "04.15 - RestrictedMist", defaultValue: true, "If true, enables the local fog effect."); CE_SE_RestrictedMistSfx = Cfg("04 - SE Blocks", "04.16 - RestrictedMistSound", defaultValue: true, "If true, enables the local fog ambience sound."); CE_SE_HealthDrain = Cfg("04 - SE Blocks", "04.17 - HealthDrain", defaultValue: true, "If true, drains player health."); CE_SE_HealthDrainPerSecond = Cfg("04 - SE Blocks", "04.17.1 - HealthDrainPerSecond", 2f, "Health drained per second."); CE_SE_HealthDrainMinHealth = Cfg("04 - SE Blocks", "04.17.2 - HealthDrainMinHealth", 1f, "Minimum health left after health drain. Use 0 to allow death."); CE_SE_Broadcast_Enabled = Cfg("05 - SE Broadcast", "05.01 - Enable", defaultValue: true, "Displays messages in the center of the screen while the SE_BiomeLock is active."); CE_SE_Broadcast_Interval = Cfg("05 - SE Broadcast", "05.02 - IntervalSeconds", 8f, "Interval (in seconds) between BiomeLock broadcast messages."); CE_GuardianPower_Enabled = Cfg("06 - Guardian Power", "06.01 - Enable", defaultValue: true, "If true, blocks claiming guardian powers at the altar until the player has the required private key."); CE_BossPrevKey_Enabled = Cfg("07 - Boss Summon Key", "07.01 - Enable", defaultValue: true, "If true, blocks boss altar interaction until the player has defeated the previous boss."); CE_BossDay_Enabled = Cfg("08 - Boss Summon Day", "08.01 - Enable", defaultValue: true, "If true, blocks boss altar interaction until the configured day."); CE_BossDay_Eikthyr = Cfg("08 - Boss Summon Day", "08.02 - Eikthyr", 100, "Minimum day required to summon Eikthyr. (0 = disabled)"); CE_BossDay_Elder = Cfg("08 - Boss Summon Day", "08.03 - Elder", 200, "Minimum day required to summon Elder. (0 = disabled)"); CE_BossDay_Bonemass = Cfg("08 - Boss Summon Day", "08.04 - Bonemass", 300, "Minimum day required to summon Bonemass. (0 = disabled)"); CE_BossDay_Moder = Cfg("08 - Boss Summon Day", "08.05 - Moder", 400, "Minimum day required to summon Moder. (0 = disabled)"); CE_BossDay_Yagluth = Cfg("08 - Boss Summon Day", "08.06 - Yagluth", 500, "Minimum day required to summon Yagluth. (0 = disabled)"); CE_BossDay_Queen = Cfg("08 - Boss Summon Day", "08.07 - Queen", 600, "Minimum day required to summon The Queen. (0 = disabled)"); CE_BossDay_Fader = Cfg("08 - Boss Summon Day", "08.08 - Fader", 700, "Minimum day required to summon Fader. (0 = disabled)"); CE_BossDay_Kall = Cfg("08 - Boss Summon Day", "08.09 - Kall", 800, "Minimum day required to summon Kall Fimbulbringer. (0 = disabled)"); CE_SkillCap_Enabled = Cfg("09 - Skill Cap", "09.01 - Enable", defaultValue: true, "If true, caps skill (all skills) levels by boss private keys."); CE_SkillCap_Eikthyr = Cfg("09 - Skill Cap", "09.02 - Eikthyr", 0, "Maximum skill level (all skills) allowed while the player does NOT have Eikthyr private key. (0 = disabled)"); CE_SkillCap_Elder = Cfg("09 - Skill Cap", "09.03 - Elder", 0, "Maximum skill level (all skills) allowed while the player does NOT have Elder private key. (0 = disabled)"); CE_SkillCap_Bonemass = Cfg("09 - Skill Cap", "09.04 - Bonemass", 0, "Maximum skill level (all skills) allowed while the player does NOT have Bonemass private key. (0 = disabled)"); CE_SkillCap_Moder = Cfg("09 - Skill Cap", "09.05 - Moder", 0, "Maximum skill level (all skills) allowed while the player does NOT have Moder private key. (0 = disabled)"); CE_SkillCap_Yagluth = Cfg("09 - Skill Cap", "09.06 - Yagluth", 0, "Maximum skill level (all skills) allowed while the player does NOT have Yagluth private key. (0 = disabled)"); CE_SkillCap_Queen = Cfg("09 - Skill Cap", "09.07 - Queen", 0, "Maximum skill level (all skills) allowed while the player does NOT have The Queen private key. (0 = disabled)"); CE_SkillCap_Fader = Cfg("09 - Skill Cap", "09.08 - Fader", 0, "Maximum skill level (all skills) allowed while the player does NOT have Fader private key. Example: (0 = disabled)"); CE_SkillCap_Kall = Cfg("09 - Skill Cap", "09.09 - Kall", 0, "Maximum skill level (all skills) allowed while the player does NOT have Kall Fimbulbringer final defeat private key. (0 = disabled)"); SetupBossCooldownBinds(); } private bool BeginConfigSetup() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; try { ConfigSync = new ConfigSync(((BaseUnityPlugin)this).Info.Metadata.GUID) { DisplayName = ((BaseUnityPlugin)this).Info.Metadata.Name, CurrentVersion = ((BaseUnityPlugin)this).Info.Metadata.Version.ToString(), MinimumRequiredVersion = ((BaseUnityPlugin)this).Info.Metadata.Version.ToString(), ModRequired = true }; _serverConfigLocked = ((BaseUnityPlugin)this).Config.Bind<bool>("01 - General", "LockConfiguration", true, new ConfigDescription("If true, the server locks synchronized configs.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = false } })); ConfigSync.AddLockingConfigEntry<bool>(_serverConfigLocked); return true; } catch (Exception ex) { Log.LogError((object)("[ConfigSync] " + ex)); return false; } } private void EndConfigSetup(bool syncReady) { if (syncReady) { ((BaseUnityPlugin)this).Config.Save(); } ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; if (syncReady) { SetupConfigWatcher(); } } protected ConfigEntry<T> Cfg<[<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] T>(string section, string key, T defaultValue, string description, bool synced = true) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description + (synced ? " [Synced with Server]" : " [Not Synced with Server]"), (AcceptableValueBase)null, Array.Empty<object>()); ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, val); SyncedConfigEntry<T> syncedConfigEntry = ConfigSync?.AddConfigEntry<T>(val2); if (syncedConfigEntry != null) { syncedConfigEntry.SynchronizedConfig = synced; } return val2; } private void SetupConfigWatcher() { DisposeConfigWatcher(); try { _configWatcher = new FileSystemWatcher(Paths.ConfigPath, Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath)) { IncludeSubdirectories = false, NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime), SynchronizingObject = ThreadingHelper.SynchronizingObject }; _configWatcher.Changed += OnConfigFileChanged; _configWatcher.Created += OnConfigFileChanged; _configWatcher.Renamed += OnConfigFileChanged; _configWatcher.EnableRaisingEvents = true; } catch (Exception ex) { Log.LogError((object)("[ConfigWatcher] " + ex)); _configWatcher = null; } } private void DisposeConfigWatcher() { if (_configWatcher != null) { _configWatcher.EnableRaisingEvents = false; _configWatcher.Dispose(); _configWatcher = null; } _reloadScheduled = false; } private void OnConfigFileChanged(object sender, FileSystemEventArgs e) { if (!(DateTime.UtcNow < _ignoreEventsUntilUtc)) { _lastCfgWriteUtc = DateTime.UtcNow; if (!_reloadScheduled) { _reloadScheduled = true; ((MonoBehaviour)this).StartCoroutine(ReloadConfigAfterQuietPeriod()); } } } private IEnumerator ReloadConfigAfterQuietPeriod() { while ((DateTime.UtcNow - _lastCfgWriteUtc).TotalSeconds < 0.75) { yield return null; } _reloadScheduled = false; FileSystemWatcher watcher = _configWatcher; if (watcher == null || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { yield break; } watcher.EnableRaisingEvents = false; try { ((BaseUnityPlugin)this).Config.Reload(); _ignoreEventsUntilUtc = DateTime.UtcNow.AddSeconds(1.0); } catch (Exception ex) { Log.LogError((object)("[ConfigReload] " + ex)); } finally { if (_configWatcher == watcher) { watcher.EnableRaisingEvents = true; } } } private void SetupBossCooldownBinds() { CE_BossCooldown_Enabled = Cfg("10 - Boss Summon Cooldown", "10.01 - Enable", defaultValue: false, "If true, enables individual boss summon cooldowns. Existing day/key restrictions and AdminBypass still apply."); CE_BossCooldown_Eikthyr = Cfg("10 - Boss Summon Cooldown", "10.02 - Eikthyr", 1, "Full in-game days between this boss's confirmed summons by the same player in the same world. (0 = disabled)"); CE_BossCooldown_Elder = Cfg("10 - Boss Summon Cooldown", "10.03 - Elder", 1, "Full in-game days between this boss's confirmed summons by the same player in the same world. (0 = disabled)"); CE_BossCooldown_Bonemass = Cfg("10 - Boss Summon Cooldown", "10.04 - Bonemass", 1, "Full in-game days between this boss's confirmed summons by the same player in the same world. (0 = disabled)"); CE_BossCooldown_Moder = Cfg("10 - Boss Summon Cooldown", "10.05 - Moder", 1, "Full in-game days between this boss's confirmed summons by the same player in the same world. (0 = disabled)"); CE_BossCooldown_Yagluth = Cfg("10 - Boss Summon Cooldown", "10.06 - Yagluth", 1, "Full in-game days between this boss's confirmed summons by the same player in the same world. (0 = disabled)"); CE_BossCooldown_Queen = Cfg("10 - Boss Summon Cooldown", "10.07 - Queen", 1, "Full in-game days between this boss's confirmed summons by the same player in the same world. (0 = disabled)"); CE_BossCooldown_Fader = Cfg("10 - Boss Summon Cooldown", "10.08 - Fader", 1, "Full in-game days between this boss's confirmed summons by the same player in the same world. (0 = disabled)"); CE_BossCooldown_Kall = Cfg("10 - Boss Summon Cooldown", "10.09 - Kall", 1, "Full in-game days between this boss's confirmed summons by the same player in the same world. (0 = disabled)"); } } internal static class BiomeLock_GuardianPowerKey { [HarmonyPatch(typeof(ItemStand), "Interact")] private static class Patch_ItemStand_Interact { [HarmonyPriority(100)] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(ItemStand __instance, Humanoid user, bool hold, bool alt, ref bool __result) { if ((Object)(object)user != (Object)(object)Player.m_localPlayer) { return true; } if (!ShouldBlock(__instance)) { return true; } if (!IsPowerActivationInteract(__instance, hold, alt)) { return true; } BiomeLock_SE.ShowMessage(Player.m_localPlayer, "$biomelock_guardian_power_locked"); __result = false; return false; } } [HarmonyPatch(typeof(ItemStand), "DelayedPowerActivation")] private static class Patch_ItemStand_DelayedPowerActivation { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] [HarmonyPriority(100)] private static bool Prefix(ItemStand __instance) { if (!ShouldBlock(__instance)) { return true; } BiomeLock_SE.ShowMessage(Player.m_localPlayer, "$biomelock_guardian_power_locked"); return false; } } [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(1)] private const string BlockedToken = "$biomelock_guardian_power_locked"; [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] internal static bool ShouldBlock(ItemStand stand) { if (!BiomeLockPlugin.CE_GuardianPower_Enabled.Value) { return false; } if ((Object)(object)Player.m_localPlayer == (Object)null) { return false; } if ((Object)(object)stand == (Object)null || (Object)(object)stand.m_guardianPower == (Object)null) { return false; } if (BiomeLockPlugin.AdminBypassActive()) { return false; } BossInfo bossInfo = BiomeLockBosses.FromGuardianPower(stand.m_guardianPower); return bossInfo != null && BiomeLockKeys.MissingProgressionKey(bossInfo.SkillCapKey); } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool IsPowerActivationInteract(ItemStand stand, bool hold, bool alt) { if (hold || !stand.HaveAttachment()) { return false; } return !alt || !Object.op_Implicit((Object)(object)stand.m_visualItemDrop) || stand.m_orientationSettings.Count <= 1; } } [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] internal sealed class BossInfo { internal readonly string Prefab; internal readonly string SkillCapKey; internal readonly string PreviousKey; internal readonly string GuardianPower; private readonly Func<ConfigEntry<int>> _summonDay; private readonly Func<ConfigEntry<int>> _skillCap; private readonly Func<ConfigEntry<int>> _cooldownDays; internal int SummonDay => _summonDay().Value; internal int SkillCap => _skillCap().Value; internal int CooldownDays => _cooldownDays().Value; internal BossInfo(string prefab, string skillCapKey, string previousKey, string guardianPower, Func<ConfigEntry<int>> summonDay, Func<ConfigEntry<int>> skillCap, Func<ConfigEntry<int>> cooldownDays) { Prefab = prefab; SkillCapKey = skillCapKey; PreviousKey = previousKey; GuardianPower = guardianPower; _summonDay = summonDay; _skillCap = skillCap; _cooldownDays = cooldownDays; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] internal static class BiomeLockBosses { internal static readonly BossInfo[] All = new BossInfo[8] { new BossInfo("Eikthyr", "defeated_eikthyr", "", "GP_Eikthyr", () => BiomeLockPlugin.CE_BossDay_Eikthyr, () => BiomeLockPlugin.CE_SkillCap_Eikthyr, () => BiomeLockPlugin.CE_BossCooldown_Eikthyr), new BossInfo("gd_king", "defeated_gdking", "defeated_eikthyr", "GP_TheElder", () => BiomeLockPlugin.CE_BossDay_Elder, () => BiomeLockPlugin.CE_SkillCap_Elder, () => BiomeLockPlugin.CE_BossCooldown_Elder), new BossInfo("Bonemass", "defeated_bonemass", "defeated_gdking", "GP_Bonemass", () => BiomeLockPlugin.CE_BossDay_Bonemass, () => BiomeLockPlugin.CE_SkillCap_Bonemass, () => BiomeLockPlugin.CE_BossCooldown_Bonemass), new BossInfo("Dragon", "defeated_dragon", "defeated_bonemass", "GP_Moder", () => BiomeLockPlugin.CE_BossDay_Moder, () => BiomeLockPlugin.CE_SkillCap_Moder, () => BiomeLockPlugin.CE_BossCooldown_Moder), new BossInfo("GoblinKing", "defeated_goblinking", "defeated_dragon", "GP_Yagluth", () => BiomeLockPlugin.CE_BossDay_Yagluth, () => BiomeLockPlugin.CE_SkillCap_Yagluth, () => BiomeLockPlugin.CE_BossCooldown_Yagluth), new BossInfo("SeekerQueen", "defeated_queen", "defeated_goblinking", "GP_Queen", () => BiomeLockPlugin.CE_BossDay_Queen, () => BiomeLockPlugin.CE_SkillCap_Queen, () => BiomeLockPlugin.CE_BossCooldown_Queen), new BossInfo("Fader", "defeated_fader", "defeated_queen", "GP_Ashlands|GP_Fader", () => BiomeLockPlugin.CE_BossDay_Fader, () => BiomeLockPlugin.CE_SkillCap_Fader, () => BiomeLockPlugin.CE_BossCooldown_Fader), new BossInfo("FrozenKing", "defeated_frozenking_p3", "defeated_fader", "GP_DeepNorth", () => BiomeLockPlugin.CE_BossDay_Kall, () => BiomeLockPlugin.CE_SkillCap_Kall, () => BiomeLockPlugin.CE_BossCooldown_Kall) }; private static readonly char[] AliasSeparator = new char[1] { '|' }; private static readonly Dictionary<string, BossInfo> ByPrefab = BuildIndex((BossInfo b) => b.Prefab); private static readonly Dictionary<string, BossInfo> ByGuardianPower = BuildIndex((BossInfo b) => b.GuardianPower); private static Dictionary<string, BossInfo> BuildIndex(Func<BossInfo, string> key) { Dictionary<string, BossInfo> dictionary = new Dictionary<string, BossInfo>(StringComparer.OrdinalIgnoreCase); BossInfo[] all = All; foreach (BossInfo bossInfo in all) { string[] array = key(bossInfo).Split(AliasSeparator, StringSplitOptions.RemoveEmptyEntries); foreach (string key2 in array) { dictionary[key2] = bossInfo; } } return dictionary; } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(2)] private static BossInfo Find([<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(1)] Dictionary<string, BossInfo> index, string name) { if (name == null) { return null; } string text = Utils.GetPrefabName(name).Trim(); if (text.Length == 0) { return null; } index.TryGetValue(text, out var value); return value; } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(2)] internal static BossInfo FromPrefab(GameObject prefab) { return ((Object)(object)prefab == (Object)null) ? null : Find(ByPrefab, ((Object)prefab).name); } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(2)] internal static BossInfo FromGuardianPower(StatusEffect guardianPower) { return ((Object)(object)guardianPower == (Object)null) ? null : Find(ByGuardianPower, ((Object)guardianPower).name); } } internal static class BiomeLock_SkillCapBoss { internal static int GetEffectiveSkillCap() { int num = 0; BossInfo[] all = BiomeLockBosses.All; foreach (BossInfo bossInfo in all) { int skillCap = bossInfo.SkillCap; if (skillCap > 0 && (num <= 0 || skillCap < num) && BiomeLockKeys.MissingProgressionKey(bossInfo.SkillCapKey)) { num = ((num <= 0) ? skillCap : Mathf.Min(num, skillCap)); } } return num; } } [HarmonyPatch(typeof(Skills), "RaiseSkill")] internal static class BiomeLock_SkillCapBoss_RaiseSkill_Patch { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static void Prefix(Skills __instance, SkillType skillType, ref float factor) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!BiomeLockPlugin.CE_SkillCap_Enabled.Value || (int)skillType == 0 || (int)skillType == 999 || factor <= 0f) { return; } int effectiveSkillCap = BiomeLock_SkillCapBoss.GetEffectiveSkillCap(); if (effectiveSkillCap > 0) { Skill skill = __instance.GetSkill(skillType); if (skill != null && skill.m_level >= (float)effectiveSkillCap) { factor = 0f; } } } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] internal static class BiomeLock_BossSummon { [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [HarmonyPatch(typeof(OfferingBowl), "InitiateSpawnBoss")] private static class Patch_OfferingBowl_InitiateSpawnBoss { [HarmonyPriority(200)] private static bool Prefix(OfferingBowl __instance, out bool __state) { __state = false; BossInfo restrictedBoss = GetRestrictedBoss(__instance); if (restrictedBoss == null) { return true; } Player localPlayer = Player.m_localPlayer; if (ShouldBlockByDay(restrictedBoss, out var requiredDay, out var currentDay)) { ((Character)localPlayer).Message((MessageType)2, BiomeLock_SE.ColorBlocked(string.Format(Localization.instance.Localize("$biomelock_boss_day_locked"), requiredDay, currentDay)), 0, (Sprite)null, false); return false; } if (ShouldBlockByPreviousKey(restrictedBoss)) { BiomeLock_SE.ShowMessage(localPlayer, "$biomelock_boss_prev_key_locked"); return false; } return BiomeLockBossCooldown.TryBegin(__instance, restrictedBoss, localPlayer, out __state); } private static void Postfix(OfferingBowl __instance, bool __state, bool __runOriginal) { if (__state && !__runOriginal) { BiomeLockBossCooldown.Cancel(__instance); } } private static void Finalizer(OfferingBowl __instance, bool __state, [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] Exception __exception) { if (__state && __exception != null) { BiomeLockBossCooldown.Cancel(__instance); } } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(OfferingBowl), "RPC_BossSpawnInitiated")] private static class Patch_OfferingBowl_BossSpawnInitiated { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static void Postfix(OfferingBowl __instance) { BiomeLockBossCooldown.Confirm(__instance); } } private const string DayLockedToken = "$biomelock_boss_day_locked"; private const string PreviousKeyLockedToken = "$biomelock_boss_prev_key_locked"; [return: <dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private static BossInfo GetRestrictedBoss(OfferingBowl bowl) { if ((Object)(object)Player.m_localPlayer == (Object)null) { return null; } if (BiomeLockPlugin.AdminBypassActive()) { return null; } if ((Object)(object)bowl == (Object)null) { return null; } return BiomeLockBosses.FromPrefab(bowl.m_bossPrefab); } internal static bool ShouldBlockByDay(BossInfo boss, out int requiredDay, out int currentDay) { requiredDay = 0; currentDay = 0; if (!BiomeLockPlugin.CE_BossDay_Enabled.Value) { return false; } requiredDay = boss.SummonDay; if (requiredDay <= 0) { return false; } currentDay = (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetDay() : 0); return currentDay < requiredDay; } internal static bool ShouldBlockByPreviousKey(BossInfo boss) { if (!BiomeLockPlugin.CE_BossPrevKey_Enabled.Value) { return false; } if (boss.PreviousKey.Length == 0) { return false; } return BiomeLockKeys.MissingProgressionKey(boss.PreviousKey); } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] internal static class BiomeLockBossCooldown { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private sealed class PendingSummon { [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(1)] internal OfferingBowl Bowl = null; internal float Expires; } private const string SavePrefix = "BL_BossSummon_"; private const float RequestTimeoutSeconds = 10f; private static readonly Dictionary<string, PendingSummon> Pending = new Dictionary<string, PendingSummon>(); [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private static Player _player; private static long _world; private static bool TryGetClock(Player player, out double now, out double dayLength) { now = (dayLength = 0.0); if ((Object)(object)player != (Object)(object)Player.m_localPlayer || (Object)(object)ZNet.instance == (Object)null || ZNet.World == null || (Object)(object)EnvMan.instance == (Object)null) { return false; } long uid = ZNet.World.m_uid; if ((Object)(object)_player != (Object)(object)player || _world != uid) { ClearPending(); _player = player; _world = uid; } now = ZNet.instance.GetTimeSeconds(); dayLength = EnvMan.instance.m_dayLengthSec; return IsValidTime(now) && dayLength > 0.0; } private static bool IsValidTime(double time) { return time >= 0.0 && !double.IsNaN(time) && !double.IsInfinity(time); } private static string FormatRemaining(double days) { int num = Math.Max(1, (int)Math.Ceiling(days * 1440.0)); int num2 = num / 1440; int num3 = num % 1440 / 60; int num4 = num % 60; if (num2 > 0) { return (num3 > 0) ? (num2 + "d " + num3 + "h") : (num2 + "d"); } return (num3 <= 0) ? (num4 + "min") : ((num4 > 0) ? (num3 + "h " + num4 + "min") : (num3 + "h")); } private static string SaveKey(BossInfo boss) { return "BL_BossSummon_" + _world.ToString(CultureInfo.InvariantCulture) + "_" + boss.Prefab; } internal static bool TryBegin(OfferingBowl bowl, BossInfo boss, Player player, out bool reserved) { reserved = false; if (!BiomeLockPlugin.CE_BossCooldown_Enabled.Value || boss.CooldownDays <= 0 || !TryGetClock(player, out var now, out var dayLength)) { return true; } string key = SaveKey(boss); if (player.m_customData != null && player.m_customData.TryGetValue(key, out var value) && double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && IsValidTime(result)) { double num = Math.Min((result + (double)boss.CooldownDays * dayLength - now) / dayLength, boss.CooldownDays); if (num > 0.0) { string text = string.Format(Localization.instance.Localize("$biomelock_boss_cooldown_locked"), FormatRemaining(num)); ((Character)player).Message((MessageType)2, BiomeLock_SE.ColorBlocked(text), 0, (Sprite)null, false); return false; } } if (Pending.TryGetValue(key, out var value2) && value2.Expires > Time.realtimeSinceStartup) { BiomeLock_SE.ShowMessage(player, "$biomelock_boss_summon_pending"); return false; } Pending[key] = new PendingSummon { Bowl = bowl, Expires = Time.realtimeSinceStartup + 10f }; reserved = true; return true; } internal static void Confirm(OfferingBowl bowl) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)bowl.m_interactUser != (Object)(object)localPlayer) { return; } BossInfo bossInfo = BiomeLockBosses.FromPrefab(bowl.m_bossPrefab); if (bossInfo == null || !TryGetClock(localPlayer, out var now, out var _)) { return; } string key = SaveKey(bossInfo); if (!Pending.TryGetValue(key, out var value) || (Object)(object)value.Bowl != (Object)(object)bowl) { return; } Pending.Remove(key); if (BiomeLockPlugin.CE_BossCooldown_Enabled.Value && bossInfo.CooldownDays > 0 && !BiomeLockPlugin.AdminBypassActive()) { Player val = localPlayer; if (val.m_customData == null) { val.m_customData = new Dictionary<string, string>(); } localPlayer.m_customData[key] = now.ToString("R", CultureInfo.InvariantCulture); } } internal static void Cancel(OfferingBowl bowl) { BossInfo bossInfo = BiomeLockBosses.FromPrefab(bowl.m_bossPrefab); if (bossInfo != null) { string key = SaveKey(bossInfo); if (Pending.TryGetValue(key, out var value) && (Object)(object)value.Bowl == (Object)(object)bowl) { Pending.Remove(key); } } } internal static void ClearPending() { Pending.Clear(); _player = null; _world = 0L; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] internal static class BiomeLockCommands { [HarmonyPatch(typeof(Terminal), "InitTerminal")] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Terminal_InitTerminal_RegisterCommands { private static void Postfix() { Register(); } } [CompilerGenerated] private static class <>O { [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] public static ConsoleEvent <0>__ListKeys; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] public static ConsoleOptionsFetcher <1>__PlayerNames; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] public static ConsoleEvent <2>__AddKey; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] public static ConsoleEvent <3>__RemoveKey; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] public static ConsoleEvent <4>__ResetKeys; } private static void Register() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //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_0113: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown object obj = <>O.<0>__ListKeys; if (obj == null) { ConsoleEvent val = ListKeys; <>O.<0>__ListKeys = val; obj = (object)val; } object obj2 = <>O.<1>__PlayerNames; if (obj2 == null) { ConsoleOptionsFetcher val2 = PlayerNames; <>O.<1>__PlayerNames = val2; obj2 = (object)val2; } new ConsoleCommand("bl_listkeys", "[player] - BiomeLock: lists the private keys of a player (admin).", (ConsoleEvent)obj, false, true, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false); object obj3 = <>O.<2>__AddKey; if (obj3 == null) { ConsoleEvent val3 = AddKey; <>O.<2>__AddKey = val3; obj3 = (object)val3; } object obj4 = <>O.<1>__PlayerNames; if (obj4 == null) { ConsoleOptionsFetcher val4 = PlayerNames; <>O.<1>__PlayerNames = val4; obj4 = (object)val4; } new ConsoleCommand("bl_addkey", "<player> <key> - BiomeLock: grants a private key to a player (admin).", (ConsoleEvent)obj3, false, true, false, false, false, false, (ConsoleOptionsFetcher)obj4, false, false, false); object obj5 = <>O.<3>__RemoveKey; if (obj5 == null) { ConsoleEvent val5 = RemoveKey; <>O.<3>__RemoveKey = val5; obj5 = (object)val5; } object obj6 = <>O.<1>__PlayerNames; if (obj6 == null) { ConsoleOptionsFetcher val6 = PlayerNames; <>O.<1>__PlayerNames = val6; obj6 = (object)val6; } new ConsoleCommand("bl_removekey", "<player> <key> - BiomeLock: removes a private key from a player (admin).", (ConsoleEvent)obj5, false, true, false, false, false, false, (ConsoleOptionsFetcher)obj6, false, false, false); object obj7 = <>O.<4>__ResetKeys; if (obj7 == null) { ConsoleEvent val7 = ResetKeys; <>O.<4>__ResetKeys = val7; obj7 = (object)val7; } object obj8 = <>O.<1>__PlayerNames; if (obj8 == null) { ConsoleOptionsFetcher val8 = PlayerNames; <>O.<1>__PlayerNames = val8; obj8 = (object)val8; } new ConsoleCommand("bl_resetkeys", "<player> - BiomeLock: removes all private keys from a player (admin).", (ConsoleEvent)obj7, false, true, false, false, false, false, (ConsoleOptionsFetcher)obj8, false, false, false); } private static List<string> PlayerNames() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); if ((Object)(object)ZNet.instance == (Object)null) { return list; } foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { if (!string.IsNullOrEmpty(player.m_name)) { list.Add(player.m_name); } } return list; } private static void ListKeys(ConsoleEventArgs args) { if (CanRun(args)) { long uid = 0L; string text = JoinArgs(args, 1, args.Length); if (text.Length <= 0 || TryResolvePlayer(args, text, out uid)) { ZRoutedRpc.instance.InvokeRoutedRPC("BL_ServerListKeys", new object[1] { uid }); } } } private static void AddKey(ConsoleEventArgs args) { if (TryParsePlayerAndKey(args, "bl_addkey <player> <key>", out var playerName, out var uid, out var privateKey)) { if (uid == ZNet.GetUID()) { ZRoutedRpc.instance.InvokeRoutedRPC(uid, "BL_SetPrivateKey", new object[1] { privateKey }); } else { ZRoutedRpc.instance.InvokeRoutedRPC("BL_ServerSetPrivateKey", new object[2] { privateKey, uid }); } args.Context.AddString("[BL] Added " + privateKey + " to " + playerName + "."); } } private static void RemoveKey(ConsoleEventArgs args) { if (TryParsePlayerAndKey(args, "bl_removekey <player> <key>", out var playerName, out var uid, out var privateKey)) { if (uid == ZNet.GetUID()) { ZRoutedRpc.instance.InvokeRoutedRPC(uid, "BL_RemovePrivateKey", new object[1] { privateKey }); } else { ZRoutedRpc.instance.InvokeRoutedRPC("BL_ServerRemovePrivateKey", new object[2] { privateKey, uid }); } args.Context.AddString("[BL] Removed " + privateKey + " from " + playerName + "."); } } private static void ResetKeys(ConsoleEventArgs args) { if (!CanRun(args)) { return; } string text = JoinArgs(args, 1, args.Length); long uid; if (text.Length == 0) { args.Context.AddString("[BL] Usage: bl_resetkeys <player>"); } else if (TryResolvePlayer(args, text, out uid)) { if (uid == ZNet.GetUID()) { ZRoutedRpc.instance.InvokeRoutedRPC(uid, "BL_ResetPrivateKeys", Array.Empty<object>()); } else { ZRoutedRpc.instance.InvokeRoutedRPC("BL_ServerResetPrivateKeys", new object[1] { uid }); } args.Context.AddString("[BL] Reset all private keys of " + text + "."); } } private static bool CanRun(ConsoleEventArgs args) { if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null || !BiomeLockKeys.IsInMainScene()) { args.Context.AddString("[BL] Only available in game."); return false; } if (!BiomeLockPlugin.IsLocalPlayerAdmin()) { args.Context.AddString("[BL] Admin only."); return false; } return true; } private static bool TryParsePlayerAndKey(ConsoleEventArgs args, string usage, out string playerName, out long uid, out string privateKey) { playerName = string.Empty; uid = 0L; privateKey = string.Empty; if (!CanRun(args)) { return false; } if (args.Length < 3) { args.Context.AddString("[BL] Usage: " + usage); return false; } privateKey = BiomeLockKeys.ToPrivateKey(args[args.Length - 1]); if (privateKey.Length == 0) { args.Context.AddString("[BL] Invalid key."); return false; } playerName = JoinArgs(args, 1, args.Length - 1); return TryResolvePlayer(args, playerName, out uid); } private static bool TryResolvePlayer(ConsoleEventArgs args, string playerName, out long uid) { if (BiomeLockPrivateKeys.TryResolveUidByPlayerName(playerName, out uid)) { return true; } args.Context.AddString("[BL] Player not found: " + playerName); return false; } private static string JoinArgs(ConsoleEventArgs args, int start, int end) { if (start >= end) { return string.Empty; } return string.Join(" ", args.Args, start, end - start).Trim(); } } [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] internal static class BiomeLockKeys { internal const string PrivatePrefix = "bl_"; internal static readonly HashSet<string> TrackedGlobalKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen", "defeated_fader", "defeated_frozenking", "defeated_frozenking_p3", "defeated_writhan", "defeated_hive", "defeated_serpent", "killedtroll", "killed_surtling", "killed_frysling", "killedbat", "hildir1", "hildir2", "hildir3" }; private static readonly Dictionary<string, string> PrivateKeyCache = new Dictionary<string, string>(StringComparer.Ordinal); internal static bool IsInMainScene() { return (Object)(object)ZNetScene.instance != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null; } internal static string NormalizeKey([<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] string key) { return (key ?? string.Empty).Trim().ToLowerInvariant(); } internal static string ToGlobalKey(string globalOrPrivateKey) { string text = NormalizeKey(globalOrPrivateKey); return text.StartsWith("bl_", StringComparison.Ordinal) ? text.Substring("bl_".Length) : text; } internal static string ToPrivateKey(string globalOrPrivateKey) { string text = NormalizeKey(globalOrPrivateKey); if (text.Length == 0) { return string.Empty; } return text.StartsWith("bl_", StringComparison.Ordinal) ? text : ("bl_" + text); } internal static string ToPrivateKeyCached(string globalOrPrivateKey) { if (!PrivateKeyCache.TryGetValue(globalOrPrivateKey, out var value)) { value = ToPrivateKey(globalOrPrivateKey); PrivateKeyCache[globalOrPrivateKey] = value; } return value; } internal static bool IsTrackedGlobalKey(string globalOrPrivateKey) { return TrackedGlobalKeys.Contains(ToGlobalKey(globalOrPrivateKey)); } internal static bool HasLocalPrivateKey(string globalOrPrivateKey) { if (!IsInMainScene()) { return false; } string text = ToPrivateKeyCached(globalOrPrivateKey); return text.Length > 0 && BiomeLockPrivateKeys.PrivateKeys.Contains(text); } internal static bool HasProgressionKey(string globalOrPrivateKey) { if (BiomeLockPlugin.CE_GlobalKeys_PrivateKeys.Value) { return HasLocalPrivateKey(globalOrPrivateKey); } return HasVanillaGlobalKey(globalOrPrivateKey); } internal static bool MissingProgressionKey(string globalOrPrivateKey) { return !HasProgressionKey(globalOrPrivateKey); } private static bool HasVanillaGlobalKey(string globalOrPrivateKey) { if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } string text = ToGlobalKey(globalOrPrivateKey); string text2 = default(string); return text.Length > 0 && ZoneSystem.instance.GetGlobalKey(text, ref text2); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class BiomeLock_ZoneSystem_GetGlobalKey_RedirectPrivateKeys { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(string name, ref string value, ref bool __result) { if (string.IsNullOrWhiteSpace(name)) { return true; } if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsDedicated()) { return true; } if (!BiomeLockPlugin.CE_GlobalKeys_PrivateKeys.Value) { return true; } if (!BiomeLockKeys.TrackedGlobalKeys.Contains(name)) { return true; } if (BiomeLockPlugin.AdminBypassActive()) { return true; } __result = BiomeLockKeys.HasLocalPrivateKey(name); value = string.Empty; return false; } } [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] internal static class BiomeLockPrivateKeys { internal const string PlayerSaveKey = "BL_PrivateKeys"; internal const string RPC_SetPrivateKey = "BL_SetPrivateKey"; internal const string RPC_RemovePrivateKey = "BL_RemovePrivateKey"; internal const string RPC_ResetPrivateKeys = "BL_ResetPrivateKeys"; internal const string RPC_ClientListKeysBegin = "BL_ClientListKeysBegin"; internal const string RPC_ClientListKeysLine = "BL_ClientListKeysLine"; internal const string RPC_ServerListKeys = "BL_ServerListKeys"; internal const string RPC_ServerSetPrivateKeys = "BL_ServerSetPrivateKeys"; internal const string RPC_ServerSetPrivateKey = "BL_ServerSetPrivateKey"; internal const string RPC_ServerRemovePrivateKey = "BL_ServerRemovePrivateKey"; internal const string RPC_ServerResetPrivateKeys = "BL_ServerResetPrivateKeys"; internal const float ShareRadiusMeters = 120f; internal static readonly HashSet<string> PrivateKeys = new HashSet<string>(StringComparer.Ordinal); internal static readonly Dictionary<long, HashSet<string>> ServerPrivateKeysByUid = new Dictionary<long, HashSet<string>>(); private static readonly List<Player> NearbyPlayers = new List<Player>(); [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private static ZRoutedRpc _playerRpcOwner; [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private static ZRoutedRpc _serverRpcOwner; internal static void EnsurePlayerRpcRegistered() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _playerRpcOwner) { _playerRpcOwner = instance; instance.Register<string>("BL_SetPrivateKey", (Action<long, string>)RPC_BL_SetPrivateKey); instance.Register<string>("BL_RemovePrivateKey", (Action<long, string>)RPC_BL_RemovePrivateKey); instance.Register("BL_ResetPrivateKeys", (Action<long>)RPC_BL_ResetPrivateKeys); instance.Register<long, int>("BL_ClientListKeysBegin", (Action<long, long, int>)RPC_BL_ClientListKeysBegin); instance.Register<long, string>("BL_ClientListKeysLine", (Action<long, long, string>)RPC_BL_ClientListKeysLine); } } internal static void EnsureServerRpcRegistered() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _serverRpcOwner && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { _serverRpcOwner = instance; instance.Register<long>("BL_ServerListKeys", (Action<long, long>)RPC_BL_ServerListKeys); instance.Register<string, long>("BL_ServerSetPrivateKeys", (Action<long, string, long>)RPC_BL_ServerSetPrivateKeys); instance.Register<string, long>("BL_ServerSetPrivateKey", (Action<long, string, long>)RPC_BL_ServerSetPrivateKey); instance.Register<string, long>("BL_ServerRemovePrivateKey", (Action<long, string, long>)RPC_BL_ServerRemovePrivateKey); instance.Register<long>("BL_ServerResetPrivateKeys", (Action<long, long>)RPC_BL_ServerResetPrivateKeys); } } private static void SendToServer(string rpcName, string payload) { if (ZRoutedRpc.instance != null && !((Object)(object)ZNet.instance == (Object)null)) { ZRoutedRpc.instance.InvokeRoutedRPC(rpcName, new object[2] { payload, ZNet.GetUID() }); } } private static bool IsFromServer(long sender) { return ZRoutedRpc.instance != null && sender == ZRoutedRpc.instance.GetServerPeerID(); } private static bool IsFromServerOrSelf(long sender) { return ZRoutedRpc.instance != null && (sender == ZRoutedRpc.instance.GetServerPeerID() || sender == ZRoutedRpc.instance.m_id); } private static void RPC_BL_SetPrivateKey(long sender, string privateKey) { try { if (BiomeLockKeys.IsInMainScene()) { privateKey = BiomeLockKeys.NormalizeKey(privateKey); if (privateKey.Length != 0 && PrivateKeys.Add(privateKey)) { SaveKeysToPlayer(Player.m_localPlayer); BiomeLockAPI.RaisePrivateKeyAdded(privateKey); SendToServer("BL_ServerSetPrivateKey", privateKey); BiomeLock_KeyRefresh.NotifyKeysChanged(); } } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[RPC_BL_SetPrivateKey] " + ex)); } } private static void RPC_BL_RemovePrivateKey(long sender, string privateKey) { try { if (BiomeLockKeys.IsInMainScene() && IsFromServerOrSelf(sender)) { privateKey = BiomeLockKeys.NormalizeKey(privateKey); if (privateKey.Length != 0 && PrivateKeys.Remove(privateKey)) { SaveKeysToPlayer(Player.m_localPlayer); BiomeLockAPI.RaisePrivateKeyRemoved(privateKey); SendToServer("BL_ServerRemovePrivateKey", privateKey); BiomeLock_KeyRefresh.NotifyKeysChanged(); } } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[RPC_BL_RemovePrivateKey] " + ex)); } } private static void RPC_BL_ResetPrivateKeys(long sender) { try { if (BiomeLockKeys.IsInMainScene() && IsFromServerOrSelf(sender)) { PrivateKeys.Clear(); SaveKeysToPlayer(Player.m_localPlayer); BiomeLockAPI.RaisePrivateKeysReset(); SendToServer("BL_ServerSetPrivateKeys", string.Empty); BiomeLock_KeyRefresh.NotifyKeysChanged(); } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[RPC_BL_ResetPrivateKeys] " + ex)); } } private static void RPC_BL_ClientListKeysBegin(long sender, long targetUid, int count) { if (BiomeLockKeys.IsInMainScene() && IsFromServer(sender)) { ClientConsoleAdd($"[BL] TotalKeys: {count}"); } } private static void RPC_BL_ClientListKeysLine(long sender, long targetUid, string key) { if (BiomeLockKeys.IsInMainScene() && IsFromServer(sender)) { key = BiomeLockKeys.NormalizeKey(key); if (key.Length > 0) { ClientConsoleAdd(key); } } } private static void ClientConsoleAdd(string msg) { if ((Object)(object)Console.instance != (Object)null) { ((Terminal)Console.instance).AddString(msg); } } internal static void ClientDistributeBossPrivateKey(string globalKey) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) try { if (!BiomeLockKeys.IsInMainScene() || (Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsDedicated() || ZRoutedRpc.instance == null || !BiomeLockPlugin.CE_GlobalKeys_PrivateKeys.Value || !BiomeLockKeys.IsTrackedGlobalKey(globalKey)) { return; } string text = BiomeLockKeys.ToPrivateKey(globalKey); NearbyPlayers.Clear(); Player.GetPlayersInRange(((Component)Player.m_localPlayer).transform.position, 120f, NearbyPlayers); foreach (Player nearbyPlayer in NearbyPlayers) { if (!((Object)(object)nearbyPlayer == (Object)null)) { ZDOID zDOID = ((Character)nearbyPlayer).GetZDOID(); long userID = ((ZDOID)(ref zDOID)).UserID; if (userID != 0) { ZRoutedRpc.instance.InvokeRoutedRPC(userID, "BL_SetPrivateKey", new object[1] { text }); } } } NearbyPlayers.Clear(); } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[ClientDistributeBossPrivateKey] " + ex)); } } private static void RPC_BL_ServerListKeys(long sender, long targetUid) { try { if (!IsSenderAdmin(sender)) { return; } long num = ((targetUid != 0L) ? targetUid : sender); HashSet<string> value; List<string> list = (ServerPrivateKeysByUid.TryGetValue(num, out value) ? value.OrderBy<string, string>([<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] (string s) => s, StringComparer.Ordinal).ToList() : new List<string>()); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "BL_ClientListKeysBegin", new object[2] { num, list.Count }); foreach (string item in list) { ZRoutedRpc.instance.InvokeRoutedRPC(sender, "BL_ClientListKeysLine", new object[2] { num, item }); } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[RPC_BL_ServerListKeys] " + ex)); } } private static bool AllowTrackingOrAdmin(long sender, long uid) { return uid == sender || IsSenderAdmin(sender); } private static HashSet<string> GetOrCreateServerSet(long uid) { if (!ServerPrivateKeysByUid.TryGetValue(uid, out var value)) { value = new HashSet<string>(StringComparer.Ordinal); ServerPrivateKeysByUid[uid] = value; } return value; } private static bool TryNormalizePrivateKey(ref string privateKey) { privateKey = BiomeLockKeys.NormalizeKey(privateKey); return privateKey.StartsWith("bl_", StringComparison.Ordinal); } private static void RPC_BL_ServerSetPrivateKeys(long sender, string keysCsv, long targetUid) { try { long num = ((targetUid != 0L) ? targetUid : sender); if (!AllowTrackingOrAdmin(sender, num)) { return; } HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); string[] array = (keysCsv ?? string.Empty).Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string privateKey = text; if (TryNormalizePrivateKey(ref privateKey)) { hashSet.Add(privateKey); } } ServerPrivateKeysByUid[num] = hashSet; } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[RPC_BL_ServerSetPrivateKeys] " + ex)); } } private static void RPC_BL_ServerSetPrivateKey(long sender, string privateKey, long targetUid) { try { long num = ((targetUid != 0L) ? targetUid : sender); if (AllowTrackingOrAdmin(sender, num) && TryNormalizePrivateKey(ref privateKey)) { GetOrCreateServerSet(num).Add(privateKey); if (num != sender) { ZRoutedRpc.instance.InvokeRoutedRPC(num, "BL_SetPrivateKey", new object[1] { privateKey }); } } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[RPC_BL_ServerSetPrivateKey] " + ex)); } } private static void RPC_BL_ServerRemovePrivateKey(long sender, string privateKey, long targetUid) { try { long num = ((targetUid != 0L) ? targetUid : sender); if (AllowTrackingOrAdmin(sender, num) && TryNormalizePrivateKey(ref privateKey)) { if (ServerPrivateKeysByUid.TryGetValue(num, out var value)) { value.Remove(privateKey); } if (num != sender) { ZRoutedRpc.instance.InvokeRoutedRPC(num, "BL_RemovePrivateKey", new object[1] { privateKey }); } } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[RPC_BL_ServerRemovePrivateKey] " + ex)); } } private static void RPC_BL_ServerResetPrivateKeys(long sender, long targetUid) { try { long num = ((targetUid != 0L) ? targetUid : sender); if (AllowTrackingOrAdmin(sender, num)) { ServerPrivateKeysByUid[num] = new HashSet<string>(StringComparer.Ordinal); if (num != sender) { ZRoutedRpc.instance.InvokeRoutedRPC(num, "BL_ResetPrivateKeys", Array.Empty<object>()); } } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[RPC_BL_ServerResetPrivateKeys] " + ex)); } } private static bool IsSenderAdmin(long senderUid) { try { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return false; } if (ZRoutedRpc.instance != null && senderUid == ZRoutedRpc.instance.m_id) { return true; } if (!TryGetPeerByUid(senderUid, out var peer)) { return false; } string hostName = peer.m_socket.GetHostName(); return !string.IsNullOrEmpty(hostName) && ZNet.instance.IsAdmin(hostName); } catch { return false; } } private static bool TryGetPeerByUid(long uid, out ZNetPeer peer) { peer = null; if ((Object)(object)ZNet.instance == (Object)null) { return false; } foreach (ZNetPeer peer2 in ZNet.instance.GetPeers()) { if (peer2 != null && peer2.m_uid == uid) { peer = peer2; return true; } } return false; } internal static bool TryResolveUidByPlayerName(string playerName, out long uid) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) uid = 0L; if (string.IsNullOrEmpty(playerName)) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && string.Equals(localPlayer.GetPlayerName(), playerName, StringComparison.OrdinalIgnoreCase)) { uid = ZNet.GetUID(); return uid != 0; } if ((Object)(object)ZNet.instance == (Object)null) { return false; } foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { if (string.Equals(player.m_name, playerName, StringComparison.OrdinalIgnoreCase)) { ZDOID characterID = player.m_characterID; uid = ((ZDOID)(ref characterID)).UserID; return uid != 0; } } foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer != null && string.Equals(peer.m_playerName, playerName, StringComparison.OrdinalIgnoreCase)) { uid = peer.m_uid; return uid != 0; } } return false; } internal static void LoadKeysFromPlayer(Player p) { PrivateKeys.Clear(); if (p.m_customData != null && p.m_customData.TryGetValue("BL_PrivateKeys", out var value) && !string.IsNullOrEmpty(value)) { string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string key in array) { string text = BiomeLockKeys.NormalizeKey(key); if (text.Length > 0) { PrivateKeys.Add(text); } } } BiomeLock_KeyRefresh.NotifyKeysChanged(); BiomeLockAPI.RaisePrivateKeysLoaded(); } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(2)] internal static void SaveKeysToPlayer(Player p) { if (!((Object)(object)p == (Object)null)) { if (p.m_customData == null) { p.m_customData = new Dictionary<string, string>(); } p.m_customData["BL_PrivateKeys"] = GetPrivateKeysCsv(); } } internal static string GetPrivateKeysCsv() { return string.Join(",", PrivateKeys.OrderBy<string, string>([<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] (string s) => s, StringComparer.Ordinal)); } } [HarmonyPatch] [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] internal static class BL_Patches_Player_LoadSaveAndRpc { [HarmonyPatch(typeof(Player), "EquipInventoryItems")] [HarmonyPrefix] private static void Player_EquipInventoryItems_Prefix(Player __instance) { try { if (BiomeLockKeys.IsInMainScene()) { BiomeLockPrivateKeys.LoadKeysFromPlayer(__instance); BiomeLockPrivateKeys.EnsurePlayerRpcRegistered(); if (ZRoutedRpc.instance != null && (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsDedicated()) { ZRoutedRpc.instance.InvokeRoutedRPC("BL_ServerSetPrivateKeys", new object[2] { BiomeLockPrivateKeys.GetPrivateKeysCsv(), ZNet.GetUID() }); } } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[Player_EquipInventoryItems_Prefix] " + ex)); } } [HarmonyPatch(typeof(Player), "Save", new Type[] { typeof(ZPackage) })] [HarmonyPrefix] private static void Player_Save_Prefix(Player __instance) { try { if (!BiomeLockKeys.IsInMainScene()) { BiomeLockPrivateKeys.PrivateKeys.Clear(); } else { BiomeLockPrivateKeys.SaveKeysToPlayer(__instance); } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[Player_Save_Prefix] " + ex)); } } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [HarmonyPatch] internal static class BL_Patches_Server_RegisterAndDistribute { [HarmonyPatch(typeof(ZoneSystem), "Load")] [HarmonyPostfix] private static void ZoneSystem_Load_Postfix() { try { BiomeLockPrivateKeys.EnsureServerRpcRegistered(); } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[ZoneSystem_Load_Postfix] " + ex)); } } [HarmonyPatch(typeof(ZNet), "Disconnect", new Type[] { typeof(ZNetPeer) })] [HarmonyPrefix] private static void ZNet_Disconnect_Prefix(ZNet __instance, ZNetPeer peer) { if (!((Object)(object)__instance == (Object)null) && peer != null && __instance.IsServer()) { BiomeLockPrivateKeys.ServerPrivateKeysByUid.Remove(peer.m_uid); } } [HarmonyPatch(typeof(ZoneSystem), "SetGlobalKey", new Type[] { typeof(string) })] [HarmonyPostfix] private static void ZoneSystem_SetGlobalKey_Postfix(string name) { string text = BiomeLockKeys.NormalizeKey(name); if (text.Length > 0 && BiomeLockKeys.IsTrackedGlobalKey(text)) { BiomeLockPrivateKeys.ClientDistributeBossPrivateKey(text); } } } internal static class BiomeLock_KeyRefresh { private const float RefreshDelay = 0.05f; private static bool _pending; private static float _nextRunAt; internal static void NotifyKeysChanged() { _pending = true; float time = Time.time; if (_nextRunAt < time) { _nextRunAt = time + 0.05f; } } internal static void TryRunPending() { if (!_pending || Time.time < _nextRunAt) { return; } _pending = false; if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsDedicated()) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } try { BiomeLock_SE.ApplyOrRemove(localPlayer); localPlayer.UpdateKnownRecipesList(); localPlayer.UpdateAvailablePiecesList(); localPlayer.UpdateEvents(); if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.IsVisible()) { InventoryGui.instance.UpdateCraftingPanel(false); } if ((Object)(object)StoreGui.instance != (Object)null && StoreGui.IsVisible()) { StoreGui.instance.FillList(); } } catch (Exception ex) { BiomeLockPlugin.Log.LogError((object)("[KeyRefresh] " + ex)); } } } [HarmonyPatch(typeof(Hud), "Update")] internal static class BL_Hud_Update_Tick { private static void Postfix() { BiomeLock_KeyRefresh.TryRunPending(); BiomeLock_SE.UpdateBroadcast(); } } [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] internal static class BiomeLock_SE { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Player), "UpdateBiome")] private static class Player_UpdateBiome_ApplySE { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { float time = Time.time; if (!(time < _nextApplyTime)) { _nextApplyTime = time + 0.25f; ApplyOrRemove(__instance); } } } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Humanoid), "StartAttack")] private static class Humanoid_StartAttack_Block_All { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Humanoid __instance, ref bool __result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null) { return true; } if (!ShouldBlockAttack(val, ((Humanoid)val).GetCurrentWeapon())) { return true; } ShowThrottledMessage(val, "$biomelock_attack_blocked", ref _nextAttackBlockedMessageTime); __result = false; return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Humanoid), "IsBlocking")] private static class Humanoid_IsBlocking_Block_Parry { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Humanoid __instance, ref bool __result) { if (!BiomeLockPlugin.CE_SE_Block_AttackBlock.Value) { return true; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || !((Character)val).m_blocking) { return true; } if (!ShouldBlockAttack(val, ((Humanoid)val).GetCurrentBlocker())) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Attack), "OnAttackTrigger")] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Attack_OnAttackTrigger_Block_All { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Attack __instance) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)__instance.m_character != (Object)(object)localPlayer) { return true; } if (!ShouldBlockAttack(localPlayer, ((Humanoid)localPlayer).GetCurrentWeapon())) { return true; } ShowThrottledMessage(localPlayer, "$biomelock_attack_blocked", ref _nextAttackBlockedMessageTime); return false; } } [HarmonyPatch(typeof(Player), "UpdateAttackBowDraw")] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Player_UpdateAttackBowDraw_Block_Draw { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Player __instance, [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] ItemData weapon) { if (!ShouldBlockAttack(__instance, weapon)) { return true; } ((Humanoid)__instance).m_attackDrawTime = -1f; string text = weapon?.m_shared?.m_attack?.m_drawAnimationState; if (!string.IsNullOrEmpty(text)) { ((Character)__instance).m_zanim.SetBool(text, false); } return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class Player_UpdatePlacement_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Player __instance) { return !ShouldBlockBuildTool(__instance); } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Player), "PlacePiece")] private static class Player_PlacePiece_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Player __instance) { return BlockBuildToolWithMessage(__instance); } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Player), "Repair")] private static class Player_Repair_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Player __instance) { return BlockHammerWithMessage(__instance); } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Player), "RemovePiece")] private static class Player_RemovePiece_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Player __instance) { return BlockHammerWithMessage(__instance); } } [HarmonyPatch(typeof(Hud), "TogglePieceSelection")] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Hud_TogglePieceSelection_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Hud __instance) { if (!ShouldBlockBuildTool(Player.m_localPlayer)) { return true; } return (Object)(object)__instance != (Object)null && (Object)(object)__instance.m_pieceSelectionWindow != (Object)null && __instance.m_pieceSelectionWindow.activeSelf; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Teleport), "Interact")] private static class Teleport_Interact_BlockDungeon { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Teleport __instance, Humanoid character, bool hold) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!BiomeLockPlugin.CE_SE_Block_DungeonTeleport.Value || hold) { return true; } Player val = (Player)(object)((character is Player) ? character : null); if (val == null) { return true; } if (!ShouldBlockAtPosition(val, ((Component)__instance).transform.position)) { return true; } ShowMessage(val, "$biomelock_dungeon_blocked"); return false; } } [HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Player_UpdateStats_BiomeLockHealthDrain { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static void Postfix(Player __instance, float dt) { ApplyHealthDrain(__instance, dt); } } [HarmonyPatch(typeof(Container), "Interact")] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Container_Interact_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Container __instance, Humanoid character, bool hold, ref bool __result) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!BiomeLockPlugin.CE_SE_Block_ContainerInteract.Value || hold) { return true; } Player val = (Player)(object)((character is Player) ? character : null); if (val == null) { return true; } if (!ShouldBlockAtPosition(val, ((Component)__instance).transform.position)) { return true; } ShowThrottledMessage(val, "$biomelock_interact_blocked", ref _nextContainerInteractBlockedMessageTime); __result = false; return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Door), "Interact")] private static class Door_Interact_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Door __instance, Humanoid character, bool hold, ref bool __result) { if (!BiomeLockPlugin.CE_SE_Block_DoorInteract.Value || hold) { return true; } return !TryBlockDoor(__instance, character, ref __result); } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Door), "UseItem")] private static class Door_UseItem_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Door __instance, Humanoid user, ref bool __result) { if (!BiomeLockPlugin.CE_SE_Block_DoorInteract.Value) { return true; } return !TryBlockDoor(__instance, user, ref __result); } } [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(0)] [HarmonyPatch] private static class Interactable_Interact_Block { private static readonly Type[] InteractArgs = new Type[3] { typeof(Humanoid), typeof(bool), typeof(bool) }; private static bool IsTargetSignature(string first, string second) { if (first == "user") { return second == "hold" || second == "repeat"; } if (first == "character") { return second == "repeat"; } return false; } private static IEnumerable<MethodBase> TargetMethods() { Type[] types; try { types = typeof(Interactable).Assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { ReflectionTypeLoadException e = ex; types = e.Types ?? Array.Empty<Type>(); } HashSet<MethodBase> seen = new HashSet<MethodBase>(); Type[] array = types; foreach (Type t in array) { if (t == null || t.IsInterface || t.IsAbstract || !typeof(Interactable).IsAssignableFrom(t)) { continue; } MethodInfo m = t.GetMethod("Interact", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, InteractArgs, null); if (m == null || m.GetMethodBody() == null) { continue; } ParameterInfo[] ps = m.GetParameters(); if (IsTargetSignature(ps[0].Name, ps[1].Name)) { MethodBase declared = ((m.DeclaringType == t) ? m : m.DeclaringType.GetMethod("Interact", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, InteractArgs, null)); if (seen.Add(declared)) { yield return declared; } } } } private static bool Prefix(object __instance, Humanoid __0, ref bool __result) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((__0 is Player) ? __0 : null); if (val == null) { return true; } if (!IsInteractBlockEnabled(__instance)) { return true; } Component val2 = (Component)((__instance is Component) ? __instance : null); if (val2 != null && (Object)(object)val2 != (Object)null) { if (IsAllowedInteractableGO(val2.gameObject)) { return true; } if (!ShouldBlockAtPosition(val, val2.transform.position)) { return true; } } else if (!ShouldBlock(val)) { return true; } ShowThrottledMessage(val, "$biomelock_interact_blocked", ref _nextGenericInteractBlockedMessageTime); __result = false; return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Minimap), "UpdateExplore")] private static class Minimap_UpdateExplore_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Minimap __instance, Player player) { if (!BiomeLockPlugin.CE_SE_Block_MapExplore.Value) { return true; } if ((Object)(object)player == (Object)null || !ShouldBlock(player)) { return true; } __instance.m_exploreTimer = 0f; return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Minimap), "ShowPinNameInput")] private static class Minimap_ShowPinNameInput_Block_When_SE_Active { private static bool Prefix(Vector3 pos) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!BiomeLockPlugin.CE_SE_Block_MapPins.Value) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !ShouldBlockAtPosition(localPlayer, pos)) { return true; } ShowMessage(localPlayer, "$biomelock_map_pin_blocked"); return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(EnvMan), "SetEnv")] private static class EnvMan_SetEnv_RestrictedMist { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static void Postfix(EnvMan __instance) { BlendRestrictedMistFog(__instance); } } [HarmonyPatch(typeof(Player), "Update")] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Player_Update_RestrictedMist { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ApplyRestrictedMist(Time.deltaTime); } } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(SpawnSystem), "GetPlayersInZone")] private static class SpawnSystem_GetPlayersInZone_FilterRestrictedPlayers { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static void Postfix(List<Player> players) { if (!BiomeLockPlugin.CE_SE_Block_SpawnBlock.Value || players == null || players.Count == 0) { return; } for (int num = players.Count - 1; num >= 0; num--) { Player val = players[num]; if ((Object)(object)val != (Object)null && ShouldBlock(val)) { players.RemoveAt(num); } } } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Player), "IsPlayerInRange", new Type[] { typeof(Vector3), typeof(float) })] private static class Player_IsPlayerInRange_IgnoreRestrictedPlayers { private static bool Prefix(Vector3 point, float range, ref bool __result) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!BiomeLockPlugin.CE_SE_Block_SpawnBlock.Value) { return true; } if (!IsRestrictedLocalPlayer(Player.m_localPlayer)) { return true; } __result = false; foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer == (Object)null || ShouldBlockAtPosition(allPlayer, point) || !(Vector3.Distance(((Component)allPlayer).transform.position, point) < range)) { continue; } __result = true; break; } return false; } } [HarmonyPatch(typeof(Player), "IsPlayerInRange", new Type[] { typeof(Vector3), typeof(float), typeof(float) })] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Player_IsPlayerInRange_Noise_IgnoreRestrictedPlayers { private static bool Prefix(Vector3 point, float range, float minNoise, ref bool __result) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (!BiomeLockPlugin.CE_SE_Block_SpawnBlock.Value || !IsRestrictedLocalPlayer(Player.m_localPlayer)) { return true; } __result = false; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null) && !ShouldBlockAtPosition(allPlayer, point) && !(Vector3.Distance(((Component)allPlayer).transform.position, point) >= range)) { float noiseRange = ((Character)allPlayer).GetNoiseRange(); if (range <= noiseRange && noiseRange >= minNoise) { __result = true; break; } } } return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(EggHatch), "CheckSpawn")] private static class EggHatch_CheckSpawn_IgnoreRestrictedPlayers { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(EggHatch __instance) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (!BiomeLockPlugin.CE_SE_Block_SpawnBlock.Value || !IsRestrictedLocalPlayer(Player.m_localPlayer)) { return true; } if (!__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner()) { return false; } Vector3 position = ((Component)__instance).transform.position; Player val = null; float num = __instance.m_triggerDistance; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null) && !ShouldBlockAtPosition(allPlayer, position)) { float num2 = Vector3.Distance(((Component)allPlayer).transform.position, position); if (num2 < num) { num = num2; val = allPlayer; } } } if ((Object)(object)val != (Object)null && !((Character)val).InGhostMode()) { __instance.Hatch(); } return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Player), "AutoPickup")] private static class Player_AutoPickup_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Player __instance) { if (!BiomeLockPlugin.CE_SE_Block_AutoPickup.Value) { return true; } return !ShouldBlock(__instance); } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Humanoid), "Pickup")] private static class Humanoid_Pickup_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Humanoid __instance) { if (!BiomeLockPlugin.CE_SE_Block_Pickup.Value) { return true; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || !ShouldBlock(val)) { return true; } ShowThrottledMessage(val, "$biomelock_pickup_blocked", ref _nextPickupBlockedMessageTime); return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_RegisterSE { private static void Postfix() { EnsureSERegistered(); } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Vegvisir), "Interact")] private static class Vegvisir_Interact_Block_HildirMapTable { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Vegvisir __instance) { return !IsBlockedHildirMapTable(__instance); } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Vegvisir), "GetHoverText")] private static class Vegvisir_GetHoverText_Block_HildirMapTable { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Vegvisir __instance, ref string __result) { if (!IsBlockedHildirMapTable(__instance)) { return true; } __result = string.Empty; return false; } } [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] [HarmonyPatch(typeof(Vegvisir), "GetHoverName")] private static class Vegvisir_GetHoverName_Block_HildirMapTable { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Vegvisir __instance, ref string __result) { if (!IsBlockedHildirMapTable(__instance)) { return true; } __result = string.Empty; return false; } } [HarmonyPatch(typeof(Trader), "Interact", new Type[] { typeof(Humanoid), typeof(bool), typeof(bool) })] [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(0)] private static class Trader_Interact_Block { [<5a57d5fb-35e9-4f42-9b4f-0b78e262070e>NullableContext(1)] private static bool Prefix(Trader __instance, Humanoid character, bool hold) { if (!BiomeLockPlugin.CE_SE_Block_TraderInteract.Value) { return true; } if (hold) { return true; } if (BiomeLockPlugin.AdminBypassActive()) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)character != (Object)(object)localPlayer || (Object)(object)__instance == (Object)null) { return true; } if (!TryGetTraderRule(GetTraderPrefabName(__instance), out var requiredKey, out var blockedToken)) { return true; } if (BiomeLockKeys.HasProgressionKey(requiredKey)) { return true; } string text = Localization.instance.Localize(blockedToken); if (text.IndexOf('$') >= 0) { text = Localization.instance.Localize(text); } if ((Object)(object)MessageHud.instance != (Object)null && !string.IsNullOrEmpty(text)) { MessageHud.instance.ShowMessage((MessageType)2, ColorBlocked(text), 0, (Sprite)null, false, true); } return false; } } private const float ApplyInterval = 0.25f; private static readonly char[] BiomeSeparators = new char[6] { ',', ';', ' ', '\t', '\r', '\n' }; private static Biome _blockedBiomesCache = (Biome)0; private static string _blockedBiomesRaw = ""; private static float _nextApplyTime; private const string AttackBlockedToken = "$biomelock_attack_blocked"; private static float _nextAttackBlockedMessageTime; private static readonly HashSet<string> AttackBlacklistPrefabs = new HashSet<string>(); [<dbedd104-49d4-45b5-9930-e5d6d508bb9a>Nullable(2)] private static string _attackBlacklistSource; private const float MinBroadcastInterval = 2f; private static float _nextBroadcastTime; private static readonly string[] BroadcastTokens = new string[5] { "$bl_se_msg_1", "$bl_se_msg_2", "$bl_se_msg_3", "$bl_se_msg_4", "$bl_se_msg_5" }; private const string HammerBlockedToken = "$biomelock_hammer_blocked"; private const string TerrainHoeBlockedToken = "$biomelock_terrain_hoe_blocked"; private static float _nextHammerBlockedMessageTime; private const string DungeonBlockedToken = "$biomelock_dungeon_blocked"; private const float HealthDrainTick = 0.25f; private static float _healthDrainTimer; private static readonly HashSet<string> AllowedInteractables = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "TombStone", "ShipControlls", "Ladder", "Saddle", "Sadle", "Chair" }; private const string ContainerInteractBlockedToken = "$biomelock_interact_blocked"; private static float _nextContainerInteractBlockedMessageTime; private const string DoorInteractBlockedToken = "$biomelock_interact_blocked"; private static float _nextDoorInteractBlockedMessageTime; private const string