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 MagicMirror v1.0.0
MagicMirror.dll
Decompiled an hour agousing System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace MagicMirrorMod; [BepInPlugin("neck.valheim.magicmirror", "Magic Mirror", "1.0.0")] public class MagicMirrorPlugin : BaseUnityPlugin { public const string Guid = "neck.valheim.magicmirror"; public const string Prefab = "MagicMirror"; private const string Key = "item_magicmirror"; internal static MagicMirrorPlugin Instance; private static ConfigEntry<int> cfgCrystal; private static ConfigEntry<int> cfgSilver; private static ConfigEntry<int> cfgWood; private static ConfigEntry<float> cfgCooldown; private static ConfigEntry<bool> cfgIgnoreTeleportRule; private static ConfigEntry<bool> cfgFallbackSpawn; private static GameObject container; private static GameObject instance; private static Sprite icon; private static float lastUse = -999f; private void Awake() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown Instance = this; cfgCrystal = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "Crystal", 2, "Crystals needed to craft the mirror (0 = not required)"); cfgSilver = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "Silver", 1, "Silver needed to craft the mirror (0 = not required)"); cfgWood = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "Wood", 0, "Wood needed to craft the mirror (0 = not required)"); cfgCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CooldownSeconds", 5f, "Delay between uses"); cfgIgnoreTeleportRule = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IgnoreTeleportRestrictions", true, "Allow teleporting with unteleportable items (ore, metals) in the inventory"); cfgFallbackSpawn = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "TeleportToSpawnWithoutBed", true, "If you have no bed, go to the world spawn point instead of failing"); Harmony val = new Harmony("neck.valheim.magicmirror"); try { val.PatchAll(typeof(Patches)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } MethodInfo methodInfo = AccessTools.Method(typeof(Humanoid), "ConsumeItem", (Type[])null, (Type[])null); if (methodInfo == null) { methodInfo = AccessTools.Method(typeof(Player), "ConsumeItem", (Type[])null, (Type[])null); } if (methodInfo != null) { val.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Patches), "ConsumePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Debug.LogError((object)"MagicMirror: ConsumeItem not found"); } MethodInfo methodInfo2 = AccessTools.Method(typeof(Humanoid), "UseItem", (Type[])null, (Type[])null); if (methodInfo2 != null) { val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Patches), "UsePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Debug.LogError((object)"MagicMirror: UseItem not found"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("patched ConsumeItem=" + (methodInfo != null) + " UseItem=" + (methodInfo2 != null))); } private static GameObject FindItem(ObjectDB db, string name) { for (int i = 0; i < db.m_items.Count; i++) { if ((Object)(object)db.m_items[i] != (Object)null && ((Object)db.m_items[i]).name == name) { return db.m_items[i]; } } return null; } private static void AddWord(string key, string value) { MethodInfo methodInfo = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(Localization.instance, new object[2] { key, value }); } } private static bool RussianUi() { return Localization.instance != null && Localization.instance.GetSelectedLanguage() == "Russian"; } private static Sprite LoadIcon() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0092: 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) if ((Object)(object)icon != (Object)null) { return icon; } using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MagicMirrorMod.MagicMirror.png"); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { return null; } icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); return icon; } private static void BuildPrefab(ObjectDB db) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) GameObject val = FindItem(db, "Wishbone"); if ((Object)(object)val == (Object)null) { val = FindItem(db, "BeltStrength"); } if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)container == (Object)null) { container = new GameObject("MagicMirrorContainer"); container.SetActive(false); Object.DontDestroyOnLoad((Object)(object)container); } GameObject val2 = Object.Instantiate<GameObject>(val, container.transform); ((Object)val2).name = "MagicMirror"; ItemDrop component = val2.GetComponent<ItemDrop>(); component.m_itemData.m_dropPrefab = val2; SharedData shared = component.m_itemData.m_shared; shared.m_name = "$item_magicmirror"; shared.m_description = "$item_magicmirror_description"; shared.m_itemType = (ItemType)18; shared.m_maxStackSize = 1; shared.m_weight = 0.5f; shared.m_food = 0f; shared.m_foodStamina = 0f; shared.m_foodRegen = 0f; shared.m_foodBurnTime = 0f; shared.m_consumeStatusEffect = null; shared.m_setStatusEffect = null; shared.m_equipStatusEffect = null; Sprite val3 = LoadIcon(); if ((Object)(object)val3 != (Object)null) { shared.m_icons = (Sprite[])(object)new Sprite[1] { val3 }; } Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true); foreach (Renderer val4 in componentsInChildren) { Material[] materials = val4.materials; for (int j = 0; j < materials.Length; j++) { materials[j].color = new Color(0.55f, 0.8f, 1f); } val4.materials = materials; } instance = val2; } internal static void EnsureItems(ObjectDB db) { if ((Object)(object)db == (Object)null || db.m_items.Count == 0) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(ObjectDB), "m_itemByHash"); Dictionary<int, GameObject> dictionary = ((fieldInfo != null) ? ((Dictionary<int, GameObject>)fieldInfo.GetValue(db)) : null); if ((Object)(object)instance == (Object)null) { BuildPrefab(db); } if ((Object)(object)instance == (Object)null) { return; } bool flag = RussianUi(); AddWord("item_magicmirror", flag ? "Магическое зеркало" : "Magic Mirror"); AddWord("item_magicmirror_description", flag ? "Загляните в зеркало - и вы окажетесь у своей кровати. Не расходуется." : "Gaze into the mirror to return to your bed. Never used up."); if ((Object)(object)FindItem(db, "MagicMirror") == (Object)null) { db.m_items.Add(instance); if (dictionary != null) { dictionary[StringExtensionMethods.GetStableHashCode("MagicMirror")] = instance; } } AddRecipe(db); } private static void AddRecipe(ObjectDB db) { for (int i = 0; i < db.m_recipes.Count; i++) { if ((Object)(object)db.m_recipes[i] != (Object)null && ((Object)db.m_recipes[i]).name == "Recipe_MagicMirror") { return; } } List<Requirement> list = new List<Requirement>(); AddReq(db, list, "Crystal", cfgCrystal.Value); AddReq(db, list, "Silver", cfgSilver.Value); AddReq(db, list, "Wood", cfgWood.Value); if (list.Count == 0) { AddReq(db, list, "Wood", 1); } if (list.Count != 0) { Recipe val = ScriptableObject.CreateInstance<Recipe>(); ((Object)val).name = "Recipe_MagicMirror"; val.m_item = instance.GetComponent<ItemDrop>(); val.m_amount = 1; val.m_enabled = true; val.m_craftingStation = null; val.m_minStationLevel = 1; val.m_resources = list.ToArray(); db.m_recipes.Add(val); } } private static void AddReq(ObjectDB db, List<Requirement> list, string item, int amount) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (amount > 0) { GameObject val = FindItem(db, item); if (!((Object)(object)val == (Object)null)) { Requirement val2 = new Requirement(); val2.m_resItem = val.GetComponent<ItemDrop>(); val2.m_amount = amount; val2.m_amountPerLevel = 0; val2.m_recover = true; list.Add(val2); } } } internal static void RegisterInScene(ZNetScene scene) { if ((Object)(object)scene == (Object)null || (Object)(object)instance == (Object)null) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs"); Dictionary<int, GameObject> dictionary = ((fieldInfo != null) ? ((Dictionary<int, GameObject>)fieldInfo.GetValue(scene)) : null); if (dictionary != null) { int stableHashCode = StringExtensionMethods.GetStableHashCode("MagicMirror"); if (!dictionary.ContainsKey(stableHashCode)) { scene.m_prefabs.Add(instance); dictionary[stableHashCode] = instance; } } } internal static bool IsMirror(ItemData item) { return item != null && (Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == "MagicMirror"; } private static void Say(Player p, string en, string ru) { ((Character)p).Message((MessageType)2, RussianUi() ? ru : en, 0, (Sprite)null, false); } internal static bool Use(Player p) { //IL_00f1: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: 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) if ((Object)(object)p == (Object)null || (Object)(object)p != (Object)(object)Player.m_localPlayer) { return false; } if (Time.time - lastUse < cfgCooldown.Value) { Say(p, "The mirror is still glowing...", "Зеркало ещё светится..."); return false; } if (((Character)p).IsTeleporting()) { return false; } if (!cfgIgnoreTeleportRule.Value && !((Humanoid)p).GetInventory().IsTeleportable(cfgIgnoreTeleportRule.Value)) { Say(p, "You can't teleport with this cargo", "С этим грузом телепортироваться нельзя"); return false; } PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); if (val == null) { return false; } Vector3 val2; if (val.HaveCustomSpawnPoint()) { val2 = val.GetCustomSpawnPoint(); } else { if (!cfgFallbackSpawn.Value) { Say(p, "You have no bed", "У вас нет кровати"); return false; } val2 = val.GetHomePoint(); } lastUse = Time.time; Say(p, "Returning to your bed...", "Возвращение к кровати..."); ((Character)p).TeleportTo(val2 + Vector3.up * 0.5f, ((Component)p).transform.rotation, true); return true; } } internal static class Patches { [HarmonyPostfix] [HarmonyPatch(typeof(ObjectDB), "Awake")] private static void ObjectDBAwake(ObjectDB __instance) { MagicMirrorPlugin.EnsureItems(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static void ObjectDBCopy(ObjectDB __instance) { MagicMirrorPlugin.EnsureItems(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(ZNetScene), "Awake")] private static void ZNetSceneAwake(ZNetScene __instance) { MagicMirrorPlugin.EnsureItems(ObjectDB.instance); MagicMirrorPlugin.RegisterInScene(__instance); } public static bool UsePrefix(Humanoid __instance, object[] __args) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ItemData item = null; for (int i = 0; i < __args.Length; i++) { if (__args[i] is ItemData) { item = (ItemData)__args[i]; break; } } if (!MagicMirrorPlugin.IsMirror(item)) { return true; } MagicMirrorPlugin.Use((Player)(object)((__instance is Player) ? __instance : null)); return false; } public static bool ConsumePrefix(Humanoid __instance, object[] __args, ref bool __result) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ItemData item = null; for (int i = 0; i < __args.Length; i++) { if (__args[i] is ItemData) { item = (ItemData)__args[i]; break; } } if (!MagicMirrorPlugin.IsMirror(item)) { return true; } __result = MagicMirrorPlugin.Use((Player)(object)((__instance is Player) ? __instance : null)); return false; } }