Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of AnriServerFixes v1.9.3
AnriDiagnostics.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("AnriDiagnostics")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1")] [assembly: AssemblyProduct("AnriDiagnostics")] [assembly: AssemblyTitle("AnriDiagnostics")] [assembly: AssemblyVersion("1.1.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 AnriDiagnostics { [BepInPlugin("anri.diagnostics", "AnriDiagnostics", "1.1.3")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class RegisterCommands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; public static ConsoleEvent <>9__0_2; internal void <Postfix>b__0_0(ConsoleEventArgs args) { DumpDuplicates((args.Length > 1) ? args[1] : null); } internal void <Postfix>b__0_1(ConsoleEventArgs args) { Out(BuildStats(0, 0f, 0f)); } internal void <Postfix>b__0_2(ConsoleEventArgs args) { DumpPatchOwners(); } } private static void Postfix() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_006c: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { DumpDuplicates((args.Length > 1) ? args[1] : null); }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("dupeitems", "List duplicate ObjectDB item entries (optional filter text)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate { Out(BuildStats(0, 0f, 0f)); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("serverstats", "Print ZDO count, players and connection quality", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj3 = <>c.<>9__0_2; if (obj3 == null) { ConsoleEvent val3 = delegate { DumpPatchOwners(); }; <>c.<>9__0_2 = val3; obj3 = (object)val3; } new ConsoleCommand("patchowners", "List Harmony patch owners on ObjectDB/ZNetScene setup", (ConsoleEvent)obj3, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public const string GUID = "anri.diagnostics"; public const string NAME = "AnriDiagnostics"; public const string VERSION = "1.1.3"; internal static ManualLogSource Log; internal static ConfigEntry<int> StatsInterval; private float _frameMax; private float _frameSum; private int _frames; private float _nextStats; private static readonly FieldRef<ZSteamSocket, HSteamNetConnection> SteamCon = AccessTools.FieldRefAccess<ZSteamSocket, HSteamNetConnection>("m_con"); private static readonly Dictionary<Type, FieldInfo> InnerSocketFields = new Dictionary<Type, FieldInfo>(); private void Awake() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; StatsInterval = ((BaseUnityPlugin)this).Config.Bind<int>("ServerStats", "IntervalSeconds", 60, "On a dedicated server, log world/network statistics every N seconds (ZDO count, players, per-peer ping and bandwidth, server tick times). 0 disables."); new Harmony("anri.diagnostics").PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"AnriDiagnostics 1.1.3 loaded. Console: dupeitems, patchowners, serverstats"); } private void Update() { float unscaledDeltaTime = Time.unscaledDeltaTime; _frames++; _frameSum += unscaledDeltaTime; if (unscaledDeltaTime > _frameMax) { _frameMax = unscaledDeltaTime; } if (StatsInterval.Value > 0 && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && ZNet.instance.IsDedicated() && !(Time.unscaledTime < _nextStats)) { _nextStats = Time.unscaledTime + (float)StatsInterval.Value; try { Log.LogInfo((object)BuildStats(_frames, _frameSum, _frameMax)); } catch (Exception ex) { Log.LogWarning((object)("stats failed: " + ex.Message)); } _frames = 0; _frameSum = 0f; _frameMax = 0f; } } internal static string BuildStats(int frames, float frameSum, float frameMax) { StringBuilder stringBuilder = new StringBuilder(); ZDOMan instance = ZDOMan.instance; ZNet instance2 = ZNet.instance; stringBuilder.Append("[Stats] "); if (instance != null) { stringBuilder.Append($"ZDOs={instance.NrOfObjects()} sentZDO/s={instance.GetSentZDOs()} recvZDO/s={instance.GetRecvZDOs()} "); } if ((Object)(object)instance2 != (Object)null) { stringBuilder.Append($"players={instance2.GetNrOfPlayers()} "); if (frames > 0) { stringBuilder.Append($"tick avg={frameSum / (float)frames * 1000f:0.0}ms max={frameMax * 1000f:0}ms "); } foreach (ZNetPeer peer in instance2.GetPeers()) { if (peer == null || peer.m_socket == null) { continue; } try { ConnectionQuality(peer.m_socket, out var lq, out var rq, out var ping, out var outB, out var inB); stringBuilder.Append($"| {peer.m_playerName}: ping={ping}ms out={outB / 1024f:0.0}KB/s in={inB / 1024f:0.0}KB/s q={lq:0.00}/{rq:0.00} queue={peer.m_socket.GetSendQueueSize()} "); } catch (Exception ex) { string name = ((object)peer.m_socket).GetType().Name; string name2 = ex.GetType().Name; string text = ex.Message.Replace("\r\n", " ").Replace('\r', ' ').Replace('\n', ' '); string text2 = "unknown"; try { MethodBase methodBase = new StackTrace(ex).GetFrame(0)?.GetMethod(); if (methodBase != null) { text2 = methodBase.DeclaringType?.Name + "." + methodBase.Name; } } catch { } stringBuilder.Append("| " + peer.m_playerName + ": quality n/a (socket=" + name + "; " + name2 + ": " + text + "; at " + text2 + ") "); } } } return stringBuilder.ToString(); } private static ZSteamSocket FindSteamSocket(ISocket socket) { int num = 0; while (num < 8 && socket != null) { ZSteamSocket val = (ZSteamSocket)(object)((socket is ZSteamSocket) ? socket : null); if (val != null) { return val; } Type type = ((object)socket).GetType(); if (!InnerSocketFields.TryGetValue(type, out var value)) { Type type2 = type; while (type2 != null && value == null) { foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(type2)) { if (!declaredField.IsStatic) { object? value2 = declaredField.GetValue(socket); ISocket val2 = (ISocket)((value2 is ISocket) ? value2 : null); if (val2 != null && val2 != socket) { value = declaredField; break; } } } type2 = type2.BaseType; } InnerSocketFields[type] = value; } if (!(value == null)) { object? value3 = value.GetValue(socket); ISocket val3 = (ISocket)((value3 is ISocket) ? value3 : null); if (val3 != null && val3 != socket) { socket = val3; num++; continue; } } return null; } return null; } internal static void ConnectionQuality(ISocket socket, out float lq, out float rq, out int ping, out float outB, out float inB) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) ZSteamSocket val = FindSteamSocket(socket); if (val != null && (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) { SteamNetConnectionRealTimeStatus_t val2 = default(SteamNetConnectionRealTimeStatus_t); SteamNetConnectionRealTimeLaneStatus_t val3 = default(SteamNetConnectionRealTimeLaneStatus_t); if ((int)SteamGameServerNetworkingSockets.GetConnectionRealTimeStatus(SteamCon.Invoke(val), ref val2, 0, ref val3) == 1) { lq = val2.m_flConnectionQualityLocal; rq = val2.m_flConnectionQualityRemote; ping = val2.m_nPing; outB = val2.m_flOutBytesPerSec; inB = val2.m_flInBytesPerSec; } else { lq = (rq = 0f); ping = 0; outB = (inB = 0f); } } else { socket.GetConnectionQuality(ref lq, ref rq, ref ping, ref outB, ref inB); } } internal static void Out(string s) { Log.LogInfo((object)s); if ((Object)(object)Console.instance != (Object)null) { Console.instance.Print(s); } } private static void DumpDuplicates(string filter) { //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { Out("ObjectDB not ready."); return; } Dictionary<string, List<GameObject>> dictionary = new Dictionary<string, List<GameObject>>(); ItemDrop val = default(ItemDrop); foreach (GameObject item in instance.m_items) { if ((Object)(object)item == (Object)null) { Out(" <null entry in ObjectDB.m_items>"); } else { if (!item.TryGetComponent<ItemDrop>(ref val) || val.m_itemData?.m_shared == null) { continue; } string name = val.m_itemData.m_shared.m_name; if (filter == null || name.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)item).name.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0) { if (!dictionary.TryGetValue(name, out var value)) { value = (dictionary[name] = new List<GameObject>()); } value.Add(item); } } } int num = 0; Out($"ObjectDB.m_items count: {instance.m_items.Count}"); foreach (KeyValuePair<string, List<GameObject>> item2 in from g in dictionary where g.Value.Count > 1 orderby g.Key select g) { num++; Out($"== {item2.Key} x{item2.Value.Count}"); foreach (GameObject item3 in item2.Value) { SharedData shared = item3.GetComponent<ItemDrop>().m_itemData.m_shared; int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)item3).name); Dictionary<int, GameObject> value2 = Traverse.Create((object)instance).Field("m_itemByHash").GetValue<Dictionary<int, GameObject>>(); GameObject value3; bool flag = value2 != null && value2.TryGetValue(stableHashCode, out value3) && (Object)(object)value3 == (Object)(object)item3; Dictionary<int, GameObject> dictionary2 = (((Object)(object)ZNetScene.instance != (Object)null) ? Traverse.Create((object)ZNetScene.instance).Field("m_namedPrefabs").GetValue<Dictionary<int, GameObject>>() : null); GameObject value4; bool flag2 = dictionary2 != null && dictionary2.TryGetValue(stableHashCode, out value4) && (Object)(object)value4 == (Object)(object)item3; string text = (((Object)(object)item3.transform.parent != (Object)null) ? ((Object)item3.transform.parent).name : "-"); Scene scene = item3.scene; object obj; if (!((Scene)(ref scene)).IsValid()) { obj = "(asset)"; } else { scene = item3.scene; obj = ((Scene)(ref scene)).name; } string text2 = (string)obj; Out($" prefab='{((Object)item3).name}' id={((Object)item3).GetInstanceID()} set='{shared.m_setName}' sharedId={((object)shared).GetHashCode()} " + $"byHash={flag} znet={flag2} parent={text} scene={text2} hideFlags={((Object)item3).hideFlags} " + "dropPrefab=" + (((Object)(object)item3.GetComponent<ItemDrop>().m_itemData.m_dropPrefab != (Object)null) ? ((Object)item3.GetComponent<ItemDrop>().m_itemData.m_dropPrefab).name : "null")); } } Out($"{num} duplicated display name(s)."); } private static void DumpPatchOwners() { (Type, string)[] array = new(Type, string)[9] { (typeof(ObjectDB), "Awake"), (typeof(ObjectDB), "CopyOtherDB"), (typeof(ObjectDB), "UpdateRegisters"), (typeof(ZNetScene), "Awake"), (typeof(FejdStartup), "Awake"), (typeof(FejdStartup), "SetupObjectDB"), (typeof(Game), "Start"), (typeof(ItemDrop), "Awake"), (typeof(ItemDrop), "Start") }; for (int i = 0; i < array.Length; i++) { (Type, string) tuple = array[i]; Type item = tuple.Item1; string item2 = tuple.Item2; MethodInfo methodInfo = AccessTools.Method(item, item2, (Type[])null, (Type[])null); if (methodInfo == null) { Out(item.Name + "." + item2 + ": not found"); continue; } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo); if (patchInfo == null) { Out(item.Name + "." + item2 + ": no patches"); continue; } Out(item.Name + "." + item2 + ": prefix[" + Fmt(patchInfo.Prefixes) + "] postfix[" + Fmt(patchInfo.Postfixes) + "] transpiler[" + Fmt(patchInfo.Transpilers) + "]"); } static string Fmt(IEnumerable<Patch> ps) { return string.Join(", ", ps.Select((Patch p) => p.owner + ":" + p.PatchMethod.DeclaringType?.Name + "." + p.PatchMethod.Name)); } } } }
BossKillScaling.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("BossKillScaling")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BossKillScaling")] [assembly: AssemblyTitle("BossKillScaling")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 BossKillScaling { [BepInPlugin("anri.bosskillscaling", "BossKillScaling", "1.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<KeyValuePair<string, int>, bool> <>9__33_0; public static Func<string, string> <>9__42_0; public static Func<string, string> <>9__42_1; public static Func<string, string> <>9__44_0; public static Func<string, string> <>9__44_1; public static Func<string, bool> <>9__45_1; public static Func<string, string> <>9__45_2; public static ConsoleEvent <>9__45_0; internal bool <ProgressCap>b__33_0(KeyValuePair<string, int> e) { return e.Key.Equals("none", StringComparison.OrdinalIgnoreCase); } internal string <BeforeGenerateDropList>b__42_0(string e) { return e.Trim(); } internal string <BeforeGenerateDropList>b__42_1(string e) { return e.Trim(); } internal string <AfterGenerateDropList>b__44_0(string e) { return e.Trim(); } internal string <AfterGenerateDropList>b__44_1(string e) { return e.Trim(); } internal void <RegisterCommand>b__45_0(ConsoleEventArgs args) { double result; int result2; if ((Object)(object)ZoneSystem.instance == (Object)null) { args.Context.AddString("No world loaded."); } else if (args.Args.Length == 1) { foreach (string item in from k in ZoneSystem.instance.GetGlobalKeys() where k.StartsWith("anri_bosskills_", StringComparison.OrdinalIgnoreCase) orderby k select k) { args.Context.AddString(item); } string key; int num = ProgressCap(out key); args.Context.AddString($"Progress cap: {num} stars ({key})."); } else if (args.Args.Length == 4 && args.Args[1].Equals("preview", StringComparison.OrdinalIgnoreCase) && double.TryParse(args.Args[3], NumberStyles.Float, CultureInfo.InvariantCulture, out result) && result >= 0.0 && !double.IsInfinity(result)) { args.Context.AddString($"{Prefab(args.Args[2])}: kills={Count(args.Args[2])}, distance={result.ToString(CultureInfo.InvariantCulture)}m, next spawn={Stars(args.Args[2], result)} stars."); } else if (args.Args.Length == 3 && int.TryParse(args.Args[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out result2) && result2 >= 0) { ZoneSystem.instance.SetGlobalKey("anri_bosskills_" + Prefab(args.Args[1]) + " " + result2.ToString(CultureInfo.InvariantCulture)); args.Context.AddString($"Requested {Prefab(args.Args[1])} counter = {result2}."); } else { args.Context.AddString("Usage: bosskills | bosskills <prefab> <n> | bosskills preview <prefab> <distance>"); } } internal bool <RegisterCommand>b__45_1(string k) { return k.StartsWith("anri_bosskills_", StringComparison.OrdinalIgnoreCase); } internal string <RegisterCommand>b__45_2(string k) { return k; } } public const string GUID = "anri.bosskillscaling"; public const string NAME = "BossKillScaling"; public const string VERSION = "1.5.0"; private const string SLS_GUID = "MidnightsFX.StarLevelSystem"; private const string CounterPrefix = "anri_bosskills_"; private const string DefaultRings = "0:0,750:1,1200:2,2000:3,3000:4,4000:5,5000:6,6000:7,7000:8,8000:9,9100:10"; private const string DefaultProgress = "none:1,defeated_eikthyr:2,defeated_gdking:4,defeated_bonemass:5,defeated_dragon:6,defeated_goblinking:8,defeated_queen:9,defeated_fader:10,defeated_frozenking_p3:20"; internal static ManualLogSource Log; private static readonly Dictionary<int, string> BossPrefabs = new Dictionary<int, string>(); private static bool ZdoDestroyWarningLogged; private static bool DropChanceWarningLogged; private static readonly FieldRef<CharacterDrop, Character> DropCharacter = AccessTools.FieldRefAccess<CharacterDrop, Character>("m_character"); private static ConfigEntry<bool> CapBossEquipment; private static ConfigEntry<int> BossEquipmentMaxCount; private static ConfigEntry<float> BossEquipmentChanceMultiplier; private static ConfigEntry<string> BossEquipmentExtraPrefabs; private static ConfigEntry<string> BossEquipmentIgnorePrefabs; private static ConfigEntry<bool> Enabled; private static ConfigEntry<string> LadderMode; private static ConfigEntry<bool> CountCappedKills; private static ConfigEntry<bool> ApplyProgressCapToAllCreatures; private static ConfigEntry<int> MaxStars; private static ConfigEntry<bool> Verbose; private static volatile SortedDictionary<double, int> Rings = new SortedDictionary<double, int>(); private static volatile List<KeyValuePair<string, int>> Progress = new List<KeyValuePair<string, int>>(); private void Awake() { //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Expected O, but got Unknown //IL_04d5: Expected O, but got Unknown //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Expected O, but got Unknown //IL_053a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Expected O, but got Unknown //IL_055c: Expected O, but got Unknown //IL_0585: Unknown result type (might be due to invalid IL or missing references) //IL_058a: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Expected O, but got Unknown //IL_05c5: Unknown result type (might be due to invalid IL or missing references) //IL_05d3: Expected O, but got Unknown //IL_05fc: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, AdminOnly("Master switch for the deterministic boss star ladder and its caps. Off = StarLevelSystem's own rolls.")); LadderMode = ((BaseUnityPlugin)this).Config.Bind<string>("General", "LadderMode", "Sqrt", AdminOnly("Sqrt = star n costs ceil(sqrt(n)) kills, cumulative: 1,3,5,7,10,13,16,19,22,26 total kills for stars 1-10. Blocks = the original ladder in blocks of nine kills (0,1,1,2,2,2,2,2,3 then +3 per block).", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Sqrt", "Blocks" }))); CountCappedKills = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CountCappedKills", true, AdminOnly("Every boss kill advances the counter, even when a distance or progress cap lowered that fight's stars. Off = only fights that spawned at the full ladder value count.")); ApplyProgressCapToAllCreatures = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ApplyProgressCapToAllCreatures", true, AdminOnly("Also clip every creature's star level to the boss-progress cap through StarLevelSystem's GetMaxCreatureLevel. Off = bosses only.")); ConfigEntry<string> rings = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RingMaxStars", "0:0,750:1,1200:2,2000:3,3000:4,4000:5,5000:6,6000:7,7000:8,8000:9,9100:10", AdminOnly("Distance in metres:max stars pairs. Reparsed when changed.")); ConfigEntry<string> progress = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ProgressCaps", "none:1,defeated_eikthyr:2,defeated_gdking:4,defeated_bonemass:5,defeated_dragon:6,defeated_goblinking:8,defeated_queen:9,defeated_fader:10,defeated_frozenking_p3:20", AdminOnly("Ordered global key:max stars ladder; last present key wins. Reparsed when changed.")); MaxStars = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxStars", 10, AdminOnly("Absolute boss star ceiling.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2147483646))); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Verbose", false, "Log boss level selection, counted/skipped boss deaths, capped boss equipment drops, and equipment drop chance adjustments."); CapBossEquipment = ((BaseUnityPlugin)this).Config.Bind<bool>("BossDrops", "CapBossEquipment", true, AdminOnly("Cap equipment drops per boss kill.")); BossEquipmentMaxCount = ((BaseUnityPlugin)this).Config.Bind<int>("BossDrops", "BossEquipmentMaxCount", 1, AdminOnly("Maximum total copies of each equipment prefab per boss kill.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue))); BossEquipmentChanceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("BossDrops", "BossEquipmentChanceMultiplier", 2f, AdminOnly("Multiplies the base drop chance of equipment drops from bosses before the vanilla star multiplier. 1 = unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f))); BossEquipmentExtraPrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("BossDrops", "BossEquipmentExtraPrefabs", "", AdminOnly("Comma-separated prefab names to cap regardless of item type.")); BossEquipmentIgnorePrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("BossDrops", "BossEquipmentIgnorePrefabs", "", AdminOnly("Comma-separated prefab names never capped; overrides extra prefabs.")); rings.SettingChanged += delegate { ParseRings(rings.Value); }; progress.SettingChanged += delegate { ParseProgress(progress.Value); }; ParseRings(rings.Value); ParseProgress(progress.Value); if (!Chainloader.PluginInfos.ContainsKey("MidnightsFX.StarLevelSystem")) { Log.LogInfo((object)"BossKillScaling idle: StarLevelSystem not loaded."); return; } Harmony val = new Harmony("anri.bosskillscaling"); Assembly slsAssembly = ((object)Chainloader.PluginInfos["MidnightsFX.StarLevelSystem"].Instance).GetType().Assembly; Type type = FindType("LevelSelection"); Type type2 = FindType("DataObjects"); Type type3 = type2?.GetNestedType("CreatureSpecificSetting"); Type type4 = type2?.GetNestedType("BiomeSpecificSetting"); if (type == null || type3 == null || type4 == null) { Log.LogWarning((object)$"SLS types not found (LevelSelection={type != null}, DataObjects={type2 != null}, Creature={type3 != null}, Biome={type4 != null})."); } MethodInfo methodInfo = ((type == null || type3 == null || type4 == null) ? null : AccessTools.Method(type, "DetermineLevel", new Type[7] { typeof(Character), typeof(ZDO), type3, type4, typeof(Biome), typeof(int), typeof(bool) }, (Type[])null)); MethodInfo methodInfo2 = ((type == null || type3 == null || type4 == null) ? null : AccessTools.Method(type, "GetMaxCreatureLevel", new Type[5] { typeof(Character), type3, type4, typeof(Biome), typeof(bool?) }, (Type[])null)); if (methodInfo == null) { Log.LogWarning((object)"SLS LevelSelection.DetermineLevel signature missing; boss override disabled."); } else { val.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), "BeforeDetermine", (Type[])null), new HarmonyMethod(typeof(Plugin), "AfterDetermine", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo2 == null) { Log.LogWarning((object)"SLS LevelSelection.GetMaxCreatureLevel signature missing; progress cap disabled."); } else { val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "AfterMaximum", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } val.Patch((MethodBase)AccessTools.Method(typeof(CharacterDrop), "GenerateDropList", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "BeforeGenerateDropList", (Type[])null), new HarmonyMethod(typeof(Plugin), "RestoreDropChances", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.Method(typeof(CharacterDrop), "GenerateDropList", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "AfterGenerateDropList", (Type[])null) { priority = 200 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.Method(typeof(ZDOMan), "HandleDestroyedZDO", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "BeforeZdoDestroyed", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.Method(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "RegisterCommand", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)string.Format("{0} {1} active with StarLevelSystem {2}.", "BossKillScaling", "1.5.0", Chainloader.PluginInfos["MidnightsFX.StarLevelSystem"].Metadata.Version)); Type FindType(string name) { try { return slsAssembly.GetTypes().FirstOrDefault((Type t) => t.Name == name); } catch (ReflectionTypeLoadException ex) { return ex.Types.FirstOrDefault((Type t) => t != null && t.Name == name); } } } private static ConfigDescription AdminOnly(string description, AcceptableValueBase range = null) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } }); } private static void ParseRings(string text) { SortedDictionary<double, int> sortedDictionary = new SortedDictionary<double, int>(); string[] array = text.Split(new char[1] { ',' }); foreach (string text2 in array) { string[] array2 = text2.Split(new char[1] { ':' }); if (array2.Length == 2 && double.TryParse(array2[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && !double.IsNaN(result) && !double.IsInfinity(result) && result >= 0.0 && TryCap(array2[1], out var cap)) { sortedDictionary[result] = cap; } else { Log.LogWarning((object)("Ignoring invalid RingMaxStars entry '" + text2 + "'.")); } } if (!sortedDictionary.ContainsKey(0.0)) { sortedDictionary[0.0] = 0; } Rings = sortedDictionary; } private static void ParseProgress(string text) { List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(); string[] array = text.Split(new char[1] { ',' }); foreach (string text2 in array) { string[] array2 = text2.Split(new char[1] { ':' }); if (array2.Length == 2 && !string.IsNullOrWhiteSpace(array2[0]) && TryCap(array2[1], out var cap)) { list.Add(new KeyValuePair<string, int>(array2[0].Trim(), cap)); } else { Log.LogWarning((object)("Ignoring invalid ProgressCaps entry '" + text2 + "'.")); } } Progress = list; } private static bool TryCap(string text, out int cap) { if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out cap) && cap >= 0) { return cap < int.MaxValue; } return false; } private static string Prefab(string name) { return name.Replace("(Clone)", "").Trim(); } private static int Count(string prefab) { string s = default(string); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey("anri_bosskills_" + Prefab(prefab), ref s) && int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return Math.Max(0, result); } return 0; } private static int Formula(int k) { if (LadderMode.Value == "Blocks") { int num = k % 9 + 1; return 3 * (k / 9) + ((num != 1) ? ((int)Math.Floor(Math.Sqrt(num))) : 0); } int num2 = 0; int result = 0; for (int i = 1; i <= 1000; i++) { num2 += (int)Math.Ceiling(Math.Sqrt(i)); if (num2 > k) { break; } result = i; } return result; } private static int ProgressCap(out string key) { int result = 1; key = "none"; List<KeyValuePair<string, int>> progress = Progress; foreach (KeyValuePair<string, int> item in progress.Where((KeyValuePair<string, int> e) => e.Key.Equals("none", StringComparison.OrdinalIgnoreCase))) { result = item.Value; } foreach (KeyValuePair<string, int> item2 in progress) { if (!item2.Key.Equals("none", StringComparison.OrdinalIgnoreCase) && (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey(item2.Key)) { result = item2.Value; key = item2.Key; } } return result; } private static int RingCap(double distance) { int result = 0; foreach (KeyValuePair<double, int> ring in Rings) { if (ring.Key > distance) { break; } result = ring.Value; } return result; } private static int Stars(string prefab, double distance) { string key; return Math.Min(Formula(Count(prefab)), Math.Min(RingCap(distance), Math.Min(ProgressCap(out key), MaxStars.Value))); } private static void BeforeDetermine(ZDO __1, out bool __state) { __state = __1 != null && __1.GetInt(ZDOVars.s_level, 0) > 0; } private static void AfterDetermine(Character __0, ZDO __1, int __5, bool __6, bool __state, ref int __result) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!(!Enabled.Value || (Object)(object)__0 == (Object)null || __1 == null || __state) && __0.IsBoss() && !__0.IsTamed() && __6 && __5 == 0) { Vector3 position = ((Component)__0).transform.position; string text = Prefab(((Object)((Component)__0).gameObject).name); __result = 1 + Stars(text, Math.Sqrt((double)position.x * (double)position.x + (double)position.z * (double)position.z)); if (Verbose.Value) { Log.LogInfo((object)$"{text}: kills={Count(text)}, next spawn stars={__result - 1}."); } } } private static void AfterMaximum(ref int __result) { if (Enabled.Value && ApplyProgressCapToAllCreatures.Value) { __result = Math.Min(__result, ProgressCap(out var _) + 1); } } private static void BeforeZdoDestroyed(ZDOID uid) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || (Object)(object)ZoneSystem.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || ZDOMan.instance == null) { return; } ZDO zDO = ZDOMan.instance.GetZDO(uid); if (zDO == null) { return; } int prefab = zDO.GetPrefab(); if (!BossPrefabs.TryGetValue(prefab, out var value)) { GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); Character val = (((Object)(object)prefab2 == (Object)null) ? null : prefab2.GetComponent<Character>()); value = (((Object)(object)val != (Object)null && val.m_boss) ? Prefab(((Object)prefab2).name) : null); BossPrefabs[prefab] = value; } if (value != null && !zDO.GetBool(ZDOVars.s_tamed, false)) { int num = Math.Max(0, zDO.GetInt(ZDOVars.s_level, 1) - 1); int num2 = Count(value); int num3 = Formula(num2); bool flag = (CountCappedKills.Value || num >= num3) && num2 < int.MaxValue; if (flag) { ZoneSystem.instance.SetGlobalKey("anri_bosskills_" + value + " " + (num2 + 1).ToString(CultureInfo.InvariantCulture)); } if (Verbose.Value) { Log.LogInfo((object)($"{value} destroyed on server: stars={num}, uncapped requirement={num3}, counter={num2}; " + (flag ? (((num < num3) ? "counted (capped fight); " : "counted; ") + $"increment requested to {num2 + 1}.") : "skipped (clipped or counter full)."))); } } } catch (Exception ex) { if (!ZdoDestroyWarningLogged) { ZdoDestroyWarningLogged = true; Log.LogWarning((object)("Server boss kill counting failed: " + ex.Message)); } } } private static bool Equipment(ItemType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected I4, but got Unknown switch (type - 3) { case 0: case 1: case 2: case 3: case 4: case 8: case 11: case 12: case 14: case 15: case 16: case 17: case 19: return true; default: return false; } } private static bool CappedPrefab(GameObject prefab, HashSet<string> extra, HashSet<string> ignore) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) ItemDrop val = (((Object)(object)prefab == (Object)null) ? null : prefab.GetComponent<ItemDrop>()); string item = (((Object)(object)prefab == (Object)null) ? "" : Prefab(((Object)prefab).name)); if ((Object)(object)val != (Object)null && !ignore.Contains(item)) { if (!extra.Contains(item)) { return Equipment(val.m_itemData.m_shared.m_itemType); } return true; } return false; } private static void BeforeGenerateDropList(CharacterDrop __instance, out List<KeyValuePair<Drop, float>> __state) { __state = null; try { float value = BossEquipmentChanceMultiplier.Value; if (!CapBossEquipment.Value || value == 1f) { return; } Character val = DropCharacter.Invoke(__instance); if ((Object)(object)val == (Object)null || !val.IsBoss() || __instance.m_drops == null) { return; } HashSet<string> extra = new HashSet<string>(from e in BossEquipmentExtraPrefabs.Value.Split(new char[1] { ',' }) select e.Trim(), StringComparer.Ordinal); HashSet<string> ignore = new HashSet<string>(from e in BossEquipmentIgnorePrefabs.Value.Split(new char[1] { ',' }) select e.Trim(), StringComparer.Ordinal); __state = new List<KeyValuePair<Drop, float>>(); foreach (Drop drop in __instance.m_drops) { if (CappedPrefab(drop.m_prefab, extra, ignore)) { __state.Add(new KeyValuePair<Drop, float>(drop, drop.m_chance)); } } foreach (KeyValuePair<Drop, float> item in __state) { item.Key.m_chance = Mathf.Clamp01(item.Value * value); } if (!Verbose.Value) { return; } foreach (KeyValuePair<Drop, float> item2 in __state) { Log.LogInfo((object)$"{Prefab(((Object)((Component)val).gameObject).name)} equipment drop chance {Prefab(((Object)item2.Key.m_prefab).name)}: {item2.Value} -> {item2.Key.m_chance}."); } } catch (Exception ex) { RestoreDropChances(__state); __state = null; if (!DropChanceWarningLogged) { DropChanceWarningLogged = true; Log.LogWarning((object)("Boss equipment drop chance adjustment failed: " + ex.Message)); } } } private static void RestoreDropChances(List<KeyValuePair<Drop, float>> __state) { if (__state == null) { return; } foreach (KeyValuePair<Drop, float> item in __state) { item.Key.m_chance = item.Value; } } private static void AfterGenerateDropList(CharacterDrop __instance, List<KeyValuePair<GameObject, int>> __result) { Character val = DropCharacter.Invoke(__instance); if (!CapBossEquipment.Value || (Object)(object)val == (Object)null || !val.IsBoss() || __result == null) { return; } HashSet<string> extra = new HashSet<string>(from e in BossEquipmentExtraPrefabs.Value.Split(new char[1] { ',' }) select e.Trim(), StringComparer.Ordinal); HashSet<string> ignore = new HashSet<string>(from e in BossEquipmentIgnorePrefabs.Value.Split(new char[1] { ',' }) select e.Trim(), StringComparer.Ordinal); Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal); Dictionary<string, long> dictionary2 = new Dictionary<string, long>(StringComparer.Ordinal); List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); int num = Math.Max(0, BossEquipmentMaxCount.Value); foreach (KeyValuePair<GameObject, int> item in __result) { string key = (((Object)(object)item.Key == (Object)null) ? "" : Prefab(((Object)item.Key).name)); if (!CappedPrefab(item.Key, extra, ignore)) { list.Add(item); continue; } if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = list.Count); dictionary2[key] = 0L; list.Add(new KeyValuePair<GameObject, int>(item.Key, 0)); } dictionary2[key] += item.Value; list[value] = new KeyValuePair<GameObject, int>(list[value].Key, (int)Math.Min(num, dictionary2[key])); } __result.Clear(); __result.AddRange(list); if (!Verbose.Value) { return; } foreach (KeyValuePair<string, long> item2 in dictionary2) { if (item2.Value > num) { Log.LogInfo((object)$"{Prefab(((Object)((Component)val).gameObject).name)} equipment drop {item2.Key}: {item2.Value} -> {num}."); } } } private static void RegisterCommand() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__45_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { double result; int result2; if ((Object)(object)ZoneSystem.instance == (Object)null) { args.Context.AddString("No world loaded."); } else if (args.Args.Length == 1) { foreach (string item in from k in ZoneSystem.instance.GetGlobalKeys() where k.StartsWith("anri_bosskills_", StringComparison.OrdinalIgnoreCase) orderby k select k) { args.Context.AddString(item); } string key; int num = ProgressCap(out key); args.Context.AddString($"Progress cap: {num} stars ({key})."); } else if (args.Args.Length == 4 && args.Args[1].Equals("preview", StringComparison.OrdinalIgnoreCase) && double.TryParse(args.Args[3], NumberStyles.Float, CultureInfo.InvariantCulture, out result) && result >= 0.0 && !double.IsInfinity(result)) { args.Context.AddString($"{Prefab(args.Args[2])}: kills={Count(args.Args[2])}, distance={result.ToString(CultureInfo.InvariantCulture)}m, next spawn={Stars(args.Args[2], result)} stars."); } else if (args.Args.Length == 3 && int.TryParse(args.Args[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out result2) && result2 >= 0) { ZoneSystem.instance.SetGlobalKey("anri_bosskills_" + Prefab(args.Args[1]) + " " + result2.ToString(CultureInfo.InvariantCulture)); args.Context.AddString($"Requested {Prefab(args.Args[1])} counter = {result2}."); } else { args.Context.AddString("Usage: bosskills | bosskills <prefab> <n> | bosskills preview <prefab> <distance>"); } }; <>c.<>9__45_0 = val; obj = (object)val; } new ConsoleCommand("bosskills", "bosskills [<prefab> <n> | preview <prefab> <distance>]", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } }
ChestButlerPullFix.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ChestButlerPullFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ChestButlerPullFix")] [assembly: AssemblyTitle("ChestButlerPullFix")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ChestButlerPullFix { [BepInPlugin("anri.chestbutlerpullfix", "ChestButlerPullFix", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string GUID = "anri.chestbutlerpullfix"; public const string NAME = "ChestButlerPullFix"; public const string VERSION = "1.0.0"; private static ConfigEntry<bool> Enabled; private static ConfigEntry<bool> Verbose; private static ManualLogSource Log; private static bool _loggedException; private void Awake() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("PullFix", "Enabled", true, "Claim ownership of the destination chest before a ChestButler pull so the pulled items are saved; prevents item loss when another player owned the chest."); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("PullFix", "Verbose", false, "Log each destination chest ownership claim."); if (!Chainloader.PluginInfos.ContainsKey("eksolutions.chestbutler")) { Log.LogInfo((object)"ChestButlerPullFix: ChestButler is not loaded; skipping pull fixes."); return; } Assembly assembly = ((object)Chainloader.PluginInfos["eksolutions.chestbutler"].Instance).GetType().Assembly; MethodInfo methodInfo = AccessTools.Method(assembly.GetType("ChestButler.Core.PullerStorage"), "Pull", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("ChestButler.Core.Puller"), "PullInto", (Type[])null, (Type[])null); Harmony val = new Harmony("anri.chestbutlerpullfix"); HarmonyMethod val2 = new HarmonyMethod(typeof(Plugin), "ClaimDest", (Type[])null); List<string> list = new List<string>(); if (methodInfo == null) { Log.LogWarning((object)"ChestButler.Core.PullerStorage.Pull not found; skipping patch."); } else { val.Patch((MethodBase)methodInfo, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); list.Add("ChestButler.Core.PullerStorage.Pull"); } if (methodInfo2 == null) { Log.LogWarning((object)"ChestButler.Core.Puller.PullInto not found; skipping patch."); } else { val.Patch((MethodBase)methodInfo2, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); list.Add("ChestButler.Core.Puller.PullInto"); } Log.LogInfo((object)("ChestButlerPullFix 1.0.0 loaded. Patched: " + ((list.Count == 0) ? "none" : string.Join(", ", list)) + ".")); } private static void ClaimDest(Container dest) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown try { if (!Enabled.Value || (Object)(object)dest == (Object)null) { return; } ZNetView val = (ZNetView)AccessTools.Field(typeof(Container), "m_nview").GetValue(dest); if (!((Object)(object)val == (Object)null) && val.IsValid() && !val.IsOwner()) { val.ClaimOwnership(); if (Verbose.Value) { Log.LogInfo((object)"Claimed destination chest ownership before ChestButler pull."); } } } catch (Exception arg) { if (!_loggedException) { _loggedException = true; Log.LogWarning((object)$"ChestButler destination ownership claim failed: {arg}"); } } } } }
EnchantTableChestFix.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EpicLoot_UnityLib; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyCompany("EnchantTableChestFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EnchantTableChestFix")] [assembly: AssemblyTitle("EnchantTableChestFix")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 EnchantTableChestFix { [BepInPlugin("anri.enchanttablechestfix", "EnchantTableChestFix", "1.4.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string GUID = "anri.enchanttablechestfix"; public const string NAME = "EnchantTableChestFix"; public const string VERSION = "1.4.0"; private const string AZU_GUID = "Azumatt.AzuCraftyBoxes"; private const string MUC_GUID = "com.maxsch.valheim.MultiUserChest"; private const string EPICLOOT_GUID = "randyknapp.mods.epicloot"; internal static ManualLogSource Log; internal static ConfigEntry<float> FallbackRange; internal static ConfigEntry<bool> Verbose; internal static ConfigEntry<bool> MatchChest; internal static ConfigEntry<string> SourcePrefab; internal static ConfigEntry<bool> CopyHealth; internal static ConfigEntry<bool> FixBaseLevelRefund; internal static ConfigEntry<bool> CostBelowIcon; internal static ConfigEntry<bool> CostOutline; internal static ConfigEntry<float> CostFontScale; private static bool CostLabelsWarned; private static bool CostClippingLogged; private static bool DurabilityWarned; private static bool RefundWarned; [ThreadStatic] private static bool _inTableRefund; private static readonly FieldRef<Container, ZNetView> ContainerNView = AccessTools.FieldRefAccess<Container, ZNetView>("m_nview"); private void Awake() { //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Expected O, but got Unknown //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; FallbackRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FallbackRange", 30f, "Search radius (m) for chests to claim, used only if AzuCraftyBoxes' own Container Range cannot be read."); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Verbose", false, "Log every chest that gets claimed."); MatchChest = ((BaseUnityPlugin)this).Config.Bind<bool>("TableDurability", "MatchChest", true, "Copy the damage resistances of a vanilla chest onto EpicLoot's enchanting table so poison clouds and the like cannot damage it."); SourcePrefab = ((BaseUnityPlugin)this).Config.Bind<string>("TableDurability", "SourcePrefab", "piece_chest_wood", "Prefab whose WearNTear damage modifiers are copied."); CopyHealth = ((BaseUnityPlugin)this).Config.Bind<bool>("TableDurability", "CopyHealth", false, "Also copy the source prefab's WearNTear health."); FixBaseLevelRefund = ((BaseUnityPlugin)this).Config.Bind<bool>("TableRefund", "FixBaseLevelRefund", true, "When an enchanting table is deconstructed or destroyed, do not refund the cost of a feature's free starting level (EpicLoot 0.15.0 refunds Sacrifice level 1 although it is never paid)."); CostBelowIcon = ((BaseUnityPlugin)this).Config.Bind<bool>("CostLabels", "BelowIcon", true, "Move cost amounts below their icons (client-side)."); CostOutline = ((BaseUnityPlugin)this).Config.Bind<bool>("CostLabels", "Outline", true, "Give cost amounts a dark outline and bold text (client-side)."); CostFontScale = ((BaseUnityPlugin)this).Config.Bind<float>("CostLabels", "FontScale", 1f, new ConfigDescription("Scale cost amount text (client-side).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); Log.LogInfo((object)$"Cost labels: below icon={CostBelowIcon.Value}, outline={CostOutline.Value}, scale={CostFontScale.Value}"); if (!Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot")) { Log.LogInfo((object)"EnchantTableChestFix idle: EpicLoot not loaded."); return; } Harmony val = new Harmony("anri.enchanttablechestfix"); val.Patch((MethodBase)AccessTools.Method(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "MatchTableDurability", (Type[])null) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); PatchCostLabels(val); PatchTableRefund(val); PatchSetPieceDedupe(val); List<string> list = new List<string>(); string[] array = new string[2] { "Azumatt.AzuCraftyBoxes", "com.maxsch.valheim.MultiUserChest" }; foreach (string text in array) { if (!Chainloader.PluginInfos.ContainsKey(text)) { list.Add(text); } } if (list.Count > 0) { Log.LogInfo((object)("EnchantTableChestFix: chest-removal fix idle without " + string.Join(", ", list) + "; set-piece dedupe and table durability patch still active.")); return; } Log.LogInfo((object)(string.Format("Detected AzuCraftyBoxes {0}, ", Chainloader.PluginInfos["Azumatt.AzuCraftyBoxes"].Metadata.Version) + string.Format("MultiUserChest {0}, ", Chainloader.PluginInfos["com.maxsch.valheim.MultiUserChest"].Metadata.Version) + string.Format("EpicLoot {0}.", Chainloader.PluginInfos["randyknapp.mods.epicloot"].Metadata.Version))); MethodInfo methodInfo = AccessTools.Method("AzuCraftyBoxes.Compatibility.EpicLootCompat:RemoveExactItem", (Type[])null, (Type[])null); if (methodInfo == null) { Log.LogWarning((object)"AzuCraftyBoxes EpicLootCompat.RemoveExactItem not found; the mod's internals changed, fix disabled."); return; } val.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), "BeforeRemoveExactItem", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo2 = AccessTools.Method("AzuCraftyBoxes.Compatibility.EpicLootCompat:RemoveItem", (Type[])null, (Type[])null); if (methodInfo2 != null) { val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Plugin), "BeforeRemoveItemByName", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } Log.LogInfo((object)"EnchantTableChestFix 1.4.0 active: claiming chest ownership before enchanting-table removals."); } private static void PatchCostLabels(Harmony harmony) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown try { harmony.Patch((MethodBase)AccessTools.Method(typeof(MultiSelectItemListElement), "Refresh", Type.EmptyTypes, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "RefreshCostLabel", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex) { WarnCostLabels("Cost label patch failed: " + ex.Message); } } private static void RefreshCostLabel(MultiSelectItemListElement __instance) { //IL_013e: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown try { if (!__instance.ReadOnly || (Object)(object)__instance.ItemTotalQuantity == (Object)null || (Object)(object)__instance.ItemIcon == (Object)null) { return; } TMP_Text itemTotalQuantity = __instance.ItemTotalQuantity; CostLabelState costLabelState = ((Component)itemTotalQuantity).GetComponent<CostLabelState>(); if ((Object)(object)costLabelState == (Object)null) { costLabelState = ((Component)itemTotalQuantity).gameObject.AddComponent<CostLabelState>(); costLabelState.Capture(itemTotalQuantity); } itemTotalQuantity.fontSize = costLabelState.FontSize * CostFontScale.Value; if (CostBelowIcon.Value != costLabelState.BelowIcon) { RectTransform rectTransform = itemTotalQuantity.rectTransform; if (CostBelowIcon.Value) { Vector2 anchorMin = (rectTransform.anchorMax = new Vector2(0.5f, 0f)); rectTransform.anchorMin = anchorMin; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, -2f); itemTotalQuantity.alignment = (TextAlignmentOptions)514; itemTotalQuantity.enableWordWrapping = false; itemTotalQuantity.overflowMode = (TextOverflowModes)0; Rect rect = ((Graphic)__instance.ItemIcon).rectTransform.rect; rectTransform.sizeDelta = new Vector2(((Rect)(ref rect)).width + 24f, (itemTotalQuantity.preferredHeight > 0f) ? itemTotalQuantity.preferredHeight : 20f); } else { rectTransform.anchorMin = costLabelState.AnchorMin; rectTransform.anchorMax = costLabelState.AnchorMax; rectTransform.pivot = costLabelState.Pivot; rectTransform.anchoredPosition = costLabelState.Position; rectTransform.sizeDelta = costLabelState.Size; itemTotalQuantity.alignment = costLabelState.Alignment; itemTotalQuantity.enableWordWrapping = costLabelState.WordWrapping; itemTotalQuantity.overflowMode = costLabelState.Overflow; } costLabelState.BelowIcon = CostBelowIcon.Value; } if (CostBelowIcon.Value && !CostClippingLogged && ((Object)(object)((Component)__instance).GetComponentInParent<RectMask2D>(true) != (Object)null || (Object)(object)((Component)__instance).GetComponentInParent<Mask>(true) != (Object)null)) { CostClippingLogged = true; Log.LogInfo((object)"Cost labels: a parent Mask/RectMask2D is present; clipping may occur below the icon."); } if (CostOutline.Value == costLabelState.Outlined) { return; } if (CostOutline.Value) { if ((Object)(object)costLabelState.Material == (Object)null) { costLabelState.Material = new Material(itemTotalQuantity.fontSharedMaterial); } itemTotalQuantity.fontSharedMaterial = costLabelState.Material; itemTotalQuantity.outlineWidth = 0.25f; itemTotalQuantity.outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)220); itemTotalQuantity.fontStyle = (FontStyles)(itemTotalQuantity.fontStyle | 1); } else { itemTotalQuantity.fontSharedMaterial = costLabelState.OriginalMaterial; itemTotalQuantity.fontStyle = costLabelState.Style; } costLabelState.Outlined = CostOutline.Value; } catch (Exception ex) { WarnCostLabels("Cost label refresh failed: " + ex.Message); } } private static void WarnCostLabels(string message) { if (!CostLabelsWarned) { CostLabelsWarned = true; Log.LogWarning((object)message); } } private static void PatchTableRefund(Harmony harmony) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00b9: Expected O, but got Unknown //IL_00b9: Expected O, but got Unknown try { harmony.Patch((MethodBase)AccessTools.Method(typeof(EnchantingTableUpgrades), "GetUpgradeCost", new Type[2] { typeof(EnchantingFeature), typeof(int) }, (Type[])null), new HarmonyMethod(typeof(Plugin), "BeforeGetUpgradeCost", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Piece), "DropResources", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "BeforeTableRefund", (Type[])null), new HarmonyMethod(typeof(Plugin), "EndTableRefund", (Type[])null) { priority = 0 }, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "EndTableRefund", (Type[])null), (HarmonyMethod)null); } catch (Exception ex) { WarnTableRefund("Table refund patch failed: " + ex.Message); } } private static void BeforeTableRefund(Piece __instance) { _inTableRefund = false; try { _inTableRefund = FixBaseLevelRefund.Value && (Object)(object)((Component)__instance).GetComponent<EnchantingTable>() != (Object)null; } catch (Exception ex) { _inTableRefund = false; WarnTableRefund("Table refund scope failed: " + ex.Message); } } private static void EndTableRefund() { _inTableRefund = false; } private static bool BeforeGetUpgradeCost(EnchantingFeature feature, int level, ref List<InventoryItemListElement> __result) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) try { if (!_inTableRefund || level != EnchantingTable.GetDefaultFeatureLevel(feature) + 1) { return true; } List<InventoryItemListElement> list = new List<InventoryItemListElement>(); if (Verbose.Value) { Log.LogInfo((object)$"Table refund: skipped free starting level {level} for {feature}."); } __result = list; return false; } catch (Exception ex) { WarnTableRefund("Table refund suppression failed: " + ex.Message); } return true; } private static void WarnTableRefund(string message) { if (!RefundWarned) { RefundWarned = true; Log.LogWarning((object)message); } } private static void MatchTableDurability() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (!MatchChest.Value) { return; } try { GameObject prefab = ZNetScene.instance.GetPrefab("piece_enchantingtable"); WearNTear val = ((prefab != null) ? prefab.GetComponent<WearNTear>() : null); GameObject prefab2 = ZNetScene.instance.GetPrefab(SourcePrefab.Value); WearNTear val2 = ((prefab2 != null) ? prefab2.GetComponent<WearNTear>() : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { WarnTableDurability("Table durability: prefab or WearNTear missing for piece_enchantingtable or " + SourcePrefab.Value + "."); return; } val.m_damages = val2.m_damages; if (CopyHealth.Value) { val.m_health = val2.m_health; } Log.LogInfo((object)string.Format("Table durability: copied damage resistances{0} from {1} to piece_enchantingtable; poison={2}.", CopyHealth.Value ? " and health" : "", SourcePrefab.Value, val.m_damages.m_poison)); } catch (Exception ex) { WarnTableDurability("Table durability copy failed: " + ex.Message); } } private static void WarnTableDurability(string message) { if (!DurabilityWarned) { DurabilityWarned = true; Log.LogWarning((object)message); } } private static void BeforeRemoveExactItem(object __0) { ItemData item = (ItemData)((__0 is ItemData) ? __0 : null); if (item == null) { return; } ClaimChestsWhere(delegate(Inventory inv) { foreach (ItemData allItem in inv.GetAllItems()) { if (allItem == item) { return true; } if (allItem.m_shared.m_name == item.m_shared.m_name && allItem.m_quality == item.m_quality && allItem.m_variant == item.m_variant) { return true; } } return false; }); } private static void BeforeRemoveItemByName(object __0) { string name = __0 as string; if (name == null || string.IsNullOrEmpty(name)) { return; } ClaimChestsWhere(delegate(Inventory inv) { foreach (ItemData allItem in inv.GetAllItems()) { if (allItem.m_shared.m_name == name) { return true; } } return false; }); } private static void ClaimChestsWhere(Func<Inventory, bool> holds) { //IL_001c: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } float num = ReadAzuRange(); Vector3 position = ((Component)localPlayer).transform.position; int num2 = 0; Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); foreach (Container val in array) { if ((Object)(object)val == (Object)null || Vector3.Distance(((Component)val).transform.position, position) > num) { continue; } ZNetView val2 = ContainerNView.Invoke(val); if ((Object)(object)val2 == (Object)null || !val2.IsValid() || val2.IsOwner()) { continue; } Inventory inventory = val.GetInventory(); if (inventory != null && holds(inventory)) { val2.ClaimOwnership(); num2++; if (Verbose.Value) { Log.LogInfo((object)$"Claimed ownership of {((Object)val).name} at {((Component)val).transform.position}"); } } } if (num2 > 0 && Verbose.Value) { Log.LogInfo((object)$"Claimed {num2} chest(s) before enchanting-table removal."); } } private static void PatchSetPieceDedupe(Harmony harmony) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method("EpicLoot.ItemDataExtensions:GetMundaneSetPieces", (Type[])null, (Type[])null); if (methodInfo == null) { Log.LogWarning((object)"EpicLoot ItemDataExtensions.GetMundaneSetPieces not found; set-piece dedupe disabled."); return; } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "DedupeSetPieces", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"Set-piece tooltip de-duplication active."); } private static void DedupeSetPieces(ref List<string> __result) { if (__result == null || __result.Count < 2) { return; } HashSet<string> hashSet = new HashSet<string>(); List<string> list = new List<string>(__result.Count); foreach (string item in __result) { if (hashSet.Add(item)) { list.Add(item); } } __result = list; } private static float ReadAzuRange() { try { if ((AccessTools.TypeByName("AzuCraftyBoxes.AzuCraftyBoxesPlugin")?.GetField("mRange", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(null) is ConfigEntry<float> val) { return val.Value + 1f; } } catch (Exception) { } return FallbackRange.Value + 1f; } } internal sealed class CostLabelState : MonoBehaviour { internal Vector2 AnchorMin; internal Vector2 AnchorMax; internal Vector2 Pivot; internal Vector2 Position; internal Vector2 Size; internal float FontSize; internal TextAlignmentOptions Alignment; internal bool WordWrapping; internal bool BelowIcon; internal bool Outlined; internal TextOverflowModes Overflow; internal FontStyles Style; internal Material OriginalMaterial; internal Material Material; internal void Capture(TMP_Text label) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_006e: 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) RectTransform rectTransform = label.rectTransform; AnchorMin = rectTransform.anchorMin; AnchorMax = rectTransform.anchorMax; Pivot = rectTransform.pivot; Position = rectTransform.anchoredPosition; Size = rectTransform.sizeDelta; FontSize = label.fontSize; Alignment = label.alignment; WordWrapping = label.enableWordWrapping; Overflow = label.overflowMode; Style = label.fontStyle; OriginalMaterial = label.fontSharedMaterial; } private void OnDestroy() { if ((Object)(object)Material != (Object)null) { Object.Destroy((Object)(object)Material); } } } }
EpicLoot.dll
Decompiled a day 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.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using Auga; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Common; using EpicLoot; using EpicLoot.Abilities; using EpicLoot.Adventure; using EpicLoot.Adventure.Feature; using EpicLoot.Biomes; using EpicLoot.Compatibility; using EpicLoot.Compendium; using EpicLoot.Config; using EpicLoot.Crafting; using EpicLoot.CraftingV2; using EpicLoot.Data; using EpicLoot.GatedItemType; using EpicLoot.General; using EpicLoot.LegendarySystem; using EpicLoot.LootBeams; using EpicLoot.Magic; using EpicLoot.Magic.MagicItemEffects; using EpicLoot.Magic.MagicItemEffects.Helpers; using EpicLoot.MagicItemEffects; using EpicLoot.MagicItemEffects.Helpers; using EpicLoot.MagicItemEffects.Shards; using EpicLoot.Patching; using EpicLoot.QuickConfig; using EpicLoot.ShardStones; using EpicLoot.Transformation; using EpicLoot.src.Magic.MagicItemEffects.Helpers; using EpicLoot.src.Magic.MagicItemEffects.Shards; using EpicLoot_UnityLib; using GUIFramework; using HarmonyLib; using JetBrains.Annotations; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using SimpleJson; using Splatform; using StarLevelSystem; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.TextCore; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("EpicLoot")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Randy Knapp Mods")] [assembly: AssemblyProduct("EpicLoot")] [assembly: AssemblyCopyright("Copyright © Randy Knapp 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("963cf4f8-ba02-49fc-8884-97e781e6bc18")] [assembly: AssemblyFileVersion("0.13.0")] [assembly: IgnoresAccessChecksTo("assembly_googleanalytics")] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_lux")] [assembly: IgnoresAccessChecksTo("assembly_postprocessing")] [assembly: IgnoresAccessChecksTo("assembly_simplemeshcombine")] [assembly: IgnoresAccessChecksTo("assembly_sunshafts")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: IgnoresAccessChecksTo("gui_framework")] [assembly: IgnoresAccessChecksTo("SoftReferenceableAssets")] [assembly: IgnoresAccessChecksTo("Splatform")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.13.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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; } } } public static class PlayerExtensions { public static ZDO GetZDO(this Player player) { return ((Character)player).m_nview.GetZDO(); } } namespace Common { public class ConfigPositionedElement : MonoBehaviour { public ConfigEntry<TextAnchor> AnchorConfig; public ConfigEntry<Vector2> PositionConfig; protected RectTransform _rt; protected TextAnchor _currentAnchor; public virtual void Awake() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown _rt = (RectTransform)((Component)this).transform; EnsureCorrectPosition(); } public virtual void Update() { EnsureCorrectPosition(); } public virtual void EnsureCorrectPosition() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected I4, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) if (AnchorConfig != null && PositionConfig != null && (_currentAnchor != AnchorConfig.Value || !(_rt.anchoredPosition == PositionConfig.Value))) { _currentAnchor = AnchorConfig.Value; TextAnchor currentAnchor = _currentAnchor; TextAnchor val = currentAnchor; Vector2 val2 = default(Vector2); switch ((int)val) { case 0: { RectTransform rt25 = _rt; RectTransform rt26 = _rt; RectTransform rt27 = _rt; ((Vector2)(ref val2))..ctor(0f, 1f); rt27.anchorMax = val2; Vector2 pivot = (rt26.anchorMin = val2); rt25.pivot = pivot; break; } case 1: { RectTransform rt22 = _rt; RectTransform rt23 = _rt; RectTransform rt24 = _rt; ((Vector2)(ref val2))..ctor(0.5f, 1f); rt24.anchorMax = val2; Vector2 pivot = (rt23.anchorMin = val2); rt22.pivot = pivot; break; } case 2: { RectTransform rt19 = _rt; RectTransform rt20 = _rt; RectTransform rt21 = _rt; ((Vector2)(ref val2))..ctor(1f, 1f); rt21.anchorMax = val2; Vector2 pivot = (rt20.anchorMin = val2); rt19.pivot = pivot; break; } case 3: { RectTransform rt16 = _rt; RectTransform rt17 = _rt; RectTransform rt18 = _rt; ((Vector2)(ref val2))..ctor(0f, 0.5f); rt18.anchorMax = val2; Vector2 pivot = (rt17.anchorMin = val2); rt16.pivot = pivot; break; } case 4: { RectTransform rt13 = _rt; RectTransform rt14 = _rt; RectTransform rt15 = _rt; ((Vector2)(ref val2))..ctor(0.5f, 0.5f); rt15.anchorMax = val2; Vector2 pivot = (rt14.anchorMin = val2); rt13.pivot = pivot; break; } case 5: { RectTransform rt10 = _rt; RectTransform rt11 = _rt; RectTransform rt12 = _rt; ((Vector2)(ref val2))..ctor(1f, 0.5f); rt12.anchorMax = val2; Vector2 pivot = (rt11.anchorMin = val2); rt10.pivot = pivot; break; } case 6: { RectTransform rt7 = _rt; RectTransform rt8 = _rt; RectTransform rt9 = _rt; ((Vector2)(ref val2))..ctor(0f, 0f); rt9.anchorMax = val2; Vector2 pivot = (rt8.anchorMin = val2); rt7.pivot = pivot; break; } case 7: { RectTransform rt4 = _rt; RectTransform rt5 = _rt; RectTransform rt6 = _rt; ((Vector2)(ref val2))..ctor(0.5f, 0f); rt6.anchorMax = val2; Vector2 pivot = (rt5.anchorMin = val2); rt4.pivot = pivot; break; } case 8: { RectTransform rt = _rt; RectTransform rt2 = _rt; RectTransform rt3 = _rt; ((Vector2)(ref val2))..ctor(1f, 0f); rt3.anchorMax = val2; Vector2 pivot = (rt2.anchorMin = val2); rt.pivot = pivot; break; } } _rt.anchoredPosition = PositionConfig.Value; } } } internal static class ConfigUI { internal class ConfigUIInputGuard : MonoBehaviour { private bool held; internal void Hold() { if (!held) { held = true; PushInputBlock(); } } public void OnDestroy() { if (held) { held = false; PopInputBlock(); } } } internal const float RowHeight = 34f; internal const float SubRowHeight = 26f; internal const float RowGap = 4f; internal const float CloseXSize = 28f; private static int inputBlockDepth; internal static void PushInputBlock() { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { inputBlockDepth++; if (inputBlockDepth == 1) { GUIManager.BlockInput(true); } } } internal static void PopInputBlock() { if (inputBlockDepth > 0) { inputBlockDepth--; if (inputBlockDepth == 0) { GUIManager.BlockInput(false); } } } internal static GameObject NewUI(string name, Transform parent, params Type[] components) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown GameObject val = new GameObject(name, components) { layer = 5 }; if ((Object)(object)val.GetComponent<RectTransform>() == (Object)null) { val.AddComponent<RectTransform>(); } val.transform.SetParent(parent, false); return val; } internal static GameObject NewRect(string name, Transform parent, float x, float y, float w, float h) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) GameObject val = NewUI(name, parent, typeof(RectTransform)); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); val2.sizeDelta = new Vector2(w, h); val2.anchoredPosition = new Vector2(x, 0f - y); return val; } internal static GameObject NewRow(Transform parent, float width, float height) { return NewRect("Row", parent, 0f, 0f, width, height); } internal static GameObject NewLayoutRow(Transform content, float width, float height) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) GameObject val = NewUI("LayoutRow", content, typeof(RectTransform), typeof(LayoutElement)); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); val2.sizeDelta = new Vector2(width, height); LayoutElement component = val.GetComponent<LayoutElement>(); component.minHeight = height; component.preferredHeight = height; component.minWidth = width; component.preferredWidth = width; return val; } internal static void LayoutColumn(List<GameObject> rows, float x, float startY, float gap = 4f) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) float num = startY; foreach (GameObject row in rows) { if (!((Object)(object)row == (Object)null) && row.activeSelf) { RectTransform val = (RectTransform)row.transform; val.anchoredPosition = new Vector2(x, 0f - num); num += val.sizeDelta.y + gap; } } } internal static void PositionRow(GameObject row, float x, float y) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)row == (Object)null)) { ((RectTransform)row.transform).anchoredPosition = new Vector2(x, 0f - y); } } internal static GameObject CreatePanel(string title, float w, float h, out Transform body) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), w, h, true); val.AddComponent<ConfigUIInputGuard>().Hold(); AddText(val.transform, 0f, 16f, w, 34f, title, 22, (TextAnchor)4, GUIManager.Instance.ValheimYellow); body = val.transform; return val; } internal static GameObject CreateScroll(Transform parent, float x, float y, float w, float h, out Transform content, out float contentWidth) { //IL_002e: 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) GameObject val = NewRect("ScrollHolder", parent, x, y, w, h); GameObject val2 = GUIManager.Instance.CreateScrollView(val.transform, false, true, 8f, 4f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, new Color(0f, 0f, 0f, 0.5f), w, h); content = val2.transform.Find("Scroll View/Viewport/Content"); contentWidth = w - 16f; ScrollRect componentInChildren = val2.GetComponentInChildren<ScrollRect>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.scrollSensitivity = 200f; } return val2; } internal static string L(string text) { if (string.IsNullOrEmpty(text)) { return ""; } return (Localization.instance != null) ? Localization.instance.Localize(text) : text; } internal static Text AddText(Transform parent, float x, float y, float w, float h, string text, int fontSize, TextAnchor anchor, Color? color = null) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateText(L(text), parent, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, 0f - y), GUIManager.Instance.AveriaSerifBold, fontSize, (Color)(((??)color) ?? GUIManager.Instance.ValheimBeige), true, Color.black, w, h, false); RectTransform val2 = (RectTransform)val.transform; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(x, 0f - y); Text component = val.GetComponent<Text>(); component.alignment = anchor; component.horizontalOverflow = (HorizontalWrapMode)0; component.verticalOverflow = (VerticalWrapMode)0; return component; } internal static GameObject AddHeaderRow(Transform parent, float colWidth, string text, TextAnchor anchor = (TextAnchor)3) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject val = NewRow(parent, colWidth, 34f); AddText(val.transform, 0f, 0f, colWidth, 34f, text, 18, anchor, GUIManager.Instance.ValheimYellow); return val; } internal static GameObject AddTextRow(Transform parent, float colWidth, float height, string text, int fontSize, Color color, TextAnchor anchor = (TextAnchor)0) { //IL_001f: 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) GameObject val = NewRow(parent, colWidth, height); AddText(val.transform, 0f, 0f, colWidth, height, text, fontSize, anchor, color); return val; } internal static GameObject AddSpacerRow(Transform parent, float colWidth, float height) { return NewRow(parent, colWidth, height); } internal static GameObject AddDividerRow(Transform parent, float colWidth, float height = 12f) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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) GameObject val = NewRow(parent, colWidth, height); GameObject val2 = NewUI("Divider", val.transform, typeof(Image)); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(0f, 1f); val3.anchorMax = new Vector2(0f, 1f); val3.pivot = new Vector2(0f, 1f); val3.sizeDelta = new Vector2(colWidth, 2f); val3.anchoredPosition = new Vector2(0f, 0f - height * 0.5f); Image component = val2.GetComponent<Image>(); ((Graphic)component).color = new Color(0.6f, 0.5f, 0.35f, 0.6f); ((Graphic)component).raycastTarget = false; return val; } internal static void SetMessages(Text target, IList<string> errors, IList<string> warnings) { if ((Object)(object)target == (Object)null) { return; } List<string> list = new List<string>(); if (errors != null) { foreach (string error in errors) { list.Add("<color=#F87171>" + error + "</color>"); } } if (warnings != null) { foreach (string warning in warnings) { list.Add("<color=#FBBF24>" + warning + "</color>"); } } target.text = string.Join("\n", list.ToArray()); } internal static GameObject AddButton(Transform parent, float x, float y, float w, string text, UnityAction onClick, float h = 40f) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0054: 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) GameObject val = GUIManager.Instance.CreateButton(L(text), parent, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, 0f - y), w, h); RectTransform val2 = (RectTransform)val.transform; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(x, 0f - y); if (onClick != null) { ((UnityEvent)val.GetComponent<Button>().onClick).AddListener(onClick); } return val; } internal static GameObject AddCloseX(Transform panel, float panelWidth, UnityAction onClick) { return AddButton(panel, panelWidth - 28f - 16f, 12f, 28f, "X", onClick, 28f); } internal static Toggle AddToggle(Transform parent, float x, float y, float size, bool value, Action<bool> onChange) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0089: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateToggle(parent, size, size); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).localScale = Vector3.one; val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(x, 0f - y); Toggle component = val.GetComponent<Toggle>(); component.isOn = value; if (onChange != null) { ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool b) { onChange(b); }); } return component; } internal static GameObject AddToggleRow(Transform parent, float colWidth, float labelW, string label, bool value, Action<bool> onChange, bool toggleOnLeft = false) { GameObject val = NewRow(parent, colWidth, 34f); float x = (toggleOnLeft ? 0f : (labelW + 6f)); float x2 = (toggleOnLeft ? 34f : 0f); AddText(val.transform, x2, 0f, labelW, 34f, label, 15, (TextAnchor)3); AddToggle(val.transform, x, 3f, 26f, value, onChange); return val; } internal static string Fmt(float v, bool whole) { return whole ? ((int)Mathf.Round(v)).ToString(CultureInfo.InvariantCulture) : v.ToString("0.00", CultureInfo.InvariantCulture); } internal static Slider BuildSlider(Transform parent, float x, float y, float width, float min, float max, float value, bool wholeNumbers) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Expected O, but got Unknown //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Expected O, but got Unknown //IL_02dc: Unknown result type (might be due to invalid IL or missing references) GameObject val = NewUI("Slider", parent, typeof(RectTransform), typeof(Slider)); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); val2.sizeDelta = new Vector2(width, 20f); val2.anchoredPosition = new Vector2(x, 0f - y); GameObject val3 = NewUI("Background", val.transform, typeof(Image)); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = new Vector2(0f, 0.25f); val4.anchorMax = new Vector2(1f, 0.75f); val4.sizeDelta = Vector2.zero; val4.anchoredPosition = Vector2.zero; ((Graphic)val3.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.6f); GameObject val5 = NewUI("Fill Area", val.transform, typeof(RectTransform)); RectTransform val6 = (RectTransform)val5.transform; val6.anchorMin = new Vector2(0f, 0.25f); val6.anchorMax = new Vector2(1f, 0.75f); val6.sizeDelta = new Vector2(-20f, 0f); val6.anchoredPosition = Vector2.zero; GameObject val7 = NewUI("Fill", val5.transform, typeof(Image)); RectTransform val8 = (RectTransform)val7.transform; val8.sizeDelta = new Vector2(10f, 0f); ((Graphic)val7.GetComponent<Image>()).color = new Color(0.7f, 0.6f, 0.4f, 0.9f); GameObject val9 = NewUI("Handle Slide Area", val.transform, typeof(RectTransform)); RectTransform val10 = (RectTransform)val9.transform; val10.anchorMin = Vector2.zero; val10.anchorMax = Vector2.one; val10.sizeDelta = new Vector2(-20f, 0f); val10.anchoredPosition = Vector2.zero; GameObject val11 = NewUI("Handle", val9.transform, typeof(Image)); RectTransform val12 = (RectTransform)val11.transform; val12.sizeDelta = new Vector2(20f, 0f); Image component = val11.GetComponent<Image>(); component.sprite = GUIManager.Instance.GetSprite("checkbox_marker"); component.type = (Type)1; Slider component2 = val.GetComponent<Slider>(); component2.fillRect = val8; component2.handleRect = val12; ((Selectable)component2).targetGraphic = (Graphic)(object)component; component2.direction = (Direction)0; component2.minValue = min; component2.maxValue = max; component2.wholeNumbers = wholeNumbers; component2.value = Mathf.Clamp(value, min, max); GUIManager.Instance.ApplySliderStyle(component2); return component2; } internal static GameObject AddSliderRow(Transform parent, float colWidth, float labelW, float sliderW, float valueW, string label, float min, float max, float value, bool wholeNumbers, Action<float> onChange) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) GameObject val = NewRow(parent, colWidth, 34f); AddText(val.transform, 0f, 0f, labelW, 34f, label, 15, (TextAnchor)3); Slider slider = BuildSlider(val.transform, labelW, 7f, sliderW, min, max, value, wholeNumbers); float num = labelW + sliderW + 10f; GameObject val2 = GUIManager.Instance.CreateInputField(val.transform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(num, -3f), (ContentType)(wholeNumbers ? 2 : 3), (string)null, 15, valueW, 28f); RectTransform val3 = (RectTransform)val2.transform; val3.pivot = new Vector2(0f, 1f); val3.anchoredPosition = new Vector2(num, -3f); InputField box = val2.GetComponent<InputField>(); box.SetTextWithoutNotify(Fmt(slider.value, wholeNumbers)); ((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float v) { if (wholeNumbers) { v = Mathf.Round(v); } box.SetTextWithoutNotify(Fmt(v, wholeNumbers)); onChange?.Invoke(v); }); ((UnityEvent<string>)(object)box.onEndEdit).AddListener((UnityAction<string>)delegate(string str) { if (!float.TryParse(str.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { result = slider.value; } result = Mathf.Clamp(result, min, max); if (wholeNumbers) { result = Mathf.Round(result); } box.SetTextWithoutNotify(Fmt(result, wholeNumbers)); if (slider.value != result) { slider.value = result; } else { onChange?.Invoke(result); } }); return val; } internal static InputField AddTextField(Transform parent, float x, float y, float w, string value, Action<string> onCommit, ContentType contentType = (ContentType)0, string placeholder = null, int charLimit = 0) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0059: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateInputField(parent, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, 0f - y), contentType, placeholder, 15, w, 28f); RectTransform val2 = (RectTransform)val.transform; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(x, 0f - y); InputField component = val.GetComponent<InputField>(); if (charLimit > 0) { component.characterLimit = charLimit; } component.SetTextWithoutNotify(value ?? ""); if (onCommit != null) { ((UnityEvent<string>)(object)component.onEndEdit).AddListener((UnityAction<string>)delegate(string s) { onCommit(s); }); } return component; } internal static GameObject AddTextFieldRow(Transform parent, float colWidth, float labelW, float fieldW, string label, string value, Action<string> onCommit, string placeholder = null, int charLimit = 0) { GameObject val = NewRow(parent, colWidth, 34f); AddText(val.transform, 0f, 0f, labelW, 34f, label, 15, (TextAnchor)3); AddTextField(val.transform, labelW + 6f, 3f, fieldW, value, onCommit, (ContentType)0, placeholder, charLimit); return val; } internal static GameObject AddEnumCycleRow(Transform parent, float colWidth, float labelW, float ctrlW, string label, string[] options, int currentIndex, Action<int> onChange) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown GameObject val = NewRow(parent, colWidth, 34f); AddText(val.transform, 0f, 0f, labelW, 34f, label, 15, (TextAnchor)3); int idx = Mathf.Clamp(currentIndex, 0, Math.Max(0, options.Length - 1)); GameObject val2 = GUIManager.Instance.CreateButton((options.Length != 0) ? options[idx] : "", val.transform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(labelW + 6f, -2f), ctrlW, 28f); RectTransform val3 = (RectTransform)val2.transform; val3.pivot = new Vector2(0f, 1f); val3.anchoredPosition = new Vector2(labelW + 6f, -2f); Text caption = val2.GetComponentInChildren<Text>(); ((UnityEvent)val2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { if (options.Length != 0) { idx = (idx + 1) % options.Length; caption.text = options[idx]; onChange?.Invoke(idx); } }); return val; } internal static GameObject AddEnumFlagsRow(Transform parent, float colWidth, float labelW, string label, string[] names, Func<int, bool> isOn, Action<int, bool> set) { GameObject val = NewRow(parent, colWidth, 34f); AddText(val.transform, 0f, 0f, labelW, 34f, label, 15, (TextAnchor)3); float num = labelW + 6f; for (int i = 0; i < names.Length; i++) { int index = i; AddToggle(val.transform, num, 4f, 22f, isOn(index), delegate(bool on) { set(index, on); }); AddText(val.transform, num + 26f, 0f, 90f, 34f, names[index], 13, (TextAnchor)3); num += 120f; } return val; } internal static GameObject AddPickerRow(Transform parent, float colWidth, float labelW, float ctrlW, string label, string current, Func<IList<string>> options, Action<string> onPick, Func<string, bool> isKnown = null) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown GameObject val = NewRow(parent, colWidth, 34f); AddText(val.transform, 0f, 0f, labelW, 34f, label, 15, (TextAnchor)3); float num = ctrlW - 40f; InputField field = AddTextField(val.transform, labelW + 6f, 3f, num, current, delegate(string s) { onPick?.Invoke(s); }, (ContentType)0); Text marker = AddText(val.transform, labelW + 6f + num + 44f, 0f, 20f, 34f, "", 15, (TextAnchor)3, (Color?)new Color(0.98f, 0.75f, 0.14f)); Action refreshMarker = delegate { bool flag = isKnown != null && !string.IsNullOrEmpty(field.text) && !isKnown(field.text); marker.text = (flag ? "!" : ""); }; refreshMarker(); ((UnityEvent<string>)(object)field.onEndEdit).AddListener((UnityAction<string>)delegate { refreshMarker(); }); AddButton(val.transform, labelW + 6f + num + 4f, 3f, 34f, "...", (UnityAction)delegate { string title = label; IList<string> options2; if (options == null) { IList<string> list = new List<string>(); options2 = list; } else { options2 = options(); } ConfigUIPicker.ShowPicker(title, options2, field.text, delegate(string picked) { field.SetTextWithoutNotify(picked); refreshMarker(); onPick?.Invoke(picked); }); }, 28f); return val; } internal static GameObject AddStringListEditor(Transform content, float width, string label, List<string> items, Action onChanged, Func<IList<string>> options = null, Func<string, bool> isKnown = null) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown GameObject val = NewLayoutRow(content, width, 26f); AddText(val.transform, 0f, 0f, width - 90f, 26f, label, 14, (TextAnchor)3, GUIManager.Instance.ValheimOrange); AddButton(val.transform, width - 84f, 0f, 80f, "Add", (UnityAction)delegate { items.Add(""); onChanged?.Invoke(); }, 24f); for (int num = 0; num < items.Count; num++) { int index = num; GameObject val2 = NewLayoutRow(content, width, 26f); InputField field = AddTextField(val2.transform, 12f, 0f, width - 92f, items[index], delegate(string s) { items[index] = s; }, (ContentType)0); Text marker = AddText(val2.transform, width - 74f, 0f, 16f, 26f, "", 14, (TextAnchor)3, (Color?)new Color(0.98f, 0.75f, 0.14f)); Action refreshMarker = delegate { bool flag = isKnown != null && !string.IsNullOrEmpty(field.text) && !isKnown(field.text); marker.text = (flag ? "!" : ""); }; refreshMarker(); ((UnityEvent<string>)(object)field.onEndEdit).AddListener((UnityAction<string>)delegate { refreshMarker(); }); if (options != null) { AddButton(val2.transform, width - 56f, 0f, 26f, "...", (UnityAction)delegate { ConfigUIPicker.ShowPicker(label, options(), field.text, delegate(string picked) { field.SetTextWithoutNotify(picked); items[index] = picked; refreshMarker(); }); }, 24f); } AddButton(val2.transform, width - 26f, 0f, 24f, "x", (UnityAction)delegate { items.RemoveAt(index); onChanged?.Invoke(); }, 24f); } return val; } } internal enum FirstRunMode { Auto, ShowNextLaunch, Never } internal static class ConfigUIFirstRun { internal const string FolderName = "ModQuickConfig"; internal const string FileName = "FirstRun.cfg"; internal const string Section = "FirstRun"; internal const string QueueKeySuffix = ".FirstRun"; private const string LegacyPlaceholder = "\u0001"; private static string recordPath; private static readonly char[] InvalidKeyChars = new char[8] { '=', '\n', '\t', '\\', '"', '\'', '[', ']' }; internal static string RecordPath { get { if (recordPath == null) { recordPath = Path.Combine(Path.Combine(Application.persistentDataPath, "ModQuickConfig"), "FirstRun.cfg"); } return recordPath; } } internal static bool ShouldShow(string modKey, int revision, ConfigEntry<FirstRunMode> mode) { if (GUIManager.IsHeadless()) { return false; } return ModeOf(mode) switch { FirstRunMode.Never => false, FirstRunMode.ShowNextLaunch => true, _ => SeenRevision(modKey) < revision, }; } internal static int SeenRevision(string modKey) { if (GUIManager.IsHeadless() || !IsValidKey(modKey)) { return int.MaxValue; } string text = null; try { text = RecordPath; if (!File.Exists(text)) { return 0; } return Math.Max(0, BindSeen(OpenRecord(), modKey).Value); } catch (Exception ex) { ModLogger.LogWarning("Could not read the first-run record at " + text + ", so the '" + modKey + "' first-run popup is treated as seen: " + ex.Message); return int.MaxValue; } } internal static void MarkSeen(string modKey, int revision) { if (GUIManager.IsHeadless() || !IsValidKey(modKey) || revision <= 0) { return; } string text = null; try { text = RecordPath; ConfigFile val = OpenRecord(); ConfigEntry<int> val2 = BindSeen(val, modKey); if (val2.Value < revision) { val2.Value = revision; val.Save(); } } catch (Exception ex) { ModLogger.LogWarning("Could not write the first-run record at " + text + ": " + ex.Message); } } internal static bool QueueFirstRunPopup(string modKey, int revision, ConfigEntry<FirstRunMode> mode, int order, Func<bool> open, Func<bool> isOpen) { if (open == null || isOpen == null || !ShouldShow(modKey, revision, mode)) { return false; } return ConfigUIStartupPopups.Enqueue(modKey + ".FirstRun", order, () => OpenFirstRun(modKey, revision, mode, open), isOpen); } private static bool OpenFirstRun(string modKey, int revision, ConfigEntry<FirstRunMode> mode, Func<bool> open) { if (!ShouldShow(modKey, revision, mode)) { return false; } bool flag = false; if (mode != null && mode.Value == FirstRunMode.ShowNextLaunch) { mode.Value = FirstRunMode.Auto; flag = true; } bool flag2 = false; try { flag2 = open(); } finally { if (!flag2 && flag) { mode.Value = FirstRunMode.ShowNextLaunch; } } return flag2; } internal static bool TakeLegacyEntry(ConfigFile cfg, string section, string key, out string raw) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown raw = null; if (cfg == null || string.IsNullOrEmpty(section) || string.IsNullOrEmpty(key)) { return false; } bool saveOnConfigSet = cfg.SaveOnConfigSet; cfg.SaveOnConfigSet = false; try { ConfigDefinition val = new ConfigDefinition(section, key); if (cfg.ContainsKey(val)) { raw = cfg[val].GetSerializedValue(); } else { string value = cfg.Bind<string>(val, "\u0001", new ConfigDescription("Retired.", (AcceptableValueBase)null, Array.Empty<object>())).Value; raw = ((value == "\u0001") ? null : value); } cfg.Remove(val); if (saveOnConfigSet) { cfg.Save(); } } catch (Exception ex) { ModLogger.LogWarning("Could not read the retired setting [" + section + "] " + key + ": " + ex.Message); raw = null; } finally { cfg.SaveOnConfigSet = saveOnConfigSet; } return raw != null; } private static ConfigFile OpenRecord() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown BepInPlugin val = new BepInPlugin("ModQuickConfig.FirstRun", "ModQuickConfig first-run record - delete this file to see every mod's first-run popup again", "1.0.0"); return new ConfigFile(RecordPath, false, val) { SaveOnConfigSet = false }; } private static ConfigEntry<int> BindSeen(ConfigFile record, string modKey) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown return record.Bind<int>("FirstRun", modKey, 0, new ConfigDescription("The newest revision of this mod's first-run popup you have seen. 0 has not seen it; delete the line to see it again.", (AcceptableValueBase)null, Array.Empty<object>())); } private static FirstRunMode ModeOf(ConfigEntry<FirstRunMode> mode) { if (mode == null) { return FirstRunMode.Auto; } FirstRunMode value = mode.Value; return Enum.IsDefined(typeof(FirstRunMode), value) ? value : FirstRunMode.Auto; } private static bool IsValidKey(string modKey) { if (string.IsNullOrEmpty(modKey) || modKey.Trim() != modKey || modKey.IndexOfAny(InvalidKeyChars) >= 0) { ModLogger.LogError("'" + modKey + "' cannot be a first-run record key; use a plain identifier."); return false; } return true; } } internal static class ConfigUILauncher { private static Component cachedBroker; private static MethodInfo cachedRegister; private static MethodInfo cachedUnregister; private static bool loggedOwner; internal static bool IsAvailable => (Object)(object)Resolve() != (Object)null; internal static void Init() { Resolve(); } internal static bool Register(string displayName, Action openPanel) { if (string.IsNullOrEmpty(displayName) || openPanel == null) { return false; } Component val = Resolve(); if ((Object)(object)val == (Object)null) { return false; } if (cachedRegister == null) { ModLogger.LogError("The QuickConfig launcher on this machine has no compatible Register method; '" + displayName + "' will not appear in it."); return false; } try { cachedRegister.Invoke(val, new object[2] { displayName, openPanel }); return true; } catch (Exception ex) { ModLogger.LogError("Could not register '" + displayName + "' with the QuickConfig launcher: " + ex.Message); return false; } } internal static void Unregister(string displayName) { if (string.IsNullOrEmpty(displayName)) { return; } Component val = Resolve(); if ((Object)(object)val == (Object)null || cachedUnregister == null) { return; } try { cachedUnregister.Invoke(val, new object[1] { displayName }); } catch (Exception ex) { ModLogger.LogWarning("Could not unregister '" + displayName + "' from the QuickConfig launcher: " + ex.Message); } } private static Component Resolve() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if ((Object)(object)cachedBroker != (Object)null) { return cachedBroker; } cachedRegister = null; cachedUnregister = null; GameObject val = null; try { val = GameObject.Find("ModQuickConfigLauncher"); } catch (Exception) { } if ((Object)(object)val == (Object)null) { try { val = new GameObject("ModQuickConfigLauncher"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<QuickConfigBroker>(); } catch (Exception ex2) { ModLogger.LogError("Could not create the QuickConfig launcher: " + ex2.Message); return null; } } Component val2 = null; Component[] components = val.GetComponents<Component>(); foreach (Component val3 in components) { if ((Object)(object)val3 != (Object)null && ((object)val3).GetType().Name == "QuickConfigBroker") { val2 = val3; break; } } if ((Object)(object)val2 == (Object)null) { return null; } Type type = ((object)val2).GetType(); cachedRegister = type.GetMethod("Register", BindingFlags.Instance | BindingFlags.Public, null, new Type[2] { typeof(string), typeof(Action) }, null); cachedUnregister = type.GetMethod("Unregister", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); if (!loggedOwner) { loggedOwner = true; int num = 1; try { PropertyInfo property = type.GetProperty("BrokerVersion", BindingFlags.Instance | BindingFlags.Public); if (property != null) { num = (int)property.GetValue(val2, null); } } catch (Exception) { } ModLogger.LogInfo($"QuickConfig launcher v{num} owned by " + $"{type.Assembly.GetName().Name}; this mod carries v{2}."); if (num < 2) { ModLogger.LogInfo("That copy is older than this one. Registration still works; the launcher UI is whatever the owning mod shipped."); } } cachedBroker = val2; return cachedBroker; } } internal static class ConfigUIPicker { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Close; } private const float PanelW = 420f; private const float PanelH = 520f; private const float RowH = 30f; private const int MaxRows = 400; private static GameObject overlay; internal static bool IsOpen => (Object)(object)overlay != (Object)null; internal static void ShowPicker(string title, IList<string> options, string current, Action<string> onPick) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Expected O, but got Unknown Close(); if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null) { return; } List<string> all = new List<string>(); if (options != null) { foreach (string option in options) { if (!string.IsNullOrEmpty(option)) { all.Add(option); } } } all.Sort(StringComparer.OrdinalIgnoreCase); overlay = ConfigUI.NewUI("ConfigUIPickerOverlay", GUIManager.CustomGUIFront.transform, typeof(Image)); RectTransform val = (RectTransform)overlay.transform; val.anchorMin = Vector2.zero; val.anchorMax = Vector2.one; val.offsetMin = Vector2.zero; val.offsetMax = Vector2.zero; Image component = overlay.GetComponent<Image>(); ((Graphic)component).color = new Color(0f, 0f, 0f, 0.35f); Button val2 = overlay.AddComponent<Button>(); ((Selectable)val2).transition = (Transition)0; ButtonClickedEvent onClick = val2.onClick; object obj = <>O.<0>__Close; if (obj == null) { UnityAction val3 = Close; <>O.<0>__Close = val3; obj = (object)val3; } ((UnityEvent)onClick).AddListener((UnityAction)obj); overlay.AddComponent<ConfigUI.ConfigUIInputGuard>().Hold(); GameObject val4 = GUIManager.Instance.CreateWoodpanel(overlay.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 420f, 520f, true); ConfigUI.AddText(val4.transform, 0f, 14f, 420f, 30f, title, 18, (TextAnchor)4, GUIManager.Instance.ValheimYellow); InputField val5 = ConfigUI.AddTextField(val4.transform, 16f, 52f, 320f, "", null, (ContentType)0, "Filter..."); Transform transform = val4.transform; object obj2 = <>O.<0>__Close; if (obj2 == null) { UnityAction val6 = Close; <>O.<0>__Close = val6; obj2 = (object)val6; } ConfigUI.AddButton(transform, 344f, 52f, 60f, "Close", (UnityAction)obj2, 28f); ConfigUI.CreateScroll(val4.transform, 16f, 92f, 388f, 404f, out var content, out var contentW); if ((Object)(object)content == (Object)null) { return; } Action<string> rebuild = null; rebuild = delegate(string needle) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown foreach (Transform item in content) { Transform val7 = item; Object.Destroy((Object)(object)((Component)val7).gameObject); } int num = 0; foreach (string item2 in all) { if (string.IsNullOrEmpty(needle) || item2.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0) { if (num >= 400) { break; } num++; string picked = item2; GameObject val8 = ConfigUI.NewLayoutRow(content, contentW, 30f); ConfigUI.AddButton(val8.transform, 0f, 0f, contentW, picked, (UnityAction)delegate { Close(); onPick?.Invoke(picked); }, 28f); } } if (num == 0) { GameObject val9 = ConfigUI.NewLayoutRow(content, contentW, 30f); ConfigUI.AddText(val9.transform, 4f, 0f, contentW, 30f, "No matches", 14, (TextAnchor)3); } else if (num >= 400) { GameObject val10 = ConfigUI.NewLayoutRow(content, contentW, 30f); ConfigUI.AddText(val10.transform, 4f, 0f, contentW, 30f, $"... {all.Count - num} more, type to narrow", 13, (TextAnchor)3); } }; ((UnityEvent<string>)(object)val5.onValueChanged).AddListener((UnityAction<string>)delegate(string needle) { rebuild(needle); }); rebuild(""); } internal static void Close() { if (!((Object)(object)overlay == (Object)null)) { Object.Destroy((Object)(object)overlay); overlay = null; } } } internal static class ConfigUIPrompt { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Close; } private const float PanelW = 460f; private static GameObject overlay; internal static void Show(string title, string label, string initial, string warning, Action<string> onAccept) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Expected O, but got Unknown Close(); if (GUIManager.Instance != null && !((Object)(object)GUIManager.CustomGUIFront == (Object)null)) { bool flag = !string.IsNullOrEmpty(warning); float num = (flag ? 96f : 0f); float num2 = 190f + num; overlay = ConfigUI.NewUI("ConfigUIPromptOverlay", GUIManager.CustomGUIFront.transform, typeof(Image)); RectTransform val = (RectTransform)overlay.transform; val.anchorMin = Vector2.zero; val.anchorMax = Vector2.one; val.offsetMin = Vector2.zero; val.offsetMax = Vector2.zero; ((Graphic)overlay.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.45f); overlay.AddComponent<ConfigUI.ConfigUIInputGuard>().Hold(); GameObject val2 = GUIManager.Instance.CreateWoodpanel(overlay.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 460f, num2, true); ConfigUI.AddText(val2.transform, 0f, 14f, 460f, 30f, title, 18, (TextAnchor)4, GUIManager.Instance.ValheimYellow); float num3 = 56f; if (flag) { ConfigUI.AddText(val2.transform, 20f, num3, 420f, num - 8f, warning, 13, (TextAnchor)0, (Color?)new Color(0.98f, 0.75f, 0.14f)); num3 += num; } ConfigUI.AddText(val2.transform, 20f, num3, 120f, 28f, label, 15, (TextAnchor)3); InputField field = ConfigUI.AddTextField(val2.transform, 140f, num3, 300f, initial, null, (ContentType)0, null, 64); num3 += 46f; Transform transform = val2.transform; float y = num3; object obj = <>O.<0>__Close; if (obj == null) { UnityAction val3 = Close; <>O.<0>__Close = val3; obj = (object)val3; } ConfigUI.AddButton(transform, 20f, y, 190f, "Cancel", (UnityAction)obj, 34f); ConfigUI.AddButton(val2.transform, 250f, num3, 190f, "OK", (UnityAction)delegate { string text = field.text; Close(); onAccept?.Invoke(text); }, 34f); ((Selectable)field).Select(); field.ActivateInputField(); } } internal static void Close() { if (!((Object)(object)overlay == (Object)null)) { Object.Destroy((Object)(object)overlay); overlay = null; } } } internal static class ConfigUIStartupPopups { internal const int OrderWelcome = 100; internal const int OrderNotice = 200; private static Component cachedQueue; private static MethodInfo cachedEnqueue; private static MethodInfo cachedCancel; private static bool loggedOwner; internal static bool Enqueue(string key, int order, Func<bool> tryOpen, Func<bool> isOpen) { if (string.IsNullOrEmpty(key) || tryOpen == null || isOpen == null) { return false; } if (GUIManager.IsHeadless()) { return false; } Component val = Resolve(); if ((Object)(object)val == (Object)null) { return false; } if (cachedEnqueue == null) { ModLogger.LogError("The startup popup queue on this machine has no compatible Enqueue method; '" + key + "' will not be shown."); return false; } try { return (bool)cachedEnqueue.Invoke(val, new object[4] { key, order, tryOpen, isOpen }); } catch (Exception ex) { ModLogger.LogError("Could not queue the startup popup '" + key + "': " + ex.Message); return false; } } internal static void Cancel(string key) { if (string.IsNullOrEmpty(key) || GUIManager.IsHeadless()) { return; } Component val = Resolve(); if ((Object)(object)val == (Object)null || cachedCancel == null) { return; } try { cachedCancel.Invoke(val, new object[1] { key }); } catch (Exception ex) { ModLogger.LogWarning("Could not cancel the startup popup '" + key + "': " + ex.Message); } } private static Component Resolve() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if ((Object)(object)cachedQueue != (Object)null) { return cachedQueue; } cachedEnqueue = null; cachedCancel = null; GameObject val = null; try { val = GameObject.Find("ModStartupPopupQueue"); } catch (Exception) { } if ((Object)(object)val == (Object)null) { try { val = new GameObject("ModStartupPopupQueue"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<StartupPopupQueue>(); } catch (Exception ex2) { ModLogger.LogError("Could not create the startup popup queue: " + ex2.Message); return null; } } Component val2 = null; Component[] components = val.GetComponents<Component>(); foreach (Component val3 in components) { if ((Object)(object)val3 != (Object)null && ((object)val3).GetType().Name == "StartupPopupQueue") { val2 = val3; break; } } if ((Object)(object)val2 == (Object)null) { try { val2 = (Component)(object)val.AddComponent<StartupPopupQueue>(); } catch (Exception ex3) { ModLogger.LogError("Could not create the startup popup queue: " + ex3.Message); return null; } } Type type = ((object)val2).GetType(); cachedEnqueue = type.GetMethod("Enqueue", BindingFlags.Instance | BindingFlags.Public, null, new Type[4] { typeof(string), typeof(int), typeof(Func<bool>), typeof(Func<bool>) }, null); cachedCancel = type.GetMethod("Cancel", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); if (!loggedOwner) { loggedOwner = true; int num = 0; try { PropertyInfo property = type.GetProperty("QueueVersion", BindingFlags.Instance | BindingFlags.Public); if (property != null) { num = (int)property.GetValue(val2, null); } } catch (Exception) { } ModLogger.LogInfo($"Startup popup queue v{num} owned by " + $"{type.Assembly.GetName().Name}; this mod carries v{1}."); } cachedQueue = val2; return cachedQueue; } } internal class QuickConfigBroker : MonoBehaviour { internal const string BrokerObjectName = "ModQuickConfigLauncher"; internal const string BrokerTypeName = "QuickConfigBroker"; internal const string ButtonObjectName = "ModQuickConfigButton"; internal const int ContractVersion = 2; private const float ButtonW = 150f; private const float ButtonH = 38f; private const float PanelW = 320f; private static QuickConfigBroker Instance; private static Harmony harmony; private readonly Dictionary<string, Action> entries = new Dictionary<string, Action>(StringComparer.Ordinal); private readonly List<string> order = new List<string>(); private GameObject mainMenuButton; private GameObject pauseButton; private GameObject listPanel; public int BrokerVersion => 2; public void Register(string modName, Action openPanel) { if (!string.IsNullOrEmpty(modName) && openPanel != null) { if (!entries.ContainsKey(modName)) { order.Add(modName); } entries[modName] = openPanel; RefreshVisibility(); } } public void Unregister(string modName) { if (!string.IsNullOrEmpty(modName)) { if (entries.Remove(modName)) { order.Remove(modName); } if ((Object)(object)listPanel != (Object)null) { CloseList(); } RefreshVisibility(); } } public bool IsRegistered(string modName) { return !string.IsNullOrEmpty(modName) && entries.ContainsKey(modName); } public void Awake() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown Instance = this; GUIManager.OnCustomGUIAvailable += OnCustomGUIAvailable; SynchronizationManager.OnAdminStatusChanged += OnAdminStatusChanged; SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized; try { if (harmony == null) { harmony = new Harmony("ModQuickConfigLauncher.broker"); harmony.Patch((MethodBase)AccessTools.Method(typeof(Menu), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(QuickConfigBroker), "OnMenuStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Menu), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(QuickConfigBroker), "OnMenuUpdate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception ex) { ModLogger.LogWarning("QuickConfig launcher could not patch Menu: " + ex.Message); } TryBuildButtons(); } public void OnDestroy() { GUIManager.OnCustomGUIAvailable -= OnCustomGUIAvailable; SynchronizationManager.OnAdminStatusChanged -= OnAdminStatusChanged; SynchronizationManager.OnConfigurationSynchronized -= OnConfigurationSynchronized; if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void OnAdminStatusChanged() { RefreshVisibility(); } private void OnConfigurationSynchronized(object sender, EventArgs e) { RefreshVisibility(); } private static void OnMenuStart(Menu __instance) { if (!((Object)(object)Instance == (Object)null)) { Instance.EnsurePauseButton(__instance); } } private static bool OnMenuUpdate() { if ((Object)(object)Instance == (Object)null || (Object)(object)Instance.listPanel == (Object)null) { return true; } if (!ZInput.GetKeyDown((KeyCode)27, true)) { return true; } Instance.CloseList(); return false; } public void Update() { if (!((Object)(object)listPanel == (Object)null) && !((Object)(object)Menu.instance != (Object)null) && Input.GetKeyDown((KeyCode)27)) { CloseList(); } } private void OnCustomGUIAvailable() { TryBuildButtons(); } private void TryBuildButtons() { if (!GUIManager.IsHeadless() && GUIManager.Instance != null) { if ((Object)(object)FejdStartup.instance != (Object)null && (Object)(object)GUIManager.CustomGUIFront != (Object)null) { mainMenuButton = EnsureCornerButton(mainMenuButton, GUIManager.CustomGUIFront.transform); } if ((Object)(object)Menu.instance != (Object)null) { EnsurePauseButton(Menu.instance); } RefreshVisibility(); } } private void EnsurePauseButton(Menu menu) { if (!((Object)(object)menu == (Object)null) && !((Object)(object)menu.m_root == (Object)null)) { pauseButton = EnsureCornerButton(pauseButton, menu.m_root); RefreshVisibility(); } } private GameObject EnsureCornerButton(GameObject existing, Transform parent) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown if (GUIManager.IsHeadless() || GUIManager.Instance == null || (Object)(object)parent == (Object)null) { return existing; } if ((Object)(object)existing != (Object)null && (Object)(object)existing.transform.parent == (Object)(object)parent) { return existing; } Transform val = parent.Find("ModQuickConfigButton"); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } GameObject val2 = GUIManager.Instance.CreateButton(ConfigUI.L("Mod Config"), parent, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-20f, 20f), 150f, 38f); ((Object)val2).name = "ModQuickConfigButton"; RectTransform val3 = (RectTransform)val2.transform; val3.pivot = new Vector2(1f, 0f); val3.anchoredPosition = new Vector2(-20f, 20f); ((UnityEvent)val2.GetComponent<Button>().onClick).AddListener(new UnityAction(OpenList)); return val2; } private static bool CanConfigure() { if (GUIManager.IsHeadless() || GUIManager.Instance == null) { return false; } if ((Object)(object)ZNet.instance == (Object)null) { return true; } if (ZNet.instance.IsServer()) { return true; } return SynchronizationManager.Instance != null && SynchronizationManager.Instance.PlayerIsAdmin; } private void RefreshVisibility() { bool flag = entries.Count > 0 && CanConfigure(); if ((Object)(object)mainMenuButton != (Object)null) { mainMenuButton.SetActive(flag && (Object)(object)FejdStartup.instance != (Object)null); } if ((Object)(object)pauseButton != (Object)null) { pauseButton.SetActive(flag); } if (!flag && (Object)(object)listPanel != (Object)null) { CloseList(); } } private void OpenList() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown CloseList(); if (!CanConfigure()) { return; } if (order.Count == 1) { Invoke(order[0]); return; } float h = Mathf.Clamp(80f + 42f * (float)order.Count, 122f, 560f); listPanel = ConfigUI.CreatePanel("Configure a mod", 320f, h, out var body); ConfigUI.AddCloseX(body, 320f, new UnityAction(CloseList)); float num = 64f; foreach (string item in order) { string entry = item; ConfigUI.AddButton(body, 20f, num, 280f, entry, (UnityAction)delegate { CloseList(); Invoke(entry); }); num += 42f; } } private void CloseList() { if (!((Object)(object)listPanel == (Object)null)) { Object.Destroy((Object)(object)listPanel); listPanel = null; } } private void Invoke(string modName) { if (!entries.TryGetValue(modName, out var value) || value == null) { return; } try { value(); } catch (Exception arg) { ModLogger.LogError($"The config panel for '{modName}' failed to open: {arg}"); } } } internal class StartupPopupQueue : MonoBehaviour { private sealed class Entry { internal string Key; internal int Order; internal long Sequence; internal Func<bool> TryOpen; internal Func<bool> IsOpen; } internal const string QueueObjectName = "ModStartupPopupQueue"; internal const string QueueTypeName = "StartupPopupQueue"; internal const string PanelGuardTypeName = "ConfigUIInputGuard"; internal const int ContractVersion = 1; private const float FirstPopupDelay = 1f; private const float BetweenPopupsDelay = 0.5f; private readonly List<Entry> pending = new List<Entry>(); private readonly List<MonoBehaviour> componentBuffer = new List<MonoBehaviour>(); private Entry current; private long nextSequence; private float readySince = -1f; private bool shownThisVisit; private FejdStartup visit; public int QueueVersion => 1; public bool Enqueue(string key, int order, Func<bool> tryOpen, Func<bool> isOpen) { if (string.IsNullOrEmpty(key) || tryOpen == null || isOpen == null) { return false; } if (current != null && string.Equals(current.Key, key, StringComparison.Ordinal)) { return false; } Entry entry = FindPending(key); if (entry != null) { entry.Order = order; entry.TryOpen = tryOpen; entry.IsOpen = isOpen; return true; } pending.Add(new Entry { Key = key, Order = order, Sequence = nextSequence++, TryOpen = tryOpen, IsOpen = isOpen }); return true; } public void Cancel(string key) { Entry entry = FindPending(key); if (entry != null) { pending.Remove(entry); } } public bool IsQueued(string key) { if (string.IsNullOrEmpty(key)) { return false; } if (current != null && string.Equals(current.Key, key, StringComparison.Ordinal)) { return true; } return FindPending(key) != null; } public void Update() { if (current == null && pending.Count == 0) { return; } FejdStartup instance = FejdStartup.instance; if ((Object)(object)instance == (Object)null) { current = null; readySince = -1f; return; } if ((Object)(object)instance != (Object)(object)visit) { visit = instance; shownThisVisit = false; readySince = -1f; } if (current != null) { if (StillOpen(current)) { return; } current = null; readySince = -1f; } if (pending.Count == 0) { return; } if (!MainMenuReady(instance)) { readySince = -1f; return; } float unscaledTime = Time.unscaledTime; if (readySince < 0f) { readySince = unscaledTime; } else { if (unscaledTime - readySince < (shownThisVisit ? 0.5f : 1f)) { return; } while (pending.Count > 0) { Entry entry = TakeFirst(); if (TryOpen(entry)) { current = entry; shownThisVisit = true; readySince = -1f; break; } } } } private bool MainMenuReady(FejdStartup startup) { return !CinematicsManager.IsStartedPlaying() && (Object)(object)startup.m_mainMenu != (Object)null && startup.m_mainMenu.activeInHierarchy && (Object)(object)startup.m_menuList != (Object)null && startup.m_menuList.activeInHierarchy && ((Object)(object)startup.m_connectionFailedPanel == (Object)null || !startup.m_connectionFailedPanel.activeInHierarchy) && !UnifiedPopup.IsVisible() && (Object)(object)GUIManager.CustomGUIFront != (Object)null && !KitPanelOpen(); } private bool KitPanelOpen() { Transform transform = GUIManager.CustomGUIFront.transform; for (int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); if (!((Component)child).gameObject.activeSelf) { continue; } ((Component)child).GetComponents<MonoBehaviour>(componentBuffer); foreach (MonoBehaviour item in componentBuffer) { if ((Object)(object)item != (Object)null && ((object)item).GetType().Name == "ConfigUIInputGuard") { return true; } } } return false; } private Entry FindPending(string key) { if (string.IsNullOrEmpty(key)) { return null; } foreach (Entry item in pending) { if (string.Equals(item.Key, key, StringComparison.Ordinal)) { return item; } } return null; } private Entry TakeFirst() { Entry entry = pending[0]; foreach (Entry item in pending) { if (item.Order < entry.Order || (item.Order == entry.Order && item.Sequence < entry.Sequence)) { entry = item; } } pending.Remove(entry); return entry; } private static bool TryOpen(Entry entry) { bool flag = false; try { flag = entry.TryOpen(); } catch (Exception arg) { ModLogger.LogError($"The startup popup '{entry.Key}' failed to open: {arg}"); } if (flag) { return true; } return StillOpen(entry); } private static bool StillOpen(Entry entry) { try { return entry.IsOpen(); } catch (Exception ex) { ModLogger.LogWarning("Could not tell whether the startup popup '" + entry.Key + "' is still open, treating it as closed: " + ex.Message); return false; } } } [Serializable] public class RecipeRequirementConfig { public string item = ""; public int amount = 1; } [Serializable] public class RecipeConfig { public string name = ""; public string item = ""; public int amount = 1; public string craftingStation = ""; public int minStationLevel = 1; public bool enabled = true; public string repairStation = ""; public List<RecipeRequirementConfig> resources = new List<RecipeRequirementConfig>(); } [Serializable] public class RecipesConfig { public List<RecipeConfig> recipes = new List<RecipeConfig>(); } public static class GameObjectExtensions { public static RectTransform RectTransform(this GameObject go) { Transform transform = go.transform; return (RectTransform)(object)((transform is RectTransform) ? transform : null); } public static T RequireComponent<T>(this GameObject go) where T : Component { T component = go.GetComponent<T>(); return ((Object)(object)component == (Object)null) ? go.AddComponent<T>() : component; } } public class GotDestroyed : MonoBehaviour { public void OnDisable() { Debug.LogError((object)("I got destroyed! (" + ((Object)((Component)this).gameObject).name + ")")); Debug.Log((object)Environment.StackTrace); } } public static class AssetBundleLoader { private static readonly List<Stream> _liveStreams = new List<Stream>(); public static AssetBundle LoadFromResources(string filename, Assembly assembly) { if (assembly == null) { throw new ArgumentNullException("assembly"); } string text = assembly.GetName().Name + "." + filename; try { Stream manifestResourceStream = assembly.GetManifestResourceStream(text); if (manifestResourceStream == null) { ModLogger.LogError("Embedded asset bundle '" + text + "' not found in " + assembly.GetName().Name + "."); return null; } AssetBundle val = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)val == (Object)null) { manifestResourceStream.Dispose(); ModLogger.LogError("Embedded asset bundle '" + text + "' failed to load."); return null; } _liveStreams.Add(manifestResourceStream); return val; } catch (Exception ex) { ModLogger.LogError("Failed to load embedded asset bundle '" + text + "': " + ex.Message); return null; } } public static AssetBundle LoadIntoContext(string filename, Assembly assembly) { AssetBundle val = LoadFromResources(filename, assembly); if ((Object)(object)val != (Object)null) { ModContext.AssetBundle = val; } return val; } } public static class AudioMixerMocks { public static void Resolve(GameObject root, string fallbackGroup = null) { if ((Object)(object)root == (Object)null) { return; } AudioSource[] componentsInChildren = root.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val in componentsInChildren) { PrefabExtension.FixReferences((object)val); if ((Object)(object)val.outputAudioMixerGroup == (Object)null && fallbackGroup != null) { val.outputAudioMixerGroup = Cache.GetPrefab<AudioMixerGroup>(fallbackGroup); } } } } public static class ConfigBinder { private static ConfigFile Cfg => ModContext.Cfg; public static ConfigEntry<bool> BindServerConfig(string category, string key, bool value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_002f: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown return Cfg.Bind<bool>(category, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, IsAdvanced = advanced } })); } public static ConfigEntry<int> BindServerConfig(string category, string key, int value, string description, bool advanced = false, int valMin = 0, int valMax = 150) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown return Cfg.Bind<int>(category, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(valMin, valMax), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, IsAdvanced = advanced } })); } public static ConfigEntry<float> BindServerConfig(string category, string key, float value, string description, bool advanced = false, float valMin = 0f, float valMax = 150f) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown return Cfg.Bind<float>(category, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valMin, valMax), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, IsAdvanced = advanced } })); } public static ConfigEntry<string> BindServerConfig(string category, string key, string value, string description, AcceptableValueList<string> acceptableValues = null, bool advanced = false) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_002f: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown return Cfg.Bind<string>(category, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, IsAdvanced = advanced } })); } public static ConfigEntry<T> BindServerConfig<T>(string category, string key, T value, string description, AcceptableValueBase acceptableValues, bool advanced = false) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_002f: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown return Cfg.Bind<T>(category, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, IsAdvanced = advanced } })); } public static ConfigEntry<T> BindClientConfig<T>(string category, string key, T value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_002f: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown return Cfg.Bind<T>(category, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = false, IsAdvanced = advanced } })); } public static ConfigEntry<T> BindServerConfigInOrder<T>(string category, string key, T value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false) { //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_0027: Expected O, but got Unknown return ConfigFileExtensions.BindConfigInOrder<T>(Cfg, category, key, value, description, true, true, true, acceptableValues, (Action<ConfigEntryBase>)null, new ConfigurationManagerAttributes { IsAdvanced = advanced }); } public static ConfigEntry<T> BindClientConfigInOrder<T>(string category, string key, T value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false) { //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_0027: Expected O, but got Unknown return ConfigFileExtensions.BindConfigInOrder<T>(Cfg, category, key, value, description, false, true, true, acceptableValues, (Action<ConfigEntryBase>)null, new ConfigurationManagerAttributes { IsAdvanced = advanced }); } } public static class ConfigChangeDebouncer { private static readonly Dictionary<object, Action> pendingActions = new Dictionary<object, Action>(); private static readonly Dictionary<object, float> fireAt = new Dictionary<object, float>(); private static readonly HashSet<object> running = new HashSet<object>(); public static void Schedule(object key, Action action) { float num = ((ModContext.ConfigApplyDelay != null) ? ModContext.ConfigApplyDelay.Value : 0f); if (num <= 0f) { action(); return; } ThreadingHelper instance = ThreadingHelper.Instance; if (!((Object)(object)instance == (Object)null)) { pendingActions[key] = action; fireAt[key] = Time.realtimeSinceStartup + num; if (!running.Contains(key)) { running.Add(key); ((MonoBehaviour)instance).StartCoroutine(Run(key)); } } } private static IEnumerator Run(object key) { float at; while (fireAt.TryGetValue(key, out at) && Time.realtimeSinceStartup < at) { yield return null; } pendingActions.TryGetValue(key, out var action); pendingActions.Remove(key); fireAt.Remove(key); running.Remove(key); action?.Invoke(); } } internal static class ConfigDrawHelpers { private static readonly Dictionary<object, string> TextBuffer = new Dictionary<object, string>(); private static readonly Dictionary<object, float> SliderPending = new Dictionary<object, float>(); private static GUIStyle _headerButton; private static GUIStyle _groupLabel; private static GUIStyle _dim; internal static GUIStyle HeaderButton => _headerButton; internal static GUIStyle Dim => _dim; internal static void EnsureStyles() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown if (_headerButton == null) { _headerButton = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)3, fontStyle = (FontStyle)1 }; _groupLabel = new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1 }; _dim = new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)2, fontSize = 11 }; } } internal static ConfigurationManagerAttributes GetAttributes(ConfigEntryBase entry) { object result; if (entry == null) { result = null; } else { ConfigDescription description = entry.Description; result = ((description == null) ? null : description.Tags?.OfType<ConfigurationManagerAttributes>().FirstOrDefault()); } return (ConfigurationManagerAttributes)result; } internal static void Hide(ConfigEntryBase entry) { ConfigurationManagerAttributes attributes = GetAttributes(entry); if (attributes != null) { attributes.Browsable = false; } } internal static void GroupHeader(string text) { GUILayout.Space(4f); GUILayout.Label(text, _groupLabel, Array.Empty<GUILayoutOption>()); } private static bool EnterPressed() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 return (int)Event.current.type == 4 && ((int)Event.current.keyCode == 13 || (int)Event.current.keyCode == 271); } internal static void DrawBool(string label, ConfigEntry<bool> cfg) { bool flag = GUILayout.Toggle(cfg.Value, " " + label, Array.Empty<GUILayoutOption>()); if (flag != cfg.Value) { cfg.Value = flag; } } internal static void DrawString(string label, ConfigEntry<string> cfg) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }); string text = "str_" + ((object)cfg).GetHashCode(); GUI.SetNextControlName(text); bool flag = GUI.GetNameOfFocusedControl() == text; string value; string text2 = ((flag && TextBuffer.TryGetValue(cfg, out value)) ? value : cfg.Value); string text3 = GUILayout.TextField(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }); string value2; if (flag) { TextBuffer[cfg] = text3; if (EnterPressed() && cfg.Value != text3) { cfg.Value = text3; } } else if (TextBuffer.TryGetValue(cfg, out value2)) { if (cfg.Value != value2) { cfg.Value = value2; } TextBuffer.Remove(cfg); } GUILayout.EndHorizontal(); } internal static void DrawChoice(string label, ConfigEntry<string> cfg) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }); if (((ConfigEntryBase)cfg).Description.AcceptableValues is AcceptableValueList<string> val && val.AcceptableValues.Length != 0) { string[] acceptableValues = val.AcceptableValues; int num = Array.IndexOf(acceptableValues, cfg.Value); if (num < 0) { num = 0; } if (GUILayout.Button("◄", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) })) { cfg.Value = acceptableValues[(num - 1 + acceptableValues.Length) % acceptableValues.Length]; } GUILayout.Label(cfg.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) }); if (GUILayout.Button("►", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) })) { cfg.Value = acceptableValues[(num + 1) % acceptableValues.Length]; } } else { GUILayout.Label(cfg.Value, Array.Empty<GUILayoutOption>()); } GUILayout.EndHorizontal(); } internal static void DrawFloat(string label, ConfigEntry<float> cfg) { float num = 0f; float num2 = Mathf.Max(100f, cfg.Value); if (((ConfigEntryBase)cfg).Description.AcceptableValues is AcceptableValueRange<float> val) { num = val.MinValue; num2 = val.MaxValue; } float num3 = DrawSliderRow(label, cfg, cfg.Value, num, num2, isInt: false); if (num3 != cfg.Value) { cfg.Value = Mathf.Clamp(num3, num, num2); } } internal static void DrawInt(string label, ConfigEntry<int> cfg) { float num = 0f; float num2 = Mathf.Max(100f, (float)cfg.Value); if (((ConfigEntryBase)cfg).Description.AcceptableValues is AcceptableValueRange<int> val) { num = val.MinValue; num2 = val.MaxValue; } float num3 = DrawSliderRow(label, cfg, cfg.Value, num, num2, isInt: true); int num4 = Mathf.Clamp(Mathf.RoundToInt(num3), (int)num, (int)num2); if (num4 != cfg.Value) { cfg.Value = num4; } } private static float DrawSliderRow(string label, object key, float current, float min, float max, bool isInt) { float num = current; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }); float value; float num2 = (SliderPending.TryGetValue(key, out value) ? value : current); float num3 = GUILayout.HorizontalSlider(num2, min, max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); if (Mathf.Abs(num3 - num2) > Mathf.Epsilon) { SliderPending[key] = num3; } if (SliderPending.TryGetValue(key, out var value2) && !Input.GetMouseButton(0)) { SliderPending.Remove(key); num = value2; } float value3; float num4 = (SliderPending.TryGetValue(key, out value3) ? value3 : num); string text = "num_" + key.GetHashCode(); GUI.SetNextControlName(text); bool flag = GUI.GetNameOfFocusedControl() == text; string text2 = (isInt ? Mathf.RoundToInt(num4).ToString() : num4.ToString("0.###")); string value4; string text3 = ((flag && TextBuffer.TryGetValue(key, out value4)) ? value4 : text2); string text4 = GUILayout.TextField(text3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }); string value5; if (flag) { TextBuffer[key] = text4; if (EnterPressed() && float.TryParse(text4, out var result)) { num = result; } } else if (TextBuffer.TryGetValue(key, out value5)) { if (float.TryParse(value5, out var result2)) { num = result2; } TextBuffer.Remove(key); } GUILayout.Label("[" + (isInt ? min.ToString() : min.ToString("0.#")) + " - " + (isInt ? max.ToString() : max.ToString("0.#")) + "]", _dim, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); GUILayout.EndHorizontal(); return num; } } internal static class ItemConfigDrawer { private static readonly Dictionary<string, bool> Expanded = new Dictionary<string, bool>(); private static readonly Dictionary<object, List<string[]>> RecipeRows = new Dictionary<object, List<string[]>>(); private static int _order = 0; private static readonly KeyValuePair<string, ItemStat[]>[] StatGroups = new KeyValuePair<string, ItemStat[]>[5] { new KeyValuePair<string, ItemStat[]>("Damage", new ItemStat[20] { ItemStat.slash, ItemStat.slash_per_level, ItemStat.blunt, ItemStat.blunt_per_level, ItemStat.pierce, ItemStat.pierce_per_level, ItemStat.fire, ItemStat.fire_per_level, ItemStat.lightning, ItemStat.lightning_per_level, ItemStat.frost, ItemStat.frost_per_level, ItemStat.poison, ItemStat.poison_per_level, ItemStat.spirit, ItemStat.spirit_per_level, ItemStat.pickaxe, ItemStat.pickaxe_per_level, ItemStat.chop, ItemStat.chop_per_level }), new KeyValuePair<string, ItemStat[]>("Combat", new ItemStat[20] { ItemStat.attack_force, ItemStat.primary_attack_force_multiply, ItemStat.secondary_attack_force_multiply, ItemStat.primary_attack_stamina, ItemStat.primary_attack_eitr, ItemStat.primary_attack_flat_health_cost, ItemStat.primary_attack_percent_health_cost, ItemStat.primary_attack_health_returned, ItemStat.primary_attack_damage_bonus_per_missing_hp, ItemStat.primary_attack_projectile_count, ItemStat.secondary_attack_stamina, ItemStat.secondary_attack_eitr, ItemStat.secondary_attack_flat_health_cost, ItemStat.secondary_attack_percent_health_cost, ItemStat.projectile_velocity, ItemStat.projectile_accuracy_max, ItemStat.bow_draw_speed, ItemStat.crossbow_reload_speed, ItemStat.crossbow_reload_stamina_drain, ItemStat.draw_stamina_drain }), new KeyValuePair<string, ItemStat[]>("Defense", new ItemStat[5] { ItemStat.block_armor, ItemStat.block_armor_per_level, ItemStat.parry, ItemStat.block_force, ItemStat.block_force_per_level }), new KeyValuePair<string, ItemSta
GatedLootUnidentified.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EpicLoot; using EpicLoot.Biomes; using EpicLoot.Crafting; using EpicLoot.CraftingV2; using EpicLoot.Data; using EpicLoot.GatedItemType; using EpicLoot.LegendarySystem; using EpicLoot_UnityLib; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyCompany("GatedLootUnidentified")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("GatedLootUnidentified")] [assembly: AssemblyTitle("GatedLootUnidentified")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 GatedLootUnidentified { internal static class BossUniqueRarity { private static ConfigEntry<bool> enabled; private static ConfigEntry<bool> verbose; private static ConfigEntry<string> weights; private static ConfigEntry<string> ignorePrefabs; private static readonly string[] Names = new string[5] { "Plain", "Magic", "Rare", "Epic", "Legendary" }; private static readonly ItemRarity[] Rarities; internal static void Apply(Harmony harmony, ConfigFile config) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown enabled = config.Bind<bool>("BossUniqueRarity", "Enabled", true, Plugin.Synced("Roll rarity for enchantable equipment in vanilla boss drops.")); weights = config.Bind<string>("BossUniqueRarity", "Weights", "Plain:45,Magic:35,Rare:15,Epic:4,Legendary:1", Plugin.Synced("Rarity:weight pairs; locked weights fold into the next lower unlocked rarity.")); ignorePrefabs = config.Bind<string>("BossUniqueRarity", "IgnorePrefabs", "", Plugin.Synced("Comma-separated item prefab names that are never converted.")); verbose = config.Bind<bool>("BossUniqueRarity", "Verbose", false, "Log boss, prefab and result for each equipment copy."); harmony.Patch((MethodBase)AccessTools.Method(typeof(CharacterDrop), "GenerateDropList", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BossUniqueRarity), "ConvertDrops", (Type[])null) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static string Clean(string prefab) { return (prefab ?? "").Replace("(Clone)", "").Trim(); } private static double[] Weights(string boss) { double[] array = new double[Names.Length]; string[] array2 = (weights.Value ?? "").Split(new char[1] { ',' }); foreach (string text in array2) { string[] parts = text.Split(new char[1] { ':' }); if (parts.Length == 2) { int num = Array.FindIndex(Names, (string name) => string.Equals(name, parts[0].Trim(), StringComparison.OrdinalIgnoreCase)); if (num >= 0 && double.TryParse(parts[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && !double.IsNaN(result) && !double.IsInfinity(result)) { array[num] = Math.Max(0.0, result); } } } double num2 = array.Max(); if (num2 > 0.0) { for (int num3 = 0; num3 < array.Length; num3++) { array[num3] /= num2; } } for (int num4 = array.Length - 1; num4 > 0; num4--) { if (!ProgressionLoot.BossUniqueUnlocked(Rarities[num4 - 1], boss)) { array[num4 - 1] += array[num4]; array[num4] = 0.0; } } return array; } private static int Roll(double[] odds) { double max = odds.Max(); if (max <= 0.0) { return 0; } double num = odds.Sum((double x) => x / max); double num2 = (double)Random.value * num; int result = 0; for (int num3 = 0; num3 < odds.Length; num3++) { if (!(odds[num3] <= 0.0)) { result = num3; num2 -= odds[num3] / max; if (num2 < 0.0) { return num3; } } } return result; } private static void ConvertDrops(CharacterDrop __instance, Character ___m_character, List<KeyValuePair<GameObject, int>> __result) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) List<GameObject> list = new List<GameObject>(); try { if (!enabled.Value || (Object)(object)___m_character == (Object)null || !___m_character.IsBoss() || __result == null) { return; } string text = Clean(((Object)((Component)___m_character).gameObject).name); HashSet<string> hashSet = new HashSet<string>((ignorePrefabs.Value ?? "").Split(new char[1] { ',' }).Select(Clean), StringComparer.OrdinalIgnoreCase); double[] odds = Weights(text); List<KeyValuePair<GameObject, int>> list2 = new List<KeyValuePair<GameObject, int>>(); Vector3 val = ___m_character.GetCenterPoint() + ((Component)__instance).transform.TransformVector(__instance.m_spawnOffset); foreach (KeyValuePair<GameObject, int> item in __result) { ItemDrop val2 = (((Object)(object)item.Key != (Object)null) ? item.Key.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null || hashSet.Contains(Clean(((Object)item.Key).name)) || !EpicLoot.CanBeMagicItem(val2.m_itemData) || item.Value <= 0) { list2.Add(item); continue; } int num = item.Value; for (int i = 0; i < item.Value; i++) { int num2 = Roll(odds); if (num2 != 0) { GameObject val3 = LootRoller.SpawnLootForDrop(item.Key, val, true); list.Add(val3); ItemDrop component = val3.GetComponent<ItemDrop>(); ItemData itemData = component.m_itemData; MagicItemComponent component2 = ItemExtensions.Data(itemData).GetOrCreate<MagicItemComponent>(""); MagicItem magic = LootRoller.RollMagicItem(Rarities[num2 - 1], itemData, LootRoller.GetLuckFactor(val), 1f); if (LootRoller.CheatForceMagicEffect) { LootRoller.AddDebugMagicEffects(magic); } AccessTools.Method(typeof(API), "WithChangeReason", (Type[])null, (Type[])null).Invoke(null, new object[2] { "LootRoll", (Action)delegate { component2.SetMagicItem(magic); } }); AccessTools.Method(typeof(ItemDrop), "Save", (Type[])null, (Type[])null).Invoke(component, null); AccessTools.Method(typeof(LootRoller), "InitializeMagicItem", (Type[])null, (Type[])null).Invoke(null, new object[1] { itemData }); AccessTools.Method(typeof(API), "RaiseLootGenerated", (Type[])null, (Type[])null).Invoke(null, new object[1] { itemData }); num--; } if (verbose.Value) { Plugin.Log.LogInfo((object)("BossUniqueRarity boss=" + text + ", prefab=" + Clean(((Object)item.Key).name) + ", result=" + Names[num2])); } } if (num > 0) { list2.Add(new KeyValuePair<GameObject, int>(item.Key, num)); } } __result.Clear(); __result.AddRange(list2); } catch (Exception arg) { foreach (GameObject item2 in list) { try { if (!((Object)(object)item2 == (Object)null)) { if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(item2); } else { Object.Destroy((Object)(object)item2); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("BossUniqueRarity cleanup failed: " + ex.Message)); } } Plugin.Log.LogWarning((object)$"BossUniqueRarity failed; leaving vanilla drops untouched: {arg}"); } } static BossUniqueRarity() { ItemRarity[] array = new ItemRarity[4]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); Rarities = (ItemRarity[])(object)array; } } [BepInPlugin("anri.gatedlootunidentified", "GatedLootUnidentified", "1.11.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal struct UnlockCost { public string Item; public int Amount; } public const string GUID = "anri.gatedlootunidentified"; public const string NAME = "GatedLootUnidentified"; public const string VERSION = "1.11.4"; private const string EPICLOOT_GUID = "randyknapp.mods.epicloot"; internal static ManualLogSource Log; internal static ConfigEntry<bool> GatedDropsBecomeUnidentified; internal static ConfigEntry<float> GatedDropChance; internal static ConfigEntry<bool> BlockIdentifyUntilBossKilled; internal static ConfigEntry<string> UnlockCosts; internal static ConfigEntry<float> PerItemCostFraction; internal static ConfigEntry<bool> AllowPerItemPayment; internal static ConfigEntry<bool> RequireTableLevel; internal static ConfigEntry<string> TableLevelByBiome; internal static ConfigEntry<bool> Verbose; internal static ConfigEntry<string> IdentifyCostLabel; internal static ConfigEntry<bool> IdentifySelectsOne; internal static ConfigEntry<float> ExplainerFontScale; internal static ConfigEntry<bool> HideUndiscoveredPreview; internal static ConfigEntry<string> UndiscoveredName; internal static ConfigEntry<string> AugmentDetailsMode; internal static ConfigEntry<bool> AugmentDetailsAltKey; internal static ConfigEntry<bool> AugmentDetailsTooltips; internal static ConfigEntry<float> AugmentDetailsTextScale; internal static ConfigEntry<bool> RuneLabelsEnabled; internal static ConfigEntry<float> HintFontScale; internal static ConfigEntry<string> SetEtchLabel; internal static ConfigEntry<string> SetExtractLabel; internal static ConfigEntry<string> SetEtchAction; internal static ConfigEntry<string> SetExtractAction; internal static ConfigEntry<string> SetExtractHint; internal static ConfigEntry<string> SetEtchHint; internal static ConfigEntry<bool> SetDiscoveryEnabled; internal static ConfigEntry<bool> SetDiscoveryUnlockToast; internal static ConfigEntry<bool> SetDiscoverySetToast; internal static ConfigEntry<string> SetDiscoveryUnlockTopic; internal static ConfigEntry<string> SetDiscoveryUnlockDescription; internal static ConfigDescription Synced(string description, AcceptableValueBase values = null) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return new ConfigDescription(description, values, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } }); } private void Awake() { //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Expected O, but got Unknown //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Expected O, but got Unknown //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Expected O, but got Unknown //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Expected O, but got Unknown //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Expected O, but got Unknown //IL_050b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; GatedDropsBecomeUnidentified = ((BaseUnityPlugin)this).Config.Bind<bool>("Drops", "GatedDropsBecomeUnidentified", true, Synced("When EpicLoot rolls an item that is gated behind a boss you have not killed, drop it as an unidentified item of its real tier instead of downgrading it to current-tier gear.")); GatedDropChance = ((BaseUnityPlugin)this).Config.Bind<float>("Drops", "GatedDropChance", 1f, Synced("Fraction (0-1) of such gated drops that become unidentified. The rest are downgraded as EpicLoot normally does.")); BlockIdentifyUntilBossKilled = ((BaseUnityPlugin)this).Config.Bind<bool>("Identify", "BlockIdentifyUntilBossKilled", true, Synced("Lock identifying an unidentified item until its biome boss is dead, the tier is unlocked at the table, or the per-item fee is paid. Off = EpicLoot's default (identifies as lower-tier loot).")); UnlockCosts = ((BaseUnityPlugin)this).Config.Bind<string>("Identify", "UnlockCosts", "BlackForest:Bronze:20,Swamp:Iron:30,Mountain:Silver:40,Plains:BlackMetal:40,Mistlands:Eitr:20,AshLands:FlametalNew:20,DeepNorth:Gold:20", Synced("Permanent, world-wide unlock cost per biome as Biome:ItemPrefab:Amount. Paid once at the enchanting table with the Unlock button; afterwards everyone can identify that tier without the boss kill.")); PerItemCostFraction = ((BaseUnityPlugin)this).Config.Bind<float>("Identify", "PerItemCostFraction", 0.1f, Synced("Identify a single locked item by paying this fraction of the biome's unlock cost (rounded up, minimum 1) on top of the normal identify cost.")); AllowPerItemPayment = ((BaseUnityPlugin)this).Config.Bind<bool>("Identify", "AllowPerItemPayment", true, Synced("Allow the per-item payment path.")); RequireTableLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("Identify", "RequireTableLevel", false, Synced("Additionally require the table's Sacrifice feature level to reach the value in TableLevelByBiome. This is a hard lock that no payment bypasses.")); TableLevelByBiome = ((BaseUnityPlugin)this).Config.Bind<string>("Identify", "TableLevelByBiome", "Meadows:0,BlackForest:1,Ocean:1,Swamp:2,Mountain:3,Plains:4,Mistlands:5,AshLands:6,DeepNorth:7", Synced("Minimum Sacrifice feature level per biome, as Biome:Level pairs. Only used when RequireTableLevel is on.")); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Verbose", false, "Log drop conversions, refusals, payments and unlocks."); IdentifyCostLabel = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "IdentifyCostLabel", "Identify Cost:", "Text shown above the cost list while the Identify tab is selected (EpicLoot shows 'Enchant Cost:' there). Empty = leave EpicLoot's label."); IdentifySelectsOne = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "IdentifySelectsOne", true, "In the Identify tab, clicking a stack of unidentified items selects one instead of the whole stack. Type a number in the quantity box to identify more."); ExplainerFontScale = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ExplainerFontScale", 1.4f, "Multiplier for the font size of the small explainer text above the product list on the Sacrifice/Identify panel. 1 = EpicLoot's size."); HideUndiscoveredPreview = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "HideUndiscoveredPreview", true, "In the Identify tab's preview of possible results, items the player has never picked up are shown as a question mark instead of their real icon and name."); UndiscoveredName = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "UndiscoveredName", "Undiscovered", "Name shown for hidden preview entries."); AugmentDetailsMode = ((BaseUnityPlugin)this).Config.Bind<string>("AugmentDetails", "Mode", "Shift", new ConfigDescription("Shift = show effect descriptions in the Augment tab's Available Effects list while Shift (or Alt, see AltKey) is held; Always = always show them; Off = EpicLoot default.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Shift", "Always", "Off" }), Array.Empty<object>())); AugmentDetailsAltKey = ((BaseUnityPlugin)this).Config.Bind<bool>("AugmentDetails", "AltKey", true, "Also accept Left/Right Alt as the details key."); AugmentDetailsTooltips = ((BaseUnityPlugin)this).Config.Bind<bool>("AugmentDetails", "Tooltips", true, "Hovering an effect in the Augment tab's left column shows its description in a tooltip."); AugmentDetailsTextScale = ((BaseUnityPlugin)this).Config.Bind<float>("AugmentDetails", "TextScale", 0.8f, new ConfigDescription("Font size of the description lines relative to the effect line.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 1f), Array.Empty<object>())); RuneLabelsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("RuneLabels", "Enabled", true, "Relabel the Rune tab's set modes and extend their explanations."); HintFontScale = ((BaseUnityPlugin)this).Config.Bind<float>("RuneLabels", "HintFontScale", 1.3f, new ConfigDescription("Multiplier for the font size of the Rune tab's warning/hint text (EpicLoot's sentence plus our hint). 1 = EpicLoot's size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>())); SetEtchLabel = ((BaseUnityPlugin)this).Config.Bind<string>("RuneLabels", "SetEtchLabel", "Legendary Set Etch", "Label for the set etch mode."); SetExtractLabel = ((BaseUnityPlugin)this).Config.Bind<string>("RuneLabels", "SetExtractLabel", "Legendary Set Extract", "Label for the set extract mode."); SetEtchAction = ((BaseUnityPlugin)this).Config.Bind<string>("RuneLabels", "SetEtchAction", "Etch Legendary Set Rune", "Main button text for set etch."); SetExtractAction = ((BaseUnityPlugin)this).Config.Bind<string>("RuneLabels", "SetExtractAction", "Extract Legendary Set Rune", "Main button text for set extract."); SetExtractHint = ((BaseUnityPlugin)this).Config.Bind<string>("RuneLabels", "SetExtractHint", "Only EpicLoot set pieces qualify: Legendary or better gear whose tooltip names a set, such as Heimdall, Ragnar or Thor. Vanilla armour sets like Root or Troll Leather are not sets here. Equipped items are not listed.", "Explanation appended to the set extract warning."); SetEtchHint = ((BaseUnityPlugin)this).Config.Bind<string>("RuneLabels", "SetEtchHint", "You need a set rune from Legendary Set Extract first. Targets are magic items that are not already a unique or set piece, at the rune's rarity, in a slot the set has a piece for.", "Explanation appended to the set etch warning."); SetDiscoveryEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("SetDiscovery", "Enabled", true, "Hide the Rune tab's set modes until the character has had an EpicLoot set piece in their inventory."); SetDiscoveryUnlockToast = ((BaseUnityPlugin)this).Config.Bind<bool>("SetDiscovery", "UnlockToast", true, "Show an unlock message the first time a set is discovered."); SetDiscoveryUnlockTopic = ((BaseUnityPlugin)this).Config.Bind<string>("SetDiscovery", "UnlockTopic", "Legendary Set Etch unlocked", "Topic of the first set unlock message."); SetDiscoveryUnlockDescription = ((BaseUnityPlugin)this).Config.Bind<string>("SetDiscovery", "UnlockDescription", "You found a piece of a legendary set. Extract and etch set runes at the enchanting table.", "Description of the first set unlock message."); SetDiscoverySetToast = ((BaseUnityPlugin)this).Config.Bind<bool>("SetDiscovery", "SetToast", true, "Also show a message for each newly discovered set, naming it."); if (!Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot")) { Log.LogInfo((object)"GatedLootUnidentified idle: EpicLoot not loaded."); return; } try { Harmony val = new Harmony("anri.gatedlootunidentified"); Patches.Apply(val); ProgressionLoot.Apply(val, ((BaseUnityPlugin)this).Config); BossUniqueRarity.Apply(val, ((BaseUnityPlugin)this).Config); Log.LogInfo((object)string.Format("{0} {1} active with EpicLoot {2}.", "GatedLootUnidentified", "1.11.4", Chainloader.PluginInfos["randyknapp.mods.epicloot"].Metadata.Version)); } catch (Exception arg) { Log.LogError((object)string.Format("{0} failed to patch EpicLoot (its internals probably changed): {1}", "GatedLootUnidentified", arg)); } } internal static Dictionary<string, int> ParseLevelMap() { Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); string[] array = (TableLevelByBiome.Value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length == 2 && int.TryParse(array2[1].Trim(), out var result)) { dictionary[array2[0].Trim()] = result; } } return dictionary; } internal static Dictionary<string, UnlockCost> ParseUnlockCosts() { Dictionary<string, UnlockCost> dictionary = new Dictionary<string, UnlockCost>(StringComparer.OrdinalIgnoreCase); string[] array = (UnlockCosts.Value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length == 3 && int.TryParse(array2[2].Trim(), out var result) && result > 0) { dictionary[array2[0].Trim()] = new UnlockCost { Item = array2[1].Trim(), Amount = result }; } } return dictionary; } } internal static class Patches { private struct IdentifyState { public HashSet<Biome> Bypass; public HashSet<Biome> Identify; public bool GateLogged; } private const string KeyPrefix = "anri_identify_unlocked_"; private static FieldRef<MultiSelectItemListElement, IListElement> _listElementItem; private static bool _selectQuantityWarningLogged; private static bool _previewWarningLogged; private static readonly MethodInfo _memberwiseClone = AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null); private static Sprite _questionSprite; private static FieldRef<AugmentUI, List<Toggle>> _augmentSelectors; private static bool _lastDetails; private static bool _augmentWarningLogged; private static bool _augmentTooltipWarningLogged; private static bool _augmentPrefabLogged; private static readonly MethodInfo _addWord = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null); private static bool _runeLabelsWarningLogged; private static bool _runeHintWarningLogged; private const string SetDiscoveryKey = "anri.gatedloot.sets"; private static FieldRef<RuneUI, Toggle> _setEtchButton; private static FieldRef<RuneUI, Toggle> _setExtractButton; private static bool _hasDiscoveredSet; private static bool _setDiscoveryWarningLogged; private static readonly Dictionary<TMP_Text, float> _runeBaseFontSize = new Dictionary<TMP_Text, float>(); private static readonly FieldInfo _localizationInstance = AccessTools.Field(typeof(Localization), "m_instance"); [ThreadStatic] private static HashSet<Biome> _bypassBiomes; [ThreadStatic] private static HashSet<Biome> _identifyBiomes; [ThreadStatic] private static bool _identifyGateLogged; [ThreadStatic] private static bool _checkingBossLock; private static bool _itemGateWarningLogged; private static readonly MethodInfo _getBossKeyForMode = AccessTools.Method(typeof(GatedItemTypeHelper), "GetBossKeyForMode", (Type[])null, (Type[])null); private static readonly Dictionary<SacrificeUI, Button> _unlockButtons = new Dictionary<SacrificeUI, Button>(); private static readonly Dictionary<SacrificeUI, TMP_Text> _costLabels = new Dictionary<SacrificeUI, TMP_Text>(); private static readonly Dictionary<TMP_Text, float> _baseFontSize = new Dictionary<TMP_Text, float>(); private static string _costLabelOriginal; private static Sprite QuestionSprite { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_questionSprite != (Object)null) { return _questionSprite; } string[] array = new string[16] { "................", ".....######.....", "....##....##....", "...##......##...", "...##......##...", "...........##...", "..........##....", ".........##.....", "........##......", ".......##.......", ".......##.......", "................", "................", ".......##.......", ".......##.......", "................" }; Texture2D val = new Texture2D(16, 16, (TextureFormat)4, false) { filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { val.SetPixel(j, 15 - i, (Color)((array[i][j] == '#') ? new Color(0.9f, 0.85f, 0.6f, 1f) : Color.clear)); } } val.Apply(); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 16f, 16f), new Vector2(0.5f, 0.5f), 16f); ((Object)obj).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); Object.DontDestroyOnLoad((Object)(object)obj); _questionSprite = obj; return obj; } } private static HashSet<string> DiscoveredSets(Player p) { HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); if ((Object)(object)p != (Object)null && p.m_customData.TryGetValue("anri.gatedloot.sets", out var value)) { string[] array = (value ?? "").Split(new char[1] { ',' }); foreach (string text in array) { if (!string.IsNullOrWhiteSpace(text)) { hashSet.Add(text.Trim()); } } } return hashSet; } private static bool HasDiscoveredAnySet(Player p) { return DiscoveredSets(p).Count > 0; } private static void WarnSetDiscovery(Exception e) { if (!_setDiscoveryWarningLogged) { _setDiscoveryWarningLogged = true; Plugin.Log.LogWarning((object)$"Set discovery failed: {e}"); } } private static void Discover(Player p, ItemData item, bool toast) { try { MagicItem val = default(MagicItem); if (!Plugin.SetDiscoveryEnabled.Value || (Object)(object)p == (Object)null || item == null || !ItemDataExtensions.IsMagic(item, ref val) || string.IsNullOrEmpty(val.SetID)) { return; } HashSet<string> hashSet = DiscoveredSets(p); bool flag = hashSet.Count == 0; if (!hashSet.Add(val.SetID)) { return; } p.m_customData["anri.gatedloot.sets"] = string.Join(",", hashSet); _hasDiscoveredSet = true; if (toast && !((Object)(object)MessageHud.instance == (Object)null)) { if (flag && Plugin.SetDiscoveryUnlockToast.Value) { MessageHud.instance.QueueUnlockMsg(QuestionSprite, Localization.instance.Localize(Plugin.SetDiscoveryUnlockTopic.Value), Localization.instance.Localize(Plugin.SetDiscoveryUnlockDescription.Value)); } if (Plugin.SetDiscoverySetToast.Value) { LegendarySetInfo val2 = default(LegendarySetInfo); string text = (UniqueLegendaryHelper.TryGetLegendarySetInfo(val.SetID, ref val2) ? val2.Name : val.SetID); MessageHud.instance.QueueUnlockMsg(QuestionSprite, Localization.instance.Localize("Set discovered"), Localization.instance.Localize(text)); } } } catch (Exception e) { WarnSetDiscovery(e); } } private static void AddKnownItem_Postfix(Player __instance, ItemData item) { try { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Discover(__instance, item, toast: true); } } catch (Exception e) { WarnSetDiscovery(e); } } private static void OnSpawned_Postfix(Player __instance) { try { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } _hasDiscoveredSet = HasDiscoveredAnySet(__instance); foreach (ItemData allItem in ((Humanoid)__instance).GetInventory().GetAllItems()) { Discover(__instance, allItem, toast: true); } } catch (Exception e) { WarnSetDiscovery(e); } } private static void RuneAwake_Postfix(RuneUI __instance) { RuneUpdate_Postfix(__instance); try { if (!Plugin.RuneLabelsEnabled.Value) { return; } Toggle val = _setEtchButton.Invoke(__instance); Toggle val2 = _setExtractButton.Invoke(__instance); if ((Object)(object)val != (Object)null) { TMP_Text[] componentsInChildren = ((Component)val).GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = Localization.instance.Localize(Plugin.SetEtchLabel.Value); } } if ((Object)(object)val2 != (Object)null) { TMP_Text[] componentsInChildren = ((Component)val2).GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = Localization.instance.Localize(Plugin.SetExtractLabel.Value); } } } catch (Exception arg) { if (!_runeLabelsWarningLogged) { _runeLabelsWarningLogged = true; Plugin.Log.LogWarning((object)$"Rune labels failed: {arg}"); } } } private static void RuneOnEnable_Postfix(RuneUI __instance) { RuneUpdate_Postfix(__instance); } private static void RuneUpdate_Postfix(RuneUI __instance) { try { bool flag = !Plugin.SetDiscoveryEnabled.Value || (Object)(object)Player.m_localPlayer == (Object)null || _hasDiscoveredSet; if (_setEtchButton == null) { _setEtchButton = AccessTools.FieldRefAccess<RuneUI, Toggle>("_setEtchButton"); } if (_setExtractButton == null) { _setExtractButton = AccessTools.FieldRefAccess<RuneUI, Toggle>("_setExtractButton"); } Toggle val = _setEtchButton.Invoke(__instance); Toggle val2 = _setExtractButton.Invoke(__instance); if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf != flag) { ((Component)val).gameObject.SetActive(flag); } if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeSelf != flag) { ((Component)val2).gameObject.SetActive(flag); } } catch (Exception e) { WarnSetDiscovery(e); } } internal static void ApplyRuneLabels(Localization __instance) { try { if (Plugin.RuneLabelsEnabled.Value && __instance != null) { if (_addWord == null) { throw new MissingMethodException("Localization.AddWord not found"); } _addWord.Invoke(__instance, new object[2] { "mod_epicloot_rune_setetch", Plugin.SetEtchLabel.Value }); _addWord.Invoke(__instance, new object[2] { "mod_epicloot_rune_setextract", Plugin.SetExtractLabel.Value }); _addWord.Invoke(__instance, new object[2] { "mod_epicloot_rune_setetch_action", Plugin.SetEtchAction.Value }); _addWord.Invoke(__instance, new object[2] { "mod_epicloot_rune_setextract_action", Plugin.SetExtractAction.Value }); } } catch (Exception arg) { if (!_runeLabelsWarningLogged) { _runeLabelsWarningLogged = true; Plugin.Log.LogWarning((object)$"Rune labels failed: {arg}"); } } } private static void RuneSelectMode_Postfix(RuneUI __instance, object action) { try { if (!Plugin.RuneLabelsEnabled.Value || (Object)(object)__instance.Warning == (Object)null) { return; } int num = Convert.ToInt32(action); if (num == 2 || num == 3) { string text = ((num == 2) ? Plugin.SetExtractHint.Value : Plugin.SetEtchHint.Value); if (Localization.instance != null) { text = Localization.instance.Localize(text); } TMP_Text warning = __instance.Warning; warning.text = warning.text + "\n<color=#c0c0c0ff>" + text + "</color>"; } TMP_Text warning2 = __instance.Warning; if (Plugin.HintFontScale.Value > 0f) { if (!_runeBaseFontSize.TryGetValue(warning2, out var value)) { value = warning2.fontSize; _runeBaseFontSize[warning2] = value; } warning2.enableAutoSizing = false; warning2.fontSize = value * Plugin.HintFontScale.Value; } } catch (Exception arg) { if (!_runeHintWarningLogged) { _runeHintWarningLogged = true; Plugin.Log.LogWarning((object)$"Rune hints failed: {arg}"); } } } private static bool AugmentDetailsActive() { if (Plugin.AugmentDetailsMode.Value == "Off") { return false; } if (Plugin.AugmentDetailsMode.Value == "Always") { return true; } if (!MagicItem.ShowEffectDetails) { if (Plugin.AugmentDetailsAltKey.Value) { if (!ZInput.GetKey((KeyCode)308, true)) { return ZInput.GetKey((KeyCode)307, true); } return true; } return false; } return true; } private static bool IsAugmentEffectLine(string line) { line = line.TrimStart(Array.Empty<char>()); while (line.StartsWith("<", StringComparison.Ordinal)) { int num = line.IndexOf('>'); if (num < 0) { break; } line = line.Substring(num + 1).TrimStart(Array.Empty<char>()); } return line.StartsWith("‣ ", StringComparison.Ordinal); } private static void GetAvailableAugmentEffects_Postfix(ItemData item, int augmentindex, ref string __result) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) try { if (!AugmentDetailsActive() || string.IsNullOrEmpty(__result)) { return; } MagicItem val = ((item != null) ? ItemDataExtensions.GetMagicItem(item) : null); if (val == null) { return; } ItemRarity rarity = val.Rarity; bool flag = false; if (augmentindex >= 0 && augmentindex < val.Effects.Count) { flag = MagicItemEffectDefinitions.Get(val.Effects[augmentindex].EffectType).GetValuesForRarity(rarity) == null; } List<MagicItemEffectDefinition> availableEffects = MagicItemEffectDefinitions.GetAvailableEffects(ItemDataExtensions.Extended(item), ItemDataExtensions.GetMagicItem(item), flag ? (-1) : augmentindex, true, false, false); string[] array = __result.Split(new char[1] { '\n' }); if (array.Count(IsAugmentEffectLine) != availableEffects.Count) { return; } List<string> list = new List<string>(); int num = 0; string text = (Plugin.AugmentDetailsTextScale.Value * 100f).ToString("0", CultureInfo.InvariantCulture); string[] array2 = array; foreach (string text2 in array2) { list.Add(text2); if (IsAugmentEffectLine(text2)) { MagicItemEffectDefinition val2 = availableEffects[num++]; if (!string.IsNullOrEmpty(val2.Description)) { list.Add(" <size=" + text + "%><color=#c0c0c0ff>" + MagicItem.GetEffectDescriptionRange(val2, val2.GetValuesForRarity(ItemDataExtensions.GetRarity(item))) + "</color></size>"); } } } __result = string.Join("\n", list); } catch (Exception arg) { if (!_augmentWarningLogged) { _augmentWarningLogged = true; Plugin.Log.LogWarning((object)$"Augment descriptions failed: {arg}"); } } } private static void AugmentUpdate_Postfix(AugmentUI __instance) { if (((Behaviour)__instance).isActiveAndEnabled) { bool flag = AugmentDetailsActive(); if (flag != _lastDetails) { _lastDetails = flag; __instance.OnAugmentIndexChanged(); } } } private static void RefreshAugmentSelectors_Postfix(AugmentUI __instance) { //IL_0124: Unknown result type (might be due to invalid IL or missing references) try { if (!Plugin.AugmentDetailsTooltips.Value) { return; } Tuple<InventoryItemListElement, int> singleSelectedItem = ((EnchantingTableUIPanelBase)__instance).AvailableItems.GetSingleSelectedItem<InventoryItemListElement>(); ItemData obj = ((singleSelectedItem != null) ? singleSelectedItem.Item1.GetItem() : null); MagicItem val = ((obj != null) ? ItemDataExtensions.GetMagicItem(obj) : null); if (val == null) { return; } UITooltip val2 = ((Component)__instance).GetComponentInChildren<MultiSelectItemListElement>(true)?.Tooltip; if ((Object)(object)val2 == (Object)null || (Object)(object)val2.m_tooltipPrefab == (Object)null) { if (!_augmentPrefabLogged) { _augmentPrefabLogged = true; Plugin.Log.LogInfo((object)"Augment tooltip prefab unavailable; skipping effect tooltips."); } return; } if (_augmentSelectors == null) { _augmentSelectors = AccessTools.FieldRefAccess<AugmentUI, List<Toggle>>("_AugmentSelectors"); } List<Toggle> list = _augmentSelectors.Invoke(__instance); MagicItemEffectDefinition val4 = default(MagicItemEffectDefinition); for (int i = 0; i < list.Count && i < val.Effects.Count; i++) { MagicItemEffect val3 = val.Effects[i]; if (!((Object)(object)list[i] == (Object)null) && MagicItemEffectDefinitions.TryGet(val3.EffectType, ref val4) && !string.IsNullOrEmpty(val4.Description)) { UITooltip obj2 = ((Component)list[i]).GetComponent<UITooltip>() ?? ((Component)list[i]).gameObject.AddComponent<UITooltip>(); obj2.m_tooltipPrefab = val2.m_tooltipPrefab; obj2.m_topic = MagicItem.GetEffectText(val3, val.Rarity, false, (string)null); obj2.m_text = MagicItem.GetEffectDescription(val4, val3.EffectValue); } } } catch (Exception arg) { if (!_augmentTooltipWarningLogged) { _augmentTooltipWarningLogged = true; Plugin.Log.LogWarning((object)$"Augment tooltips failed: {arg}"); } } } internal static void Apply(Harmony harmony) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Expected O, but got Unknown //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Expected O, but got Unknown //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Expected O, but got Unknown //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Expected O, but got Unknown //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Expected O, but got Unknown //IL_04b2: Expected O, but got Unknown //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Expected O, but got Unknown //IL_04e8: Expected O, but got Unknown //IL_04fc: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Expected O, but got Unknown //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Expected O, but got Unknown //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05c5: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "AddKnownItem", new Type[1] { typeof(ItemData) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "AddKnownItem_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "OnSpawned", new Type[1] { typeof(bool) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "OnSpawned_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo = AccessTools.Method(typeof(RuneUI), "Awake", (Type[])null, (Type[])null); if (methodInfo == null) { Plugin.Log.LogWarning((object)"RuneUI.Awake not found; skipping Rune Awake adjustments."); } else { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "RuneAwake_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo2 = AccessTools.Method(typeof(RuneUI), "OnEnable", (Type[])null, (Type[])null); if (methodInfo2 == null) { Plugin.Log.LogWarning((object)"RuneUI.OnEnable not found; skipping Rune OnEnable adjustments."); } else { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "RuneOnEnable_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo3 = AccessTools.Method(typeof(RuneUI), "Update", (Type[])null, (Type[])null); if (methodInfo3 == null) { Plugin.Log.LogWarning((object)"RuneUI.Update not found; skipping Rune Update adjustments."); } else { harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "RuneUpdate_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo4 = AccessTools.Method(typeof(Localization), "SetupLanguage", new Type[1] { typeof(string) }, (Type[])null); if (methodInfo4 == null) { Plugin.Log.LogWarning((object)"Localization.SetupLanguage not found; skipping Rune label language refresh."); } else { harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "ApplyRuneLabels", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } try { object? obj = _localizationInstance?.GetValue(null); Localization val = (Localization)((obj is Localization) ? obj : null); if (val != null) { ApplyRuneLabels(val); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Rune labels initial apply skipped: " + ex.Message)); } MethodInfo methodInfo5 = AccessTools.Method(typeof(RuneUI), "SelectMode", (Type[])null, (Type[])null); if (methodInfo5 == null) { Plugin.Log.LogWarning((object)"RuneUI.SelectMode not found; skipping Rune set hints."); } else { harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "RuneSelectMode_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo6 = AccessTools.Method(typeof(EnchantingUIController), "GetAvailableAugmentEffects", (Type[])null, (Type[])null); if (methodInfo6 == null) { Plugin.Log.LogWarning((object)"GetAvailableAugmentEffects not found; skipping Augment descriptions."); } else { harmony.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "GetAvailableAugmentEffects_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo7 = AccessTools.Method(typeof(AugmentUI), "Update", (Type[])null, (Type[])null); if (methodInfo7 == null) { Plugin.Log.LogWarning((object)"AugmentUI.Update not found; skipping Augment details key refresh."); } else { harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "AugmentUpdate_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo8 = AccessTools.Method(typeof(AugmentUI), "RefreshAugmentSelectors", (Type[])null, (Type[])null); if (methodInfo8 == null) { Plugin.Log.LogWarning((object)"RefreshAugmentSelectors not found; skipping Augment tooltips."); } else { harmony.Patch((MethodBase)methodInfo8, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "RefreshAugmentSelectors_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo9 = AccessTools.Method(typeof(LootRoller), "SelectDropType", (Type[])null, (Type[])null); MethodInfo methodInfo10 = AccessTools.Method(typeof(SacrificeUI), "OnSelectedItemsChanged", (Type[])null, (Type[])null); MethodInfo methodInfo11 = AccessTools.Method(typeof(EnchantingUIController), "LootRollSelectedItems", (Type[])null, (Type[])null); MethodInfo methodInfo12 = AccessTools.Method(typeof(EnchantingUIController), "GetPotentialItemRollsByCategory", (Type[])null, (Type[])null); MethodInfo methodInfo13 = AccessTools.Method(typeof(GatedItemTypeHelper), "GetCurrentOrLowerBiomeByDefeatedBossSettings", (Type[])null, (Type[])null); if (methodInfo9 == null || methodInfo10 == null || methodInfo11 == null || methodInfo12 == null || methodInfo13 == null) { throw new MissingMethodException("One of SelectDropType / OnSelectedItemsChanged / LootRollSelectedItems / GetPotentialItemRollsByCategory / GetCurrentOrLowerBiomeByDefeatedBossSettings not found"); } harmony.Patch((MethodBase)methodInfo9, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "SelectDropType_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo10, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "OnSelectedItemsChanged_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo11, new HarmonyMethod(typeof(Patches), "LootRollSelectedItems_Prefix", (Type[])null), new HarmonyMethod(typeof(Patches), "LootRollSelectedItems_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo12, new HarmonyMethod(typeof(Patches), "PotentialRolls_Prefix", (Type[])null), new HarmonyMethod(typeof(Patches), "PotentialRolls_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo13, new HarmonyMethod(typeof(Patches), "BiomeCap_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo14 = AccessTools.Method(typeof(GatedItemTypeHelper), "CheckGateBossKill", (Type[])null, (Type[])null); if (methodInfo14 == null) { Plugin.Log.LogWarning((object)"CheckGateBossKill not found; skipping Identify item boss gate patch."); } else { harmony.Patch((MethodBase)methodInfo14, new HarmonyMethod(typeof(Patches), "CheckGateBossKill_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo15 = AccessTools.Method(typeof(MultiSelectItemListElement), "SelectMaxQuantity", new Type[1] { typeof(bool) }, (Type[])null); if (methodInfo15 == null) { Plugin.Log.LogWarning((object)"SelectMaxQuantity not found; skipping Identify quantity patch."); } else { harmony.Patch((MethodBase)methodInfo15, new HarmonyMethod(typeof(Patches), "SelectMaxQuantity_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool SelectMaxQuantity_Prefix(MultiSelectItemListElement __instance, bool noSound) { try { if (!Plugin.IdentifySelectsOne.Value) { return true; } if (_listElementItem == null) { _listElementItem = AccessTools.FieldRefAccess<MultiSelectItemListElement, IListElement>("_item"); } IListElement obj = _listElementItem.Invoke(__instance); ItemData val = ((obj != null) ? obj.GetItem() : null); if (val == null || !ItemDataExtensions.IsUnidentified(val)) { return true; } SacrificeUI componentInParent = ((Component)__instance).GetComponentInParent<SacrificeUI>(); if ((Object)(object)componentInParent == (Object)null) { return true; } object value = Traverse.Create((object)componentInParent).Field("_sacrificeMode").GetValue(); if (value == null || Convert.ToInt32(value) != 1) { return true; } if ((Object)(object)((Component)__instance).GetComponentInParent<MultiSelectItemList>() != (Object)(object)((EnchantingTableUIPanelBase)componentInParent).AvailableItems) { return true; } __instance.SelectQuantity(1, noSound); return false; } catch (Exception arg) { if (!_selectQuantityWarningLogged) { _selectQuantityWarningLogged = true; Plugin.Log.LogWarning((object)$"SelectMaxQuantity prefix failed: {arg}"); } return true; } } private static bool BossCapActive() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.BlockIdentifyUntilBossKilled.Value) { return false; } if (LootRoller.CheatDisableGating) { return false; } return GatedItemTypeHelper.UsesBossBiomeCap(EpicLoot.GetGatedItemTypeMode()); } internal static string BiomeName(Biome b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return BiomeDataManager.GetName(b); } internal static bool IsUnlockedByKey(Biome biome) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance != (Object)null) { return ZoneSystem.instance.GetGlobalKey("anri_identify_unlocked_" + BiomeName(biome)); } return false; } internal static bool BossLocked(Biome biome) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) //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) if (!BossCapActive() || (int)biome == 0) { return false; } HashSet<Biome> bypassBiomes = _bypassBiomes; bool checkingBossLock = _checkingBossLock; _bypassBiomes = null; _checkingBossLock = true; try { GatedItemTypeMode gatedItemTypeMode = EpicLoot.GetGatedItemTypeMode(); return GatedItemTypeHelper.GetCurrentOrLowerBiomeByDefeatedBossSettings(biome, gatedItemTypeMode) != biome; } finally { _bypassBiomes = bypassBiomes; _checkingBossLock = checkingBossLock; } } private static Biome BiomeOf(ItemData item) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (item == null || (Object)(object)item.m_dropPrefab == (Object)null || !ItemDataExtensions.IsUnidentified(item)) { return (Biome)0; } return EnchantHelper.GetBiomeFromUnidentifiedItem(item); } private static HashSet<Biome> PayableBiomes(IEnumerable<ItemData> items) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002f: Unknown result type (might be due to invalid IL or missing references) HashSet<Biome> hashSet = new HashSet<Biome>(); foreach (ItemData item in items) { Biome val = BiomeOf(item); if ((int)val != 0 && BossLocked(val) && !IsUnlockedByKey(val)) { hashSet.Add(val); } } return hashSet; } private static HashSet<Biome> IdentifyBiomes(IEnumerable<ItemData> items) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) HashSet<Biome> hashSet = new HashSet<Biome>(); Dictionary<string, Plugin.UnlockCost> dictionary = Plugin.ParseUnlockCosts(); if (items == null) { return hashSet; } foreach (ItemData item in items) { Biome val = BiomeOf(item); if (BossLocked(val) && (IsUnlockedByKey(val) || (Plugin.AllowPerItemPayment.Value && dictionary.ContainsKey(BiomeName(val))))) { hashSet.Add(val); } } return hashSet; } private static bool TableLevelBlocked(IEnumerable<ItemData> items, out string reason) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0083: Unknown result type (might be due to invalid IL or missing references) reason = null; if (!Plugin.RequireTableLevel.Value) { return false; } EnchantingTable val = (((Object)(object)EnchantingTableUI.instance != (Object)null) ? EnchantingTableUI.instance.SourceTable : null); int num = (((Object)(object)val != (Object)null) ? val.GetFeatureLevel((EnchantingFeature)0) : 0); Dictionary<string, int> dictionary = Plugin.ParseLevelMap(); foreach (ItemData item in items) { Biome val2 = BiomeOf(item); if ((int)val2 != 0 && dictionary.TryGetValue(BiomeName(val2), out var value) && num < value) { reason = $"Sacrifice level {value} required to identify {BiomeName(val2)} gear (table is level {num})."; return true; } } return false; } private static int PerItemAmount(Plugin.UnlockCost c) { return Math.Max(1, Mathf.CeilToInt((float)c.Amount * Plugin.PerItemCostFraction.Value)); } private static Dictionary<string, int> PerItemFee(List<Tuple<ItemData, int>> items, out string missingBiome) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) missingBiome = null; Dictionary<string, Plugin.UnlockCost> dictionary = Plugin.ParseUnlockCosts(); Dictionary<string, int> dictionary2 = new Dictionary<string, int>(); foreach (Tuple<ItemData, int> item in items) { Biome val = BiomeOf(item.Item1); if ((int)val != 0 && BossLocked(val) && !IsUnlockedByKey(val)) { if (!dictionary.TryGetValue(BiomeName(val), out var value)) { missingBiome = BiomeName(val); continue; } int num = PerItemAmount(value) * Math.Max(1, item.Item2); dictionary2[value.Item] = (dictionary2.TryGetValue(value.Item, out var value2) ? (value2 + num) : num); } } return dictionary2; } private static bool CanAfford(Dictionary<string, int> cost) { if ((Object)(object)Player.m_localPlayer == (Object)null) { return false; } if (Player.m_localPlayer.NoCostCheat()) { return true; } InventoryManagement instance = InventoryManagement.Instance; foreach (KeyValuePair<string, int> item in cost) { if (instance.CountItem(item.Key) < item.Value) { return false; } } return true; } private static void Pay(Dictionary<string, int> cost) { if ((Object)(object)Player.m_localPlayer == (Object)null || Player.m_localPlayer.NoCostCheat()) { return; } InventoryManagement instance = InventoryManagement.Instance; foreach (KeyValuePair<string, int> item in cost) { instance.RemoveItem(item.Key, item.Value); } } private static string DisplayName(string prefab) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 != (Object)null)) { return prefab; } return Localization.instance.Localize(val2.m_itemData.m_shared.m_name); } private static List<InventoryItemListElement> CostRows(Dictionary<string, int> cost) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown List<InventoryItemListElement> list = new List<InventoryItemListElement>(); foreach (KeyValuePair<string, int> item in cost) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(item.Key) : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Unlock cost item '" + item.Key + "' not found in ObjectDB; check UnlockCosts.")); continue; } ItemData val2 = val.GetComponent<ItemDrop>().m_itemData.Clone(); val2.m_dropPrefab = val; val2.m_stack = item.Value; list.Add(new InventoryItemListElement { Item = val2 }); } return list; } private static void SelectDropType_Postfix(LootDrop lootDrop, bool __1, bool cheatsActive, ref LootDropType __result) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) try { if (!Plugin.GatedDropsBecomeUnidentified.Value || (int)__result != 0 || __1 || cheatsActive || LootRoller.CheatDisableGating || (Object)(object)Player.m_localPlayer == (Object)null || lootDrop == null || string.IsNullOrEmpty(lootDrop.Item)) { return; } GatedItemTypeMode gatedItemTypeMode = EpicLoot.GetGatedItemTypeMode(); if ((int)gatedItemTypeMode == 0 || GatedItemTypeHelper.IsItemAvailableUngated(lootDrop.Item, gatedItemTypeMode)) { return; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(lootDrop.Item) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 == (Object)null) && EpicLoot.IsAllowedMagicItemType(val2.m_itemData) && !(Random.value > Plugin.GatedDropChance.Value)) { __result = (LootDropType)2; if (Plugin.Verbose.Value) { Plugin.Log.LogInfo((object)("Gated drop '" + lootDrop.Item + "' converted to an unidentified item of its own tier.")); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("SelectDropType postfix failed: " + ex.Message)); } } private static bool BiomeCap_Prefix(Biome biome, ref Biome __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001e: Expected I4, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected I4, but got Unknown try { if ((int)biome == 0) { return true; } if (_bypassBiomes != null && _bypassBiomes.Contains(biome)) { __result = (Biome)(int)biome; return false; } if (!_checkingBossLock && Plugin.BlockIdentifyUntilBossKilled.Value && IsUnlockedByKey(biome)) { __result = (Biome)(int)biome; return false; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("BiomeCap prefix failed: " + ex.Message)); } return true; } private static bool CheckGateBossKill_Prefix(string itemName, GatedItemTypeMode mode, ref bool __result) { //IL_0035: 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_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (_identifyBiomes == null || _identifyBiomes.Count == 0) { return true; } try { if (!GatedItemTypeHelper.AllItemsWithDetails.TryGetValue(itemName, out var value) || value.RequiredBosses == null) { return true; } Biome val = (Biome)0; foreach (string requiredBoss in value.RequiredBosses) { string text = (string)_getBossKeyForMode.Invoke(null, new object[2] { requiredBoss, mode }); if (string.IsNullOrEmpty(text) || ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey(text))) { continue; } bool flag = false; foreach (KeyValuePair<Biome, List<string>> biomesToBossKey in GatedItemTypeHelper.BiomesToBossKeys) { if (biomesToBossKey.Value != null && biomesToBossKey.Value.Contains<string>(text, StringComparer.OrdinalIgnoreCase) && _identifyBiomes.Contains(biomesToBossKey.Key)) { flag = true; val = biomesToBossKey.Key; break; } } if (!flag) { __result = true; return false; } } __result = false; if ((int)val != 0 && Plugin.Verbose.Value && !_identifyGateLogged) { _identifyGateLogged = true; Plugin.Log.LogInfo((object)("Identify: item boss gate lifted for " + BiomeName(val))); } return false; } catch (Exception ex) { if (!_itemGateWarningLogged) { _itemGateWarningLogged = true; Plugin.Log.LogWarning((object)("CheckGateBossKill prefix failed: " + ex.Message)); } return true; } } private static void PotentialRolls_Prefix(List<ItemData> itemsSelected, out IdentifyState __state) { __state = new IdentifyState { Bypass = _bypassBiomes, Identify = _identifyBiomes, GateLogged = _identifyGateLogged }; try { _identifyBiomes = IdentifyBiomes(itemsSelected); _identifyGateLogged = false; if (Plugin.AllowPerItemPayment.Value && itemsSelected != null) { _bypassBiomes = PayableBiomes(itemsSelected); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("PotentialRolls prefix failed: " + ex.Message)); } } private static void PotentialRolls_Postfix(IdentifyState __state, ref List<InventoryItemListElement> __result) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown _bypassBiomes = __state.Bypass; _identifyBiomes = __state.Identify; _identifyGateLogged = __state.GateLogged; try { if (!Plugin.HideUndiscoveredPreview.Value || __result == null) { return; } List<InventoryItemListElement> list = new List<InventoryItemListElement>(__result.Count); foreach (InventoryItemListElement item2 in __result) { ItemData val = item2?.Item; if (val == null || ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.IsMaterialKnown(val.m_shared.m_name))) { list.Add(item2); continue; } ItemData item = MakePlaceholder(val); list.Add(new InventoryItemListElement { Item = item }); } __result = list; } catch (Exception ex) { if (!_previewWarningLogged) { _previewWarningLogged = true; Plugin.Log.LogWarning((object)("PotentialRolls preview failed: " + ex.Message)); } } } private static ItemData MakePlaceholder(ItemData original) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_002c: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) ItemData val = original.Clone(); val.m_shared = (SharedData)_memberwiseClone.Invoke(val.m_shared, null); SharedData shared = val.m_shared; shared.m_itemType = (ItemType)16; shared.m_weight = 0f; shared.m_scaleWeightByQuality = 0f; shared.m_maxStackSize = 1; shared.m_maxQuality = 1; shared.m_useDurability = false; shared.m_maxDurability = 0f; shared.m_durabilityPerLevel = 0f; shared.m_movementModifier = 0f; shared.m_eitrRegenModifier = 0f; shared.m_armor = 0f; shared.m_armorPerLevel = 0f; shared.m_blockPower = 0f; shared.m_blockPowerPerLevel = 0f; shared.m_deflectionForce = 0f; shared.m_deflectionForcePerLevel = 0f; shared.m_timedBlockBonus = 0f; shared.m_backstabBonus = 1f; shared.m_damages = default(DamageTypes); shared.m_damagesPerLevel = default(DamageTypes); shared.m_damageModifiers = new List<DamageModPair>(); shared.m_food = 0f; shared.m_foodStamina = 0f; shared.m_foodEitr = 0f; shared.m_foodRegen = 0f; shared.m_foodBurnTime = 0f; shared.m_setName = ""; shared.m_setSize = 0; shared.m_setStatusEffect = null; shared.m_equipStatusEffect = null; shared.m_consumeStatusEffect = null; shared.m_dlc = ""; shared.m_teleportable = true; shared.m_questItem = false; shared.m_value = 0; shared.m_attack = new Attack(); shared.m_secondaryAttack = new Attack(); shared.m_skillType = (SkillType)0; shared.m_toolTier = 0; val.m_crafterID = 0L; val.m_crafterName = ""; val.m_quality = 1; val.m_variant = 0; val.m_stack = 1; val.m_customData = new Dictionary<string, string>(); shared.m_name = Plugin.UndiscoveredName.Value; shared.m_description = "You have not found this item yet."; shared.m_icons = (Sprite[])(object)new Sprite[1] { QuestionSprite }; return val; } private static bool LootRollSelectedItems_Prefix(List<Tuple<ItemData, int>> items, ref List<InventoryItemListElement> __result, out object __state) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) __state = null; _identifyBiomes = null; _identifyGateLogged = false; try { if (items == null || items.Count == 0) { return true; } List<ItemData> items2 = items.Select((Tuple<ItemData, int> t) => t.Item1).ToList(); if (TableLevelBlocked(items2, out var reason)) { return Refuse(reason, ref __result); } HashSet<Biome> hashSet = PayableBiomes(items2); _identifyBiomes = IdentifyBiomes(items2); _identifyGateLogged = false; if (hashSet.Count == 0) { return true; } if (!Plugin.AllowPerItemPayment.Value) { return Refuse("Locked: defeat the " + BiomeName(hashSet.First()) + " boss or unlock the tier at this table first.", ref __result); } string missingBiome; Dictionary<string, int> dictionary = PerItemFee(items, out missingBiome); if (missingBiome != null) { return Refuse("No unlock cost configured for " + missingBiome + " gear.", ref __result); } if (!CanAfford(dictionary)) { return Refuse("Locked: you cannot afford the identify fee (" + string.Join(", ", dictionary.Select((KeyValuePair<string, int> kv) => $"{kv.Value} {DisplayName(kv.Key)}")) + ").", ref __result); } __state = dictionary; _bypassBiomes = hashSet; return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("LootRollSelectedItems prefix failed: " + ex.Message)); _bypassBiomes = null; _identifyBiomes = null; return true; } } private static void LootRollSelectedItems_Postfix(List<InventoryItemListElement> __result, object __state) { _bypassBiomes = null; _identifyBiomes = null; try { if (!(__state is Dictionary<string, int> dictionary) || __result == null || __result.Count <= 0) { return; } Pay(dictionary); if (Plugin.Verbose.Value) { Plugin.Log.LogInfo((object)("Identify fee paid: " + string.Join(", ", dictionary.Select((KeyValuePair<string, int> kv) => $"{kv.Value} {kv.Key}")))); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("LootRollSelectedItems postfix failed: " + ex.Message)); } } private static bool Refuse(string reason, ref List<InventoryItemListElement> result) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, reason, 0, (Sprite)null, false); } if (Plugin.Verbose.Value) { Plugin.Log.LogInfo((object)("Identify refused: " + reason)); } result = null; return false; } private static void ApplyIdentifyUi(SacrificeUI ui, bool identify) { try { string want = Plugin.IdentifyCostLabel.Value; if (!string.IsNullOrEmpty(want)) { if (!_costLabels.TryGetValue(ui, out var value) || (Object)(object)value == (Object)null) { string vanilla = Localization.instance.Localize("$mod_epicloot_enchantcost"); value = ((IEnumerable<TMP_Text>)((Component)ui).GetComponentsInChildren<TMP_Text>(true)).FirstOrDefault((Func<TMP_Text, bool>)((TMP_Text t) => t.text == vanilla || t.text == _costLabelOriginal || t.text == want)); if ((Object)(object)value != (Object)null) { _costLabels[ui] = value; if (_costLabelOriginal == null) { _costLabelOriginal = ((value.text == want) ? vanilla : value.text); } } } if ((Object)(object)value != (Object)null) { value.text = (identify ? want : (_costLabelOriginal ?? value.text)); } } TMP_Text explainer = ui.Explainer; if ((Object)(object)explainer != (Object)null && Plugin.ExplainerFontScale.Value > 0f) { if (!_baseFontSize.TryGetValue(explainer, out var value2)) { value2 = explainer.fontSize; _baseFontSize[explainer] = value2; } explainer.enableAutoSizing = false; explainer.fontSize = value2 * Plugin.ExplainerFontScale.Value; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("ApplyIdentifyUi failed: " + ex.Message)); } } private static string PrefabName(ItemData d) { if (!((Object)(object)d?.m_dropPrefab != (Object)null)) { return d?.m_shared?.m_name; } return ((Object)d.m_dropPrefab).name; } private static void OnSelectedItemsChanged_Postfix(SacrificeUI __instance) { //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0582: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Expected O, but got Unknown try { object value = Traverse.Create((object)__instance).Field("_sacrificeMode").GetValue(); bool flag = value != null && Convert.ToInt32(value) == 1; Button unlockButton = GetUnlockButton(__instance); ApplyIdentifyUi(__instance, flag); if (!flag) { if (Object.op_Implicit((Object)(object)unlockButton)) { ((Component)unlockButton).gameObject.SetActive(false); } return; } List<Tuple<ItemData, int>> list = (from x in ((EnchantingTableUIPanelBase)__instance).AvailableItems.GetSelectedItems<IListElement>() select new Tuple<ItemData, int>(x.Item1.GetItem(), x.Item2)).ToList(); int num = list.Sum((Tuple<ItemData, int> t) => Math.Max(1, t.Item2)); if (num > 1) { Append(__instance, $"{num} items selected; the cost shown is the total for all of them."); } List<ItemData> items = list.Select((Tuple<ItemData, int> t) => t.Item1).ToList(); if (TableLevelBlocked(items, out var reason)) { ((Selectable)((EnchantingTableUIPanelBase)__instance).MainButton).interactable = false; Append(__instance, reason); if (Object.op_Implicit((Object)(object)unlockButton)) { ((Component)unlockButton).gameObject.SetActive(false); } return; } HashSet<Biome> hashSet = PayableBiomes(items); if (hashSet.Count == 0) { if (Object.op_Implicit((Object)(object)unlockButton)) { ((Component)unlockButton).gameObject.SetActive(false); } return; } Dictionary<string, Plugin.UnlockCost> dictionary = Plugin.ParseUnlockCosts(); Biome biome = hashSet.First(); string text = BiomeName(biome); string text2 = "<color=#ff7a7a>" + text + " boss not defeated.</color>"; if (!Plugin.AllowPerItemPayment.Value || !dictionary.TryGetValue(text, out var value2)) { ((Selectable)((EnchantingTableUIPanelBase)__instance).MainButton).interactable = false; Append(__instance, text2 + " Locked until the boss is killed" + (dictionary.ContainsKey(text) ? " or the tier is unlocked." : ".")); } else { string missingBiome; Dictionary<string, int> dictionary2 = PerItemFee(list, out missingBiome); string text3 = __instance.IdentifyStyle.options[__instance.IdentifyStyle.value].text; Tuple<float, float> featureCurrentValue = EnchantingTableUI.instance.SourceTable.GetFeatureCurrentValue((EnchantingFeature)0); float num2 = ((featureCurrentValue.Item1 == 0f || float.IsNaN(featureCurrentValue.Item1)) ? 1f : (1f - featureCurrentValue.Item1 / 100f)); List<InventoryItemListElement> list2 = new List<InventoryItemListElement>(((List<InventoryItemListElement>)AccessTools.Method(typeof(EnchantingUIController), "GetIdentifyCostForCategory", (Type[])null, (Type[])null).Invoke(null, new object[3] { text3, list, num2 })) ?? new List<InventoryItemListElement>()); Dictionary<string, int> dictionary3 = new Dictionary<string, int>(); foreach (InventoryItemListElement item2 in list2) { string text4 = PrefabName(item2.Item); if (text4 != null) { dictionary3[text4] = (dictionary3.TryGetValue(text4, out var value3) ? value3 : 0) + item2.Item.m_stack; } } foreach (KeyValuePair<string, int> kv in dictionary2) { InventoryItemListElement val = ((IEnumerable<InventoryItemListElement>)list2).FirstOrDefault((Func<InventoryItemListElement, bool>)((InventoryItemListElement r) => PrefabName(r.Item) == kv.Key)); if (val != null) { ItemData item = val.Item; item.m_stack += kv.Value; } else { list2.AddRange(CostRows(new Dictionary<string, int> { { kv.Key, kv.Value } })); } dictionary3[kv.Key] = (dictionary3.TryGetValue(kv.Key, out var value4) ? value4 : 0) + kv.Value; } __instance.CostList.SetItems(list2.Cast<IListElement>().ToList()); bool interactable = ((Selectable)((EnchantingTableUIPanelBase)__instance).MainButton).interactable && CanAfford(dictionary3); ((Selectable)((EnchantingTableUIPanelBase)__instance).MainButton).interactable = interactable; Append(__instance, text2 + $" Identify fee: {PerItemAmount(value2)} {DisplayName(value2.Item)} per item, or unlock {text} permanently for {value2.Amount} {DisplayName(value2.Item)}."); } if (Object.op_Implicit((Object)(object)unlockButton) && dictionary.TryGetValue(text, out var value5)) { ((Component)unlockButton).gameObject.SetActive(true); SetLabel(unlockButton, $"Unlock {text} ({value5.Amount} {DisplayName(value5.Item)})"); Dictionary<string, int> full = new Dictionary<string, int> { { value5.Item, value5.Amount } }; ((Selectable)unlockButton).interactable = CanAfford(full); ((UnityEventBase)unlockButton.onClick).RemoveAllListeners(); ((UnityEvent)unlockButton.onClick).AddListener((UnityAction)delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) DoUnlock(__instance, biome, full); }); } else if (Object.op_Implicit((Object)(object)unlockButton)) { ((Component)unlockButton).gameObject.SetActive(false); } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"OnSelectedItemsChanged postfix failed: {arg}"); } } private static void Append(SacrificeUI ui, string line) { if ((Object)(object)ui.Explainer != (Object)null) { TMP_Text explainer = ui.Explainer; explainer.text = explainer.text + "\n" + line; } } private static void DoUnlock(SacrificeUI ui, Biome biome, Dictionary<string, int> cost) { //IL_0036: 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_007f: Unknown result type (might be due to invalid IL or missing references) try { if (!CanAfford(cost)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "$msg_missingrequirement", 0, (Sprite)null, false); } return; } Pay(cost); ZoneSystem.instance.SetGlobalKey("anri_identify_unlocked_" + BiomeName(biome)); Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Character)localPlayer2).Message((MessageType)2, BiomeName(biome) + " identification unlocked for this world.", 0, (Sprite)null, false); } Plugin.Log.LogInfo((object)("Unlocked identify for " + BiomeName(biome) + " (paid " + string.Join(", ", cost.Select((KeyValuePair<string, int> kv) => $"{kv.Value} {kv.Key}")) + ").")); Traverse.Create((object)ui).Method("OnSelectedItemsChanged", Array.Empty<object>()).GetValue(); } catch (Exception arg) { Plugin.Log.LogWarning((object)$"Unlock failed: {arg}"); } } private static Button GetUnlockButton(SacrificeUI ui) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (_unlockButtons.TryGetValue(ui, out var value) && (Object)(object)value != (Object)null) { return value; } try { if ((Object)(object)((EnchantingTableUIPanelBase)ui).MainButton == (Object)null) { return null; } GameObject obj = Object.Instantiate<GameObject>(((Component)((EnchantingTableUIPanelBase)ui).MainButton).gameObject, ((Component)((EnchantingTableUIPanelBase)ui).MainButton).transform.parent, false); ((Object)obj).name = "AnriUnlockTierButton"; Button component = obj.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); RectTransform component2 = obj.GetComponent<RectTransform>(); RectTransform component3 = ((Component)((EnchantingTableUIPanelBase)ui).MainButton).GetComponent<RectTransform>(); Vector2 anchoredPosition = component3.anchoredPosition; Rect rect = component3.rect; component2.anchoredPosition = anchoredPosition + new Vector2(0f, ((Rect)(ref rect)).height + 6f); obj.SetActive(false); _unlockButtons[ui] = component; return component; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not create unlock button: " + ex.Message)); return null; } } private static void SetLabel(Button btn, string text) { Text componentInChildren = ((Component)btn).GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = text; return; } TMP_Text componentInChildren2 = ((Component)btn).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.text = text; } } } internal static class ProgressionLoot { private sealed class Kill { internal string Prefab; internal int Stars; internal bool Processed; } private struct KillScope { internal int Depth; internal Kill Previous; internal bool SetCurrent; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<string, string> <>9__32_0; public static Func<string, bool> <>9__32_1; public static Func<ItemRarity, ItemRarity> <>9__35_0; public static Func<ItemRarity, double> <>9__35_1; public static ConsoleEvent <>9__37_0; public static Func<LootDrop, double> <>9__44_0; internal string <UnlockPrefabs>b__32_0(string p) { return p.Trim(); } internal bool <UnlockPrefabs>b__32_1(string p) { return p.Length > 0; } internal ItemRarity <Odds>b__35_0(ItemRarity r) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return r; } internal double <Odds>b__35_1(ItemRarity r) { return 0.0; } internal void <RegisterCommand>b__37_0(ConsoleEventArgs args) { int result = 0; if (args.Length > 1 && !int.TryParse(args[1], out result)) { args.Context.AddString("Usage: lootodds [stars] [prefab]"); return; } string text = ((args.Length > 2) ? args[2] : ""); args.Context.AddString($"ProgressionLoot enabled={enabled.Value}, stars={result}, prefab={text}: {Table(Odds(result, text))}"); } internal double <AddEquipment>b__44_0(LootDrop x) { return x.Weight; } } private const string PreviousUnlocks = "Epic:defeated_eikthyr:Eikthyr,Legendary:defeated_gdking:gd_king,Mythic:defeated_bonemass:Bonemass,Ancient:defeated_goblinking:GoblinKing"; private const string DefaultUnlocks = "Epic:defeated_eikthyr:Eikthyr|BossAsmodeus_TW,Legendary:defeated_gdking:gd_king|BossSvalt_TW,Mythic:defeated_bonemass:Bonemass|BossVrykolathas_TW,Ancient:defeated_goblinking:GoblinKing"; private const string PreviousBossFloors = "Eikthyr:Epic:0.10,gd_king:Legendary:0.05,Bonemass:Legendary:0.07,Dragon:Legendary:0.10,GoblinKing:Legendary:0.15,SeekerQueen:Legendary:0.20,Fader:Legendary:0.50"; private const string DefaultBossFloors = "Eikthyr:Epic:0.10,gd_king:Legendary:0.05,Bonemass:Legendary:0.07,Dragon:Legendary:0.10,GoblinKing:Legendary:0.15,SeekerQueen:Legendary:0.20,Fader:Legendary:0.50,BossAsmodeus_TW:Epic:0.05,BossSvalt_TW:Epic:0.05,BossVrykolathas_TW:Legendary:0.02"; private static ConfigEntry<bool> enabled; private static ConfigEntry<bool> verbose; private static ConfigEntry<string> baseline; private static ConfigEntry<string> unlocks; private static ConfigEntry<string> floors; private static ConfigEntry<float> growthStart; private static ConfigEntry<float> growthPerKill; private static ConfigEntry<float> starBase; private static ConfigEntry<float> apexChance; private static ConfigEntry<int> apexStars; private static readonly ItemRarity[] Rarities; [ThreadStatic] private static Kill current; [ThreadStatic] private static ItemRarity? forced; [ThreadStatic] private static int creatureRollDepth; private static readonly Type OutputType; private static MethodInfo Method(string name, params Type[] types) { return AccessTools.Method(typeof(LootRoller), name, (types.Length == 0) ? null : types, (Type[])null); } internal static void Apply(Harmony harmony, ConfigFile config) { //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown //IL_0214: Expected O, but got Unknown //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Expected O, but got Unknown //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Expected O, but got Unknown //IL_0308: Expected O, but got Unknown //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Expected O, but got Unknown //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Expected O, but got Unknown //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Expected O, but got Unknown enabled = config.Bind<bool>("ProgressionLoot", "Enabled", true, Plugin.Synced("Replace creature magic equipment rolls with world progression odds.")); baseline = config.Bind<string>("ProgressionLoot", "Baseline", "Magic:1,Rare:0.5,Epic:0.25,Legendary:0.2,Mythic:0.1,Ancient:0.01", Plugin.Synced("Rarity:percent pairs.")); unlocks = config.Bind<string>("ProgressionLoot", "Unlocks", "Epic:defeated_eikthyr:Eikthyr|BossAsmodeus_TW,Legendary:defeated_gdking:gd_king|BossSvalt_TW,Mythic:defeated_bonemass:Bonemass|BossVrykolathas_TW,Ancient:defeated_goblinking:GoblinKing", Plugin.Synced("Rarity:globalkey:bossPrefab entries; separate multiple boss prefabs with | to sum their growth kill counters.")); if (string.Equals(unlocks.Value, "Epic:defeated_eikthyr:Eikthyr,Legendary:defeated_gdking:gd_king,Mythic:defeated_bonemass:Bonemass,Ancient:defeated_goblinking:GoblinKing", StringComparison.Ordinal)) { unlocks.Value = "Epic:defeated_eikthyr:Eikthyr|BossAsmodeus_TW,Legendary:defeated_gdking:gd_king|BossSvalt_TW,Mythic:defeated_bonemass:Bonemass|BossVrykolathas_TW,Ancient:defeated_goblinking:GoblinKing"; Plugin.Log.LogInfo((object)"ProgressionLoot: migrated default Unlocks to include Monstrum miniboss growth."); } growthStart = config.Bind<float>("ProgressionLoot", "GrowthStart", 0.25f, Plugin.Synced("Starting multiplier for unlocked rarities.")); growthPerKill = config.Bind<float>("ProgressionLoot", "GrowthPerKill", 0.25f, Plugin.Synced("Multiplier added per recorded boss kill, capped at one.")); starBase = config.Bind<float>("ProgressionLoot", "StarBase", 5f, Plugin.Synced("Multiplier per ten stars.")); apexStars = config.Bind<int>("ProgressionLoot", "ApexStars", 20, Plugin.Synced("Stars required for the Ancient floor.")); apexChance = config.Bind<float>("ProgressionLoot", "ApexAncientChance", 0.1f, Plugin.Synced("Ancient probability floor when unlocked and at apex stars.")); floors = config.Bind<string>("ProgressionLoot", "BossFloors", "Eikthyr:Epic:0.10,gd_king:Legendary:0.05,Bonemass:Legendary:0.07,Dragon:Legendary:0.10,GoblinKing:Legendary:0.15,SeekerQueen:Legendary:0.20,Fader:Legendary:0.50,BossAsmodeus_TW:Epic:0.05,BossSvalt_TW:Epic:0.05,BossVrykolathas_TW:Legendary:0.02", Plugin.Synced("BossPrefab:rarity:chance entries; a floor bypasses that rarity's unlock for that boss only.")); if (string.Equals(floors.Value, "Eikthyr:Epic:0.10,gd_king:Legendary:0.05,Bonemass:Legendary:0.07,Dragon:Legendary:0.10,GoblinKing:Legendary:0.15,SeekerQueen:Legendary:0.20,Fader:Legendary:0.50", StringComparison.Ordinal)) { floors.Value = "Eikthyr:Epic:0.10,gd_king:Legendary:0.05,Bonemass:Legendary:0.07,Dragon:Legendary:0.10,GoblinKing:Legendary:0.15,SeekerQueen:Legendary:0.20,Fader:Legendary:0.50,BossAsmodeus_TW:Epic:0.05,BossSvalt_TW:Epic:0.05,BossVrykolathas_TW:Legendary:0.02"; Plugin.Log.LogInfo((object)"ProgressionLoot: migrated default BossFloors to include Monstrum altar bosses."); } verbose = config.Bind<bool>("ProgressionLoot", "Verbose", false, "Log probabilities and result once per creature kill."); harmony.Patch((MethodBase)AccessTools.Method(typeof(CharacterDrop), "OnDeath", (Type[])null, (Type[])null), new HarmonyMethod(typeof(ProgressionLoot), "BeginKill", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ProgressionLoot), "EndKill", (Type[])null), (HarmonyMethod)null); harmony.Patch((MethodBase)Method("RollLootTableAndSpawnObjects", typeof(List<LootTable>), typeof(int), typeof(string), typeof(Vector3), typeof(bool)), new HarmonyMethod(typeof(ProgressionLoot), "RollCreature", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(EpicLootDropsHelper), "OnCharacterDeath", new Type[4] { typeof(string), typeof(int), typeof(Vector3), typeof(bool) }, (Type[])null), new HarmonyMethod(typeof(ProgressionLoot), "BeginCreatureRoll", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ProgressionLoot), "EndCreatureRoll", (Type[])null), (HarmonyMethod)null); harmony.Patch((MethodBase)Method("RollItemRarity"), new HarmonyMethod(typeof(ProgressionLoot), "ForceRarity", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)Method("SelectDropType"), new HarmonyMethod(typeof(ProgressionLoot), "ForceEquipment", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(ProgressionLoot), "RegisterCommand", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static string Clean(string prefab) { return (prefab ?? "").Replace("(Clone)", "").Trim(); } private static void BeginKill(CharacterDrop __instance, out Kill __state) { __state = current; Character component = ((Component)__instance).GetComponent<Character>(); if (enabled.Value && (Object)(object)component != (Object)null) { current = new Kill { Prefab = Clean(((Object)((Component)component).gameObject).name), Stars = component.GetLevel() - 1 }; } } private static void EndKill(Kill __state) { current = __state; } private static void BeginCreatureRoll(string characterName, int level, bool allowBonusRolls, out KillScope __state) { __state = new KillScope { Depth = creatureRollDepth, Previous = current }; creatureRollDepth++; if (enabled.Value && allowBonusRolls && current == null && !string.IsNullOrEmpty(characterName)) { current = new Kill { Prefab = Clean(characterName), Stars = Math.Max(0, level - 1) }; __state.SetCurrent = true; if (verbose.Value) { Plugin.Log.LogInfo((object)$"ProgressionLoot: ragdoll/deferred roll scoped for {current.Prefab} ({current.Stars} stars)"); } } } private static void EndCreatureRoll(KillScope __state) { creatureRollDepth = __state.Depth; current = __state.Previous; } private static bool Number(string value, out double result) { if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out result) && !double.IsNaN(result)) { return !double.IsInfinity(result); } return false; } private static bool Rarity(string value, out ItemRarity result) { if (Enum.TryParse<ItemRarity>(value.Trim(), ignoreCase: true, out result)) { return Rarities.Contains(result); } return false; } private static double Clamp(double value) { if (!double.IsNaN(value)) { return Math.Max(0.0, Math.Min(1.0, value)); } return 0.0; } private static Dictionary<ItemRarity, string[]> UnlockMap() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) Dictionary<ItemRarity, string[]> dictionary = new Dictionary<ItemRarity, string[]>(); string[] array = (unlocks.Value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length == 3 && Rarity(array2[0], out var result)) { dictionary[result] = array2; } } return dictionary; } private static IEnumerable<string> UnlockPrefabs(string[] parts) { return from p in parts[2].Split(new char[1] { '|' }) select p.Trim() into p where p.Length > 0 select p; } private static bool UnlockKeySatisfied(string[] parts) { if ((Object)(object)ZoneSystem.instance != (Object)null) { return ZoneSystem.instance.GetGlobalKey(parts[1].Trim().ToLowerInvariant()); } return false; } internal static bool BossUniqueUnlocked(ItemRarity rarity, string prefab) { //IL_000d: 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_0012: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) if ((int)rarity == 0 || (int)rarity == 1) { return true; } if (UnlockMap().TryGetValue(rarity, out var value) && !UnlockKeySatisfied(value)) { return UnlockPrefabs(value).Any((string p) => string.Equals(Clean(p), Clean(prefab), StringComparison.OrdinalIgnoreCase)); } return true; } internal static Dictionary<ItemRarity, double> Odds(int stars, string prefab) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Invalid comparison between Unknown and I4 //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) Dictionary<ItemRarity, double> dictionary = Rarities.ToDictionary((ItemRarity r) => r, (ItemRarity r) => 0.0); string[] array = baseline.Value.Split(new char[1] { ',' }); for (int num = 0; num < array.Length; num++) { string[] array2 = array[num].Split(new char[1] { ':' }); if (array2.Length == 2 && Rarity(array2[0], out var result) && Number(array2[1], out var result2)) { dictionary[result] = Math.Max(0.0, result2 / 100.0); } } Dictionary<ItemRarity, string[]> dictionary2 = UnlockMap(); Dictionary<ItemRarity, double> dictionary3 = new Dictionary<ItemRarity, double>(); array = floors.Value.Split(new char[1] { ',' }); for (int num = 0; num < array.Length; num++) { string[] array3 = array[num].Split(new char[1] { ':' }); if (array3.Length == 3 && string.Equals(array3[0].Trim(), Clean(prefab), StringComparison.OrdinalIgnoreCase) && Rarity(array3[1], out var result3) && Number(array3[2], out var result4)) { dictionary3[result3] = Math.Max(dictionary3.TryGetValue(result3, out var value) ? value : 0.0, Clamp(result4)); } } Dictionary<ItemRarity, double> dictionary4 = new Dictionary<ItemRarity, double>(); ItemRarity[] rarities = Rarities; string s = default(string); foreach (ItemRarity val in rarities) { bool flag = true; double num2 = 1.0; if (dictionary2.TryGetValue(val, out var value2)) { flag = UnlockKeySatisfied(value2); double num3 = 0.0; if ((Object)(object)ZoneSystem.instance != (Object)null) { foreach (string item in UnlockPrefabs(value2)) { if (ZoneSystem.instance.GetGlobalKey("anri_bosskills_" + item.ToLowerInvariant(), ref s) && int.TryParse(s, out var result5)) { num3 += (double)result5; } } } num2 = Clamp((double)growthStart.Value + (double)growthPerKill.Value * num3); } flag |= dictionary3.ContainsKey(val); double num4 = (flag ? Clamp(dictionary[val] * num2 * Math.Pow(Math.Max(0f, starBase.Value), (double)stars / 10.0)) : 0.0); if ((int)val == 5 && flag && stars >= apexStars.Value) { num4 = Math.Max(num4, Clamp(apexChance.Value)); } if (dictionary3.TryGetValue(val, out var value3)) { num4 = Math.Max(num4, value3); } dictionary4[val] = num4; } return dictionary4; } private unsafe static string Table(Dictionary<ItemRarity, double> odds) { return string.Join(", ", Rarities.Select((ItemRarity r) => ((object)(*(ItemRarity*)(&r))/*cast due to .constrained prefix*/).ToString() + "=" + (odds[r] * 100.0).ToString("0.####", CultureInfo.InvariantCulture) + "%")); } private static void RegisterCommand() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__37_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { int result = 0; if (args.Length > 1 && !int.TryParse(args[1], out result)) { args.Context.AddString("Usage: lootodds [stars] [prefab]"); } else { string text = ((args.Length > 2) ? args[2] : ""); args.Context.AddString($"ProgressionLoot enabled={enabled.Value}, stars={result}, prefab={text}: {Table(Odds(result, text))}"); } }; <>c.<>9__37_0 = val; obj = (object)val; } new ConsoleCommand("lootodds", "[stars] [prefab] Show world progression probabilities (independent top-down rolls)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static bool ForceRarity(ref ItemRarity __result) { //IL_0014: Unknown re
RecipeDiscovery.dll
Decompiled a day agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("RecipeDiscovery")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RecipeDiscovery")] [assembly: AssemblyTitle("RecipeDiscovery")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 RecipeDiscovery { [BepInPlugin("anri.recipediscovery", "RecipeDiscovery", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string GUID = "anri.recipediscovery"; public const string NAME = "RecipeDiscovery"; public const string VERSION = "1.0.0"; private static ConfigEntry<bool> IgnoreStationLevel; private static ConfigEntry<bool> Verbose; private static ManualLogSource Log; private static bool _loggedException; private static readonly MethodInfo HaveRequirementItems = AccessTools.Method(typeof(Player), "HaveRequirementItems", new Type[4] { typeof(Recipe), typeof(bool), typeof(int), typeof(int) }, (Type[])null); private static readonly MethodInfo KnowStationLevel = AccessTools.Method(typeof(Player), "KnowStationLevel", (Type[])null, (Type[])null); private void Awake() { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; IgnoreStationLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("Discovery", "IgnoreStationLevel", true, "Learn a recipe as soon as all its ingredients are known materials, even if you have not yet seen the required crafting station level. Crafting still requires the real station."); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("Discovery", "Verbose", false, "Log each recipe learned through this rule."); MethodInfo methodInfo = AccessTools.Method(typeof(Player), "HaveRequirements", new Type[4] { typeof(Recipe), typeof(bool), typeof(int), typeof(int) }, (Type[])null); if (methodInfo == null) { Log.LogWarning((object)"Player.HaveRequirements(Recipe, bool, int, int) not found; skipping recipe discovery patch."); } else { new Harmony("anri.recipediscovery").Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } Log.LogInfo((object)"RecipeDiscovery 1.0.0 loaded."); } private static bool Prefix(Player __instance, Recipe recipe, bool discover, int qualityLevel, int amount, ref bool __result) { if (!discover || !IgnoreStationLevel.Value) { return true; } try { string dlc = recipe.m_item.m_itemData.m_shared.m_dlc; if (dlc.Length > 0 && !DLCMan.instance.IsDLCInstalled(dlc)) { __result = false; } else { __result = (bool)HaveRequirementItems.Invoke(__instance, new object[4] { recipe, discover, qualityLevel, amount }); } if ((Verbose.Value & __result) && (Object)(object)recipe.m_craftingStation != (Object)null && !(bool)KnowStationLevel.Invoke(__instance, new object[2] { recipe.m_craftingStation.m_name, recipe.m_minStationLevel })) { Log.LogInfo((object)$"Learned {recipe.m_item.m_itemData.m_shared.m_name} before seeing {recipe.m_craftingStation.m_name} level {recipe.m_minStationLevel}"); } return false; } catch (Exception arg) { if (!_loggedException) { _loggedException = true; Log.LogWarning((object)$"Recipe discovery failed; falling back to vanilla: {arg}"); } return true; } } } }
SpawnLimiter.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("SpawnLimiter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SpawnLimiter")] [assembly: AssemblyTitle("SpawnLimiter")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 SpawnLimiter { [BepInPlugin("anri.spawnlimiter", "SpawnLimiter", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal sealed class Rule { internal HashSet<int> PrefabHashes; internal int Max; internal float Radius; internal string DisplayName; } [HarmonyPatch(typeof(CreatureSpawner), "Spawn", new Type[] { })] private static class CreatureSpawnerPatch { private static bool Prefix(CreatureSpawner __instance, ref ZNetView __result) { //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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) try { if (!Enabled.Value) { return true; } string name = ((Object)__instance.m_creaturePrefab).name; Vector3 position = ((Component)__instance).transform.position; ZNetView val = (ZNetView)CreatureView.GetValue(__instance); ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null); long ticks = ZNet.instance.GetTime().Ticks; if (!IsDeferred((val2 != null) ? val2.GetLong(DeferKey, 0L) : 0, ticks)) { if (!TryDefer(name, position, ticks, out var deadline)) { return true; } if (val2 != null) { val2.Set(DeferKey, deadline); } } __result = null; return false; } catch (Exception error) { WarnOnce("CreatureSpawner.Spawn", error); return true; } } } [HarmonyPatch(typeof(SpawnSystem), "Spawn", new Type[] { typeof(SpawnData), typeof(Vector3), typeof(bool) })] private static class SpawnSystemPatch { private static bool Prefix(SpawnSystem __instance, SpawnData critter, Vector3 spawnPoint) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) try { if (!Enabled.Value) { return true; } string name = ((Object)critter.m_prefab).name; int stableHashCode = StringExtensionMethods.GetStableHashCode("anri_sl_defer_" + name); ZNetView val = (ZNetView)SpawnSystemView.GetValue(__instance); ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null); Vector2s zone = ZoneSystem.GetZone(((Component)__instance).transform.position); (ZDOID, int) key = (new ZDOID((long)zone.x, (uint)zone.y), StringExtensionMethods.GetStableHashCode(name)); ZoneDeferrals.TryGetValue(key, out var value); long ticks = ZNet.instance.GetTime().Ticks; long deadline = ((val2 != null) ? val2.GetLong(stableHashCode, value) : value); if (IsDeferred(deadline, ticks)) { if (val2 != null && value != 0L) { val2.Set(stableHashCode, deadline); ZoneDeferrals.Remove(key); } return false; } ZoneDeferrals.Remove(key); if (!TryDefer(name, spawnPoint, ticks, out deadline)) { return true; } if (val2 != null) { val2.Set(stableHashCode, deadline); } else { ZoneDeferrals[key] = deadline; } return false; } catch (Exception error) { WarnOnce("SpawnSystem.Spawn", error); return true; } } } [HarmonyPatch(typeof(BaseAI), "Awake")] private static class BaseAiPatch { private static void Prefix(BaseAI __instance, out bool __state) { __state = false; try { if (Enabled.Value && CatchAllSpawns.Value) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); __state = (Object)(object)component != (Object)null && component.IsValid() && component.IsOwner() && component.GetZDO().GetLong(ZDOVars.s_spawnTime, 0L) == 0; } } catch (Exception error) { WarnOnce("BaseAI.Awake prefix", error); } } private static void Postfix(BaseAI __instance, Character ___m_character, bool __state) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) try { if (!Enabled.Value || !CatchAllSpawns.Value || !__state) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { return; } ZDO zDO = component.GetZDO(); if (!(___m_character is Player) && (!((Object)(object)___m_character != (Object)null) || !___m_character.IsTamed()) && !zDO.GetBool(ZDOVars.s_tamed, false)) { string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject); Vector3 position = ((Component)__instance).transform.position; if (Blocked(prefabName, position, zDO.m_uid, out var _)) { ((MonoBehaviour)Instance).StartCoroutine(DestroyBlockedSpawn(((Component)__instance).gameObject)); } } } catch (Exception error) { WarnOnce("BaseAI.Awake postfix", error); } } } public const string GUID = "anri.spawnlimiter"; public const string NAME = "SpawnLimiter"; public const string VERSION = "1.1.0"; private const string DefaultRules = "StoneGolem|ObsidianGolem_TW:1:200"; private static Plugin Instance; private static ManualLogSource Log; private static ConfigEntry<bool> Enabled; private static ConfigEntry<bool> Verbose; private static ConfigEntry<bool> CatchAllSpawns; private static volatile List<Rule> Rules = new List<Rule>(); private static readonly List<ZDO> TempZdos = new List<ZDO>(); private static readonly HashSet<string> Warnings = new HashSet<string>(); private static ConfigEntry<float> FirstMinMinutes; private static ConfigEntry<float> FirstMaxMinutes; private static ConfigEntry<float> MinutesPerCreature; private static readonly int DeferKey = StringExtensionMethods.GetStableHashCode("anri_sl_defer"); private static readonly Dictionary<(ZDOID zone, int prefabHash), long> ZoneDeferrals = new Dictionary<(ZDOID, int), long>(); private static readonly FieldInfo CreatureView = AccessTools.Field(typeof(CreatureSpawner), "m_nview"); private static readonly FieldInfo SpawnSystemView = AccessTools.Field(typeof(SpawnSystem), "m_nview"); private void Awake() { //IL_0168: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, AdminOnly("Enable creature group spawn limits.")); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Verbose", false, "Log one Info line for each new deferral or catch-all removal. Local setting; not synced."); CatchAllSpawns = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CatchAllSpawns", true, AdminOnly("Also enforce limits on newly created creatures from other spawn paths through BaseAI.Awake.")); AcceptableValueRange<float> range = new AcceptableValueRange<float>(0.01f, 1440f); FirstMinMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("Defer", "FirstMinMinutes", 5f, AdminOnly("Minimum random delay in minutes with one creature (also used for empty groups with max zero).", (AcceptableValueBase)(object)range)); FirstMaxMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("Defer", "FirstMaxMinutes", 10f, AdminOnly("Maximum random delay in minutes with one creature. Reversed bounds are sorted.", (AcceptableValueBase)(object)range)); MinutesPerCreature = ((BaseUnityPlugin)this).Config.Bind<float>("Defer", "MinutesPerCreature", 10f, AdminOnly("Delay in minutes per creature when two or more remain.", (AcceptableValueBase)(object)range)); ConfigEntry<string> rules = ((BaseUnityPlugin)this).Config.Bind<string>("Rules", "Rules", "StoneGolem|ObsidianGolem_TW:1:200", AdminOnly("Rules separated by ; in prefab1|prefab2:max:radiusMeters format. Max is the count at which deferral starts. A spawn must satisfy every matching rule. Max must be nonnegative; radius must be positive and is clamped to 300 m because the nearby-sector lookup cannot fully cover radii above approximately 320 m. Tamed creatures do not count. Reparsed when changed, including server sync.")); rules.SettingChanged += delegate { ParseRules(rules.Value); }; ParseRules(rules.Value); new Harmony("anri.spawnlimiter").PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)(string.Format("{0} {1} loaded. {2} rule(s): ", "SpawnLimiter", "1.1.0", Rules.Count) + string.Join("; ", Rules.Select((Rule r) => $"{r.DisplayName}:{r.Max}:{r.Radius.ToString(CultureInfo.InvariantCulture)}")))); } private static ConfigDescription AdminOnly(string description, AcceptableValueBase range = null) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } }); } private static void ParseRules(string text) { List<Rule> list = new List<Rule>(); string[] array = (text ?? "").Split(new char[1] { ';' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0) { continue; } string[] array2 = text2.Split(new char[1] { ':' }); if (array2.Length != 3 || !int.TryParse(array2[1].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result < 0 || !float.TryParse(array2[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || float.IsNaN(result2) || float.IsInfinity(result2) || result2 <= 0f) { Log.LogWarning((object)("Ignoring malformed rule '" + text2 + "'.")); continue; } string[] array3 = (from n in array2[0].Split(new char[1] { '|' }) select n.Trim() into n where n.Length > 0 select n).ToArray(); if (array3.Length == 0) { Log.LogWarning((object)("Ignoring malformed rule '" + text2 + "'.")); continue; } list.Add(new Rule { PrefabHashes = new HashSet<int>(array3.Select((string n) => StringExtensionMethods.GetStableHashCode(n))), Max = result, Radius = Math.Min(result2, 300f), DisplayName = string.Join("|", array3) }); } Rules = list; } internal static int CountGroup(Rule rule, Vector3 center, ZDOID exclude) { //IL_000f: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) TempZdos.Clear(); ZDOMan.instance.FindSectorObjects(ZoneSystem.GetZone(center), SimulationDistance.OriginalDistance, TempZdos, (List<ZDO>)null); int num = 0; foreach (ZDO tempZdo in TempZdos) { if (tempZdo.m_uid != exclude && rule.PrefabHashes.Contains(tempZdo.GetPrefab()) && !tempZdo.GetBool(ZDOVars.s_tamed, false) && Vector3.Distance(tempZdo.GetPosition(), center) <= rule.Radius) { num++; } } return num; } internal static bool Blocked(string prefabName, Vector3 center, ZDOID exclude, out Rule rule) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) int stableHashCode = StringExtensionMethods.GetStableHashCode(prefabName); foreach (Rule rule2 in Rules) { if (rule2.PrefabHashes.Contains(stableHashCode) && CountGroup(rule2, center, exclude) >= rule2.Max) { rule = rule2; return true; } } rule = null; return false; } private static void LogBlocked(string prefab, Vector3 center, ZDOID exclude, Rule rule) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (Verbose.Value) { Log.LogInfo((object)string.Format(CultureInfo.InvariantCulture, "[SpawnLimiter] blocked {0} at ({1:0.#},{2:0.#}): {3} of group '{4}' within {5} m", prefab, center.x, center.z, CountGroup(rule, center, exclude), rule.DisplayName, rule.Radius)); } } private static bool IsDeferred(long deadline, long now) { if (deadline > now) { return deadline - now <= 864000000000L; } return false; } private static bool TryDefer(string prefab, Vector3 center, long now, out long deadline) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) int stableHashCode = StringExtensionMethods.GetStableHashCode(prefab); foreach (Rule rule in Rules) { if (!rule.PrefabHashes.Contains(stableHashCode)) { continue; } int num = CountGroup(rule, center, ZDOID.None); if (num >= rule.Max) { double num2 = ((num <= 1) ? ((double)Random.Range(Math.Min(FirstMinMinutes.Value, FirstMaxMinutes.Value), Math.Max(FirstMinMinutes.Value, FirstMaxMinutes.Value))) : ((double)num * (double)MinutesPerCreature.Value)); deadline = now + (long)(num2 * 600000000.0); if (Verbose.Value) { Log.LogInfo((object)string.Format(CultureInfo.InvariantCulture, "[SpawnLimiter] deferred {0} at ({1:0.#},{2:0.#}) for {3:0.0} min: {4} of group '{5}' within {6} m", prefab, center.x, center.z, num2, num, rule.DisplayName, rule.Radius)); } return true; } } deadline = 0L; return false; } private static void WarnOnce(string patch, Exception error) { if (Warnings.Add(patch)) { Log.LogWarning((object)(patch + " spawn limit failed; allowing vanilla behavior: " + error.Message)); } } private static IEnumerator DestroyBlockedSpawn(GameObject go) { WaitForEndOfFrame val; try { val = new WaitForEndOfFrame(); } catch (Exception error) { WarnOnce("BaseAI.Awake deferred destroy", error); yield break; } yield return val; try { if ((Object)(object)go == (Object)null) { yield break; } ZNetView component = go.GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { yield break; } ZDO zDO = component.GetZDO(); long num = ZNet.instance.GetTime().Ticks - zDO.GetLong(ZDOVars.s_spawnTime, 0L); if (num < -50000000 || num > 50000000) { yield break; } Character component2 = go.GetComponent<Character>(); if (component2 is Player || ((Object)(object)component2 != (Object)null && component2.IsTamed()) || zDO.GetBool(ZDOVars.s_tamed, false)) { yield break; } string prefabName = Utils.GetPrefabName(go); Vector3 position = go.transform.position; if (Blocked(prefabName, position, zDO.m_uid, out var rule)) { LogBlocked(prefabName, position, zDO.m_uid, rule); CharacterDrop component3 = go.GetComponent<CharacterDrop>(); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } ZNetScene.instance.Destroy(go); } } catch (Exception error2) { WarnOnce("BaseAI.Awake deferred destroy", error2); } } } }