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 Quads Bird Trap v1.2.3
plugins/BirdTrap.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DHack.Shared; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially or fully created with the assistance of Generative AI (Claude Code).")] [assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.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 BirdTrap { internal static class Look { private static readonly Dictionary<string, Material> Materials = new Dictionary<string, Material>(); private static readonly Dictionary<string, Color> Plain = new Dictionary<string, Color> { { "StoneDark", new Color(0.36f, 0.36f, 0.38f) }, { "Coal", new Color(0.15f, 0.15f, 0.17f) }, { "Parchment", new Color(0.9f, 0.82f, 0.63f) }, { "Ink", new Color(0.16f, 0.11f, 0.08f) }, { "Bone", new Color(0.92f, 0.89f, 0.8f) }, { "Red", new Color(0.66f, 0.1f, 0.08f) }, { "Gold", new Color(0.93f, 0.72f, 0.2f) }, { "Leather", new Color(0.42f, 0.26f, 0.13f) }, { "Glow", new Color(1f, 0.72f, 0.28f) }, { "Cream", new Color(0.95f, 0.92f, 0.84f) }, { "Black", new Color(0.06f, 0.06f, 0.07f) }, { "Green", new Color(0.18f, 0.5f, 0.25f) }, { "Blue", new Color(0.2f, 0.35f, 0.7f) }, { "Teal", new Color(0.25f, 0.75f, 0.8f) }, { "RedDark", new Color(0.38f, 0.05f, 0.05f) }, { "Chrome", new Color(0.78f, 0.8f, 0.84f) }, { "Wicker", new Color(0.68f, 0.52f, 0.31f) }, { "Grey", new Color(0.64f, 0.66f, 0.7f) } }; private static readonly Dictionary<string, float> Glows = new Dictionary<string, float> { { "Glow", 1.1f }, { "Gold", 0.18f } }; private static Material Find(ZNetScene scene, string prefab, string material) { GameObject prefab2 = scene.GetPrefab(prefab); if ((Object)(object)prefab2 == (Object)null) { return null; } Renderer[] componentsInChildren = prefab2.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name == material) { return val2; } } } return null; } internal static void Harvest(ZNetScene scene, Material fallbackBase) { //IL_00be: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Expected O, but got Unknown //IL_0221: 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_01f5: Unknown result type (might be due to invalid IL or missing references) Materials.Clear(); Materials["Stone"] = Find(scene, "stone_wall_1x1", "stone_mat"); Materials["Planks"] = Find(scene, "wood_floor", "woodwall"); Materials["Dark"] = Find(scene, "darkwood_pole", "DarkWood_mat"); Materials["Iron"] = Find(scene, "iron_grate", "metalwall"); Material val = Find(scene, "piece_cauldron", "cauldron_chain"); Material val2 = (((Object)(object)val != (Object)null) ? val : fallbackBase); foreach (KeyValuePair<string, Color> item in Plain) { Material val3 = new Material(val2) { color = item.Value }; if (val3.HasProperty("_MainTex")) { val3.mainTexture = null; } if (Glows.TryGetValue(item.Key, out var value) && val3.HasProperty("_EmissionColor")) { val3.EnableKeyword("_EMISSION"); val3.SetColor("_EmissionColor", item.Value * value); } Materials[item.Key] = val3; } string[] array = new string[4] { "Stone", "Planks", "Dark", "Iron" }; foreach (string text in array) { if ((Object)(object)Materials[text] == (Object)null) { Materials[text] = new Material(val2) { color = (Color)(text switch { "Dark" => new Color(0.25f, 0.17f, 0.11f), "Planks" => new Color(0.5f, 0.34f, 0.2f), "Stone" => new Color(0.5f, 0.5f, 0.52f), _ => new Color(0.38f, 0.38f, 0.42f), }) }; } } Debug.Log((object)("[BirdTrap] materials: " + string.Join(", ", Materials.Select((KeyValuePair<string, Material> kv) => kv.Key + "=" + ((Object)kv.Value).name).ToArray()))); } internal static Material Of(string name) { if (!Materials.TryGetValue(name, out var value)) { return Materials.Values.FirstOrDefault(); } return value; } internal static void Clear() { Materials.Clear(); } } internal static class ModelBuilder { internal static GameObject Build(Transform parent, object[][] parts, int layer) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_00ef: 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_00fd: Expected O, but got Unknown //IL_0194: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Model") { layer = layer }; val.transform.SetParent(parent, false); Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>(); Vector3 localPosition = default(Vector3); Vector3 localScale = default(Vector3); Vector3 val2 = default(Vector3); Transform val3; GameObject val4; for (int i = 0; i < parts.Length; val4.transform.SetParent(val3, false), val4.transform.localPosition = localPosition, val4.transform.localRotation = Quaternion.Euler(val2), i++) { object[] array = parts[i]; string text = (string)array[0]; string text2 = (string)array[1]; string text3 = (string)array[2]; ((Vector3)(ref localPosition))..ctor((float)array[3], (float)array[4], (float)array[5]); ((Vector3)(ref localScale))..ctor((float)array[6], (float)array[7], (float)array[8]); ((Vector3)(ref val2))..ctor((float)array[9], (float)array[10], (float)array[11]); val3 = ((text3.Length > 0 && dictionary.TryGetValue(text3, out var value)) ? value : val.transform); int num; switch (text2) { case "Group": val4 = new GameObject(text) { layer = layer }; dictionary[text] = val4.transform; continue; default: num = 0; break; case "Cylinder": num = 2; break; case "Cube": num = 3; break; } val4 = GameObject.CreatePrimitive((PrimitiveType)num); ((Object)val4).name = text; Object.DestroyImmediate((Object)(object)val4.GetComponent<Collider>()); val4.layer = layer; val4.GetComponent<Renderer>().sharedMaterial = Look.Of((string)array[12]); val4.transform.localScale = localScale; } return val; } } internal static class ModelData { internal const float Scale = 1f; internal static readonly object[][] Parts = new object[120][] { new object[13] { "runner", "Cylinder", "", 0f, 0.03f, -0.22f, 0.06f, 0.46f, 0.06f, 0f, 0f, 90f, "Dark" }, new object[13] { "runner", "Cylinder", "", 0f, 0.03f, 0.22f, 0.06f, 0.46f, 0.06f, 0f, 0f, 90f, "Dark" }, new object[13] { "basePlank", "Cube", "", -0.336f, 0.052f, 0f, 0.16f, 0.036f, 0.62f, 0f, 0f, 0f, "Planks" }, new object[13] { "basePlank", "Cube", "", -0.168f, 0.052f, 0f, 0.16f, 0.036f, 0.62f, 0f, 0f, 0f, "Planks" }, new object[13] { "basePlank", "Cube", "", 0f, 0.052f, 0f, 0.16f, 0.036f, 0.62f, 0f, 0f, 0f, "Planks" }, new object[13] { "basePlank", "Cube", "", 0.168f, 0.052f, 0f, 0.16f, 0.036f, 0.62f, 0f, 0f, 0f, "Planks" }, new object[13] { "basePlank", "Cube", "", 0.336f, 0.052f, 0f, 0.16f, 0.036f, 0.62f, 0f, 0f, 0f, "Planks" }, new object[13] { "baseBatten", "Cube", "", 0f, 0.074f, -0.26f, 0.82f, 0.012f, 0.035f, 0f, 0f, 0f, "Dark" }, new object[13] { "baseBatten", "Cube", "", 0f, 0.074f, 0.26f, 0.82f, 0.012f, 0.035f, 0f, 0f, 0f, "Dark" }, new object[13] { "post", "Cube", "", -0.4f, 0.28f, -0.27f, 0.045f, 0.42f, 0.045f, 0f, 0f, 0f, "Dark" }, new object[13] { "post", "Cube", "", -0.4f, 0.28f, 0.27f, 0.045f, 0.42f, 0.045f, 0f, 0f, 0f, "Dark" }, new object[13] { "post", "Cube", "", 0.4f, 0.28f, -0.27f, 0.045f, 0.42f, 0.045f, 0f, 0f, 0f, "Dark" }, new object[13] { "post", "Cube", "", 0.4f, 0.28f, 0.27f, 0.045f, 0.42f, 0.045f, 0f, 0f, 0f, "Dark" }, new object[13] { "frameX", "Cube", "", 0f, 0.49f, -0.27f, 0.84f, 0.04f, 0.045f, 0f, 0f, 0f, "Dark" }, new object[13] { "frameX", "Cube", "", 0f, 0.49f, 0.27f, 0.84f, 0.04f, 0.045f, 0f, 0f, 0f, "Dark" }, new object[13] { "frameZ", "Cube", "", -0.4f, 0.49f, 0f, 0.045f, 0.04f, 0.58f, 0f, 0f, 0f, "Dark" }, new object[13] { "frameZ", "Cube", "", 0.4f, 0.49f, 0f, 0.045f, 0.04f, 0.58f, 0f, 0f, 0f, "Dark" }, new object[13] { "midZ", "Cube", "", -0.4f, 0.28f, 0f, 0.03f, 0.028f, 0.54f, 0f, 0f, 0f, "Dark" }, new object[13] { "midZ", "Cube", "", 0.4f, 0.28f, 0f, 0.03f, 0.028f, 0.54f, 0f, 0f, 0f, "Dark" }, new object[13] { "midBack", "Cube", "", 0f, 0.28f, 0.27f, 0.8f, 0.028f, 0.03f, 0f, 0f, 0f, "Dark" }, new object[13] { "slatSide", "Cube", "", -0.4f, 0.28f, -0.215f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatSide", "Cube", "", 0.4f, 0.28f, -0.215f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatSide", "Cube", "", -0.4f, 0.28f, -0.1433f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatSide", "Cube", "", 0.4f, 0.28f, -0.1433f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatSide", "Cube", "", -0.4f, 0.28f, -0.0717f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatSide", "Cube", "", 0.4f, 0.28f, -0.0717f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatSide", "Cube", "", -0.4f, 0.28f, 0f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatSide", "Cube", "", 0.4f, 0.28f, 0f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatSide", "Cube", "", -0.4f, 0.28f, 0.0717f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatSide", "Cube", "", 0.4f, 0.28f, 0.0717f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatSide", "Cube", "", -0.4f, 0.28f, 0.1433f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatSide", "Cube", "", 0.4f, 0.28f, 0.1433f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatSide", "Cube", "", -0.4f, 0.28f, 0.215f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatSide", "Cube", "", 0.4f, 0.28f, 0.215f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatBack", "Cube", "", -0.345f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatBack", "Cube", "", -0.2683f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatBack", "Cube", "", -0.1917f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatBack", "Cube", "", -0.115f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatBack", "Cube", "", -0.0383f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatBack", "Cube", "", 0.0383f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatBack", "Cube", "", 0.115f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatBack", "Cube", "", 0.1917f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatBack", "Cube", "", 0.2683f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatBack", "Cube", "", 0.345f, 0.28f, 0.27f, 0.022f, 0.4f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatTop", "Cube", "", -0.345f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatTop", "Cube", "", -0.2683f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatTop", "Cube", "", -0.1917f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatTop", "Cube", "", -0.115f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatTop", "Cube", "", -0.0383f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatTop", "Cube", "", 0.0383f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatTop", "Cube", "", 0.115f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatTop", "Cube", "", 0.1917f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Planks" }, new object[13] { "slatTop", "Cube", "", 0.2683f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Wicker" }, new object[13] { "slatTop", "Cube", "", 0.345f, 0.502f, 0f, 0.022f, 0.022f, 0.55f, 0f, 0f, 0f, "Planks" }, new object[13] { "cornerLash", "Cube", "", -0.4f, 0.48f, -0.27f, 0.06f, 0.05f, 0.06f, 0f, 0f, 0f, "Leather" }, new object[13] { "cornerLash", "Cube", "", -0.4f, 0.48f, 0.27f, 0.06f, 0.05f, 0.06f, 0f, 0f, 0f, "Leather" }, new object[13] { "cornerLash", "Cube", "", 0.4f, 0.48f, -0.27f, 0.06f, 0.05f, 0.06f, 0f, 0f, 0f, "Leather" }, new object[13] { "cornerLash", "Cube", "", 0.4f, 0.48f, 0.27f, 0.06f, 0.05f, 0.06f, 0f, 0f, 0f, "Leather" }, new object[13] { "lash", "Cube", "", -0.4f, 0.28f, -0.215f, 0.04f, 0.04f, 0.03f, 0f, 0f, 0f, "Leather" }, new object[13] { "lash", "Cube", "", 0.4f, 0.28f, -0.215f, 0.04f, 0.04f, 0.03f, 0f, 0f, 0f, "Leather" }, new object[13] { "lash", "Cube", "", -0.4f, 0.28f, 0.215f, 0.04f, 0.04f, 0.03f, 0f, 0f, 0f, "Leather" }, new object[13] { "lash", "Cube", "", 0.4f, 0.28f, 0.215f, 0.04f, 0.04f, 0.03f, 0f, 0f, 0f, "Leather" }, new object[13] { "guide", "Cube", "", -0.4f, 0.45f, -0.295f, 0.05f, 0.76f, 0.035f, 0f, 0f, 0f, "Dark" }, new object[13] { "guideKnob", "Sphere", "", -0.4f, 0.85f, -0.295f, 0.07f, 0.06f, 0.07f, 0f, 0f, 0f, "Dark" }, new object[13] { "guide", "Cube", "", 0.4f, 0.45f, -0.295f, 0.05f, 0.76f, 0.035f, 0f, 0f, 0f, "Dark" }, new object[13] { "guideKnob", "Sphere", "", 0.4f, 0.85f, -0.295f, 0.07f, 0.06f, 0.07f, 0f, 0f, 0f, "Dark" }, new object[13] { "guideTop", "Cube", "", 0f, 0.83f, -0.295f, 0.86f, 0.04f, 0.05f, 0f, 0f, 0f, "Dark" }, new object[13] { "door", "Group", "", 0f, 0.37f, -0.32f, 1f, 1f, 1f, 0f, 0f, 0f, "" }, new object[13] { "doorSlat", "Cube", "door", -0.335f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "doorSlat", "Cube", "door", -0.2512f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "doorSlat", "Cube", "door", -0.1675f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "doorSlat", "Cube", "door", -0.0837f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "doorSlat", "Cube", "door", 0f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "doorSlat", "Cube", "door", 0.0837f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "doorSlat", "Cube", "door", 0.1675f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "doorSlat", "Cube", "door", 0.2512f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Wicker" }, new object[13] { "doorSlat", "Cube", "door", 0.335f, 0.195f, 0f, 0.026f, 0.38f, 0.022f, 0f, 0f, 0f, "Planks" }, new object[13] { "doorBar", "Cube", "door", 0f, 0.025f, -0.006f, 0.76f, 0.04f, 0.03f, 0f, 0f, 0f, "Dark" }, new object[13] { "doorBar", "Cube", "door", 0f, 0.365f, -0.006f, 0.76f, 0.04f, 0.03f, 0f, 0f, 0f, "Dark" }, new object[13] { "doorBrace", "Cube", "door", -0.17f, 0.195f, -0.01f, 0.025f, 0.351f, 0.02f, 0f, 0f, -52f, "Dark" }, new object[13] { "doorBrace", "Cube", "door", 0.17f, 0.195f, -0.01f, 0.025f, 0.351f, 0.02f, 0f, 0f, 52f, "Dark" }, new object[13] { "doorRing", "Cylinder", "door", 0f, 0.395f, -0.012f, 0.05f, 0.006f, 0.05f, 90f, 0f, 0f, "Iron" }, new object[13] { "prop", "Group", "", 0f, 0.07f, -0.36f, 1f, 1f, 1f, 0f, 0f, 0f, "" }, new object[13] { "propStick", "Cylinder", "prop", 0f, 0.14f, 0f, 0.026f, 0.14f, 0.026f, -6f, 0f, 0f, "Planks" }, new object[13] { "propFork", "Cylinder", "prop", -0.018f, 0.29f, -0.005f, 0.016f, 0.035f, 0.016f, 0f, 0f, 30f, "Planks" }, new object[13] { "propFork", "Cylinder", "prop", 0.018f, 0.29f, -0.005f, 0.016f, 0.035f, 0.016f, 0f, 0f, -30f, "Planks" }, new object[13] { "cord", "Cylinder", "prop", 0f, 0.16f, 0.12f, 0.008f, 0.2f, 0.008f, 58f, 0f, 0f, "Leather" }, new object[13] { "pedal", "Cube", "", 0f, 0.082f, 0.03f, 0.18f, 0.016f, 0.12f, 0f, 0f, 0f, "Planks" }, new object[13] { "pedalPin", "Cylinder", "", 0f, 0.095f, 0.09f, 0.02f, 0.012f, 0.02f, 0f, 0f, 0f, "Dark" }, new object[13] { "bait", "Group", "", 0f, 0.092f, 0.03f, 1f, 1f, 1f, 0f, 0f, 0f, "" }, new object[13] { "leaf", "Sphere", "bait", 0f, 0f, 0f, 0.16f, 0.012f, 0.1f, 0f, 0f, 0f, "Green" }, new object[13] { "berry", "Sphere", "bait", -0.03f, 0.018f, 0.01f, 0.03f, 0.03f, 0.03f, 0f, 0f, 0f, "Red" }, new object[13] { "berry", "Sphere", "bait", 0.02f, 0.018f, -0.015f, 0.03f, 0.03f, 0.03f, 0f, 0f, 0f, "Red" }, new object[13] { "berry", "Sphere", "bait", 0.035f, 0.018f, 0.02f, 0.03f, 0.03f, 0.03f, 0f, 0f, 0f, "Red" }, new object[13] { "berry", "Sphere", "bait", -0.01f, 0.018f, -0.03f, 0.03f, 0.03f, 0.03f, 0f, 0f, 0f, "Red" }, new object[13] { "berry", "Sphere", "bait", 0f, 0.018f, 0.025f, 0.03f, 0.03f, 0.03f, 0f, 0f, 0f, "Red" }, new object[13] { "seed", "Sphere", "bait", -0.05f, 0.01f, -0.01f, 0.018f, 0.012f, 0.026f, 0f, 0f, 0f, "Leather" }, new object[13] { "seed", "Sphere", "bait", 0.055f, 0.01f, -0.02f, 0.018f, 0.012f, 0.026f, 0f, 0f, 0f, "Leather" }, new object[13] { "seed", "Sphere", "bait", -0.045f, 0.01f, 0.03f, 0.018f, 0.012f, 0.026f, 0f, 0f, 0f, "Leather" }, new object[13] { "seed", "Sphere", "bait", 0.06f, 0.01f, 0.03f, 0.018f, 0.012f, 0.026f, 0f, 0f, 0f, "Leather" }, new object[13] { "bird", "Group", "", 0.02f, 0.074f, -0.02f, 1f, 1f, 1f, 0f, 160f, 0f, "" }, new object[13] { "birdBody", "Group", "bird", 0f, 0f, 0f, 1f, 1f, 1f, 0f, 0f, 0f, "" }, new object[13] { "body", "Sphere", "birdBody", 0f, 0.1105f, 0.0065f, 0.156f, 0.13f, 0.26f, -12f, 0f, 0f, "Cream" }, new object[13] { "back", "Sphere", "birdBody", 0f, 0.1365f, 0.039f, 0.1495f, 0.078f, 0.208f, -12f, 0f, 0f, "Grey" }, new object[13] { "head", "Sphere", "birdBody", 0f, 0.208f, -0.0975f, 0.0975f, 0.0936f, 0.104f, 0f, 0f, 0f, "Cream" }, new object[13] { "beak", "Cube", "birdBody", 0f, 0.1989f, -0.1586f, 0.0234f, 0.0234f, 0.0585f, 6f, 0f, 0f, "Gold" }, new object[13] { "beakTip", "Cube", "birdBody", 0f, 0.1937f, -0.1846f, 0.0182f, 0.0208f, 0.013f, 0f, 0f, 0f, "RedDark" }, new object[13] { "eye", "Sphere", "birdBody", -0.039f, 0.221f, -0.1274f, 0.0182f, 0.0182f, 0.0182f, 0f, 0f, 0f, "Black" }, new object[13] { "wing", "Sphere", "birdBody", -0.0715f, 0.13f, 0.039f, 0.039f, 0.091f, 0.221f, -14f, 0f, 0f, "Grey" }, new object[13] { "wingTip", "Sphere", "birdBody", -0.0585f, 0.1456f, 0.1495f, 0.0286f, 0.039f, 0.104f, -20f, 0f, 0f, "Black" }, new object[13] { "eye", "Sphere", "birdBody", 0.039f, 0.221f, -0.1274f, 0.0182f, 0.0182f, 0.0182f, 0f, 0f, 0f, "Black" }, new object[13] { "wing", "Sphere", "birdBody", 0.0715f, 0.13f, 0.039f, 0.039f, 0.091f, 0.221f, -14f, 0f, 0f, "Grey" }, new object[13] { "wingTip", "Sphere", "birdBody", 0.0585f, 0.1456f, 0.1495f, 0.0286f, 0.039f, 0.104f, -20f, 0f, 0f, "Black" }, new object[13] { "tail", "Cube", "birdBody", 0f, 0.1365f, 0.1495f, 0.078f, 0.0182f, 0.078f, -16f, 0f, 0f, "Black" }, new object[13] { "leg", "Cylinder", "bird", -0.0286f, 0.026f, 0f, 0.0143f, 0.0312f, 0.0143f, 0f, 0f, 0f, "Gold" }, new object[13] { "foot", "Cube", "bird", -0.0286f, 0.0039f, -0.0156f, 0.039f, 0.0078f, 0.0455f, 0f, 0f, 0f, "Gold" }, new object[13] { "leg", "Cylinder", "bird", 0.0286f, 0.026f, 0f, 0.0143f, 0.0312f, 0.0143f, 0f, 0f, 0f, "Gold" }, new object[13] { "foot", "Cube", "bird", 0.0286f, 0.0039f, -0.0156f, 0.039f, 0.0078f, 0.0455f, 0f, 0f, 0f, "Gold" }, new object[13] { "weightStone", "Sphere", "", 0.1f, 0.535f, 0.1f, 0.22f, 0.075f, 0.16f, 0f, 20f, 0f, "Stone" }, new object[13] { "weightStone2", "Sphere", "", 0.2f, 0.53f, 0.16f, 0.12f, 0.05f, 0.1f, 0f, -30f, 0f, "StoneDark" } }; } [BepInPlugin("com.quad.birdtrap", "BirdTrap", "1.2.3")] public class Plugin : BaseUnityPlugin { public const string Guid = "com.quad.birdtrap"; public const string OldGuid = "com.dhack.birdtrap"; public const string Name = "BirdTrap"; public const string Version = "1.2.3"; public const string PiecePrefab = "piece_birdtrap"; internal static ConfigEntry<float> MinMinutes; internal static ConfigEntry<float> MaxMinutes; internal static ConfigEntry<int> MinFeathers; internal static ConfigEntry<int> MaxFeathers; internal static ConfigEntry<int> MaxBait; internal static ConfigEntry<bool> NeedsSky; internal static ConfigEntry<bool> RestsAtNight; private static GameObject _holder; private static GameObject _prefab; private static PieceTable _table; internal static EffectList DoorShut; internal static EffectList DoorOpen; internal static ServerSettings Synced; internal static ConfigEntry<string> Cost; internal static ManualLogSource Log; private static bool _tellNoServer; internal const string DefaultCost = "Wood:8, LeatherScraps:2"; private Harmony _harmony; private BaseUnityPlugin _claudeTools; private float _nextClaudeCheck; private void Awake() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown Migration.FromOldGuid((BaseUnityPlugin)(object)this, "com.dhack.birdtrap"); Translations.Load((BaseUnityPlugin)(object)this); Log = ((BaseUnityPlugin)this).Logger; Synced = new ServerSettings("com.quad.birdtrap", ((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); MinMinutes = Synced.Add<float>(((BaseUnityPlugin)this).Config.Bind<float>("Catching", "MinutesMin", 8f, new ConfigDescription("Shortest wait (real minutes, in game time) from baiting to a bird. In multiplayer the server's value applies.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 120f), Array.Empty<object>()))); MaxMinutes = Synced.Add<float>(((BaseUnityPlugin)this).Config.Bind<float>("Catching", "MinutesMax", 14f, new ConfigDescription("Longest wait (real minutes, in game time) from baiting to a bird. In multiplayer the server's value applies.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 240f), Array.Empty<object>()))); MaxBait = Synced.Add<int>(((BaseUnityPlugin)this).Config.Bind<int>("Catching", "BaitHeld", 5, new ConfigDescription("How many pieces of bait a trap holds (each bird eats one). In multiplayer the server's value applies.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()))); NeedsSky = Synced.Add<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Catching", "NeedsOpenSky", true, "Birds only come to a trap with open sky above it (not under a roof). In multiplayer the server's value applies.")); RestsAtNight = Synced.Add<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Catching", "BirdsRoostAtNight", true, "No birds come at night: one due then comes in the morning. In multiplayer the server's value applies.")); MinFeathers = Synced.Add<int>(((BaseUnityPlugin)this).Config.Bind<int>("Plucking", "FeathersMin", 2, new ConfigDescription("Fewest feathers a bird gives. In multiplayer the server's value applies.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()))); MaxFeathers = Synced.Add<int>(((BaseUnityPlugin)this).Config.Bind<int>("Plucking", "FeathersMax", 3, new ConfigDescription("Most feathers a bird gives. In multiplayer the server's value applies.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()))); Cost = Synced.Bind("Building", "Cost", "Wood:8, LeatherScraps:2", "What a bird trap costs to build with the hammer (at a workbench). Item prefab names and amounts, separated by commas, like FineWood:12, BronzeNails:30 (Claude Tools' `prefabs <text>` shows exact names). A cost with a mistake in it keeps the last good one.", null); Cost.SettingChanged += delegate { ApplyCost(); }; Synced.ServerChanged += delegate { _tellNoServer = Synced.Server == ServerSettings.ServerMod.Missing; }; _harmony = new Harmony("com.quad.birdtrap"); _harmony.PatchAll(); if ((Object)(object)ZNetScene.instance != (Object)null) { Register(ZNetScene.instance); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"BirdTrap 1.2.3 loaded"); } private void Update() { Synced?.Update(); if (_tellNoServer && (Object)(object)Player.m_localPlayer != (Object)null) { _tellNoServer = false; ((Character)Player.m_localPlayer).Message((MessageType)2, "$birdtrap_server_missing", 0, (Sprite)null, false); } if (Time.unscaledTime < _nextClaudeCheck) { return; } _nextClaudeCheck = Time.unscaledTime + 5f; PluginInfo value; BaseUnityPlugin val = (Chainloader.PluginInfos.TryGetValue("com.quad.claudetools", out value) ? value.Instance : null); if ((Object)(object)val == (Object)(object)_claudeTools) { return; } _claudeTools = val; if ((Object)(object)val == (Object)null) { return; } try { MethodInfo method = ((object)val).GetType().GetMethod("RegisterCommand", BindingFlags.Static | BindingFlags.Public); Func<string[], Action<JObject>, Action<string>, IEnumerator> func = delegate(string[] a, Action<JObject> output, Action<string> error) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0035: Expected O, but got Unknown //IL_007c: 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) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown Vector3 me = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero); JArray val2 = new JArray(); foreach (TrapPiece item in TrapPiece.All.OrderBy((TrapPiece x) => Vector3.Distance(((Component)x).transform.position, me))) { if ((Object)(object)item != (Object)null) { val2.Add((JToken)(object)item.Report(me)); } } output(new JObject { ["traps"] = (JToken)(object)val2, ["day"] = JToken.op_Implicit(((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetDay() : 0), ["night"] = JToken.op_Implicit((Object)(object)EnvMan.instance != (Object)null && EnvMan.IsNight()) }); return (IEnumerator)null; }; method?.Invoke(null, new object[4] { "BirdTrap", "traps", "traps: every bird trap loaded: bait, bird, minutes to the next bird, open sky, owner", func }); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not add the traps command to Claude Tools: " + ex.Message)); } } private void OnDestroy() { try { ((object)_claudeTools)?.GetType().GetMethod("UnregisterAll", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { "BirdTrap" }); } catch { } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Unregister(); Synced?.Dispose(); Translations.Unload(); } internal static void Register(ZNetScene scene) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown GameObject prefab = scene.GetPrefab("piece_chest_wood"); GameObject prefab2 = scene.GetPrefab("Hammer"); GameObject prefab3 = scene.GetPrefab("piece_workbench"); if ((Object)(object)prefab == (Object)null || (Object)(object)prefab2 == (Object)null) { Debug.LogWarning((object)"BirdTrap: chest or hammer prefab not found"); return; } if ((Object)(object)_prefab == (Object)null) { _holder = new GameObject("BirdTrapPrefabs"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); try { Look.Harvest(scene, prefab.GetComponentInChildren<Renderer>(true).sharedMaterial); } catch (Exception ex) { Debug.LogWarning((object)("BirdTrap: could not take the game's materials, the trap looks plain: " + ex.Message)); } Container component = prefab.GetComponent<Container>(); DoorShut = (((Object)(object)component != (Object)null) ? component.m_closeEffects : null); DoorOpen = (((Object)(object)component != (Object)null) ? component.m_openEffects : null); _prefab = Make(prefab, ((Object)(object)prefab3 != (Object)null) ? prefab3.GetComponent<CraftingStation>() : null); } Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(scene); PieceTable buildPieces = prefab2.GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces; if (!scene.m_prefabs.Contains(_prefab)) { scene.m_prefabs.Add(_prefab); } dictionary[StringExtensionMethods.GetStableHashCode(((Object)_prefab).name)] = _prefab; buildPieces.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null); if (!buildPieces.m_pieces.Contains(_prefab)) { buildPieces.m_pieces.Add(_prefab); } _table = buildPieces; Synced.NeedsServer(_prefab); RefreshPlaced(); } private static void RefreshPlaced() { int num = 0; ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0); foreach (ZNetView val in array) { if ((Object)(object)val == (Object)null || val.GetZDO() == null || !((Object)((Component)val).gameObject).name.StartsWith("piece_birdtrap")) { continue; } MonoBehaviour[] components = ((Component)val).GetComponents<MonoBehaviour>(); foreach (MonoBehaviour val2 in components) { if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name == "TrapPiece" && ((object)val2).GetType() != typeof(TrapPiece)) { Object.DestroyImmediate((Object)(object)val2); } } if ((Object)(object)((Component)val).GetComponent<TrapPiece>() == (Object)null) { ((Component)val).gameObject.AddComponent<TrapPiece>(); num++; } } if (num > 0) { Debug.Log((object)string.Format("[{0}] refreshed {1} trap(s) already built", "BirdTrap", num)); } } internal static void ApplyCost() { Piece val = (((Object)(object)_prefab != (Object)null) ? _prefab.GetComponent<Piece>() : null); if ((Object)(object)val != (Object)null) { Costs.Apply(val, Cost.Value, Log); } } private static GameObject Make(GameObject source, CraftingStation workbench) { //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_00a2: 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_00af: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(source, _holder.transform); ((Object)val).name = "piece_birdtrap"; Container component = val.GetComponent<Container>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } int num = LayerMask.NameToLayer("piece"); if (num < 0) { num = val.layer; } Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { val2.enabled = false; } Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true); foreach (Collider val3 in componentsInChildren2) { Object.DestroyImmediate((Object)(object)val3); } GameObject val4 = new GameObject("Hitbox") { layer = num }; val4.transform.SetParent(val.transform, false); BoxCollider val5 = val4.AddComponent<BoxCollider>(); val5.center = new Vector3(0f, 0.42f, 0f); val5.size = new Vector3(0.92f, 0.84f, 0.66f); try { ModelBuilder.Build(val.transform, ModelData.Parts, val.layer); } catch (Exception ex) { Debug.LogWarning((object)("BirdTrap: could not build the trap's model: " + ex.Message)); } Piece component2 = val.GetComponent<Piece>(); component2.m_name = "$birdtrap_piece"; component2.m_description = "$birdtrap_piece_desc"; component2.m_category = (PieceCategory)0; component2.m_usage = (UsageTagFlags)1; component2.m_craftingStation = workbench; if (!Costs.Apply(component2, Cost.Value, Log) && !Costs.Apply(component2, "Wood:8, LeatherScraps:2", Log)) { component2.m_resources = source.GetComponent<Piece>().m_resources; } try { component2.m_icon = Icon.Make(val, (Vector3?)new Vector3(0.55f, 0.42f, -1f), (Action<GameObject>)delegate(GameObject copy) { //IL_0023: 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) Transform[] componentsInChildren3 = copy.GetComponentsInChildren<Transform>(true); foreach (Transform val6 in componentsInChildren3) { if (((Object)val6).name == "bird") { val6.localPosition = TrapPiece.PerchPos; val6.localRotation = Quaternion.Euler(0f, 205f, 0f); } } }, "icon.png"); } catch (Exception ex2) { Debug.LogWarning((object)("BirdTrap: could not draw the build-menu picture: " + ex2.Message)); } val.AddComponent<TrapPiece>(); return val; } internal static void Unregister() { if ((Object)(object)_prefab == (Object)null) { return; } if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.m_prefabs.Remove(_prefab); Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(ZNetScene.instance); int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)_prefab).name); if (dictionary.TryGetValue(stableHashCode, out var value) && (Object)(object)value == (Object)(object)_prefab) { dictionary.Remove(stableHashCode); } } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("Hammer") : null); (_table ?? (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces : null))?.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || (Object)(object)p == (Object)(object)_prefab); _table = null; _prefab = null; Object.Destroy((Object)(object)_holder); _holder = null; Look.Clear(); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ZNetScene_Awake { private static void Postfix(ZNetScene __instance) { Plugin.Register(__instance); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] internal static class ObjectDB_Awake { private static void Postfix() { if ((Object)(object)ZNetScene.instance != (Object)null) { Plugin.Register(ZNetScene.instance); } } } public class TrapPiece : MonoBehaviour, Interactable, Hoverable { private class BaitAsk { public long To; public string[] Items; public float At; public bool Back; } private const string KeyBait = "bt_bait"; private const string KeyKinds = "bt_kinds"; private const string KeyNext = "bt_next"; private const string KeyBird = "bt_bird"; private const string KeyWhy = "bt_why"; private const string KeyFrom = "bt_from"; private const float Lift = 0.3f; internal static readonly Vector3 PerchPos = new Vector3(0.16f, 0.85f, -0.295f); internal const float PerchYaw = 205f; private static readonly string[] Baits = new string[9] { "Raspberry", "Blueberries", "Cloudberry", "BeechSeeds", "BirchSeeds", "Barley", "CarrotSeeds", "TurnipSeeds", "OnionSeeds" }; internal static readonly HashSet<TrapPiece> All = new HashSet<TrapPiece>(); private ZNetView _nview; private Transform _door; private Transform _prop; private Transform _bait; private Transform _bird; private Transform _birdBody; private Vector3 _doorUp; private Vector3 _birdHome; private Quaternion _birdTurn; private float _doorAt = 1f; private bool _hadBird; private bool _seen; private float _nextThink; private float _pluckAskedAt = -9f; private WearNTear _wnt; private readonly List<BaitAsk> _asks = new List<BaitAsk>(); private const float AnswerWait = 5f; private const string RpcBait = "bt_Bait"; private const string RpcBaitTaken = "bt_BaitTaken"; private const string RpcPluck = "bt_Pluck"; private const string RpcPlucked = "bt_Plucked"; private static readonly string[] Rpcs = new string[4] { "bt_Bait", "bt_BaitTaken", "bt_Pluck", "bt_Plucked" }; private ZDO Zdo { get { if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid()) { return null; } return _nview.GetZDO(); } } private int Bait { get { ZDO zdo = Zdo; if (zdo == null) { return 0; } return zdo.GetInt("bt_bait", 0); } } private bool HasBird { get { ZDO zdo = Zdo; if (zdo == null) { return false; } return zdo.GetBool("bt_bird", false); } } private static double Now { get { if (!((Object)(object)ZNet.instance != (Object)null)) { return 0.0; } return ZNet.instance.GetTimeSeconds(); } } private void OnDestroy() { All.Remove(this); if ((Object)(object)_nview != (Object)null) { string[] rpcs = Rpcs; foreach (string text in rpcs) { _nview.Unregister(text); } } if ((Object)(object)_wnt != (Object)null) { WearNTear wnt = _wnt; wnt.m_onDestroyed = (Action)Delegate.Remove(wnt.m_onDestroyed, new Action(OnPieceDestroyed)); } foreach (BaitAsk ask in _asks) { if (!ask.Back) { GiveBack(ask, 0); } } _asks.Clear(); } private void Awake() { //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) _nview = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)_nview != (Object)null && _nview.GetZDO() != null) { All.Add(this); string[] rpcs = Rpcs; foreach (string text in rpcs) { _nview.Unregister(text); } _nview.Register<string>("bt_Bait", (Action<long, string>)RPC_Bait); _nview.Register<int>("bt_BaitTaken", (Action<long, int>)RPC_BaitTaken); _nview.Register("bt_Pluck", (Action<long>)RPC_Pluck); _nview.Register<int>("bt_Plucked", (Action<long, int>)RPC_Plucked); _wnt = ((Component)this).GetComponent<WearNTear>(); if ((Object)(object)_wnt != (Object)null) { WearNTear wnt = _wnt; wnt.m_onDestroyed = (Action)Delegate.Combine(wnt.m_onDestroyed, new Action(OnPieceDestroyed)); } } Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { switch (((Object)val).name) { case "door": _door = val; break; case "prop": _prop = val; break; case "bait": _bait = val; break; case "bird": _bird = val; break; case "birdBody": _birdBody = val; break; } } if ((Object)(object)_door != (Object)null) { _doorUp = _door.localPosition; } if ((Object)(object)_bird != (Object)null) { _birdHome = _bird.localPosition; _birdTurn = _bird.localRotation; } } private void Update() { ZDO zdo = Zdo; if (zdo != null) { if (_asks.Count > 0) { CheckAsks(); } if (zdo.IsOwner() && Time.time >= _nextThink) { _nextThink = Time.time + 1f; Think(zdo); } Show(zdo); } } private void Think(ZDO zdo) { if (zdo.GetBool("bt_bird", false)) { return; } int num = zdo.GetInt("bt_bait", 0); double num2 = zdo.GetLong("bt_next", 0L); if (num <= 0) { if (num2 != 0.0) { zdo.Set("bt_next", 0L); } return; } if (num2 == 0.0) { zdo.Set("bt_next", (long)(Now + Wait())); zdo.Set("bt_from", (long)Now); return; } bool flag = (Object)(object)EnvMan.instance != (Object)null && !EnvMan.IsNight() && EnvMan.instance.GetDay(Now) > EnvMan.instance.GetDay((double)zdo.GetLong("bt_from", 0L)); if (Now < num2 && !flag) { return; } string text = null; if (Plugin.NeedsSky.Value && !OpenSky()) { text = "roof"; } else if (Plugin.RestsAtNight.Value && (Object)(object)EnvMan.instance != (Object)null && EnvMan.IsNight()) { text = "night"; } if (text != null) { zdo.Set("bt_next", (long)(Now + 60.0)); if (zdo.GetString("bt_why", "") != text) { zdo.Set("bt_why", text); } return; } zdo.Set("bt_why", ""); zdo.Set("bt_bait", num - 1); List<string> list = Kinds(zdo); if (list.Count >= num && list.Count > 0) { list.RemoveAt(0); zdo.Set("bt_kinds", string.Join(",", list.ToArray())); } zdo.Set("bt_next", 0L); zdo.Set("bt_bird", true); } internal JObject Report(Vector3 from) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0023: 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_0061: 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_0082: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) ZDO zdo = Zdo; JObject val = new JObject(); val["position"] = (JToken)new JArray(new object[3] { Math.Round(((Component)this).transform.position.x, 1), Math.Round(((Component)this).transform.position.y, 1), Math.Round(((Component)this).transform.position.z, 1) }); val["distance"] = JToken.op_Implicit(Math.Round(Vector3.Distance(((Component)this).transform.position, from), 1)); val["openSky"] = JToken.op_Implicit(OpenSky()); JObject val2 = val; if (zdo == null) { return val2; } val2["owner"] = JToken.op_Implicit(zdo.IsOwner() ? "this game" : zdo.GetOwner().ToString()); val2["bait"] = JToken.op_Implicit(zdo.GetInt("bt_bait", 0)); val2["bird"] = JToken.op_Implicit(zdo.GetBool("bt_bird", false)); long num = zdo.GetLong("bt_next", 0L); long num2 = zdo.GetLong("bt_from", 0L); val2["nextInMinutes"] = ((num == 0L) ? null : JToken.op_Implicit(Math.Round(((double)num - Now) / 60.0, 1))); val2["setOnDay"] = ((num2 == 0L || (Object)(object)EnvMan.instance == (Object)null) ? null : JToken.op_Implicit(EnvMan.instance.GetDay((double)num2))); val2["why"] = JToken.op_Implicit(zdo.GetString("bt_why", "")); return val2; } private static double Wait() { float num = Mathf.Min(Plugin.MinMinutes.Value, Plugin.MaxMinutes.Value); float num2 = Mathf.Max(Plugin.MinMinutes.Value, Plugin.MaxMinutes.Value); return (double)Random.Range(num, num2) * 60.0; } private bool OpenSky() { //IL_0022: 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_0031: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) int mask = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" }); RaycastHit[] array = Physics.RaycastAll(((Component)this).transform.position + Vector3.up * 1f, Vector3.up, 40f, mask); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if ((Object)(object)((RaycastHit)(ref val)).collider != (Object)null && !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)this).transform)) { return false; } } return true; } private void Show(ZDO zdo) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //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_0296: Unknown result type (might be due to invalid IL or missing references) bool flag = zdo.GetBool("bt_bird", false); int num = zdo.GetInt("bt_bait", 0); if (!_seen) { _seen = true; _hadBird = flag; _doorAt = (flag ? 0f : 1f); } if (flag != _hadBird) { _hadBird = flag; Effect(flag ? Plugin.DoorShut : Plugin.DoorOpen); } _doorAt = (flag ? Mathf.MoveTowards(_doorAt, 0f, Time.deltaTime / 0.12f) : Mathf.MoveTowards(_doorAt, 1f, Time.deltaTime / 0.7f)); if ((Object)(object)_door != (Object)null) { _door.localPosition = _doorUp - new Vector3(0f, 0.3f * (1f - _doorAt), 0f); } if ((Object)(object)_prop != (Object)null && ((Component)_prop).gameObject.activeSelf != (!flag && _doorAt > 0.99f)) { ((Component)_prop).gameObject.SetActive(!flag && _doorAt > 0.99f); } if ((Object)(object)_bait != (Object)null && ((Component)_bait).gameObject.activeSelf != num > 0) { ((Component)_bait).gameObject.SetActive(num > 0); } if ((Object)(object)_bird != (Object)null) { if (((Component)_bird).gameObject.activeSelf != flag) { ((Component)_bird).gameObject.SetActive(flag); } if (flag && (Object)(object)_birdBody != (Object)null) { float num2 = Time.time + (float)((Object)this).GetInstanceID() * 0.37f; float num3 = Mathf.Max(0f, Mathf.Sin(num2 * 2.3f)) * Mathf.Max(0f, Mathf.Sin(num2 * 0.7f)) * 0.025f; _birdBody.localPosition = new Vector3(0f, num3, 0f); _bird.localRotation = _birdTurn * Quaternion.Euler(0f, Mathf.Sin(num2 * 0.9f) * 25f, 0f); _birdBody.localRotation = Quaternion.Euler(Mathf.Max(0f, Mathf.Sin(num2 * 3.1f + 1f)) * 18f, 0f, 0f); } } } private void Effect(EffectList fx) { //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_0019: 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_0029: 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: Unknown result type (might be due to invalid IL or missing references) try { if (fx != null) { fx.Create(((Component)this).transform.position + Vector3.up * 0.4f, ((Component)this).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } } catch { } } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!hold) { Player val = (Player)(object)((user is Player) ? user : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } ZDO zdo = Zdo; if (zdo == null) { return false; } if (zdo.GetBool("bt_bird", false)) { if (Time.time - _pluckAskedAt > 1f) { _pluckAskedAt = Time.time; _nview.InvokeRPC("bt_Pluck", Array.Empty<object>()); } return true; } int num = zdo.GetInt("bt_bait", 0); int value = Plugin.MaxBait.Value; if (num >= value) { ((Character)val).Message((MessageType)2, Translations.T("birdtrap_full"), 0, (Sprite)null, false); return true; } if (_asks.Exists((BaitAsk a) => !a.Back)) { return true; } Inventory inventory = ((Humanoid)val).GetInventory(); List<string> list = new List<string>(); while (num + list.Count < value) { ItemData val2 = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)IsBait); if (val2 == null) { break; } list.Add(((Object)val2.m_dropPrefab).name); inventory.RemoveItem(val2, 1); if (!alt) { break; } } if (list.Count == 0) { ((Character)val).Message((MessageType)2, Translations.T("birdtrap_need_bait"), 0, (Sprite)null, false); return true; } _asks.Add(new BaitAsk { To = zdo.GetOwner(), Items = list.ToArray(), At = Time.time }); _nview.InvokeRPC("bt_Bait", new object[1] { string.Join(",", list.ToArray()) }); return true; } } return false; } private void CheckAsks() { foreach (BaitAsk ask in _asks) { if (!ask.Back && Time.time - ask.At > 5f) { GiveBack(ask, 0); ask.Back = true; } } _asks.RemoveAll((BaitAsk a) => a.Back && Time.time - a.At > 120f); } private static void GiveBack(BaitAsk ask, int taken) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return; } for (int i = taken; i < ask.Items.Length; i++) { GameObject prefab = ZNetScene.instance.GetPrefab(ask.Items[i]); if (!((Object)(object)prefab == (Object)null)) { if (((Humanoid)localPlayer).GetInventory().CanAddItem(prefab, 1)) { ((Humanoid)localPlayer).GetInventory().AddItem(prefab, 1); } else { Object.Instantiate<GameObject>(prefab, ((Component)localPlayer).transform.position + Vector3.up, Quaternion.identity); } } } } private static void TakeAgain(Player player, BaitAsk ask, int taken) { Inventory inventory = ((Humanoid)player).GetInventory(); for (int i = 0; i < taken; i++) { string kind = ask.Items[i]; ItemData val = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData x) => (Object)(object)x.m_dropPrefab != (Object)null && ((Object)x.m_dropPrefab).name == kind)) ?? ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)IsBait); if (val != null) { inventory.RemoveItem(val, 1); continue; } break; } } private static List<string> Kinds(ZDO zdo) { return zdo.GetString("bt_kinds", "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); } private void OnPieceDestroyed() { //IL_007d: 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_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_0096: 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) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) ZDO zdo = Zdo; if (zdo == null || !_nview.IsOwner() || (Object)(object)ZNetScene.instance == (Object)null) { return; } int num = zdo.GetInt("bt_bait", 0); List<string> list = Kinds(zdo); foreach (string item in list.Skip(Mathf.Max(0, list.Count - num))) { GameObject prefab = ZNetScene.instance.GetPrefab(item); if (!((Object)(object)prefab == (Object)null)) { ItemDrop.OnCreateNew(Object.Instantiate<GameObject>(prefab, ((Component)this).transform.position + Vector3.up * 0.5f + Random.insideUnitSphere * 0.3f, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)), false); } } zdo.Set("bt_bait", 0); zdo.Set("bt_kinds", ""); } private void RPC_Bait(long sender, string items) { ZDO zdo = Zdo; if (zdo == null || !_nview.IsOwner()) { _nview.InvokeRPC(sender, "bt_BaitTaken", new object[1] { 0 }); return; } string[] array = (items ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries).TakeWhile((string n) => Baits.Contains(n)).ToArray(); int num = zdo.GetInt("bt_bait", 0); int num2 = Mathf.Clamp(Plugin.MaxBait.Value - num, 0, array.Length); if (zdo.GetBool("bt_bird", false)) { num2 = 0; } if (num2 > 0) { zdo.Set("bt_bait", num + num2); zdo.Set("bt_kinds", string.Join(",", Kinds(zdo).Concat(array.Take(num2)).ToArray())); } _nview.InvokeRPC(sender, "bt_BaitTaken", new object[1] { num2 }); } private void RPC_BaitTaken(long sender, int taken) { Player localPlayer = Player.m_localPlayer; BaitAsk baitAsk = _asks.Find((BaitAsk a) => a.To == sender) ?? ((_asks.Count > 0) ? _asks[0] : null); if ((Object)(object)localPlayer == (Object)null || baitAsk == null) { return; } _asks.Remove(baitAsk); taken = Mathf.Clamp(taken, 0, baitAsk.Items.Length); if (baitAsk.Back) { if (taken == 0) { return; } TakeAgain(localPlayer, baitAsk, taken); } else { GiveBack(baitAsk, taken); } string text = baitAsk.Items[0]; ZDO zdo = Zdo; int num = ((zdo != null) ? zdo.GetInt("bt_bait", 0) : taken); int value = Plugin.MaxBait.Value; GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(text) : null); string text2 = (((Object)(object)val != (Object)null) ? Localization.instance.Localize(val.GetComponent<ItemDrop>().m_itemData.m_shared.m_name) : text); ((Character)localPlayer).Message((MessageType)2, (taken > 0) ? Translations.T("birdtrap_baited", text2, Mathf.Max(num, taken), value) : Translations.T("birdtrap_full"), 0, (Sprite)null, false); } private void RPC_Pluck(long sender) { ZDO zdo = Zdo; if (zdo == null || !_nview.IsOwner() || !zdo.GetBool("bt_bird", false)) { _nview.InvokeRPC(sender, "bt_Plucked", new object[1] { 0 }); return; } zdo.Set("bt_bird", false); int num = Random.Range(Mathf.Min(Plugin.MinFeathers.Value, Plugin.MaxFeathers.Value), Mathf.Max(Plugin.MinFeathers.Value, Plugin.MaxFeathers.Value) + 1); _nview.InvokeRPC(sender, "bt_Plucked", new object[1] { Mathf.Max(1, num) }); } private void RPC_Plucked(long sender, int n) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { if (n <= 0) { ((Character)localPlayer).Message((MessageType)2, Translations.T("birdtrap_gone"), 0, (Sprite)null, false); } else { Pluck(localPlayer, n); } } } public bool UseItem(Humanoid user, ItemData item) { if (IsBait(item)) { Player val = (Player)(object)((user is Player) ? user : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !HasBird) { return Interact(user, hold: false, alt: false); } } return false; } public string GetHoverName() { return Translations.T("birdtrap_piece"); } public float GetHoverOffset() { return 0f; } public string GetHoverText() { ZDO zdo = Zdo; if (zdo == null) { return Translations.T("birdtrap_piece"); } int num = zdo.GetInt("bt_bait", 0); int value = Plugin.MaxBait.Value; string text = Translations.T("birdtrap_piece"); if (zdo.GetBool("bt_bird", false)) { text = text + "\n<color=#9BE37A>" + Translations.T("birdtrap_caught") + "</color>\n[<color=yellow><b>$KEY_Use</b></color>] " + Translations.T("birdtrap_hover_pluck"); } else { string text2; if (num <= 0) { text2 = Translations.T("birdtrap_no_bait"); } else { string text3 = zdo.GetString("bt_why", ""); double num2 = (double)zdo.GetLong("bt_next", 0L) - (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : 0.0); text2 = ((text3 == "roof") ? ("<color=#E8B04B>" + Translations.T("birdtrap_roof") + "</color>") : ((text3 == "night") ? Translations.T("birdtrap_night") : ((num2 > 60.0) ? Translations.T("birdtrap_soon", Mathf.CeilToInt((float)(num2 / 60.0))) : Translations.T("birdtrap_any_moment")))); } text = text + "\n" + Translations.T("birdtrap_bait_state", num, value, text2); if (num < value) { text = text + "\n[<color=yellow><b>$KEY_Use</b></color>] " + Translations.T("birdtrap_hover_add") + "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] " + Translations.T("birdtrap_hover_fill"); } } return Localization.instance.Localize(text); } private static bool IsBait(ItemData i) { if ((Object)(object)i?.m_dropPrefab != (Object)null) { return Baits.Contains(((Object)i.m_dropPrefab).name); } return false; } private void Pluck(Player player, int n) { //IL_004c: 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_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) GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("Feathers") : null); if ((Object)(object)val != (Object)null) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory.CanAddItem(val, n)) { inventory.AddItem(val, n); } else { Object.Instantiate<GameObject>(val, ((Component)this).transform.position + Vector3.up * 0.9f, Quaternion.identity).GetComponent<ItemDrop>().SetStack(n); } } ((Character)player).Message((MessageType)2, Translations.T("birdtrap_plucked", n), 0, (Sprite)null, false); FlyAway(); } private void FlyAway() { //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_0048: 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) if (!((Object)(object)_bird == (Object)null)) { GameObject val = Object.Instantiate<GameObject>(((Component)_bird).gameObject, _bird.parent); val.SetActive(true); val.transform.localPosition = _birdHome + Vector3.up * 0.5f; val.AddComponent<Flutter>(); } } } internal class Flutter : MonoBehaviour { private float _t; private Vector3 _dir; private Transform _wingL; private Transform _wingR; private void Start() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_004e: Unknown result type (might be due to invalid IL or missing references) _dir = (((Object)(object)((Component)this).transform.parent != (Object)null) ? ((Component)this).transform.parent.rotation : Quaternion.identity) * new Vector3(Random.Range(-0.4f, 0.4f), 0f, -1f); Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(); foreach (Transform val in componentsInChildren) { if (((Object)val).name == "wing") { if ((Object)(object)_wingL == (Object)null) { _wingL = val; } else { _wingR = val; } } } ((Component)this).transform.SetParent((Transform)null, true); } private void Update() { //IL_0019: 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_002e: 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_004a: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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) //IL_007e: 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_0097: 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_00dd: 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) _t += Time.deltaTime; Transform transform = ((Component)this).transform; transform.position += (((Vector3)(ref _dir)).normalized * 3.5f + Vector3.up * (2.5f + _t * 2f)) * Time.deltaTime; ((Component)this).transform.rotation = Quaternion.LookRotation(-((Vector3)(ref _dir)).normalized, Vector3.up) * Quaternion.Euler(15f, 0f, 0f); float num = Mathf.Sin(_t * 40f) * 60f; if ((Object)(object)_wingL != (Object)null) { _wingL.localRotation = Quaternion.Euler(-14f, 0f, num); } if ((Object)(object)_wingR != (Object)null) { _wingR.localRotation = Quaternion.Euler(-14f, 0f, 0f - num); } if (_t > 2.5f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } } namespace DHack.Shared { internal static class Migration { private sealed class Notice : MonoBehaviour { public string Text; private float _next; private void Update() { if (!(Time.unscaledTime < _next) && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)MessageHud.instance == (Object)null)) { ((Character)Player.m_localPlayer).Message((MessageType)2, Text, 0, (Sprite)null, false); _next = Time.unscaledTime + 60f; } } } public static void FromOldGuid(BaseUnityPlugin plugin, string oldGuid) { BepInPlugin metadata = MetadataHelper.GetMetadata((object)plugin); string text = ((metadata != null) ? metadata.GUID : null); if (string.IsNullOrEmpty(oldGuid) || string.IsNullOrEmpty(text) || oldGuid == text) { return; } ManualLogSource val = Logger.CreateLogSource(text); try { bool flag = false; if (Directory.Exists(Paths.ConfigPath)) { string[] files = Directory.GetFiles(Paths.ConfigPath, oldGuid + ".*"); foreach (string text2 in files) { string fileName = Path.GetFileName(text2); if (!fileName.EndsWith(".cfg") && !fileName.EndsWith(".json") && !fileName.EndsWith(".txt")) { continue; } string text3 = Path.Combine(Paths.ConfigPath, text + fileName.Substring(oldGuid.Length)); if (!File.Exists(text3)) { File.Copy(text2, text3); val.LogInfo((object)("Settings moved over from " + fileName + " (the mod's id is now " + text + "; the old file is kept as a backup)")); if (fileName == oldGuid + ".cfg") { flag = true; } } } } if (flag) { plugin.Config.Reload(); } } catch (Exception ex) { val.LogWarning((object)("Couldn't move the settings over from " + oldGuid + ".cfg: " + ex.Message)); } finally { Logger.Sources.Remove((ILogSource)(object)val); } ((MonoBehaviour)plugin).StartCoroutine(StandDownIfTwin(plugin, oldGuid)); } private static IEnumerator StandDownIfTwin(BaseUnityPlugin plugin, string oldGuid) { yield return null; yield return null; if (!((Object)(object)plugin == (Object)null) && Chainloader.PluginInfos.TryGetValue(oldGuid, out var value) && !((Object)(object)value.Instance == (Object)null) && !((Object)(object)value.Instance == (Object)(object)plugin)) { BepInPlugin metadata = MetadataHelper.GetMetadata((object)plugin); string text = ((metadata != null) ? metadata.Name : null) ?? oldGuid; string text2 = (string.IsNullOrEmpty(value.Location) ? "an older copy" : value.Location); string text3 = text + ": two copies are installed, an old one (" + text2 + ") and this one. Both would run and do everything twice, so this one stands down. Delete the old copy, then restart the game."; Debug.LogError((object)("[" + text + "] " + text3)); Object.Destroy((Object)(object)plugin); GameObject val = new GameObject("Migration_TwoCopies_" + text); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<Notice>().Text = text3; } } } internal static class Translations { private sealed class Blank { public string Tag; public Func<string> Value; public Action Unhook; } public static readonly string[] Shipped = new string[9] { "English", "Russian", "German", "Chinese", "Portuguese_Brazilian", "Spanish", "French", "Polish", "Turkish" }; private static readonly Dictionary<string, Dictionary<string, string>> Languages = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); private static Dictionary<string, string> _english = new Dictionary<string, string>(); private static string _overrideDir; private static bool _hooked; private static readonly MethodInfo AddWord = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null); private static readonly FieldInfo Cache = AccessTools.Field(typeof(Localization), "m_cache"); private static readonly FieldInfo GameWords = AccessTools.Field(typeof(Localization), "m_translations"); private static Dictionary<string, string> _given = new Dictionary<string, string>(); private static Dictionary<string, string> _files = new Dictionary<string, string>(); private static readonly Dictionary<string, Dictionary<string, Dictionary<string, string>>> Runtime = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>(); private static readonly HashSet<string> _runtimeGiven = new HashSet<string>(); private static readonly Dictionary<string, List<Blank>> Fills = new Dictionary<string, List<Blank>>(); public static void Load(BaseUnityPlugin plugin) { Languages.Clear(); Assembly assembly = ((object)plugin).GetType().Assembly; foreach (string item in from n in assembly.GetManifestResourceNames() where n.StartsWith("translations/") && n.EndsWith(".json") select n) { using StreamReader streamReader = new StreamReader(assembly.GetManifestResourceStream(item)); Languages[Path.GetFileNameWithoutExtension(item.Substring("translations/".Length))] = Parse(streamReader.ReadToEnd()); } _english = (Languages.TryGetValue("English", out var value) ? value : new Dictionary<string, string>()); _overrideDir = Path.Combine(Paths.ConfigPath, "translations", plugin.Info.Metadata.GUID); if (!_hooked) { Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(Apply)); _hooked = true; } Apply(); } public static void Unload() { if (_hooked) { Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(Apply)); _hooked = false; } foreach (List<Blank> value2 in Fills.Values) { foreach (Blank item in value2) { item.Unhook?.Invoke(); } } Fills.Clear(); Runtime.Clear(); Localization val = ((_runtimeGiven.Count > 0) ? Localization.instance : null); if (val != null && AddWord != null) { Dictionary<string, string> dictionary = GameWords?.GetValue(val) as Dictionary<string, string>; foreach (string item2 in _runtimeGiven) { if (_files.TryGetValue(item2, out var value)) { AddWord.Invoke(val, new object[2] { item2, value }); } else { dictionary?.Remove(item2); } } EvictCache(val); } _runtimeGiven.Clear(); } public static string T(string key, params object[] args) { string text = ((Localization.instance != null) ? Localization.instance.Localize("$" + key) : null); if (string.IsNullOrEmpty(text) || text == "[" + key + "]") { text = (_english.TryGetValue(key, out var value) ? FillIn(key, value) : key); } if (args == null || args.Length == 0) { return text; } try { return string.Format(text, args); } catch (FormatException) { string value2; return _english.TryGetValue(key, out value2) ? SafeFormat(FillIn(key, value2), args) : text; } } private static string SafeFormat(string text, object[] args) { try { return string.Format(text, args); } catch (FormatException) { return text; } } public static void Fill<TValue>(string key, string placeholder, ConfigEntry<TValue> setting, Func<TValue, string> format = null) { if (setting != null) { Fill(key, placeholder, () => (format == null) ? Text(setting.Value) : format(setting.Value), (ConfigEntryBase)setting); } } public static void Fill(string key, string placeholder, Func<string> value, params ConfigEntryBase[] settings) { if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(placeholder) || value == null) { return; } key = key.TrimStart(new char[1] { '$' }); string tag = (placeholder.StartsWith("{") ? placeholder : ("{" + placeholder + "}")); if (!Fills.TryGetValue(key, out var value2)) { value2 = (Fills[key] = new List<Blank>()); } int num = value2.FindIndex((Blank b) => b.Tag == tag); if (num >= 0) { value2[num].Unhook?.Invoke(); value2.RemoveAt(num); } Blank blank = new Blank { Tag = tag, Value = value }; if (settings != null) { EventHandler changed = delegate { Show(key); }; foreach (ConfigEntryBase setting in settings.Where((ConfigEntryBase s) => s != null).Distinct()) { EventInfo ev = ((object)setting).GetType().GetEvent("SettingChanged"); if (!(ev == null)) { ev.AddEventHandler(setting, changed); blank.Unhook = (Action)Delegate.Combine(blank.Unhook, (Action)delegate { ev.RemoveEventHandler(setting, changed); }); } } } value2.Add(blank); Show(key); } public static void Refresh() { Localization instance = Localization.instance; if (instance == null || AddWord == null) { return; } foreach (string key in Fills.Keys) { if (_given.TryGetValue(key, out var value)) { AddWord.Invoke(instance, new object[2] { key, FillIn(key, value) }); } } EvictCache(instance); } private static void Show(string key) { Localization instance = Localization.instance; if (instance != null && !(AddWord == null) && _given.TryGetValue(key, out var value)) { AddWord.Invoke(instance, new object[2] { key, FillIn(key, value) }); EvictCache(instance); } } private static string FillIn(string key, string text) { if (text == null || !Fills.TryGetValue(key, out var value)) { return text; } foreach (Blank item in value) { if (text.IndexOf(item.Tag, StringComparison.Ordinal) >= 0) { try { text = text.Replace(item.Tag, item.Value() ?? ""); } catch (Exception ex) { Debug.LogWarning((object)("Translations: filling " + item.Tag + " in " + key + ": " + ex.Message)); } } } return text; } private static string Text(object value) { object obj; if (!(value is IFormattable formattable)) { obj = value?.ToString(); if (obj == null) { return ""; } } else { obj = formattable.ToString(null, CultureInfo.InvariantCulture); } return (string)obj; } public static void AddWords(string group, string language, IDictionary<string, string> words) { if (!string.IsNullOrEmpty(group) && !string.IsNullOrEmpty(language)) { SetWords(group, language, words); Apply(); } } public static void AddWords(string group, IDictionary<string, Dictionary<string, string>> languages) { if (string.IsNullOrEmpty(group)) { return; } Runtime.Remove(group); if (languages != null) { foreach (KeyValuePair<string, Dictionary<string, string>> language in languages) { if (!string.IsNullOrEmpty(language.Key)) { SetWords(group, language.Key, language.Value); } } } Apply(); } public static void RemoveWords(string group) { if (group != null && Runtime.Remove(group)) { Apply(); } } public static Dictionary<string, string> ParseJson(string json) { if (!string.IsNullOrEmpty(json)) { return Parse(json); } return new Dictionary<string, string>(); } private static void SetWords(string group, string language, IDictionary<string, string> words) { if (!Runtime.TryGetValue(group, out var value)) { value = (Runtime[group] = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase)); } if (words == null || words.Count == 0) { value.Remove(language); return; } Dictionary<string, string> dictionary2 = new Dictionary<string, string>(); foreach (KeyValuePair<string, string> word in words) { if (!string.IsNullOrEmpty(word.Key) && word.Value != null) { dictionary2[word.Key.TrimStart(new char[1] { '$' })] = word.Value; } } value[language] = dictionary2; } private static void AddRuntime(Dictionary<string, string> words, string language) { foreach (Dictionary<string, Dictionary<string, string>> value2 in Runtime.Values) { if (!value2.TryGetValue(language, out var value)) { continue; } foreach (KeyValuePair<string, string> item in value) { words[item.Key] = item.Value; } } } private static void Apply() { Localization instance = Localization.instance; if (instance == null || AddWord == null) { return; } string selectedLanguage = instance.GetSelectedLanguage(); Dictionary<string, string> dictionary = new Dictionary<string, string>(_english); Dictionary<string, string> dictionary2 = new Dictionary<string, string>(_english); AddRuntime(dictionary, "English"); if (!string.Equals(selectedLanguage, "English", StringComparison.OrdinalIgnoreCase)) { if (Languages.TryGetValue(selectedLanguage, out var value)) { foreach (KeyValuePair<string, string> item in value) { dictionary[item.Key] = item.Value; dictionary2[item.Key] = item.Value; } } AddRuntime(dictionary, selectedLanguage); } try { string path = Path.Combine(_overrideDir ?? "", selectedLanguage + ".json"); if (_overrideDir != null && File.Exists(path)) { foreach (KeyValuePair<string, string> item2 in Parse(File.ReadAllText(path))) { dictionary[item2.Key] = item2.Value; dictionary2[item2.Key] = item2.Value; } } } catch (Exception ex) { Debug.LogWarning((object)("Translations: couldn't read the player's " + selectedLanguage + " file: " + ex.Message)); } Dictionary<string, string> dictionary3 = GameWords?.GetValue(instance) as Dictionary<string, string>; foreach (string item3 in _runtimeGiven) { if (!dictionary.ContainsKey(item3)) { dictionary3?.Remove(item3); } } _runtimeGiven.Clear(); foreach (Dictionary<string, Dictionary<string, string>> value2 in Runtime.Values) { foreach (Dictionary<string, string> value3 in value2.Values) { foreach (string key in value3.Keys) { _runtimeGiven.Add(key); } } } _given = dictionary; _files = dictionary2; foreach (KeyValuePair<string, string> item4 in dictionary) { AddWord.Invoke(instance, new object[2] { item4.Key, FillIn(item4.Key, item4.Value) }); } EvictCache(instance); } private static void EvictCache(Localization loc) { object obj = Cache?.GetValue(loc); obj?.GetType().GetMethod("EvictAll")?.Invoke(obj, null); } private static Dictionary<string, string> Parse(string json) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (Match item in Regex.Matches(json, "\"((?:[^\"\\\\]|\\\\.)*)\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"")) { dictionary[Unescape(item.Groups[1].Value)] = Unescape(item.Groups[2].Value); } return dictionary; } private static string Unescape(string s) { return Regex.Replace(s, "\\\\(u[0-9a-fA-F]{4}|.)", delegate(Match m) { string value = m.Groups[1].Value; return value[0] switch { 'n' => "\n", 't' => "\t", 'u' => ((char)Convert.ToInt32(value.Substring(1), 16)).ToString(), _ => value, }; }); } } internal sealed class ServerSettings : IDisposable { public enum ServerMod { NotConnected, Checking, Installed, Missing } private sealed class ConfigurationManagerAttributes { public bool? ReadOnly; } private sealed class SyncedText { public string Key; public Func<string> Own; public Action<string> Use; public string Given; public bool FromServer; public bool Pending; public byte[] Packed; public bool TooBig; public MemoryStream Incoming; public int NextPart; } private sealed class Sending { public ZRpc Rpc; public string Key; public byte[] Data; public int Next; public int Parts; } private const int Protocol = 2; private const float ChangeSendGap = 0.5f; private const float AnswerWait = 20f; private const float FileWait = 1f; private const int PartSize = 65536; private const int CompressFrom = 1024; private const int WarnBytes = 262144; private const int MaxBytes = 8388608; private const int PaceBelow = 10240; private readonly string _send; private readonly string _ask; private readonly string _dAsk; private readonly string _dHello; private readonly string _dSend; private readonly string _edit; private readonly string _dTextAsk; private readonly string _dText; private readonly string _dAgain; private readonly ConfigFile _config; private readonly ManualLogSource _log; private readonly string _name; private readonly List<ConfigEntryBase> _entries = new List<ConfigEntryBase>(); private readonly Dictionary<ConfigEntryBase, object> _own = new Dictionary<ConfigEntryBase, object>(); private readonly Dictionary<ConfigEntryBase, object> _server = new Dictionary<ConfigEntryBase, object>(); private readonly List<GameObject> _guardedPieces = new List<GameObject>(); private readonly List<Recipe> _guardedRecipes = new List<Recipe>(); private ZRoutedRpc _registeredOn; private bool _applying; private bool _reloading; private bool _changePending; private float _nextChangeSend; private float _askedAt = -1f; private int _serverProtocol; private bool _directSeen; private readonly HashSet<ZRpc> _directPeers = new HashSet<ZRpc>(); private readonly List<SyncedText> _texts = new List<SyncedText>(); private readonly Dictionary<ZRpc, HashSet<string>> _textPeers = new Dictionary<ZRpc, HashSet<string>>(); private bool _textPending; private float _nextTextSend; private bool _readOnlyShown; private float _nextAdminCheck; private FileSystemWatcher _watcher; private volatile bool _fileTouched; private float _reloadAt = -1f; private string _fileText; private readonly List<Sending> _outbox = new List<Sending>(); private static readonly MethodInfo UpdateAvailablePieces = AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null); private static readonly List<ServerSettings> Live = new List<ServerSettings>(); private static Harmony _saveHarmony; public string Version { get; } public bool FromServer => _server.Count > 0; public ServerMod Server { get; private set; } public string ServerVersion { get; private set; } public bool CanEditServer { get { if (!IsServer) { if (Server == ServerMod.Installed && _serverProtocol >= 1 && (Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.LocalPlayerIsAdminOrHost(); } return false; } return true; } } private static bool IsServer { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } public event Action ServerChanged; public ServerSettings(string guid, ConfigFile config, ManualLogSource log) { _send = guid + ".settings"; _ask = guid + ".settings.ask"; _dAsk = guid + ".settings.d.ask"; _dHello = guid + ".settings.d.hello"; _dSend = guid + ".settings.d.values"; _edit = guid + ".settings.d.edit"; _dTextAsk = guid + ".settings.d.textask"; _dAgain = guid + ".settings.d.again"; _dText = guid + ".settings.d.text"; _config = config; _log = log; BepInPlugin val = PluginOf(guid); _name = ((val != null) ? val.Name : null) ?? guid; Version = ((val == null) ? null : val.Version?.ToString()) ?? ""; Live.Add(this); if (Live.Count == 1) { PatchSave(); } WatchFile(); } public ConfigEntry<T> Add<T>(ConfigEntry<T> entry) { if (entry == null || _entries.Contains((ConfigEntryBase)(object)entry)) { return entry; } _entries.Add((ConfigEntryBase)(object)entry); entry.SettingChanged += OnChanged; GiveManagerAttributes((ConfigEntryBase)(object)entry); return entry; } private static void GiveManagerAttributes(ConfigEntryBase entry) { ConfigDescription description = entry.Description; if (description == null || description == ConfigDescription.Empty || (description.Tags ?? new object[0]).Any(IsManagerAttributes)) { return; } try { object[] value = new object[1] { new ConfigurationManagerAttributes() }.Concat(description.Tags ?? new object[0]).ToArray(); AccessTools.Field(typeof(ConfigDescription), "<Tags>k__BackingField")?.SetValue(description, value); } catch (Exception) { } } public ConfigEntry<T> Bind<T>(string section, string key, T value, string description, AcceptableValueBase range = null, params object[] tags) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (!description.Contains("[Synced with Server]")) { description += " [Synced with Server]"; } return Add<T>(_config.Bind<T>(section, key, value, new ConfigDescription(description, range, tags ?? new object[0]))); } public void NeedsServer(GameObject piecePrefab) { if (!((Object)(object)piecePrefab == (Object)null)) { _guardedPieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ((Object)p).name == ((Object)piecePrefab).name); _guardedPieces.Add(piecePrefab); Guard(); } } public void NeedsServer(Recipe recipe) { if (!((Object)(object)recipe == (Object)null)) { _guardedRecipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || (Object)(object)r == (Object)(object)recipe || (!string.IsNullOrEmpty(((Object)recipe).name) && ((Object)r).name == ((Object)recipe).name)); _guardedRecipes.Add(recipe); Guard(); } } public void AddText(string key, Func<string> own, Action<string> use) { if (string.IsNullOrEmpty(key) || own == null || use == null) { ManualLogSource log = _log; if (log != null) { log.LogError((object)"AddText needs a key, own and use"); } return; } _texts.RemoveAll((SyncedText x) => x.Key == key); SyncedText syncedText = new SyncedText { Key = key, Own = own, Use = use }; _texts.Add(syncedText); Give(syncedText, OwnText(syncedText)); ZRpc val = ((!((Object)(object)ZNet.instance != (Object)null) || IsServer) ? null : ZNet.instance.GetServerPeer()?.m_rpc); if (_registeredOn != null && val != null) { val.Register<ZPackage>(_dText, (Action<ZRpc, ZPackage>)OnText); AskTexts(val); } } public void TextChanged(string key) { SyncedText syncedText = _texts.FirstOrDefault((SyncedText x) => x.Key == key); if (syncedText != null) { syncedText.Packed = null; if (!syncedText.FromServer) { Give(syncedText, OwnText(syncedText)); } if (IsServer) { syncedText.Pending = true; _textPending = true; } } } public bool TextFromServer(string key) { return _texts.Any((SyncedText x) => x.Key == key && x.FromServer); } public void Update() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != _registeredOn) { Unregister(); Restore(); RestoreTexts(give: true); _changePending = false; _textPending = false; SetServer(ServerMod.NotConnected, null, 0); if (instance != null) { Register(instance); } } float unscaledTime = Time.unscaledTime; if (_changePending && unscaledTime >= _nextChangeSend) { SendChange(); } if (_textPending && unscaledTime >= _nextTextSend) { SendTexts(); } if (_outbox.Count > 0) { Pump(); } if (Server == ServerMod.Checking && _askedAt >= 0f && unscaledTime - _askedAt > 20f) { if (_guardedPieces.Count + _guardedRecipes.Count > 0) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("The server didn't answer: " + _name + " isn't installed there (or its copy is older than 2026-10-11), so its pieces and items can't be made on this server.")); } } else { ManualLogSource log2 = _log; if (log2 != null) { log2.LogInfo((object)("The server didn't answer: " + _name + " isn't installed there, or its copy is older" + (FromServer ? " (its settings apply)." : " (your own settings apply)."))); } } SetServer(ServerMod.Missing, null, 0); } if (_fileTouched) { _fileTouched = false; _reloadAt = unscaledTime + 1f; } if (_reloadAt >= 0f && unscaledTime >= _reloadAt) { _reloadAt = -1f; ReloadFile(); } if (FromServer && unscaledTime >= _nextAdminCheck) { _nextAdminCheck = unscaledTime + 1f; ShowReadOnly(); } } public void Dispose() { Unregister(); Restore(); RestoreTexts(give: false); SetServer(ServerMod.NotConnected, null, 0); foreach (ConfigEntryBase entry in _entries) { Unsubscribe(entry); } _entries.Clear(); _texts.Clear(); try { _watcher?.Dispose(); } catch (Exception) { } _watcher = null; Live.Remove(this); if (Live.Count == 0) { UnpatchSave(); } } private void Register(ZRoutedRpc rpc) { Forget(rpc, _send); Forget(rpc, _ask); rpc.Register<ZPackage>(_send, (Action<long, ZPackage>)OnRoutedValues); rpc.Register(_ask, (Action<long>)OnRoutedAsk); rpc.m_onNewPeer = (Action<long>)Delegate.Combine(rpc.m_onNewPeer, new Action<long>(OnNewPeer)); _registeredOn = rpc; if (IsServer) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { ListenTo(peer); if (peer != null) { ZRpc rpc2 = peer.m_rpc; if (rpc2 != null) { rpc2.Invoke(_dAgain, Array.Empty<object>()); } } } return; } if ((Object)(object)ZNet.instance != (Object)null) { SetServer(ServerMod.Checking, null, 0); if (ZNet.instance.GetServerPeer() != null) { AskServer(); } } } private void Unregister() { if (_registeredOn == null) { return; } ZRoutedRpc registeredOn = _registeredOn; registeredOn.m_onNewPeer = (Action<long>)Delegate.Remove(registeredOn.m_onNewPeer, new Action<long>(OnNewPeer)); Forget(_registeredOn, _send); Forget(_registeredOn, _ask); if ((Object)(object)ZNet.instance != (Object)null) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer?.m_rpc != null) { string[] array = new string[7] { _dAsk, _dHello, _dSend, _edit, _dTextAsk, _dText, _dAgain }; foreach (string name in array) { ForgetDirect(peer.m_rpc, name); } } } } _directPeers.Clear(); _textPeers.Clear(); _outbox.Clear(); _directSeen = false; _registeredOn = null; } private static void Forget(ZRoutedRpc rpc, string name) { if (AccessTools.Field(typeof(ZRoutedRpc), "m_functions")?.GetValue(rpc) is IDictionary dictionary) { dictionary.Remove(StringExtensionMethods.GetStableHashCode(name)); } } private static void ForgetDirect(ZRpc rpc, string name) { if (AccessTools.Field(typeof(ZRpc), "m_functions")?.GetValue(rpc) is IDictionary dictionary) { dictionary.Remove(StringExtensionMethods.GetStableHashCode(name)); } } private void OnNewPeer(long uid) { if (IsServer) { ZNetPeer peer = ZNet.instance.GetPeer(uid); ListenTo(peer); if (peer?.m_rpc != null) { SendDirect(peer.m_rpc); } SendRouted(uid); } else if ((Object)(object)ZNet.instance != (Object)null) { ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer != null && serverPeer.m_uid == uid) { AskServer(); } } } private void ListenTo(ZNetPeer peer) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (peer?.m_rpc != null) { peer.m_rpc.Register(_dAsk, new Method(OnDirectAsk)); peer.m_rpc.Register<ZPackage>(_edit, (Action<ZRpc, ZPackage>)OnEdit); peer.m_rpc.Register<ZPackage>(_dTextAsk, (Action<ZRpc, ZPackage>)OnTextAsk); } } private void OnDirectAsk(ZRpc rpc) { if (IsServer) { _directPeers.Add(rpc); SendDirect(rpc); } } private void OnRoutedAsk(long sender) { if (IsServer) { SendRouted(sender); } } private void SendDirect(ZRpc rpc) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(2); val.Write(Version); rpc.Invoke(_dHello, new object[1] { val }); if (_entries.Count > 0) { rpc.Invoke(_dSend, new object[1] { Values() }); } } private void SendRouted(long target) { if (ZRoutedRpc.instance != null && _entries.Count > 0) { ZRoutedRpc.instance.InvokeRoutedRPC(target, _send, new object[1] { Values() }); } } private ZPackage Values() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(_entries.Count); foreach (ConfigEntryBase entry in _entries) { val.Write(entry.Definition.Section); val.Write(entry.Definition.Key); val.Write(TomlTypeConverter.ConvertToString(entry.BoxedValue, entry.SettingType)); } return val; } private void AskServer() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null); if (val?.m_rpc == null) { return; } _askedAt = Time.unscaledTime; val.m_rpc.Register<ZPackage>(_dHello, (Action<ZRpc, ZPackage>)OnDirectHello); val.m_rpc.Register<ZPackage>(_dSend, (Action<ZRpc, ZPackage>)OnDirectValues); val.m_rpc.Register<ZPackage>(_dText, (Action<ZRpc, ZPackage>)OnText); val.m_rpc.Register(_dAgain, new Method(OnAskAgain)); val.m_rpc.Invoke(_dAsk, Array.Empty<object>()); AskTexts(val.m_rpc); try { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(val.m_uid, _ask, Array.Empty<object>()); } } catch (Exception) { } } private static bool IsServerConnection(ZRpc rpc) { if (!IsServer) { ZNet instance = ZNet.instance; return ((instance == null) ? null : instance.GetServerPeer()?.m_rpc) == rpc; } return false; } private void OnAskAgain(ZRpc rpc) { if (IsServerConnection(rpc)) { rpc.Invoke(_dAsk, Array.Empty<object>()); AskTexts(rpc); } } private void OnDirectHello(ZRpc rpc, ZPackage pkg) { if (!IsServerConnection(rpc)) { return; } try { int protocol = pkg.ReadInt(); string text = pkg.ReadString(); if (text != Version && text != ServerVersion) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)("The server has " + _name + " " + text + ", you have " + Version + ": some things may not match. Use the same version as the server.")); } } _directSeen = true; SetServer(ServerMod.Installed, text, protocol); } catch (Exception ex) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("Could not read the server's hello: " + ex.Message)); } } } private void OnDirectValues(ZRpc rpc, ZPackage pkg) { if (IsServerConnection(rpc)) { TakeValues(pkg); } } private void OnRoutedValues(long sender, ZPackage pkg) { if (!_directSeen && !IsServer) { ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null); if (val != null && val.m_uid == sender) { TakeValues(pkg); } } } private void TakeValues(ZPackage pkg) { try { int num = pkg.ReadInt(); List<string> list = new List<string>(); for (int i = 0; i < num; i++) { string section = pkg.ReadString(); string key = pkg.ReadString(); string text = pkg.ReadString(); ConfigEntryBase val = ((IEnumerable<ConfigEntryBase>)_entries).FirstOrDefault((Func<ConfigEntryBase, bool>)((ConfigEntryBase x) => x.Definition.Section == section && x.Definition.Key == key)); if (val != null) { object obj; try { obj = TomlTypeConverter.ConvertToValue(text, val.SettingType); } catch (Exception) { continue; } if (!_own.ContainsKey(val)) { _own[val] = val.BoxedValue; } _server[val] = obj; if (!object.Equals(val.BoxedValue, obj)) { Apply(val, obj); list.Add(section + "/" + key + " = " + text); } } } ManualLogSource