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 StonesCompass v1.6.0
StonesCompass_v1.6.0.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("StonesCompass")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.6.0.0")] [assembly: AssemblyInformationalVersion("1.6.0")] [assembly: AssemblyProduct("StonesCompass")] [assembly: AssemblyTitle("StonesCompass")] [assembly: AssemblyVersion("1.6.0.0")] namespace StonesCompass; [BepInPlugin("frost.stonescompass", "StonesCompass", "1.6.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class StonesCompassPlugin : BaseUnityPlugin { public const string PluginGuid = "frost.stonescompass"; public const string PluginName = "StonesCompass"; public const string PluginVersion = "1.6.0"; public const string ItemPrefabName = "Compass_Stones"; public const string ItemName = "Компас странника"; public const string TempleLocationName = "StartTemple"; internal static ManualLogSource Log; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; new Harmony("frost.stonescompass").PatchAll(); PrefabManager.OnVanillaPrefabsAvailable += CreateCompassItem; CompassCommand.Register(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"StonesCompass 1.6.0 загружен"); } private void CreateCompassItem() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= CreateCompassItem; try { ItemConfig val = new ItemConfig(); val.Name = "Компас странника"; val.Description = "Странный компас странника: всегда знает дорогу назад — к Жертвенным камням. Возьми в руку и нажми <color=yellow>ПКМ</color> — он укажет путь."; val.Icons = (Sprite[])(object)new Sprite[1] { StonesIcon.Create() }; val.Weight = 0.3f; val.StackSize = 1; ItemConfig val2 = val; CustomItem val3 = new CustomItem(PrefabManager.Instance.CreateClonedPrefab("Compass_Stones", "Amber"), false, val2); ItemManager.Instance.AddItem(val3); Log.LogInfo((object)"Компас странника зарегистрирован через Jötunn"); } catch (Exception ex) { Debug.LogError((object)("[StonesCompass] Ошибка создания предмета: " + ex)); } } } [HarmonyPatch(typeof(Game), "Start")] internal static class Game_Start_Patch { private static void Postfix() { //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Expected O, but got Unknown //IL_02c3: 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_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_02df: 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) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Expected O, but got Unknown //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Expected O, but got Unknown //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Expected O, but got Unknown RegisterRPC(); try { ZNetScene instance = ZNetScene.instance; ObjectDB instance2 = ObjectDB.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null) { return; } bool flag = false; foreach (Recipe recipe in instance2.m_recipes) { if ((Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null && ((Object)((Component)recipe.m_item).gameObject).name == "Compass_Stones") { flag = true; break; } } if (flag) { return; } GameObject val = null; foreach (GameObject prefab in instance.m_prefabs) { if ((Object)(object)prefab != (Object)null && ((Object)prefab).name == "Compass_Stones") { val = prefab; break; } } if ((Object)(object)val == (Object)null) { StonesCompassPlugin.Log.LogWarning((object)"Компас не найден в ZNetScene — рецепт не добавлен"); return; } CraftingStation craftingStation = null; foreach (Recipe recipe2 in instance2.m_recipes) { if ((Object)(object)recipe2 != (Object)null && (Object)(object)recipe2.m_craftingStation != (Object)null && recipe2.m_craftingStation.m_name == "$piece_workbench") { craftingStation = recipe2.m_craftingStation; break; } } GameObject itemPrefab = instance2.GetItemPrefab("HardAntler"); GameObject itemPrefab2 = instance2.GetItemPrefab("Stone"); GameObject itemPrefab3 = instance2.GetItemPrefab("GreydwarfEye"); GameObject itemPrefab4 = instance2.GetItemPrefab("Flint"); GameObject itemPrefab5 = instance2.GetItemPrefab("Raspberry"); List<string> list = new List<string>(); if ((Object)(object)itemPrefab == (Object)null) { list.Add("HardAntler"); } if ((Object)(object)itemPrefab2 == (Object)null) { list.Add("Stone"); } if ((Object)(object)itemPrefab3 == (Object)null) { list.Add("GreydwarfEye"); } if ((Object)(object)itemPrefab4 == (Object)null) { list.Add("Flint"); } if ((Object)(object)itemPrefab5 == (Object)null) { list.Add("Raspberry"); } if (list.Count > 0) { StonesCompassPlugin.Log.LogWarning((object)("Рецепт компаса: не найдены компоненты — " + string.Join(", ", list))); return; } Recipe val2 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val2).name = "Recipe_Compass_Stones"; val2.m_item = val.GetComponent<ItemDrop>(); val2.m_amount = 1; val2.m_craftingStation = craftingStation; val2.m_minStationLevel = 1; val2.m_resources = (Requirement[])(object)new Requirement[5] { new Requirement { m_resItem = itemPrefab.GetComponent<ItemDrop>(), m_amount = 1 }, new Requirement { m_resItem = itemPrefab2.GetComponent<ItemDrop>(), m_amount = 1 }, new Requirement { m_resItem = itemPrefab3.GetComponent<ItemDrop>(), m_amount = 10 }, new Requirement { m_resItem = itemPrefab4.GetComponent<ItemDrop>(), m_amount = 3 }, new Requirement { m_resItem = itemPrefab5.GetComponent<ItemDrop>(), m_amount = 1 } }; instance2.m_recipes.Add(val2); StonesCompassPlugin.Log.LogInfo((object)"Рецепт компаса создан: верстак, рог 1 + камень 1 + глаза грейдворфа 10 + кремень 3 + малина 1"); } catch (Exception ex) { Debug.LogError((object)("[StonesCompass] Ошибка создания рецепта: " + ex)); } } private static void RegisterRPC() { StonesSync.Reset(); if (ZRoutedRpc.instance == null) { StonesCompassPlugin.Log.LogWarning((object)"ZRoutedRpc недоступен при старте мира — RPC не зарегистрированы"); return; } ZRoutedRpc.instance.Register("StonesCompass_RequestTemple", (Action<long>)StonesRPC.OnTempleRequested); ZRoutedRpc.instance.Register<Vector3, bool>("StonesCompass_Temple", (Action<long, Vector3, bool>)StonesRPC.OnTempleReceived); StonesCompassPlugin.Log.LogInfo((object)"RPC зарегистрированы (запрос позиции камней и ответ)"); } } [HarmonyPatch(typeof(InventoryGui), "UpdateCraftingPanel")] internal static class InventoryGui_UpdateCraftingPanel_Patch { private static void Postfix() { try { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { RecipeUnlocker.UnlockFor(localPlayer); } } catch (Exception ex) { Debug.LogError((object)("[StonesCompass] Ошибка обновления меню: " + ex)); } } } [HarmonyPatch(typeof(InventoryGui), "AddRecipeToList")] internal static class InventoryGui_AddRecipeToList_Patch { private static void Postfix(InventoryGui __instance, Recipe recipe, ItemData item, bool canCraft) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) try { if (canCraft || (Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null || ((Object)((Component)recipe.m_item).gameObject).name != "Compass_Stones" || !(AccessTools.Field(typeof(InventoryGui), "m_availableRecipes")?.GetValue(__instance) is IEnumerable enumerable)) { return; } object obj = null; foreach (object item2 in enumerable) { obj = item2; } object? obj2 = AccessTools.Property(obj.GetType(), "InterfaceElement")?.GetValue(obj); GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); object obj3; if (!((Object)(object)val != (Object)null)) { obj3 = null; } else { Transform obj4 = val.transform.Find("icon"); obj3 = ((obj4 != null) ? ((Component)obj4).GetComponent<Image>() : null); } Image val2 = (Image)obj3; if ((Object)(object)val2 != (Object)null && ((Graphic)val2).color.a < 0.05f) { ((Graphic)val2).color = new Color(1f, 1f, 1f, 0.4f); } } catch { } } } internal static class RecipeUnlocker { public static void UnlockFor(Player player) { try { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || player.IsRecipeKnown("Компас странника")) { return; } Recipe val = null; foreach (Recipe recipe in instance.m_recipes) { if ((Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null && ((Object)((Component)recipe.m_item).gameObject).name == "Compass_Stones") { val = recipe; break; } } if (!((Object)(object)val == (Object)null)) { AccessTools.Method(typeof(Player), "AddKnownRecipe", (Type[])null, (Type[])null)?.Invoke(player, new object[1] { val }); StonesCompassPlugin.Log.LogInfo((object)("Рецепт выдан игроку " + player.GetPlayerName())); } } catch (Exception ex) { Debug.LogError((object)("[StonesCompass] Ошибка выдачи рецепта: " + ex)); } } } [HarmonyPatch(typeof(Humanoid), "UseItem", new Type[] { typeof(Inventory), typeof(ItemData), typeof(bool) })] internal static class Humanoid_UseItem_Patch { private const float CooldownSeconds = 600f; private static float _nextUseTime; private static bool Prefix(Humanoid __instance, ItemData item) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (item == null || item.m_shared == null || item.m_shared.m_name != "Компас странника") { return true; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val == (Object)null) { return true; } if (Time.time < _nextUseTime) { float num = _nextUseTime - Time.time; ((Character)val).Message((MessageType)2, $"Компас остывает: ещё {(int)(num / 60f)} мин {(int)(num % 60f)} с", 0, (Sprite)null, false); return false; } if (!TryFindStones(val, out var pos)) { RequestTemplePosFromServer(val); return false; } ShowStonesDirection(val, pos); _nextUseTime = Time.time + 600f; return false; } private static bool TryFindStones(Player player, out Vector3 pos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) pos = Vector3.zero; ZoneSystem instance = ZoneSystem.instance; Vector3 val = default(Vector3); if ((Object)(object)instance != (Object)null && instance.GetLocationIcon("StartTemple", ref val)) { pos = val; return true; } if (StonesSync.Valid) { pos = StonesSync.Pos; return true; } return false; } private static void ShowStonesDirection(Player player, Vector3 stonesPos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) Vector3 val = stonesPos - ((Component)player).transform.position; val.y = 0f; ((Character)player).SetLookDir(val, 3.5f); ((Character)player).Message((MessageType)1, $"Жертвенные камни: {BearingName(val)} ({((Vector3)(ref val)).magnitude:F0} м)", 0, (Sprite)null, false); } private static void RequestTemplePosFromServer(Player player) { if (!(Time.time < StonesSync.NextRequestTime)) { StonesSync.NextRequestTime = Time.time + 5f; if (ZRoutedRpc.instance == null) { StonesCompassPlugin.Log.LogWarning((object)"ZRoutedRpc недоступен — запрос позиции не отправлен"); return; } ((Character)player).Message((MessageType)2, "Запрашиваю позицию камней у сервера...", 0, (Sprite)null, false); StonesCompassPlugin.Log.LogInfo((object)"Локально камни не найдены — отправляю запрос на сервер"); ZRoutedRpc.instance.InvokeRoutedRPC("StonesCompass_RequestTemple", Array.Empty<object>()); } } private static string BearingName(Vector3 dir) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Atan2(dir.x, 0f - dir.z) * 57.29578f; if (num < 0f) { num += 360f; } return (new string[8] { "С", "СВ", "В", "ЮВ", "Ю", "ЮЗ", "З", "СЗ" })[(int)Mathf.Round(num / 45f) % 8]; } } internal static class StonesRPC { public static void OnTempleRequested(long sender) { //IL_00d8: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { ZoneSystem instance = ZoneSystem.instance; Vector3 val = default(Vector3); if ((Object)(object)instance != (Object)null && instance.GetLocationIcon("StartTemple", ref val)) { StonesCompassPlugin.Log.LogInfo((object)$"RPC: отвечаю клиенту {sender}: камни ({val.x:F0}, {val.y:F0}, {val.z:F0})"); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "StonesCompass_Temple", new object[2] { val, true }); } else { StonesCompassPlugin.Log.LogWarning((object)"RPC: StartTemple не найден среди локаций мира — мир ещё генерируется?"); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "StonesCompass_Temple", new object[2] { Vector3.zero, false }); } } } catch (Exception ex) { Debug.LogError((object)("[StonesCompass] Ошибка ответа на запрос: " + ex)); } } public static void OnTempleReceived(long sender, Vector3 pos, bool found) { //IL_0037: 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_004d: 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_0063: Unknown result type (might be due to invalid IL or missing references) try { if (!found) { StonesCompassPlugin.Log.LogInfo((object)"RPC: сервер ответил — камни пока не найдены в мире"); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Камни пока не известны серверу — мир ещё генерируется, попробуй позже", 0, (Sprite)null, false); } return; } StonesSync.Pos = pos; StonesSync.Valid = true; StonesCompassPlugin.Log.LogInfo((object)$"RPC: получена позиция камней ({pos.x:F0}, {pos.y:F0}, {pos.z:F0})"); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Позиция камней получена — нажми ПКМ ещё раз", 0, (Sprite)null, false); } } catch (Exception ex) { Debug.LogError((object)("[StonesCompass] Ошибка приёма позиции: " + ex)); } } } internal static class RpcNames { public const string RequestTemple = "StonesCompass_RequestTemple"; public const string Temple = "StonesCompass_Temple"; } internal static class StonesSync { public static Vector3 Pos; public static bool Valid; public static float NextRequestTime; public static void Reset() { Valid = false; NextRequestTime = 0f; } } internal static class CompassCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; internal void <Register>b__0_0(ConsoleEventArgs <p0>) { Player localPlayer = Player.m_localPlayer; ObjectDB instance = ObjectDB.instance; if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null) { return; } ItemDrop val = null; foreach (GameObject item in instance.m_items) { if ((Object)(object)item != (Object)null && ((Object)item).name == "Compass_Stones") { val = item.GetComponent<ItemDrop>(); break; } } if ((Object)(object)val == (Object)null) { ((Character)localPlayer).Message((MessageType)2, "Компас ещё не готов, попробуй через секунду", 0, (Sprite)null, false); } else if (((Humanoid)localPlayer).GetInventory().AddItem(((Component)val).gameObject, 1)) { ((Character)localPlayer).Message((MessageType)1, "Компас странника получен", 0, (Sprite)null, false); } else { ((Character)localPlayer).Message((MessageType)2, "В инвентаре нет места", 0, (Sprite)null, false); } } } public static void Register() { //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__0_0; if (obj == null) { ConsoleEvent val = delegate { Player localPlayer = Player.m_localPlayer; ObjectDB instance = ObjectDB.instance; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)instance == (Object)null)) { ItemDrop val2 = null; foreach (GameObject item in instance.m_items) { if ((Object)(object)item != (Object)null && ((Object)item).name == "Compass_Stones") { val2 = item.GetComponent<ItemDrop>(); break; } } if ((Object)(object)val2 == (Object)null) { ((Character)localPlayer).Message((MessageType)2, "Компас ещё не готов, попробуй через секунду", 0, (Sprite)null, false); } else if (((Humanoid)localPlayer).GetInventory().AddItem(((Component)val2).gameObject, 1)) { ((Character)localPlayer).Message((MessageType)1, "Компас странника получен", 0, (Sprite)null, false); } else { ((Character)localPlayer).Message((MessageType)2, "В инвентаре нет места", 0, (Sprite)null, false); } } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("stonescompass", "выдать компас странника в инвентарь", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } internal static class StonesIcon { private static Sprite _sprite; public static Sprite Create() { //IL_0057: 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) if ((Object)(object)_sprite != (Object)null) { return _sprite; } Texture2D val = LoadEmbeddedTexture(); if ((Object)(object)val == (Object)null) { val = CreateProceduralTexture(); } ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; val.Apply(true, true); _sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); return _sprite; } private static Texture2D LoadEmbeddedTexture() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown try { Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("stones_icon.png"); if (manifestResourceStream == null) { return null; } using (manifestResourceStream) { byte[] array = new byte[manifestResourceStream.Length]; using (MemoryStream memoryStream = new MemoryStream()) { manifestResourceStream.CopyTo(memoryStream); array = memoryStream.ToArray(); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); return ImageConversion.LoadImage(val, array) ? val : null; } } catch (Exception ex) { Debug.LogError((object)("[StonesCompass] Не удалось загрузить иконку: " + ex)); return null; } } private static Texture2D CreateProceduralTexture() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; Color32[] array = (Color32[])(object)new Color32[4096]; float num = 31.5f; float num2 = 30f; Color32 val2 = default(Color32); for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num3 = (float)j - num; float num4 = (float)i - num; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); ((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0); if (num5 <= num2) { ((Color32)(ref val2))..ctor((byte)52, (byte)48, (byte)56, byte.MaxValue); if (num5 > num2 - 4f) { ((Color32)(ref val2))..ctor((byte)198, (byte)156, (byte)82, byte.MaxValue); } float num6 = 7f * (1f - Mathf.Abs(num4) / 28f); if (Mathf.Abs(num4) <= 28f && Mathf.Abs(num3) <= num6) { val2 = ((num4 > 0f) ? new Color32((byte)214, (byte)62, (byte)48, byte.MaxValue) : new Color32((byte)232, (byte)228, (byte)220, byte.MaxValue)); } } array[i * 64 + j] = val2; } } val.SetPixels32(array); ((Texture)val).filterMode = (FilterMode)1; val.Apply(false, true); return val; } }