Decompiled source of Wonderland v1.0.5
plugins/Wonderland.dll
Decompiled 21 hours 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()