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 GAP Perfect Gear v1.0.0
plugins/GapPerfectGear.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using EpicLoot; using EpicLoot.ShardStones; using Newtonsoft.Json; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("gap.perfectgear", "GAP Perfect Gear", "1.0.0")] public class GapPerfectGear : BaseUnityPlugin { private string testDirectory; private bool tested; private float nextCheck; private void Awake() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) string[] commandLineArgs = Environment.GetCommandLineArgs(); int num = Array.IndexOf(commandLineArgs, "-gapgearselftest"); if (num >= 0 && num + 1 < commandLineArgs.Length) { testDirectory = commandLineArgs[num + 1]; } new ConsoleCommand("perfectgear", "perfectgear sword|bow|trinket|both|all [empty] - Ancient endgame gear, host only", new ConsoleEvent(Run), false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); ((BaseUnityPlugin)this).Logger.LogInfo((object)"perfectgear registered; host-only, no automatic inventory changes."); } private void Run(ConsoleEventArgs args) { try { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { throw new Exception("Only the local world host may use perfectgear."); } if (args.Args.Length < 2) { throw new Exception("Usage: perfectgear sword|bow|trinket|both|all [empty]"); } string text = args.Args[1].ToLowerInvariant(); if (text != "sword" && text != "bow" && text != "bowprecision" && text != "trinket" && text != "both" && text != "all") { throw new Exception("Choose sword, bow, trinket, both or all."); } bool flag = args.Args.Length == 3 && args.Args[2].ToLowerInvariant() == "empty"; if (args.Args.Length > 3 || (args.Args.Length == 3 && !flag)) { throw new Exception("Optional argument: empty"); } List<ItemData> list = new List<ItemData>(); switch (text) { case "sword": case "both": case "all": list.Add(Build("sword", flag)); break; } switch (text) { case "bow": case "both": case "all": list.Add(Build("bow", flag)); break; } if (text == "trinket" || text == "all") { list.Add(Build("trinket", flag)); } if (text == "bowprecision") { list.Add(Build("bowprecision", flag)); } Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); if (inventory.GetEmptySlots() < list.Count) { throw new Exception("Free " + list.Count + " inventory slots first."); } foreach (ItemData item in list) { if (!inventory.AddItem(item)) { throw new Exception("Inventory rejected item; no item was dropped."); } } args.Context.AddString("Created " + list.Count + " Ancient item(s), 8 maximally tempered effects, 4 " + (flag ? "empty" : "filled") + " sockets."); } catch (Exception ex) { args.Context.AddString("perfectgear: " + ex.Message); ((BaseUnityPlugin)this).Logger.LogWarning((object)ex); } } private static ItemData Clone(string prefab) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); if ((Object)(object)itemPrefab == (Object)null) { throw new Exception("Missing prefab: " + prefab); } ItemData val = itemPrefab.GetComponent<ItemDrop>().m_itemData.Clone(); val.m_dropPrefab = itemPrefab; val.m_stack = 1; val.m_equipped = false; val.m_customData = new Dictionary<string, string>(val.m_customData); return val; } private static ItemData Build(string choice, bool empty) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0050: 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_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown string prefab = ((choice == "trinket") ? "TrinketBloodGoldHealth" : ((choice == "sword") ? "SwordGold_FrostFire" : "BowGold_FrostFire")); ItemData val = Clone(prefab); val.m_quality = val.m_shared.m_maxQuality; MagicItem val2 = new MagicItem(); val2.Rarity = (ItemRarity)5; val2.SocketCount = 4; MagicItem val3 = val2; string[] array = ((choice == "trinket") ? new string[8] { "IncreaseHealth", "IncreaseStamina", "ModifyStaminaRegen", "ModifyMovementSpeed", "CoinHoarder", "DodgeBuff", "DecreaseForsakenCooldown", "IncreaseEitr" } : ((choice == "sword") ? new string[8] { "AddSlashingDamage", "AddSwordsSkill", "ModifyAttackSpeed", "Executioner", "ModifyStaggerDamage", "SpellSword", "ChainLightning", "EitrLeech" } : new string[8] { "AddPiercingDamage", "AddBowsSkill", "QuickDraw", "ExplosiveArrows", "Executioner", "ModifyStaggerDamage", "ModifyBackstab", "ModifyProjectileSpeed" })); string[] array2 = array; foreach (string text in array2) { if (!API.GetAvailableEffectTypes(val, JsonConvert.SerializeObject((object)val3), 5).Contains(text)) { throw new Exception("Effect no longer allowed: " + text); } MagicItemEffectDefinition val4 = MagicItemEffectDefinitions.AllDefinitions[text]; ValueDef rollRange = MagicItemEffectDefinitions.GetRollRange(val4, val3.Rarity, val3.LegendaryID, (ValueDef)null); val3.Effects.Add(new MagicItemEffect(text, rollRange?.MaxValue ?? 1f)); } MagicItemEffect[] array3 = val3.Effects.ToArray(); foreach (MagicItemEffect val5 in array3) { val3.Effects.Remove(val5); bool flag = API.GetAvailableEffectTypes(val, JsonConvert.SerializeObject((object)val3), 5).Contains(val5.EffectType); val3.Effects.Add(val5); if (!flag) { throw new Exception("Conflicting effect: " + val5.EffectType); } } if (!API.ApplyMagicItemJson(val, JsonConvert.SerializeObject((object)val3))) { throw new Exception("Epic Loot rejected metadata."); } MaxTemper(val); if (!empty) { string[] array4 = ((choice == "trinket") ? new string[4] { "Orange", "Pink", "LightGreen", "DarkRed" } : ((choice == "sword") ? new string[4] { "Golden", "White", "Black", "Yagluth" } : new string[4] { "Golden", "Golden", "Stormcaller", "Yagluth" })); string[] array5 = array4; string text3 = default(string); foreach (string text2 in array5) { ItemData val6 = Clone(text2 + "_Ancient_ShardStone"); if (!ShardSocketManager.CanSocket(val, val6, ref text3)) { throw new Exception("Cannot socket " + text2 + ": " + text3); } if (!ShardSocketManager.AddShard(val, val6)) { throw new Exception("Failed to socket " + text2); } } } val.m_durability = val.GetMaxDurability(); return val; } private static void MaxTemper(ItemData item) { //IL_0008: 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_00b3: Expected O, but got Unknown MagicItem magicItem = ItemDataExtensions.GetMagicItem(item); if (!TemperMan.IsTemperableRarity(magicItem.Rarity)) { throw new Exception("Ancient tempering is unavailable in the loaded Epic Loot configuration."); } string[] array = magicItem.Effects.Select((MagicItemEffect x) => x.EffectType).ToArray(); foreach (string effectType in array) { int num2 = 0; while (true) { magicItem = ItemDataExtensions.GetMagicItem(item); MagicItemEffect val = magicItem.Effects.Single((MagicItemEffect x) => x.EffectType == effectType); if (!TemperData.IsTemperable(magicItem, val)) { break; } TemperData val2 = new TemperData(item, effectType); if (float.IsNaN(val2.probability) || float.IsInfinity(val2.probability)) { throw new Exception("Invalid tempering probability: " + effectType); } if (val2.probability <= 0f) { break; } if (num2 >= 4096) { throw new Exception("No finite tempering maximum found: " + effectType); } MagicItem updatedMagicItem = val2.GetUpdatedMagicItem(); int num3 = updatedMagicItem.Effects.FindIndex((MagicItemEffect x) => x.EffectType == effectType); float effectValue = updatedMagicItem.Effects[num3].EffectValue; if (!(effectValue > val.EffectValue) || float.IsInfinity(effectValue)) { throw new Exception("Invalid tempering increment: " + effectType); } if (!updatedMagicItem.TemperedEffectIndices.Contains(num3)) { updatedMagicItem.TemperedEffectIndices.Add(num3); } if (!API.ApplyMagicItemJson(item, JsonConvert.SerializeObject((object)updatedMagicItem))) { throw new Exception("Epic Loot rejected tempered metadata: " + effectType); } num2++; } } } private static void ValidateTemper(ItemData item) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) MagicItem magicItem = ItemDataExtensions.GetMagicItem(item); for (int i = 0; i < magicItem.Effects.Count; i++) { MagicItemEffect val = magicItem.Effects[i]; if (TemperData.IsTemperable(magicItem, val)) { if (new TemperData(item, val.EffectType).probability > 0f) { throw new Exception("Effect can still be tempered: " + val.EffectType); } ValueDef temperRange = TemperData.GetTemperRange(magicItem, val); if (val.EffectValue > temperRange.MaxValue && !magicItem.TemperedEffectIndices.Contains(i)) { throw new Exception("Missing temper history: " + val.EffectType); } } } } private void Update() { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_0142: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Expected O, but got Unknown //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Expected O, but got Unknown if (testDirectory == null || tested || Time.realtimeSinceStartup < nextCheck) { return; } nextCheck = Time.realtimeSinceStartup + 3f; if ((Object)(object)ObjectDB.instance == (Object)null || (Object)(object)ObjectDB.instance.GetItemPrefab("BowGold_BloodLightning") == (Object)null || MagicItemEffectDefinitions.AllDefinitions.Count == 0) { return; } tested = true; try { Directory.CreateDirectory(testDirectory); Dictionary<string, object> dictionary = new Dictionary<string, object>(); string[] array = new string[7] { "SwordGold_BloodLightning", "BowGold_BloodLightning", "ArrowBloodGold", "THSwordGold_BloodLightning", "SwordGold_FrostFire", "BowGold_FrostFire", "TrinketBloodGoldHealth" }; foreach (string text in array) { ItemData val = Clone(text); int maxQuality = val.m_shared.m_maxQuality; SharedData shared = val.m_shared; dictionary[text] = new { maxQuality = maxQuality, damage = shared.m_damages, damagePerLevel = shared.m_damagesPerLevel, attack = shared.m_attack, secondaryAttack = shared.m_secondaryAttack, availableEffects = API.GetAvailableEffectTypes(val, (string)null, 5) }; } string path = Path.Combine(testDirectory, "probe.json"); JsonSerializerSettings val2 = new JsonSerializerSettings(); val2.ReferenceLoopHandling = (ReferenceLoopHandling)1; File.WriteAllText(path, JsonConvert.SerializeObject((object)dictionary, (Formatting)1, val2)); string[] array2 = new string[4] { "sword", "bow", "bowprecision", "trinket" }; foreach (string text2 in array2) { bool[] array3 = new bool[2] { true, false }; foreach (bool flag in array3) { ItemData val3 = Build(text2, flag); ValidateTemper(val3); Inventory val4 = new Inventory("GAP isolated self-test", (Sprite)null, 4, 2); if (!val4.AddItem(val3)) { throw new Exception("Test inventory add failed"); } ZPackage val5 = new ZPackage(); val4.Save(val5); Inventory val6 = new Inventory("GAP isolated restore", (Sprite)null, 4, 2); val6.Load(new ZPackage(val5.GetArray())); ItemData val7 = val6.GetAllItems().Single(); string magicItemJson = API.GetMagicItemJson(val3); string magicItemJson2 = API.GetMagicItemJson(val7); if (magicItemJson != magicItemJson2 || val3.m_quality != val7.m_quality) { throw new Exception("Save/load mismatch: " + text2); } ValidateTemper(val7); File.WriteAllText(Path.Combine(testDirectory, text2 + (flag ? "-empty" : "-filled") + ".json"), magicItemJson2); } } File.WriteAllText(Path.Combine(testDirectory, "SUCCESS.txt"), "All presets: effect legality, tempering limits, socket rules, inventory serialization round-trip passed. No live player or save was accessed."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"GAP_SELFTEST_SUCCESS"); } catch (Exception ex) { File.WriteAllText(Path.Combine(testDirectory, "FAILED.txt"), ex.ToString()); ((BaseUnityPlugin)this).Logger.LogError((object)ex); } if (Environment.GetCommandLineArgs().Contains("-gaptestquit")) { Application.Quit(); } } }