Please disclose if your mod was created primarily 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 Wonderland v1.0.5
plugins/Wonderland.dll
Decompiled 3 months 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.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using Wonderland.Subsystems.AutoSort; using Wonderland.Subsystems.Combat; using Wonderland.Subsystems.Common; using Wonderland.Subsystems.Environment; using Wonderland.Subsystems.Equipment; using Wonderland.Subsystems.Movement; using Wonderland.Subsystems.Server; using Wonderland.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Wonderlandd.Subsystems.Environment { public class ClockUI : MonoBehaviour { public Text timeText; public Text dayText; public Image dayNightIcon; public Sprite daySprite; public Sprite nightSprite; private void Update() { if (Object.op_Implicit((Object)(object)timeText) && Object.op_Implicit((Object)(object)dayText) && Object.op_Implicit((Object)(object)dayNightIcon)) { EnvSubsystem.UpdateCache(); float dayFraction = EnvSubsystem.GetDayFraction(); int day = EnvSubsystem.GetDay(); float num = dayFraction * 1440f; int num2 = Mathf.FloorToInt(num / 60f); int num3 = Mathf.FloorToInt(num % 60f); timeText.text = $"{num2:00}:{num3:00}"; dayText.text = $"Day {day}"; dayNightIcon.sprite = (EnvSubsystem.IsDaylight() ? daySprite : nightSprite); } } } public class CompassUI : MonoBehaviour { public RectTransform windArrow; public Text biomeText; public Text envText; private void Update() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) //IL_007a: 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: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)windArrow) && Object.op_Implicit((Object)(object)biomeText) && Object.op_Implicit((Object)(object)envText)) { EnvSubsystem.UpdateCache(); Vector3 windDir = EnvSubsystem.GetWindDir(); if (((Vector3)(ref windDir)).sqrMagnitude > 0.001f) { float num = Mathf.Atan2(windDir.x, windDir.z) * 57.29578f; ((Transform)windArrow).localRotation = Quaternion.Euler(0f, 0f, 0f - num); } Biome biome = EnvSubsystem.GetBiome(); biomeText.text = ((object)(Biome)(ref biome)).ToString(); string environmentName = EnvSubsystem.GetEnvironmentName(); envText.text = environmentName ?? ""; } } } public static class EnvSubsystem { private static float _cachedDayFraction; private static float _cachedWindIntensity; private static Vector3 _cachedWindDir; private static Vector3 _cachedSunDir; private static Biome _cachedBiome; private static string _cachedEnvName = "Unknown"; private static float _cacheTimer; private const float CacheInterval = 0.25f; public static void UpdateCache() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) EnvMan instance = EnvMan.instance; if (Object.op_Implicit((Object)(object)instance)) { _cacheTimer += Time.deltaTime; if (!(_cacheTimer < 0.25f)) { _cacheTimer = 0f; _cachedDayFraction = instance.GetDayFraction(); _cachedWindDir = instance.GetWindDir(); _cachedWindIntensity = instance.GetWindIntensity(); _cachedSunDir = instance.GetSunDirection(); _cachedBiome = instance.GetCurrentBiome(); _cachedEnvName = instance.GetCurrentEnvironment()?.m_name ?? "Unknown"; } } } public static float GetDayFraction() { return _cachedDayFraction; } public static int GetDay() { EnvMan instance = EnvMan.instance; if (instance == null) { return 0; } return instance.GetDay(); } public static bool IsDay() { return EnvMan.IsDay(); } public static bool IsNight() { return EnvMan.IsNight(); } public static bool IsAfternoon() { return EnvMan.IsAfternoon(); } public static bool IsDaylight() { return EnvMan.IsDaylight(); } public static bool IsCold() { return EnvMan.IsCold(); } public static bool IsFreezing() { return EnvMan.IsFreezing(); } public static bool IsWet() { return EnvMan.IsWet(); } public static Vector3 GetWindDir() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return _cachedWindDir; } public static float GetWindIntensity() { return _cachedWindIntensity; } public static Vector3 GetSunDir() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return _cachedSunDir; } public static Biome GetBiome() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return _cachedBiome; } public static string GetEnvironmentName() { return _cachedEnvName; } public static bool IsTimeSkipping() { EnvMan instance = EnvMan.instance; if (instance == null) { return false; } return instance.IsTimeSkipping(); } } } namespace Wonderlandd.Subsystems.Spawns { [HarmonyPatch(typeof(RandEventSystem), "GetPossibleRandomEvents")] public static class RaidSafety { private static void Postfix(ref List<KeyValuePair<RandomEvent, Vector3>> __result) { } } } namespace Wonderlandd.Subsystems.AutoSort { public static class AutoVacuum { private const string LightningVFX = "vfx_lightning"; public static void VacuumItems(Container container, float radius, string itemName) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) ZNetView nView = GetNView(container); if ((Object)(object)nView == (Object)null || !nView.IsOwner()) { return; } Inventory inventory = container.GetInventory(); if (inventory == null || !inventory.HaveItem(itemName, true)) { return; } Vector3 position = ((Component)container).transform.position; Collider[] array = Physics.OverlapSphere(position, radius); List<(ItemDrop, ItemData)> list = new List<(ItemDrop, ItemData)>(); Collider[] array2 = array; for (int i = 0; i < array2.Length; i++) { ItemDrop componentInParent = ((Component)array2[i]).GetComponentInParent<ItemDrop>(); if ((Object)(object)componentInParent == (Object)null) { continue; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { continue; } ItemData itemData = componentInParent.m_itemData; if (itemData != null && !(itemData.m_shared.m_name != itemName)) { ItemData val = itemData.Clone(); if (val != null) { list.Add((componentInParent, val)); } } } if (list.Count == 0) { return; } foreach (var item2 in list) { if (!inventory.CanAddItem(item2.Item2, -1)) { return; } } foreach (var item3 in list) { inventory.AddItem(item3.Item2); } foreach (var item4 in list) { ItemDrop item = item4.Item1; if (!((Object)(object)item == (Object)null)) { ZNetView component2 = ((Component)item).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && component2.IsValid()) { ZNetScene.instance.Destroy(((Component)item).gameObject); } else { Object.Destroy((Object)(object)((Component)item).gameObject); } } } SpawnVFX(position, "vfx_lightning"); } private static void SpawnVFX(Vector3 pos, string prefab) { //IL_0016: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); if ((Object)(object)prefab2 != (Object)null) { Object.Instantiate<GameObject>(prefab2, pos + Vector3.up * 0.5f, Quaternion.identity); } } private static ZNetView GetNView(Container c) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown return (ZNetView)AccessTools.Field(typeof(Container), "m_nview").GetValue(c); } } } namespace Wonderland { [BepInPlugin("com.ross.wonderland", "Wonderland", "1.0.5")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; private Harmony _harmony; internal static ConfigEntry<float> Combat_AttackStaminaMult; internal static ConfigEntry<float> Combat_AttackMoveSlowMult; internal static ConfigEntry<float> Combat_AttackTurnSlowMult; internal static ConfigEntry<float> Combat_BowDrawSpeedMult; internal static ConfigEntry<float> Combat_BowDrawStaminaMult; internal static ConfigEntry<float> Combat_DamageMult; internal static ConfigEntry<float> Combat_BackstabMult; internal static ConfigEntry<float> Combat_StaggerMult; internal static ConfigEntry<bool> Combat_EnableProjectileTweaks; internal static ConfigEntry<float> Combat_ProjectileVelocityMult; internal static ConfigEntry<float> Combat_ProjectileSpreadMult; internal static ConfigEntry<bool> Equip_OnlyEquippedStaysOnDeath; internal static ConfigEntry<bool> Food_Eternal; internal static ConfigEntry<bool> Food_EnableTweaks; internal static ConfigEntry<float> Food_HealthMult; internal static ConfigEntry<float> Food_StaminaMult; internal static ConfigEntry<float> Food_EitrMult; internal static ConfigEntry<int> Food_DefaultDuration; internal static ConfigEntry<bool> Food_EnableAutoEat; internal static ConfigEntry<float> Food_AutoEatStaminaThreshold; internal static ConfigEntry<bool> Stamina_EnableTweaks; internal static ConfigEntry<float> Stamina_RegenMult; internal static ConfigEntry<float> Stamina_UsageMult; internal static ConfigEntry<float> Stamina_RunDrainMult; internal static ConfigEntry<float> Stamina_SneakDrainMult; internal static ConfigEntry<float> Stamina_SwimDrainMult; internal static ConfigEntry<float> Stamina_DodgeCostMult; internal static ConfigEntry<float> BoatSpeedMultiplier; internal static ConfigEntry<float> Crafting_ChestScanRadius; internal static ConfigEntry<bool> Server_AutoReloadConfig; internal static ConfigEntry<int> Server_ConfigReloadIntervalSeconds; internal static ConfigEntry<bool> Debug_Enable; internal static ConfigEntry<bool> Smelter_InfiniteFuel; internal static ConfigEntry<bool> Furnace_InfiniteFuel; internal static ConfigEntry<bool> Refinery_InfiniteFuel; internal static ConfigEntry<int> Smelter_MaxOre; internal static ConfigEntry<int> Smelter_MaxFuel; internal static ConfigEntry<int> Furnace_MaxOre; internal static ConfigEntry<int> Furnace_MaxFuel; internal static ConfigEntry<float> Smelter_SmeltTimeMult; internal static ConfigEntry<float> Smelter_ChestScanRadius; internal static ConfigEntry<bool> Smelter_LeaveOneOreInChest; internal static ConfigEntry<bool> Smelter_AutoFuel; internal static ConfigEntry<bool> Smelter_AutoOre; internal static ConfigEntry<float> Smelter_SearchRadius; internal static ConfigEntry<int> Smelter_TargetFuel; internal static ConfigEntry<int> Smelter_TargetOre; internal static ConfigEntry<float> Smelter_TimeMultiplier; internal static ConfigEntry<bool> InfiniteProduction_AllSmelters; internal static ConfigEntry<bool> Fireplace_InfiniteFuel; internal static ConfigEntry<bool> Beehive_InfiniteProduction; internal static ConfigEntry<bool> Windmill_InfiniteProduction; internal static ConfigEntry<bool> SpinningWheel_InfiniteProduction; internal static ConfigEntry<bool> Beehive_AllowAnyBiome; internal static ConfigEntry<float> Beehive_TimeMultiplier; internal static ConfigEntry<float> SpawnSafety_SearchRadius; internal static ConfigEntry<float> SpawnSafety_HazardRadius; internal static ConfigEntry<float> SpawnSafety_EnemyCheckRadius; private void Awake() { //IL_07e3: Unknown result type (might be due to invalid IL or missing references) //IL_07ed: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Wonderland initializing..."); Combat_AttackStaminaMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "AttackStaminaMult", 1f, "Multiplier for stamina cost of all attacks."); Combat_AttackMoveSlowMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "AttackMoveSlowMult", 0.5f, "Movement slowdown multiplier during attacks."); Combat_AttackTurnSlowMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "AttackTurnSlowMult", 1f, "Rotation slowdown multiplier during attacks."); Combat_BowDrawSpeedMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "BowDrawSpeedMult", 0.4f, "Bow draw speed multiplier."); Combat_BowDrawStaminaMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "BowDrawStaminaMult", 1f, "Bow draw stamina drain multiplier."); Combat_DamageMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "DamageMult", 1f, "Global damage multiplier."); Combat_BackstabMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "BackstabMult", 1f, "Backstab damage multiplier."); Combat_StaggerMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "StaggerMult", 1f, "Stagger damage multiplier."); Combat_EnableProjectileTweaks = ((BaseUnityPlugin)this).Config.Bind<bool>("Combat", "EnableProjectileTweaks", true, "Enable projectile tweaks."); Combat_ProjectileVelocityMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "ProjectileVelocityMult", 3f, "Projectile speed multiplier."); Combat_ProjectileSpreadMult = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "ProjectileSpreadMult", 1f, "Projectile spread multiplier."); Equip_OnlyEquippedStaysOnDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("Equipment", "OnlyEquippedStaysOnDeath", true, "Only equipped items remain on death."); Food_Eternal = ((BaseUnityPlugin)this).Config.Bind<bool>("Food", "Eternal", false, "Food never expires."); Food_EnableTweaks = ((BaseUnityPlugin)this).Config.Bind<bool>("Food", "EnableTweaks", true, "Enable food stat multipliers."); Food_HealthMult = ((BaseUnityPlugin)this).Config.Bind<float>("Food", "HealthMult", 1f, "Food health multiplier."); Food_StaminaMult = ((BaseUnityPlugin)this).Config.Bind<float>("Food", "StaminaMult", 1f, "Food stamina multiplier."); Food_EitrMult = ((BaseUnityPlugin)this).Config.Bind<float>("Food", "EitrMult", 1f, "Food eitr multiplier."); Food_DefaultDuration = ((BaseUnityPlugin)this).Config.Bind<int>("Food", "DefaultDuration", 1200, "Default food duration in seconds."); Food_EnableAutoEat = ((BaseUnityPlugin)this).Config.Bind<bool>("Food", "EnableAutoEat", false, "Automatically eat food when stamina is low."); Food_AutoEatStaminaThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Food", "AutoEatStaminaThreshold", 0.3f, "Stamina threshold for auto-eating."); Stamina_EnableTweaks = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "EnableTweaks", true, "Enable stamina tweaks."); Stamina_RegenMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "RegenMult", 1f, "Stamina regeneration multiplier."); Stamina_UsageMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "UsageMult", 1f, "Stamina usage multiplier."); Stamina_RunDrainMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "RunDrainMult", 1f, "Running stamina drain multiplier."); Stamina_SneakDrainMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "SneakDrainMult", 1f, "Sneaking stamina drain multiplier."); Stamina_SwimDrainMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "SwimDrainMult", 0f, "Swimming stamina drain multiplier."); Stamina_DodgeCostMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "DodgeCostMult", 1f, "Dodge stamina cost multiplier."); BoatSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Sailing", "BoatSpeedMultiplier", 4f, "Boat speed multiplier."); Crafting_ChestScanRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Crafting", "ChestScanRadius", 15f, "Radius for scanning chests for crafting materials."); Server_AutoReloadConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Server", "AutoReloadConfig", true, "Automatically reload config."); Server_ConfigReloadIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Server", "ConfigReloadIntervalSeconds", 10, "Seconds between config reload checks."); Debug_Enable = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enable", false, "Enable debug logging and optional global method logger."); Smelter_InfiniteFuel = ((BaseUnityPlugin)this).Config.Bind<bool>("Smelter", "Smelter_InfiniteFuel", true, "Infinite fuel for smelters."); Furnace_InfiniteFuel = ((BaseUnityPlugin)this).Config.Bind<bool>("Smelter", "Furnace_InfiniteFuel", true, "Infinite fuel for furnaces."); Refinery_InfiniteFuel = ((BaseUnityPlugin)this).Config.Bind<bool>("Smelter", "Refinery_InfiniteFuel", true, "Infinite fuel for refineries."); Smelter_MaxOre = ((BaseUnityPlugin)this).Config.Bind<int>("Smelter", "Smelter_MaxOre", 50, "Max ore capacity for smelters."); Smelter_MaxFuel = ((BaseUnityPlugin)this).Config.Bind<int>("Smelter", "Smelter_MaxFuel", 50, "Max fuel capacity for smelters."); Furnace_MaxOre = ((BaseUnityPlugin)this).Config.Bind<int>("Smelter", "Furnace_MaxOre", 50, "Max ore capacity for furnaces."); Furnace_MaxFuel = ((BaseUnityPlugin)this).Config.Bind<int>("Smelter", "Furnace_MaxFuel", 50, "Max fuel capacity for furnaces."); Smelter_SmeltTimeMult = ((BaseUnityPlugin)this).Config.Bind<float>("Smelter", "SmeltTimeMult", 0.5f, "Smelting time multiplier."); Smelter_ChestScanRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Smelter", "Smelter_ChestScanRadius", 10f, "Radius for scanning chests for smelter input."); Smelter_LeaveOneOreInChest = ((BaseUnityPlugin)this).Config.Bind<bool>("Smelter", "Smelter_LeaveOneOreInChest", true, "Leave one ore in chest to prevent emptying."); Smelter_AutoFuel = ((BaseUnityPlugin)this).Config.Bind<bool>("SmelterAutomation", "Smelter_AutoFuel", true, "Automatically add fuel from nearby chests."); Smelter_AutoOre = ((BaseUnityPlugin)this).Config.Bind<bool>("SmelterAutomation", "Smelter_AutoOre", true, "Automatically add ore from nearby chests."); Smelter_SearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("SmelterAutomation", "Smelter_SearchRadius", 10f, "Radius for scanning chests around smelters."); Smelter_TargetFuel = ((BaseUnityPlugin)this).Config.Bind<int>("SmelterAutomation", "Smelter_TargetFuel", 10, "Desired fuel level to maintain."); Smelter_TargetOre = ((BaseUnityPlugin)this).Config.Bind<int>("SmelterAutomation", "Smelter_TargetOre", 10, "Desired ore queue size to maintain."); Smelter_TimeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("SmelterAutomation", "Smelter_TimeMultiplier", 1f, "Global smelter processing speed multiplier."); InfiniteProduction_AllSmelters = ((BaseUnityPlugin)this).Config.Bind<bool>("SmelterAutomation", "InfiniteProduction_AllSmelters", false, "Make all smelter-based buildings process instantly with infinite fuel."); Fireplace_InfiniteFuel = ((BaseUnityPlugin)this).Config.Bind<bool>("Environment", "Fireplace_InfiniteFuel", true, "Infinite fireplace fuel."); Beehive_InfiniteProduction = ((BaseUnityPlugin)this).Config.Bind<bool>("Environment", "Beehive_InfiniteProduction", true, "Infinite beehive production."); Windmill_InfiniteProduction = ((BaseUnityPlugin)this).Config.Bind<bool>("Environment", "Windmill_InfiniteProduction", true, "Infinite windmill production."); SpinningWheel_InfiniteProduction = ((BaseUnityPlugin)this).Config.Bind<bool>("Environment", "SpinningWheel_InfiniteProduction", true, "Infinite spinning wheel production."); Beehive_AllowAnyBiome = ((BaseUnityPlugin)this).Config.Bind<bool>("Environment", "Beehive_AllowAnyBiome", true, "Allow beehives to produce in any biome."); Beehive_TimeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Environment", "Beehive_TimeMultiplier", 1f, "Beehive production speed multiplier."); SpawnSafety_SearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("SpawnSafety", "SearchRadius", 20f, "Radius to search for safe spawn points."); SpawnSafety_HazardRadius = ((BaseUnityPlugin)this).Config.Bind<float>("SpawnSafety", "HazardRadius", 10f, "Radius to detect hazards near spawn."); SpawnSafety_EnemyCheckRadius = ((BaseUnityPlugin)this).Config.Bind<float>("SpawnSafety", "EnemyCheckRadius", 20f, "Radius to check for enemies near spawn."); _harmony = new Harmony("com.ross.wonderland"); try { HarmonyPatcher.PatchAllSafe(_harmony, Assembly.GetExecutingAssembly()); Log.LogInfo((object)"Harmony attribute patches applied (safe)."); } catch (Exception arg) { Log.LogWarning((object)$"PatchAllSafe failed: {arg}"); } Patch_StaminaTweaks(); Patch_EquipmentTweaks(); Patch_SanctuaryZones(); Patch_DamageTweaks(); if (Debug_Enable.Value) { try { FilteredGlobalMethodLogger.Enable(); Log.LogInfo((object)"FilteredGlobalMethodLogger enabled (debug logging ON)."); } catch (Exception arg2) { Log.LogError((object)$"Failed to enable FilteredGlobalMethodLogger: {arg2}"); } } else { Log.LogInfo((object)"FilteredGlobalMethodLogger is disabled by config (recommended for release builds)."); } Log.LogInfo((object)"Wonderland loaded successfully."); } private void Patch_StaminaTweaks() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown try { Type typeFromHandle = typeof(StaminaAndMovementTweaks); MethodInfo method = typeFromHandle.GetMethod("UpdateStats_Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { int num = HarmonyPatcher.PatchAllOverloads(postfix: new HarmonyMethod(method), harmony: _harmony, targetType: AccessTools.TypeByName("Player"), methodName: "UpdateStats"); Log.LogInfo((object)$"[Stamina] Patched {num} overload(s) of Player.UpdateStats."); } MethodInfo method2 = typeFromHandle.GetMethod("UseStamina_Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method2 != null) { HarmonyMethod prefix = new HarmonyMethod(method2); bool flag = HarmonyPatcher.PatchSpecificOverload(_harmony, AccessTools.TypeByName("Player"), "UseStamina", new Type[1] { typeof(float) }, prefix); Log.LogInfo((object)$"[Stamina] Patched Player.UseStamina(float): {flag}"); } } catch (Exception arg) { Log.LogWarning((object)$"[Stamina] Error applying stamina patches: {arg}"); } } private void Patch_EquipmentTweaks() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown try { MethodInfo method = typeof(EquipmentTweaks).GetMethod("CreateTombstone_Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { HarmonyMethod prefix = new HarmonyMethod(method); bool flag = HarmonyPatcher.PatchSpecificOverload(_harmony, AccessTools.TypeByName("Player"), "CreateTombStone", Type.EmptyTypes, prefix); Log.LogInfo((object)$"[Equipment] Patched Player.CreateTombStone(): {flag}"); } } catch (Exception arg) { Log.LogWarning((object)$"[Equipment] Error applying equipment patches: {arg}"); } } private void Patch_SanctuaryZones() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Expected O, but got Unknown try { Type typeFromHandle = typeof(SanctuaryZones); MethodInfo method = typeFromHandle.GetMethod("BlockDamage_Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { HarmonyMethod prefix = new HarmonyMethod(method); bool flag = HarmonyPatcher.PatchSpecificOverload(_harmony, AccessTools.TypeByName("Character"), "Damage", new Type[1] { typeof(HitData) }, prefix); Log.LogInfo((object)$"[Sanctuary] Patched Character.Damage(HitData): {flag}"); } MethodInfo method2 = typeFromHandle.GetMethod("BlockStamina_Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method2 != null) { HarmonyMethod prefix2 = new HarmonyMethod(method2); bool flag2 = HarmonyPatcher.PatchSpecificOverload(_harmony, AccessTools.TypeByName("Player"), "UseStamina", new Type[1] { typeof(float) }, prefix2); Log.LogInfo((object)$"[Sanctuary] Patched Player.UseStamina(float): {flag2}"); } MethodInfo method3 = typeFromHandle.GetMethod("BlockSkillLoss_Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method3 != null) { HarmonyMethod prefix3 = new HarmonyMethod(method3); bool flag3 = HarmonyPatcher.PatchSpecificOverload(_harmony, AccessTools.TypeByName("Skills"), "OnDeath", Type.EmptyTypes, prefix3); Log.LogInfo((object)$"[Sanctuary] Patched Skills.OnDeath(): {flag3}"); } MethodInfo method4 = typeFromHandle.GetMethod("BlockAggroVision_Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method4 != null) { HarmonyMethod postfix = new HarmonyMethod(method4); int num = HarmonyPatcher.PatchAllOverloads(_harmony, AccessTools.TypeByName("BaseAI"), "CanSeeTarget", null, postfix); Log.LogInfo((object)$"[Sanctuary] Patched {num} overload(s) of BaseAI.CanSeeTarget."); } MethodInfo method5 = typeFromHandle.GetMethod("BlockAggroHearing_Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method5 != null) { HarmonyMethod postfix2 = new HarmonyMethod(method5); int num2 = HarmonyPatcher.PatchAllOverloads(_harmony, AccessTools.TypeByName("BaseAI"), "CanHearTarget", null, postfix2); Log.LogInfo((object)$"[Sanctuary] Patched {num2} overload(s) of BaseAI.CanHearTarget."); } MethodInfo method6 = typeFromHandle.GetMethod("BlockProjectiles_Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method6 != null) { HarmonyMethod prefix4 = new HarmonyMethod(method6); bool flag4 = HarmonyPatcher.PatchSpecificOverload(_harmony, AccessTools.TypeByName("Projectile"), "UpdateProjectile", Type.EmptyTypes, prefix4); Log.LogInfo((object)$"[Sanctuary] Patched Projectile.UpdateProjectile(): {flag4}"); } } catch (Exception arg) { Log.LogWarning((object)$"[Sanctuary] Error applying sanctuary patches: {arg}"); } } private void Patch_DamageTweaks() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown try { Type typeFromHandle = typeof(DamageTweaks); MethodInfo method = typeFromHandle.GetMethod("ApplyArmor_Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { HarmonyMethod postfix = new HarmonyMethod(method); bool flag = HarmonyPatcher.PatchSpecificOverload(_harmony, AccessTools.TypeByName("HitData"), "ApplyArmor", new Type[1] { typeof(float) }, null, postfix); Log.LogInfo((object)$"[Damage] Patched HitData.ApplyArmor(float): {flag}"); } MethodInfo method2 = typeFromHandle.GetMethod("ApplyDamage_Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method2 != null) { HarmonyMethod prefix = new HarmonyMethod(method2); int num = HarmonyPatcher.PatchAllOverloads(_harmony, AccessTools.TypeByName("Character"), "ApplyDamage", prefix); Log.LogInfo((object)$"[Damage] Patched {num} overload(s) of Character.ApplyDamage."); } } catch (Exception arg) { Log.LogWarning((object)$"[Damage] Error applying damage patches: {arg}"); } } private void OnDestroy() { try { FilteredGlobalMethodLogger.Disable(); } catch (Exception arg) { Log.LogWarning((object)$"Error while disabling FilteredGlobalMethodLogger: {arg}"); } try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Log.LogInfo((object)"Harmony instance unpatched (UnpatchSelf)."); } catch (Exception arg2) { Log.LogWarning((object)$"Error while unpatching Harmony: {arg2}"); } Log.LogInfo((object)"Wonderland unloaded."); } private void Update() { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { try { ConfigAutoReload.Update(); } catch (Exception arg) { Log.LogWarning((object)$"Error in server periodic update: {arg}"); } } } private static void Player_UpdateStats_Prefix(object __instance) { try { ConfigEntry<bool> debug_Enable = Debug_Enable; if (debug_Enable != null && debug_Enable.Value) { Log.LogDebug((object)"[Patch] Player.UpdateStats prefix called."); } } catch { } } private static void Player_UpdateStats_Postfix(object __instance) { try { ConfigEntry<bool> debug_Enable = Debug_Enable; if (debug_Enable != null && debug_Enable.Value) { Log.LogDebug((object)"[Patch] Player.UpdateStats postfix called."); } } catch { } } } } namespace Wonderland.Subsystems.Safety { [HarmonyPatch] public static class SpawnSafety { private static readonly string[] ExactNames = new string[6] { "SpawnPlayer", "RespawnPlayer", "Spawn", "Respawn", "SpawnAtPoint", "SpawnPlayerAt" }; private static readonly string[] SubstringMatches = new string[2] { "Spawn", "Respawn" }; private const float DefaultSearchRadius = 20f; private const float DefaultHazardRadius = 10f; private const float DefaultEnemyCheckRadius = 20f; private const float MaxSafeSlopeDegrees = 35f; private const int SafePointSamples = 24; [HarmonyTargetMethods] public static MethodBase[] TargetMethods() { try { Type typeFromHandle = typeof(Player); if (typeFromHandle == null) { Plugin.Log.LogWarning((object)"[SpawnSafety] Player type not found; aborting spawn safety patch."); return Array.Empty<MethodBase>(); } MethodInfo[] array = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where(delegate(MethodInfo m) { if (ExactNames.Contains(m.Name)) { return true; } string[] substringMatches = SubstringMatches; foreach (string value in substringMatches) { if (m.Name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; }).ToArray(); if (array.Length == 0) { Plugin.Log.LogWarning((object)("[SpawnSafety] No Player spawn methods found. Tried names: " + string.Join(", ", ExactNames) + ". SpawnSafety will remain idle.")); } else { Plugin.Log.LogInfo((object)($"[SpawnSafety] Found {array.Length} Player spawn method(s): " + string.Join(", ", array.Select((MethodInfo m) => m.Name)))); } return array; } catch (Exception arg) { Plugin.Log.LogError((object)$"[SpawnSafety] TargetMethods failed: {arg}"); return Array.Empty<MethodBase>(); } } [HarmonyPostfix] public static void EnsureSafeSpawnPostfix(object __instance, MethodBase __originalMethod) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_00e5: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.SpawnSafety_SearchRadius == null || Plugin.SpawnSafety_HazardRadius == null || Plugin.SpawnSafety_EnemyCheckRadius == null) { return; } Player val = (Player)((__instance is Player) ? __instance : null); if (val == null) { return; } float num = Plugin.SpawnSafety_SearchRadius?.Value ?? 20f; float hazardRadius = Plugin.SpawnSafety_HazardRadius?.Value ?? 10f; float radius = Plugin.SpawnSafety_EnemyCheckRadius?.Value ?? 20f; Vector3 position = ((Component)val).transform.position; bool flag = Plugin.Debug_Enable?.Value ?? false; if (flag) { Plugin.Log.LogDebug((object)$"[SpawnSafety] Postfix intercepted {__originalMethod.DeclaringType?.Name}.{__originalMethod.Name} for player '{GetPlayerNameSafe(val)}' at {position}."); } bool flag2 = HasNearbyHostileCharacters(position, radius, val); bool flag3 = IsGroundTooSteep(position, 35f); if (!(flag2 || flag3)) { return; } if (flag) { Plugin.Log.LogInfo((object)$"[SpawnSafety] Unsafe spawn detected (enemies: {flag2}, steep: {flag3}). Searching for safe point within {num}m."); } Vector3? val2 = FindNearestSafePoint(position, num, hazardRadius, 35f, val); if (val2.HasValue) { Vector3 value = val2.Value; TryMovePlayerTo(val, value); if (flag) { Plugin.Log.LogInfo((object)$"[SpawnSafety] Moved player '{GetPlayerNameSafe(val)}' to safe position {value}."); } } else { Plugin.Log.LogWarning((object)$"[SpawnSafety] No safe spawn point found within {num}m for player '{GetPlayerNameSafe(val)}'. Leaving original spawn."); } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[SpawnSafety] Postfix threw an exception: {arg}"); } } private static string GetPlayerNameSafe(Player player) { try { MethodInfo method = ((object)player).GetType().GetMethod("GetPlayerName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null && method.Invoke(player, null) is string text && !string.IsNullOrEmpty(text)) { return text; } } catch { } return ((Object)player).name ?? "<player>"; } private static bool HasNearbyHostileCharacters(Vector3 center, float radius, Player player) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) try { Character[] array = Object.FindObjectsOfType<Character>(); foreach (Character val in array) { if ((Object)(object)val == (Object)null || val is Player) { continue; } bool flag = false; try { PropertyInfo property = ((object)val).GetType().GetProperty("IsTamed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(bool)) { flag = (bool)property.GetValue(val); } else { FieldInfo field = ((object)val).GetType().GetField("m_tamed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(bool)) { flag = (bool)field.GetValue(val); } } } catch { } if (flag || !(Vector3.Distance(center, ((Component)val).transform.position) <= radius)) { continue; } try { FieldInfo field2 = ((object)val).GetType().GetField("m_health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null) { object value = field2.GetValue(val); if (value is float) { float num = (float)value; if (num <= 0f) { continue; } } } } catch { } return true; } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[SpawnSafety] HasNearbyHostileCharacters error: {arg}"); } return false; } private static bool IsGroundTooSteep(Vector3 pos, float maxDegrees) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) try { RaycastHit val = default(RaycastHit); if (Physics.Raycast(pos + Vector3.up * 1.5f, Vector3.down, ref val, 5f, -1, (QueryTriggerInteraction)1)) { return Vector3.Angle(((RaycastHit)(ref val)).normal, Vector3.up) > maxDegrees; } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[SpawnSafety] IsGroundTooSteep error: {arg}"); } return false; } private static Vector3? FindNearestSafePoint(Vector3 origin, float searchRadius, float hazardRadius, float maxSlopeDegrees, Player player) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //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_0085: 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_0094: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) try { if (!HasNearbyHostileCharacters(origin, hazardRadius, player) && !IsGroundTooSteep(origin, maxSlopeDegrees)) { return origin; } int num = Mathf.Max(1, Mathf.CeilToInt(searchRadius / 2f)); RaycastHit val = default(RaycastHit); for (int i = 1; i <= num; i++) { float num2 = (float)i * searchRadius / (float)num; for (int j = 0; j < 24; j++) { float num3 = (float)j / 24f * (float)Math.PI * 2f; if (Physics.Raycast(origin + new Vector3(Mathf.Cos(num3), 0f, Mathf.Sin(num3)) * num2 + Vector3.up * 10f, Vector3.down, ref val, 30f, -1, (QueryTriggerInteraction)1)) { Vector3 point = ((RaycastHit)(ref val)).point; if (!IsGroundTooSteep(point, maxSlopeDegrees) && !HasNearbyHostileCharacters(point, hazardRadius, player)) { return point + Vector3.up * 0.5f; } } } } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[SpawnSafety] FindNearestSafePoint error: {arg}"); } return null; } private static void TryMovePlayerTo(Player player, Vector3 target) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) try { Rigidbody component = ((Component)player).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.velocity = Vector3.zero; component.angularVelocity = Vector3.zero; } ((Component)player).transform.position = target; try { MethodInfo method = ((object)player).GetType().GetMethod("TeleportTo", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(Vector3)) { method.Invoke(player, new object[1] { target }); } else if (parameters.Length == 2 && parameters[0].ParameterType == typeof(Vector3) && parameters[1].ParameterType == typeof(Quaternion)) { method.Invoke(player, new object[2] { target, Quaternion.identity }); } } } catch { } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[SpawnSafety] TryMovePlayerTo error: {arg}"); } } } } namespace Wonderland.Subsystems.Smelter { [HarmonyPatch] public static class SmelterAutomation { [HarmonyPatch(typeof(Smelter), "UpdateSmelter")] [HarmonyPostfix] public static void AutomateSmelter(Smelter __instance) { if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner()) { return; } try { if (Plugin.Smelter_AutoFuel.Value) { TryAutoFuel(__instance); } if (Plugin.Smelter_AutoOre.Value) { TryAutoOre(__instance); } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"SmelterAutomation: exception {arg}"); } } private static void TryAutoFuel(Smelter smelter) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) float fuel = smelter.GetFuel(); int maxFuel = smelter.m_maxFuel; if (maxFuel <= 0) { return; } int num = Mathf.Clamp(Plugin.Smelter_TargetFuel.Value, 0, maxFuel); if (fuel >= (float)num) { return; } int num2 = Mathf.CeilToInt((float)num - fuel); if (num2 <= 0 || (Object)(object)Player.m_localPlayer == (Object)null) { return; } string name = smelter.m_fuelItem.m_itemData.m_shared.m_name; List<Inventory> list = FindNearbyInventories(((Component)smelter).transform.position); List<SafeItemTransaction.ItemRequest> list2 = new List<SafeItemTransaction.ItemRequest>(); foreach (Inventory item in list) { if (num2 <= 0) { break; } int num3 = CountAvailable(item, name); if (num3 > 0) { int num4 = Mathf.Min(num3, num2); list2.Add(new SafeItemTransaction.ItemRequest { Source = item, Target = null, SharedName = name, Amount = num4 }); num2 -= num4; } } if (list2.Count != 0 && SafeItemTransaction.Execute(list2, delegate(string msg) { Plugin.Log.LogDebug((object)msg); })) { int num5 = list2.Sum((SafeItemTransaction.ItemRequest r) => r.Amount); float num6 = fuel + (float)num5; if (num6 > (float)maxFuel) { num6 = maxFuel; } smelter.SetFuel(num6); smelter.m_fuelAddedEffects.Create(((Component)smelter).transform.position, ((Component)smelter).transform.rotation, ((Component)smelter).transform, 1f, -1); } } private static void TryAutoOre(Smelter smelter) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) int queueSize = smelter.GetQueueSize(); int maxOre = smelter.m_maxOre; if (maxOre <= 0) { return; } int num = Mathf.Clamp(Plugin.Smelter_TargetOre.Value, 0, maxOre); if (queueSize >= num) { return; } int num2 = num - queueSize; if (num2 <= 0 || (Object)(object)Player.m_localPlayer == (Object)null) { return; } List<string> list = new List<string>(); foreach (ItemConversion item in smelter.m_conversion) { if (item?.m_from?.m_itemData?.m_shared != null) { string name = item.m_from.m_itemData.m_shared.m_name; if (!string.IsNullOrEmpty(name) && !list.Contains(name)) { list.Add(name); } } } if (list.Count == 0) { return; } List<Inventory> list2 = FindNearbyInventories(((Component)smelter).transform.position); List<SafeItemTransaction.ItemRequest> list3 = new List<SafeItemTransaction.ItemRequest>(); Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (Inventory item2 in list2) { if (num2 <= 0) { break; } foreach (string item3 in list) { if (num2 <= 0) { break; } int num3 = CountAvailable(item2, item3); if (num3 > 0) { int num4 = Mathf.Min(num3, num2); list3.Add(new SafeItemTransaction.ItemRequest { Source = item2, Target = null, SharedName = item3, Amount = num4 }); if (!dictionary.ContainsKey(item3)) { dictionary[item3] = 0; } dictionary[item3] += num4; num2 -= num4; } } } if (list3.Count == 0 || !SafeItemTransaction.Execute(list3, delegate(string msg) { Plugin.Log.LogDebug((object)msg); })) { return; } int num5 = queueSize; foreach (KeyValuePair<string, int> item4 in dictionary) { string key = item4.Key; int value = item4.Value; ItemConversion val = FindConversionBySharedName(smelter, key); if (val == null) { Plugin.Log.LogWarning((object)("SmelterAutomation: no conversion found for " + key)); continue; } string name2 = ((Object)((Component)val.m_from).gameObject).name; for (int i = 0; i < value; i++) { if (num5 >= maxOre) { break; } smelter.QueueOre(name2); num5++; } } smelter.m_oreAddedEffects.Create(((Component)smelter).transform.position, ((Component)smelter).transform.rotation, (Transform)null, 1f, -1); } private static List<Inventory> FindNearbyInventories(Vector3 center) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) float value = Plugin.Smelter_SearchRadius.Value; List<Inventory> list = new List<Inventory>(); Container[] array = Object.FindObjectsOfType<Container>(); foreach (Container val in array) { if (!((Object)(object)val == (Object)null) && val.m_inventory != null && !(Vector3.Distance(center, ((Component)val).transform.position) > value)) { list.Add(val.m_inventory); } } return list; } private static int CountAvailable(Inventory inv, string sharedName) { if (inv == null || string.IsNullOrEmpty(sharedName)) { return 0; } int num = 0; foreach (ItemData allItem in inv.GetAllItems()) { if (allItem.m_shared.m_name == sharedName) { num += allItem.m_stack; } } return num; } private static ItemConversion FindConversionBySharedName(Smelter smelter, string sharedName) { foreach (ItemConversion item in smelter.m_conversion) { if (item?.m_from?.m_itemData?.m_shared != null && item.m_from.m_itemData.m_shared.m_name == sharedName) { return item; } } return null; } } } namespace Wonderland.Subsystems.Server { public static class ConfigAutoReload { private static float _timer; public static void Update() { if (!Plugin.Server_AutoReloadConfig.Value || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } _timer += Time.deltaTime; if (_timer < (float)Plugin.Server_ConfigReloadIntervalSeconds.Value) { return; } _timer = 0f; try { BaseUnityPlugin val = null; BaseUnityPlugin[] array = Object.FindObjectsOfType<BaseUnityPlugin>(); for (int i = 0; i < array.Length; i++) { if (array[i] is Plugin plugin) { val = (BaseUnityPlugin)(object)plugin; break; } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[ServerConfig] Could not find Plugin instance to reload config."); return; } val.Config.Reload(); Plugin.Log.LogInfo((object)"[ServerConfig] Reloaded configuration from disk."); } catch (Exception arg) { Plugin.Log.LogError((object)$"[ServerConfig] Failed to reload config: {arg}"); } } } } namespace Wonderland.Subsystems.Sailing { [HarmonyPatch(typeof(Ship))] public static class SailingSpeed { [HarmonyPatch("GetSailForce")] [HarmonyPostfix] public static void ScaleSailForce(ref Vector3 __result) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) float value = Plugin.BoatSpeedMultiplier.Value; if (!Mathf.Approximately(value, 1f)) { __result *= value; } } } } namespace Wonderland.Subsystems.Movement { public static class StaminaAndMovementTweaks { internal static void UpdateStats_Postfix(Player __instance) { if (Plugin.Stamina_EnableTweaks.Value) { __instance.m_staminaRegen *= Plugin.Stamina_RegenMult.Value; __instance.m_runStaminaDrain *= Plugin.Stamina_RunDrainMult.Value; __instance.m_sneakStaminaDrain *= Plugin.Stamina_SneakDrainMult.Value; __instance.m_swimStaminaDrainMinSkill *= Plugin.Stamina_SwimDrainMult.Value; __instance.m_swimStaminaDrainMaxSkill *= Plugin.Stamina_SwimDrainMult.Value; } } internal static void UseStamina_Prefix(Player __instance, ref float v) { if (Plugin.Stamina_EnableTweaks.Value) { v *= Plugin.Stamina_UsageMult.Value; if (((Character)__instance).InDodge()) { v *= Plugin.Stamina_DodgeCostMult.Value; } } } } } namespace Wonderland.Subsystems.Food { [HarmonyPatch(typeof(Player), "UpdateFood")] public static class EternalFood { [HarmonyPrefix] public static void KeepFoodAtFullStrength(Player __instance, float dt, bool forceUpdate) { if (!Plugin.Food_Eternal.Value) { return; } List<Food> foods = __instance.GetFoods(); if (foods == null) { return; } foreach (Food item in foods) { if (item.m_time > 0f) { item.m_health = item.m_item.m_shared.m_food; item.m_stamina = item.m_item.m_shared.m_foodStamina; item.m_eitr = item.m_item.m_shared.m_foodEitr; } } } } [HarmonyPatch] public static class FoodSystem { private class ActiveFood { public float health; public float stamina; public float eitr; public float expireTime; } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] public static class Patch_GetTotalFoodValue { [HarmonyPostfix] public static void Postfix(Player __instance, ref float hp, ref float stamina, ref float eitr) { long playerId = GetPlayerId(__instance); if (playerId == 0L || !s_food.TryGetValue(playerId, out var value) || value.Count == 0) { return; } float time = Time.time; bool flag = false; for (int num = value.Count - 1; num >= 0; num--) { if (value[num].expireTime <= time) { value.RemoveAt(num); flag = true; } } if (value.Count == 0) { if (flag) { s_food.Remove(playerId); } return; } float num2 = 0f; float num3 = 0f; float num4 = 0f; foreach (ActiveFood item in value) { num2 += item.health; num3 += item.stamina; num4 += item.eitr; } hp = Mathf.Max(hp, __instance.m_baseHP + num2); stamina = Mathf.Max(stamina, __instance.m_baseStamina + num3); eitr = Mathf.Max(eitr, num4); } } [HarmonyPatch(typeof(Player), "Update")] public static class Patch_Player_Update { [HarmonyPostfix] public static void Postfix(Player __instance) { if (!((Object)(object)__instance == (Object)null) && Plugin.Food_EnableAutoEat.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !(__instance.GetStamina() > Plugin.Food_AutoEatStaminaThreshold.Value)) { TryAutoEat(__instance); } } } private static readonly Dictionary<long, List<ActiveFood>> s_food = new Dictionary<long, List<ActiveFood>>(); private static long GetPlayerId(Player p) { if (p == null) { return 0L; } return p.GetPlayerID(); } [HarmonyPatch(typeof(Player), "EatFood")] [HarmonyPostfix] public static void EatFood_Postfix(Player __instance, ItemData item, bool __result) { if (!__result || (Object)(object)__instance == (Object)null || item == null) { return; } long playerId = GetPlayerId(__instance); if (playerId != 0L) { float num = item.m_shared.m_foodBurnTime; if (num <= 0f) { num = Plugin.Food_DefaultDuration.Value; } ActiveFood item2 = new ActiveFood { health = item.m_shared.m_food, stamina = item.m_shared.m_foodStamina, eitr = item.m_shared.m_foodEitr, expireTime = Time.time + num }; if (!s_food.TryGetValue(playerId, out var value)) { value = new List<ActiveFood>(); s_food[playerId] = value; } value.Add(item2); } } private static void TryAutoEat(Player player) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } ItemData val = FindBestFood(inventory); if (val != null) { ConsumeFood(player, inventory, val); return; } string text = FindBestFoodNameNearby(player); if (!string.IsNullOrEmpty(text) && CraftingFromChests.TryPullItem(player, text, 1)) { ItemData item = ((Humanoid)player).GetInventory().GetItem(text, -1, false); if (item != null) { ConsumeFood(player, ((Humanoid)player).GetInventory(), item); } } } private static void ConsumeFood(Player player, Inventory inv, ItemData item) { inv.RemoveItem(item, 1); player.EatFood(item); } private static ItemData FindBestFood(Inventory inv) { ItemData val = null; foreach (ItemData allItem in inv.GetAllItems()) { if (IsFood(allItem) && (val == null || FoodValue(allItem) > FoodValue(val))) { val = allItem; } } return val; } private static string FindBestFoodNameNearby(Player player) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) float value = Plugin.Crafting_ChestScanRadius.Value; long playerID = player.GetPlayerID(); Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, value); ItemData val = null; Collider[] array2 = array; for (int i = 0; i < array2.Length; i++) { Container componentInParent = ((Component)array2[i]).GetComponentInParent<Container>(); if ((Object)(object)componentInParent == (Object)null || !CraftingFromChests.CheckAccess(componentInParent, playerID)) { continue; } Inventory inventory = componentInParent.GetInventory(); if (inventory == null) { continue; } foreach (ItemData allItem in inventory.GetAllItems()) { if (IsFood(allItem) && (val == null || FoodValue(allItem) > FoodValue(val))) { val = allItem; } } } return val?.m_shared.m_name; } private static bool IsFood(ItemData item) { if (item == null) { return false; } if (!(item.m_shared.m_food > 0f) && !(item.m_shared.m_foodStamina > 0f)) { return item.m_shared.m_foodEitr > 0f; } return true; } private static float FoodValue(ItemData item) { return item.m_shared.m_food + item.m_shared.m_foodStamina + item.m_shared.m_foodEitr; } } } namespace Wonderland.Subsystems.Equipment { public static class EquipmentTweaks { internal static bool CreateTombstone_Prefix(Player __instance) { if (!Plugin.Equip_OnlyEquippedStaysOnDeath.Value) { return true; } if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return true; } Inventory inventory = ((Humanoid)__instance).GetInventory(); if (inventory == null) { return true; } List<ItemData> allItems = inventory.GetAllItems(); if (allItems == null || allItems.Count == 0) { return true; } List<ItemData> list = new List<ItemData>(); foreach (ItemData item in allItems) { if (!item.m_equipped && (Object)(object)item.m_dropPrefab != (Object)null) { list.Add(item); } } foreach (ItemData item2 in list) { inventory.RemoveItem(item2); } __instance.CreateTombStone(); return false; } } } namespace Wonderland.Subsystems.Environment { public class FloatingItems : MonoBehaviour { [Serializable] private struct FloatingItemEntry { public Rigidbody Rigidbody; public float TargetFloatHeight; public float FloatStrength; public float MaxVerticalSpeed; } [Tooltip("How quickly items try to return to their target float height.")] public float DefaultFloatStrength = 2f; [Tooltip("Maximum vertical speed applied when correcting height.")] public float DefaultMaxVerticalSpeed = 3f; [Tooltip("Default target height above ground for floating items.")] public float DefaultTargetHeight = 0.5f; [Tooltip("Default linear damping applied to floating items.")] public float DefaultLinearDamping = 0.5f; [Tooltip("Default angular damping applied to floating items.")] public float DefaultAngularDamping = 0.5f; private readonly List<FloatingItemEntry> _items = new List<FloatingItemEntry>(); private void Awake() { GameObject[] array = GameObject.FindGameObjectsWithTag("FloatingItem"); for (int i = 0; i < array.Length; i++) { Rigidbody component = array[i].GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { AddFloatingItem(component, DefaultTargetHeight, DefaultFloatStrength, DefaultMaxVerticalSpeed); } } } public void AddFloatingItem(Rigidbody rb, float targetHeight = 0.5f, float floatStrength = 2f, float maxVerticalSpeed = 3f) { if ((Object)(object)rb == (Object)null) { return; } for (int i = 0; i < _items.Count; i++) { if ((Object)(object)_items[i].Rigidbody == (Object)(object)rb) { return; } } try { rb.linearDamping = DefaultLinearDamping; rb.angularDamping = DefaultAngularDamping; } catch { } _items.Add(new FloatingItemEntry { Rigidbody = rb, TargetFloatHeight = targetHeight, FloatStrength = floatStrength, MaxVerticalSpeed = maxVerticalSpeed }); } public void RemoveFloatingItem(Rigidbody rb) { if (!((Object)(object)rb == (Object)null)) { _items.RemoveAll((FloatingItemEntry e) => (Object)(object)e.Rigidbody == (Object)(object)rb); } } private void FixedUpdate() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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) RaycastHit val2 = default(RaycastHit); for (int num = _items.Count - 1; num >= 0; num--) { FloatingItemEntry floatingItemEntry = _items[num]; Rigidbody rigidbody = floatingItemEntry.Rigidbody; if ((Object)(object)rigidbody == (Object)null) { _items.RemoveAt(num); } else { try { Vector3 val = rigidbody.position + Vector3.up * 1f; float y = rigidbody.position.y; if (Physics.Raycast(val, Vector3.down, ref val2, 10f, -1, (QueryTriggerInteraction)1)) { y = ((RaycastHit)(ref val2)).point.y; } float num2 = (y + floatingItemEntry.TargetFloatHeight - rigidbody.position.y) * floatingItemEntry.FloatStrength; _ = rigidbody.linearVelocity; float y2 = Mathf.Clamp(num2, 0f - floatingItemEntry.MaxVerticalSpeed, floatingItemEntry.MaxVerticalSpeed); Vector3 linearVelocity = rigidbody.linearVelocity; linearVelocity.y = y2; rigidbody.linearVelocity = linearVelocity; rigidbody.linearDamping = Mathf.Max(0f, rigidbody.linearDamping); rigidbody.angularDamping = Mathf.Max(0f, rigidbody.angularDamping); } catch (Exception arg) { try { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"[FloatingItems] physics update error: {arg}"); } } catch { } } } } } public static void StopItem(Rigidbody rb) { //IL_000c: 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) if ((Object)(object)rb == (Object)null) { return; } try { rb.linearVelocity = Vector3.zero; rb.angularVelocity = Vector3.zero; rb.linearDamping = Mathf.Max(0f, rb.linearDamping); rb.angularDamping = Mathf.Max(0f, rb.angularDamping); } catch { } } } [HarmonyPatch(typeof(Fireplace), "UpdateFireplace")] public static class InfiniteFireplaceFuel { [HarmonyPrefix] public static void Prefix(Fireplace __instance) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && Plugin.Fireplace_InfiniteFuel.Value && !__instance.m_infiniteFuel && !(__instance.m_maxFuel <= 0f)) { __instance.SetFuel(__instance.m_maxFuel); } } } [HarmonyPatch] public static class InfiniteFuelAndProduction { [HarmonyPatch(typeof(Smelter), "GetDeltaTime")] [HarmonyPostfix] public static void AdjustSmelterSpeed(Smelter __instance, ref double __result) { float value = Plugin.Smelter_TimeMultiplier.Value; if (!(value <= 0f) && !(Mathf.Abs(value - 1f) < 0.001f)) { __result *= value; } } [HarmonyPatch(typeof(Smelter), "UpdateSmelter")] [HarmonyPrefix] public static void InfiniteSmelterAndFurnaceFuel(Smelter __instance) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && __instance.m_maxFuel > 0) { if (Plugin.Smelter_InfiniteFuel.Value) { __instance.SetFuel((float)__instance.m_maxFuel); } else if (Plugin.Furnace_InfiniteFuel.Value && (((Object)__instance).name ?? string.Empty).IndexOf("blast", StringComparison.OrdinalIgnoreCase) >= 0) { __instance.SetFuel((float)__instance.m_maxFuel); } } } [HarmonyPatch(typeof(Smelter), "UpdateSmelter")] [HarmonyPostfix] public static void InfiniteSmelterProduction(Smelter __instance) { if (!Plugin.InfiniteProduction_AllSmelters.Value || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid()) { return; } if (__instance.m_maxFuel > 0) { __instance.SetFuel((float)__instance.m_maxFuel); } int queueSize = __instance.GetQueueSize(); while (queueSize > 0) { string queuedOre = __instance.GetQueuedOre(); if (!string.IsNullOrEmpty(queuedOre)) { __instance.RemoveOneOre(); __instance.QueueProcessed(queuedOre); queueSize = __instance.GetQueueSize(); continue; } Plugin.Log.LogDebug((object)"InfiniteSmelterProduction: Encountered empty ore name, breaking."); break; } } [HarmonyPatch(typeof(Fireplace), "UpdateFireplace")] [HarmonyPrefix] public static void InfiniteFireplaceFuel(Fireplace __instance) { if (Plugin.Fireplace_InfiniteFuel.Value && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && !__instance.m_infiniteFuel && __instance.m_maxFuel > 0f) { __instance.SetFuel(__instance.m_maxFuel); } } [HarmonyPatch(typeof(Beehive), "CheckBiome")] [HarmonyPrefix] public static bool BeehiveAllowAnyBiome(Beehive __instance, ref bool __result) { if (!Plugin.Beehive_AllowAnyBiome.Value) { return true; } __result = true; return false; } [HarmonyPatch(typeof(Beehive), "GetTimeSinceLastUpdate")] [HarmonyPostfix] public static void AdjustBeehiveTimer(Beehive __instance, ref float __result) { float value = Plugin.Beehive_TimeMultiplier.Value; if (!(value <= 0f) && !(Mathf.Abs(value - 1f) < 0.001f)) { __result *= value; } } [HarmonyPatch(typeof(Beehive), "UpdateBees")] [HarmonyPostfix] public static void InfiniteBeehive(Beehive __instance) { if (Plugin.Beehive_InfiniteProduction.Value && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid()) { ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null) { zDO.Set(ZDOVars.s_level, __instance.m_maxHoney, false); zDO.Set(ZDOVars.s_product, 0f); } } } } public static class SanctuaryZones { public static bool IsInSanctuary(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return WardSystem.IsInWard(pos); } public static Vector3? FindNearestSanctuary(Vector3 center) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) float value = Plugin.SpawnSafety_SearchRadius.Value; PrivateArea val = WardSystem.FindNearestWard(center, value); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).transform.position; } internal static bool BlockDamage_Prefix(Character __instance, HitData hit) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return true; } if (!IsInSanctuary(((Component)__instance).transform.position)) { return true; } if (hit != null) { ((DamageTypes)(ref hit.m_damage)).Modify(0f); hit.m_pushForce = 0f; } return false; } internal static bool BlockStamina_Prefix(Player __instance, float v) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } if (!IsInSanctuary(((Component)__instance).transform.position)) { return true; } return false; } internal static bool BlockSkillLoss_Prefix(Skills __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } if (!IsInSanctuary(((Component)localPlayer).transform.position)) { return true; } return false; } internal static void BlockAggroVision_Postfix(BaseAI __instance, Character target, ref bool __result) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && IsInSanctuary(((Component)target).transform.position)) { __result = false; } } internal static void BlockAggroHearing_Postfix(BaseAI __instance, Character target, ref bool __result) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && IsInSanctuary(((Component)target).transform.position)) { __result = false; } } internal static bool BlockProjectiles_Prefix(Projectile __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } if (!IsInSanctuary(((Component)__instance).transform.position)) { return true; } if ((Object)(object)((Component)__instance).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)__instance).gameObject); } return false; } } } namespace Wonderland.Subsystems.Common { public static class SafeItemTransaction { public sealed class ItemRequest { public Inventory Source; public Inventory Target; public string SharedName; public int Amount; } private sealed class Snapshot { public Inventory Inv; public List<ItemData> Items = new List<ItemData>(); public float TotalWeight; } public static bool Execute(List<ItemRequest> ops, Action<string> log = null) { if (ops == null || ops.Count == 0) { return true; } if (log == null) { log = delegate { }; } Dictionary<Inventory, Snapshot> snapshots = new Dictionary<Inventory, Snapshot>(); foreach (ItemRequest op in ops) { SnapshotInventory(op.Source); if (op.Target != null) { SnapshotInventory(op.Target); } } try { foreach (ItemRequest op2 in ops) { int num = CountAvailable(op2.Source, op2.SharedName); if (num < op2.Amount) { log($"SafeItemTransaction: insufficient {op2.SharedName} ({num} < {op2.Amount})"); throw new InvalidOperationException("Insufficient items"); } } foreach (ItemRequest op3 in ops) { if (!MoveItems(op3.Source, op3.Target, op3.SharedName, op3.Amount, log)) { throw new InvalidOperationException("Move failed"); } } return true; } catch (Exception arg) { log($"SafeItemTransaction: exception {arg}"); foreach (Snapshot value in snapshots.Values) { RestoreInventory(value); } return false; } void SnapshotInventory(Inventory inv) { if (inv != null && !snapshots.ContainsKey(inv)) { Snapshot snapshot = new Snapshot { Inv = inv, TotalWeight = inv.GetTotalWeight() }; foreach (ItemData allItem in inv.GetAllItems()) { snapshot.Items.Add(allItem.Clone()); } snapshots[inv] = snapshot; } } } private static int CountAvailable(Inventory inv, string sharedName) { if (inv == null || string.IsNullOrEmpty(sharedName)) { return 0; } int num = 0; foreach (ItemData allItem in inv.GetAllItems()) { if (allItem.m_shared.m_name == sharedName) { num += allItem.m_stack; } } return num; } private static bool MoveItems(Inventory src, Inventory dst, string sharedName, int amount, Action<string> log) { if (src == null || amount <= 0 || string.IsNullOrEmpty(sharedName)) { return false; } int num = amount; foreach (ItemData allItem in src.GetAllItems()) { if (num <= 0) { break; } if (allItem.m_shared.m_name != sharedName) { continue; } int num2 = Mathf.Min(allItem.m_stack, num); if (dst != null) { ItemData val = allItem.Clone(); val.m_stack = num2; if (!dst.AddItem(val)) { log("SafeItemTransaction: AddItem failed for " + sharedName); return false; } } src.RemoveItem(allItem, num2); num -= num2; } return num == 0; } private static void RestoreInventory(Snapshot snap) { Inventory inv = snap.Inv; if (inv == null) { return; } inv.RemoveAll(); foreach (ItemData item in snap.Items) { inv.AddItem(item); } } } public static class WardSystem { public static bool IsInWard(Vector3 pos) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) foreach (PrivateArea allArea in PrivateArea.m_allAreas) { if (!((Object)(object)allArea == (Object)null) && allArea.IsEnabled() && allArea.IsInside(pos, 0f)) { return true; } } return false; } public static PrivateArea FindNearestWard(Vector3 center, float radius) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) float num = radius * radius; PrivateArea result = null; foreach (PrivateArea allArea in PrivateArea.m_allAreas) { if (!((Object)(object)allArea == (Object)null) && allArea.IsEnabled()) { Vector3 position = ((Component)allArea).transform.position; Vector3 val = new Vector3(position.x, center.y, position.z) - center; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = allArea; } } } return result; } public static bool HasAccess(PrivateArea ward, long playerID) { if ((Object)(object)ward == (Object)null) { return false; } if ((Object)(object)ward.m_piece != (Object)null && ward.m_piece.GetCreator() == playerID) { return true; } if (ward.IsPermitted(playerID)) { return true; } return false; } public static bool CheckAccess(Vector3 pos, long playerID) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) foreach (PrivateArea allArea in PrivateArea.m_allAreas) { if (!((Object)(object)allArea == (Object)null) && allArea.IsEnabled() && allArea.IsInside(pos, 0f) && !HasAccess(allArea, playerID)) { return false; } } return true; } } } namespace Wonderland.Subsystems.Combat { [HarmonyPatch] public static class AttackTweaks { [HarmonyPatch(typeof(Attack), "GetAttackStamina")] [HarmonyPostfix] public static void AttackStaminaPostfix(ref float __result) { __result *= Plugin.Combat_AttackStaminaMult.Value; } [HarmonyPatch(typeof(Humanoid), "GetAttackSpeedFactorMovement")] [HarmonyPostfix] public static void AttackMoveSlowPostfix(ref float __result) { float value = Plugin.Combat_AttackMoveSlowMult.Value; if (value != 0f) { __result /= value; } } [HarmonyPatch(typeof(Humanoid), "GetAttackSpeedFactorRotation")] [HarmonyPostfix] public static void AttackTurnSlowPostfix(ref float __result) { float value = Plugin.Combat_AttackTurnSlowMult.Value; if (value != 0f) { __result /= value; } } [HarmonyPatch(typeof(Attack), "Start")] [HarmonyPrefix] public static void BowDrawSpeedPrefix(Attack __instance) { if (__instance.m_bowDraw) { float value = Plugin.Combat_BowDrawSpeedMult.Value; if (!(value <= 0f) && value != 1f) { __instance.m_drawDurationMin /= value; } } } [HarmonyPatch(typeof(Attack), "Update")] [HarmonyPrefix] public static void BowDrawStaminaPrefix(Attack __instance) { if (__instance.m_bowDraw) { float value = Plugin.Combat_BowDrawStaminaMult.Value; if (!(value <= 0f) && value != 1f) { __instance.m_drawStaminaDrain *= value; } } } } public static class DamageTweaks { internal static void ApplyArmor_Postfix(HitData __instance) { if (__instance != null) { float value = Plugin.Combat_DamageMult.Value; if (!Mathf.Approximately(value, 1f)) { ((DamageTypes)(ref __instance.m_damage)).Modify(value); } } } internal static void ApplyDamage_Prefix(HitData hit) { if (hit != null) { hit.m_backstabBonus *= Plugin.Combat_BackstabMult.Value; hit.m_staggerMultiplier *= Plugin.Combat_StaggerMult.Value; } } } [HarmonyPatch] public static class ProjectileTweaks { [HarmonyPatch(typeof(Attack), "FireProjectileBurst")] [HarmonyPrefix] public static void FireProjectileBurstPrefix(Attack __instance, ref float ___m_projectileVel, ref float ___m_projectileAccuracy) { if (Plugin.Combat_EnableProjectileTweaks.Value) { float num = ___m_projectileVel; float num2 = ___m_projectileAccuracy; ___m_projectileVel = num * Plugin.Combat_ProjectileVelocityMult.Value; float value = Plugin.Combat_ProjectileSpreadMult.Value; if (value != 0f) { ___m_projectileAccuracy = num2 / value; } } } } } namespace Wonderland.Subsystems.AutoSort { public static class CraftingFromChests { public static bool TryPullItem(Player player, string itemName, int amount) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); Inventory inventory = ((Humanoid)player).GetInventory(); int num = inventory.CountItems(itemName, -1, true); if (num >= amount) { inventory.RemoveItem(itemName, amount, -1, true); return true; } int num2 = amount - num; float value = Plugin.Crafting_ChestScanRadius.Value; Vector3 position = ((Component)player).transform.position; List<(Inventory, ItemData, int)> list = new List<(Inventory, ItemData, int)>(); Collider[] array = Physics.OverlapSphere(position, value); foreach (Collider val in array) { if (num2 <= 0) { break; } Container componentInParent = ((Component)val).GetComponentInParent<Container>(); if ((Object)(object)componentInParent == (Object)null || !CheckAccess(componentInParent, playerID)) { continue; } Inventory inventory2 = componentInParent.GetInventory(); if (inventory2 == null) { continue; } ItemData item = inventory2.GetItem(itemName, -1, false); if (item != null) { int num3 = Mathf.Min(num2, item.m_stack); if (num3 > 0) { list.Add((inventory2, item, num3)); num2 -= num3; } } } if (num2 > 0) { return false; } if (num > 0) { inventory.RemoveItem(itemName, num, -1, true); } foreach (var item2 in list) { if (item2.Item1.ContainsItem(item2.Item2)) { item2.Item1.RemoveItem(item2.Item2, item2.Item3); } } return true; } internal static bool CheckAccess(Container c, long playerID) { return (bool)AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null).Invoke(c, new object[1] { playerID }); } } [HarmonyPatch] public static class CraftingUIEnhancer { [CompilerGenerated] private sealed class <Pulse>d__9 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TextMeshProUGUI text; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Pulse>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; _isAnimating = true; break; case 1: <>1__state = -1; break; } if ((Object)(object)text != (Object)null && ((Component)text).gameObject.activeSelf) { float num = (Mathf.Sin(Time.time * 4f) + 1f) * 0.5f; float num2 = Mathf.Lerp(1f, 1.15f, num); ((TMP_Text)text).transform.localScale = new Vector3(num2, num2, 1f); <>2__current = null; <>1__state = 1; return true; } _isAnimating = false; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static TextMeshProUGUI _craftableText; private static bool _isAnimating = false; private static readonly Dictionary<GameObject, (Recipe recipe, ItemData item)> _buttonMap = new Dictionary<GameObject, (Recipe, ItemData)>(); private static Recipe _currentRecipe; private static ItemData _currentItem; [HarmonyPatch(typeof(InventoryGui), "AddRecipeToList")] [HarmonyPostfix] public static void AddRecipeToListPostfix(InventoryGui __instance, Player player, Recipe recipe, ItemData item, bool canCraft) { RectTransform recipeListRoot = __instance.m_recipeListRoot; if (((Transform)recipeListRoot).childCount != 0) { GameObject gameObject = ((Component)((Transform)recipeListRoot).GetChild(((Transform)recipeListRoot).childCount - 1)).gameObject; _buttonMap[gameObject] = (recipe, item); } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedRecipe")] [HarmonyPrefix] public static void OnSelectedRecipePrefix(GameObject button) { if ((Object)(object)button != (Object)null && _buttonMap.TryGetValue(button, out (Recipe, ItemData) value)) { (_currentRecipe, _currentItem) = value; } else { _currentRecipe = null; _currentItem = null; } } [HarmonyPatch(typeof(InventoryGui), "UpdateCraftingPanel")] [HarmonyPostfix] public static void UpdateCraftingPanelPostfix(InventoryGui __instance) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_currentRecipe == (Object)null) { if ((Object)(object)_craftableText != (Object)null) { ((Component)_craftableText).gameObject.SetActive(false); } return; } if ((Object)(object)_craftableText == (Object)null) { _craftableText = CreateCraftableText(__instance); } int num = CalculateCraftable(__instance, _currentRecipe); ((TMP_Text)_craftableText).text = $"Craftable: {num}"; ((Component)_craftableText).gameObject.SetActive(true); if (num > 0) { ((Graphic)_craftableText).color = new Color(0.2f, 1f, 0.2f, 1f); if (!_isAnimating) { ((MonoBehaviour)__instance).StartCoroutine(Pulse(_craftableText)); } } else { ((Graphic)_craftableText).color = new Color(1f, 0.2f, 0.2f, 1f); ((TMP_Text)_craftableText).transform.localScale = Vector3.one; _isAnimating = false; } } private static TextMeshProUGUI CreateCraftableText(InventoryGui gui) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Transform parent = ((Component)gui.m_craftButton).transform.parent; GameObject val = new GameObject("CraftableText"); val.transform.SetParent(parent, false); TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).fontSize = 20f; ((Graphic)obj).color = Color.white; ((TMP_Text)obj).alignment = (TextAlignmentOptions)513; ((TMP_Text)obj).rectTransform.anchoredPosition = new Vector2(0f, -35f); return obj; } [IteratorStateMachine(typeof(<Pulse>d__9))] private static IEnumerator Pulse(TextMeshProUGUI text) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Pulse>d__9(0) { text = text }; } private static int CalculateCraftable(InventoryGui gui, Recipe recipe) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return 0; } int num = int.MaxValue; Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (val != null && !((Object)(object)val.m_resItem == (Object)null)) { string name = val.m_resItem.m_itemData.m_shared.m_name; int amount = val.GetAmount(1); int num2 = ((Humanoid)localPlayer).GetInventory().CountItems(name, -1, true); int num3 = CountNearbyChests(localPlayer, name); int num4 = num2 + num3; int num5 = ((amount > 0) ? (num4 / amount) : 0); if (num5 < num) { num = num5; } } } return Mathf.Max(0, num); } private static int CountNearbyChests(Player player, string itemName) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) float value = Plugin.Crafting_ChestScanRadius.Value; Vector3 position = ((Component)player).transform.position; long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); int num = 0; Collider[] array = Physics.OverlapSphere(position, value); for (int i = 0; i < array.Length; i++) { Container componentInParent = ((Component)array[i]).GetComponentInParent<Container>(); if (!((Object)(object)componentInParent == (Object)null) && CraftingFromChests.CheckAccess(componentInParent, playerID)) { Inventory inventory = componentInParent.GetInventory(); if (inventory != null) { num += inventory.CountItems(itemName, -1, true); } } } return num; } } } namespace Wonderland.Utilities { public static class FilteredGlobalMethodLogger { private static Harmony _harmony; private static readonly string HarmonyId = "com.ross.wonderland.logger"; private static bool _enabled = false; private static readonly List<MethodBase> _patchedMethods = new List<MethodBase>(); public static void Enable() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown if (_enabled) { return; } try { _harmony = new Harmony(HarmonyId); (Type, string[])[] array = new(Type, string[])[1] { (AccessTools.TypeByName("Player"), new string[1] { "UpdateStats" }) }; for (int i = 0; i < array.Length; i++) { (Type, string[]) tuple = array[i]; if (tuple.Item1 == null) { Plugin.Log.LogDebug((object)"[GlobalLogger] Target type not found; skipping."); continue; } string[] item = tuple.Item2; foreach (string text in item) { try { HarmonyMethod prefix = new HarmonyMethod(typeof(FilteredGlobalMethodLogger).GetMethod("GenericPrefix", BindingFlags.Static | BindingFlags.NonPublic)); HarmonyMethod postfix = new HarmonyMethod(typeof(FilteredGlobalMethodLogger).GetMethod("GenericPostfix", BindingFlags.Static | BindingFlags.NonPublic)); int num = HarmonyPatcher.PatchAllOverloads(_harmony, tuple.Item1, text, prefix, postfix); if (num > 0) { Plugin.Log.LogInfo((object)$"[GlobalLogger] Patched {num} overload(s) of {tuple.Item1.FullName}.{text}."); continue; } Plugin.Log.LogDebug((object)("[GlobalLogger] No patchable overloads found for " + tuple.Item1.FullName + "." + text + ".")); } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[GlobalLogger] Error patching {tuple.Item1.FullName}.{text}: {arg}"); } } } _enabled = true; } catch (Exception arg2) { try { Plugin.Log.LogWarning((object)$"[GlobalLogger] Enable failed: {arg2}"); } catch { } } } public static void Disable() { if (!_enabled) { return; } try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch (Exception arg) { try { Plugin.Log.LogWarning((object)$"[GlobalLogger] Disable unpatch failed: {arg}"); } catch { } } finally { _patchedMethods.Clear(); _enabled = false; } } private static void GenericPrefix(object __instance, MethodBase __originalMethod) { try { ConfigEntry<bool> debug_Enable = Plugin.Debug_Enable; if (debug_Enable != null && debug_Enable.Value) { Plugin.Log.LogDebug((object)("[GlobalLogger] Enter: " + __originalMethod.DeclaringType?.Name + "." + __originalMethod.Name)); } } catch { } } private static void GenericPostfix(object __instance, MethodBase __originalMethod) { try { ConfigEntry<bool> debug_Enable = Plugin.Debug_Enable; if (debug_Enable != null && debug_Enable.Value) { Plugin.Log.LogDebug((object)("[GlobalLogger] Exit: " + __originalMethod.DeclaringType?.Name + "." + __originalMethod.Name)); } } catch { } } } public static class HarmonyPatcher { public static int PatchAllOverloads(Harmony harmony, Type targetType, string methodName, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null) { if (harmony == null) { throw new ArgumentNullException("harmony"); } if (targetType == null) { throw new ArgumentNullException("targetType"); } if (string.IsNullOrEmpty(methodName)) { throw new ArgumentNullException("methodName"); } MethodInfo[] array; try { array = (from m in targetType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where string.Equals(m.Name, methodName, StringComparison.Ordinal) select m).ToArray(); } catch (Exception ex) { LoggerWarning("PatchAllOverloads: failed to enumerate methods on " + targetType.FullName + ": " + ex.Message); return 0; } if (array.Length == 0) { LoggerDebug("PatchAllOverloads: no methods named '" + methodName + "' found on " + targetType.FullName + "."); return 0; } int num = 0; MethodInfo[] array2 = array; foreach (MethodInfo methodInfo in array2) { if (!IsPatchable(methodInfo)) { LoggerDebug("PatchAllOverloads: skipping non-patchable " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + ")"); continue; } try { harmony.Patch((MethodBase)methodInfo, prefix, postfix, transpiler, (HarmonyMethod)null, (HarmonyMethod)null); num++; LoggerInfo("Patched " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + ")"); } catch (Exception ex2) { LoggerWarning("PatchAllOverloads: failed to patch " + targetType.FullName + "." + methodInfo.Name + "(" + ParamTypes(methodInfo) + "): " + ex2.Message); } } return num; } public static bool PatchSpecificOverload(Harmony harmony, Type targetType, string methodName, Type[] parameterTypes, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null) { if (harmony == null) { throw new ArgumentNullException("harmony"); } if (targetType == null) { throw new ArgumentNullException("targetType"); } if (string.IsNullOrEmpty(methodName)) { throw new ArgumentNullException("methodName"); } parameterTypes = parameterTypes ?? Type.EmptyTypes; MethodInfo methodInfo = null; try { methodInfo = targetType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null); } catch (AmbiguousMatchException) { LoggerWarning("PatchSpecificOverload: ambiguous match for " + targetType.FullName + "." + methodName + "(" + string.Join(", ", parameterTypes.Select((Type t) => t?.Name ?? "null")) + "). Consider PatchAllOverloads."); return false; } catch (Exception ex2) { LoggerWarning("PatchSpecificOverload: error resolving " + targetType.FullName + "." + methodName + ": " + ex2.Message); return false; } if (methodInfo == null) { LoggerDebug("PatchSpecificOverload: method not found " + targetType.FullName + "." + methodName + "(" + string.Join(", ", parameterTypes.Select((Type t) => t?.Name ?? "null")) + ")."); return false; } if (!IsPatchable(methodInfo)) { LoggerWarning("PatchSpecificOverload: method " + targetType.FullName + "." + methodName + "(" + ParamTypes(methodInfo) + ") is not patchable (abstract/extern/no body)."); return false; } try { harmony.Patch((MethodBase)methodInfo, prefix, postfix, transpiler, (HarmonyMethod)null, (HarmonyMethod)null); LoggerInfo("Patched specific overload " + targetType.FullName + "." + methodName + "(" + ParamTypes(methodInfo) + ")"); return true; } catch (Exception ex3) { LoggerWarning("PatchSpecificOverload: failed to patch " + targetType.FullName + "." + methodName + "(" + ParamTypes(methodInfo) + "): " + ex3.Message); return false; } } public static int SafePatchMethods(Harmony harmony, IEnumerable<MethodBase> methods, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null) { if (harmony == null) { throw new ArgumentNullException("harmony"); } if (methods == null) { throw new ArgumentNullException("methods"); } int num = 0; foreach (MethodBase method in methods) { if (method == null) { continue; } if (!IsPatchable(method)) { LoggerDebug("SafePatchMethods: skipping non-patchable " + method.DeclaringType?.FullName + "." + method.Name + "(" + ParamTypes(method) + ")"); continue; } try { harmony.Patch(method, prefix, postfix, transpiler, (HarmonyMethod)null, (HarmonyMethod)null); num++; LoggerInfo("Patched " + method.DeclaringType?.FullName + "." + method.Name + "(" + ParamTypes(method) + ")"); } catch (Exception ex) { LoggerWarning("SafePatchMethods: failed to patch " + method.DeclaringType?.FullName + "." + method.Name + "(" + ParamTypes(method) + "): " + ex.Message); } } return num; } public static void PatchAllSafe(Harmony harmony, Assembly assembly) { if (harmony == null) { throw new ArgumentNullException("harmony"); } if (assembly == null) { throw new ArgumentNullException("assembly"); } Type[] array; try { array = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { array = ex.Types.Where((Type t) => t != null).ToArray(); } catch (Exception ex2) { LoggerWarning("PatchAllSafe: failed to enumerate types in assembly: " + ex2.Message); return; } int num = 0; Type[] array2 = array; foreach (Type type in array2) { if (!(type == null) && type.IsClass && type.GetCustomAttributes(inherit: false).Where(delegate(object a) { string? fullName = a.GetType().FullName; return (fullName != null && fullName.StartsWith("HarmonyLib.HarmonyPatch")) || (a.GetType().FullName?.Contains("HarmonyPatch") ?? false); }).ToArray() .Length != 0) { try { int num2 = SafePatchClass(harmony, type); num += num2; } catch (Exception ex3) { LoggerWarning("PatchAllSafe: error processing patch class " + type.FullName + ": " + ex3.Message); } } } LoggerInfo($"PatchAllSafe: completed. Total patched methods: {num}"); } private static int SafePatchClass(Harmony harmony, Type patchClass) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (harmony == null) { throw new ArgumentNullException("harmony"); } if (patchClass == null) { throw new ArgumentNullException("patchClass"); } int num = 0; object[] customAttributes = patchClass.GetCustomAttributes(inherit: false); if (customAttributes.Any((object a) => a.GetType().Name == "HarmonyPatchAllAttribute")) { LoggerDebug("SafePatchClass: skipping HarmonyPatchAll on " + patchClass.FullName + " (too broad)."); return 0; } object[] array = customAttributes.Where((object a) => a.GetType().Name == "HarmonyPatchAttribute").ToArray(); if (array.Length == 0) { try { new PatchClassProcessor(harmony, patchClass).Patch(); LoggerInfo("SafePatchClass: PatchClassProcessor applied for " + patchClass.FullName + "."); return 1; } catch (Exception ex) { LoggerWarning("SafePatchClass: PatchClassProcessor failed for " + patchClass.FullName + ": " + ex.Message); return 0; } } object[] array2 = array; foreach (object obj in array2) { try { Type type = obj.GetType()