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 RoboticInbox v1.2.0
RoboticInbox.dll
Decompiled 2 weeks agousing System; 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.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("RoboticInbox")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+9e93eaebfc77bdaed2d41d492483d337a0d8bb7b")] [assembly: AssemblyProduct("RoboticInbox")] [assembly: AssemblyTitle("RoboticInbox")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DarthJML.RoboticInbox { internal static class Cybercrate { private const string ResourceName = "RoboticInbox.cybercrate"; private const string VisualName = "Cybercrate"; private static readonly string[,] TextureSlots = new string[4, 2] { { "_MainTex", "cybercrate_v3_basecolor" }, { "_BumpMap", "cybercrate_v3_normal_gl" }, { "_EmissionMap", "cybercrate_v3_emission" }, { "_MetallicTex", "cybercrate_v3_metallic" } }; private static AssetBundle _bundle; private static bool _loadFailed; private static Material _material; private static AssetBundle LoadBundle() { if ((Object)(object)_bundle != (Object)null || _loadFailed) { return _bundle; } try { using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("RoboticInbox.cybercrate")) { if (stream == null) { throw new Exception("embedded resource RoboticInbox.cybercrate missing"); } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { throw new EndOfStreamException(); } } _bundle = AssetBundle.LoadFromMemory(array); } if ((Object)(object)_bundle == (Object)null) { throw new Exception("AssetBundle.LoadFromMemory returned null"); } Debug.Log((object)("RoboticInbox: Cybercrate bundle loaded: " + string.Join(", ", _bundle.GetAllAssetNames()))); } catch (Exception ex) { _loadFailed = true; Debug.LogError((object)("RoboticInbox: Cybercrate bundle failed to load, keeping the wood chest look: " + ex)); } return _bundle; } internal static void Apply(GameObject clone) { //IL_012c: 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_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_0487: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_0617: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Unknown result type (might be due to invalid IL or missing references) //IL_062f: Unknown result type (might be due to invalid IL or missing references) AssetBundle val = LoadBundle(); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = val.LoadAsset<GameObject>("Cybercrate"); if ((Object)(object)val2 == (Object)null) { Debug.LogError((object)"RoboticInbox: Cybercrate prefab missing from bundle, keeping the wood chest look."); return; } WearNTear component = clone.GetComponent<WearNTear>(); Container component2 = clone.GetComponent<Container>(); Piece component3 = clone.GetComponent<Piece>(); List<GameObject> oldVisuals = new List<GameObject>(); Transform obj = clone.transform.Find("New"); AddOld((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)component != (Object)null) { AddOld(component.m_new); AddOld(component.m_worn); AddOld(component.m_broken); } GameObject val3 = (((Object)(object)component != (Object)null && (Object)(object)component.m_new != (Object)null) ? component.m_new : ((oldVisuals.Count > 0) ? oldVisuals[0] : null)); Material val4 = null; float num = 0f; int num2 = (((Object)(object)val3 != (Object)null) ? val3.layer : clone.layer); Bounds bounds = default(Bounds); bool flag = (Object)(object)val3 != (Object)null && Encapsulate(clone.transform, val3.transform, ref bounds); if ((Object)(object)val3 != (Object)null) { LODGroup component4 = val3.GetComponent<LODGroup>(); if ((Object)(object)component4 != (Object)null && component4.lodCount > 0) { num = component4.GetLODs()[component4.lodCount - 1].screenRelativeTransitionHeight; } } MeshRenderer[] componentsInChildren; foreach (GameObject item in oldVisuals) { componentsInChildren = item.GetComponentsInChildren<MeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material sharedMaterial = ((Renderer)componentsInChildren[i]).sharedMaterial; if (!((Object)(object)sharedMaterial == (Object)null)) { if ((Object)(object)sharedMaterial.shader != (Object)null && ((Object)sharedMaterial.shader).name == "Custom/Piece") { val4 = sharedMaterial; break; } if ((Object)(object)val4 == (Object)null) { val4 = sharedMaterial; } } } } Material sharedMaterial2 = (_material = MakeMaterial(val4, val)); GameObject val5 = Object.Instantiate<GameObject>(val2, clone.transform, false); ((Object)val5).name = "Cybercrate"; Transform[] componentsInChildren2 = val5.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Component)componentsInChildren2[i]).gameObject.layer = num2; } MeshRenderer[] componentsInChildren3 = val5.GetComponentsInChildren<MeshRenderer>(true); componentsInChildren = componentsInChildren3; foreach (MeshRenderer obj2 in componentsInChildren) { ((Renderer)obj2).sharedMaterial = sharedMaterial2; ((Renderer)obj2).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)obj2).receiveShadows = true; } Renderer[] array2; if (num > 0f) { LODGroup val6 = val5.AddComponent<LODGroup>(); LOD[] array = new LOD[1]; float num3 = num; array2 = (Renderer[])(object)componentsInChildren3; array[0] = new LOD(num3, array2); val6.SetLODs((LOD[])(object)array); val6.RecalculateBounds(); } Bounds bounds2 = default(Bounds); Encapsulate(val5.transform, val5.transform, ref bounds2); BoxCollider val7 = val5.AddComponent<BoxCollider>(); val7.center = ((Bounds)(ref bounds2)).center; val7.size = ((Bounds)(ref bounds2)).size; MeshRenderer val8 = (((Object)(object)component != (Object)null) ? component.m_snow : null); if ((Object)(object)val8 != (Object)null && flag && !IsUnderAny(((Component)val8).transform, oldVisuals)) { Bounds bounds3 = default(Bounds); Encapsulate(clone.transform, val5.transform, ref bounds3); Transform transform = ((Component)val8).transform; Vector3 localScale = transform.localScale; if (((Bounds)(ref bounds)).size.x > 0.01f) { localScale.x *= ((Bounds)(ref bounds3)).size.x / ((Bounds)(ref bounds)).size.x; } if (((Bounds)(ref bounds)).size.z > 0.01f) { localScale.z *= ((Bounds)(ref bounds3)).size.z / ((Bounds)(ref bounds)).size.z; } transform.localScale = localScale; transform.localPosition += new Vector3(((Bounds)(ref bounds3)).center.x - ((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds3)).max.y - ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds3)).center.z - ((Bounds)(ref bounds)).center.z); } string text = string.Join(",", oldVisuals.ConvertAll((GameObject g) => ((Object)g).name)); foreach (GameObject item2 in oldVisuals) { Object.DestroyImmediate((Object)(object)item2); } array2 = clone.GetComponentsInChildren<Renderer>(true); foreach (Renderer val9 in array2) { if (!((Component)val9).transform.IsChildOf(val5.transform) && (!((Object)(object)val8 != (Object)null) || !((Object)(object)val9 == (Object)(object)val8))) { Debug.LogWarning((object)("RoboticInbox: hiding leftover chest renderer " + ((Object)val9).name)); val9.enabled = false; } } if ((Object)(object)component != (Object)null) { component.m_new = (component.m_worn = (component.m_broken = val5)); } if ((Object)(object)component2 != (Object)null) { component2.m_open = null; component2.m_closed = null; } Sprite val10 = val.LoadAsset<Sprite>("cybercrate_icon"); if ((Object)(object)component3 != (Object)null && (Object)(object)val10 != (Object)null) { component3.m_icon = val10; } else { Debug.LogWarning((object)"RoboticInbox: Cybercrate icon not found in bundle."); } string text2 = $"RoboticInbox: Cybercrate visual applied: renderers={componentsInChildren3.Length} layer={LayerMask.LayerToName(num2)} lod={num:F3} "; object[] array3 = new object[5]; Vector3 val11 = val7.center; array3[0] = ((Vector3)(ref val11)).ToString("F3"); val11 = val7.size; array3[1] = ((Vector3)(ref val11)).ToString("F3"); array3[2] = text; array3[3] = (Object)(object)val8 != (Object)null && flag; array3[4] = (Object)(object)val10 != (Object)null; Debug.Log((object)(text2 + string.Format("collider center={0} size={1} oldVisuals=[{2}] snowFitted={3} icon={4}", array3))); void AddOld(GameObject go) { if ((Object)(object)go != (Object)null && (Object)(object)go != (Object)(object)clone && !oldVisuals.Contains(go)) { oldVisuals.Add(go); } } } private static Material MakeMaterial(Material source, AssetBundle bundle) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) Shader val = (((Object)(object)source != (Object)null) ? source.shader : Shader.Find("Custom/Piece")); Material val2 = (((Object)(object)source != (Object)null) ? new Material(source) : new Material(val)); ((Object)val2).name = "RoboticInbox_Cybercrate"; List<string> list = new List<string>(); List<string> list2 = new List<string>(); for (int i = 0; i < TextureSlots.GetLength(0); i++) { string text = TextureSlots[i, 0]; string text2 = TextureSlots[i, 1]; Texture2D val3 = bundle.LoadAsset<Texture2D>(text2); if ((Object)(object)val3 != (Object)null && val2.HasProperty(text)) { val2.SetTexture(text, (Texture)(object)val3); list.Add(text + "=" + text2); } else { list2.Add(text + (((Object)(object)val3 == (Object)null) ? "(no texture)" : "(no property)")); } } if (val2.HasProperty("_MainTex")) { val2.mainTextureScale = Vector2.one; val2.mainTextureOffset = Vector2.zero; } SetFloat(val2, "_BumpScale", 1f, list, list2); SetFloat(val2, "_Metallic", 1f, list, list2); SetFloat(val2, "_Glossiness", 0.08f, list, list2); SetFloat(val2, "_MetallicAlphaGloss", 0.35f, list, list2); SetColor(val2, "_Color", Color.white, list, list2); SetColor(val2, "_MetalColor", Color.white, list, list2); UpdateGlow(val2); list.Add("_EmissionColor=white*" + RoboticInboxPlugin.GlowIntensity.Value); List<string> list3 = new List<string>(); if ((Object)(object)val != (Object)null) { for (int j = 0; j < val.GetPropertyCount(); j++) { list3.Add(val.GetPropertyName(j) + ":" + ((object)val.GetPropertyType(j)/*cast due to .constrained prefix*/).ToString()); } } Debug.Log((object)("RoboticInbox: Cybercrate material from '" + (((Object)(object)source != (Object)null) ? ((Object)source).name : "<none>") + "' shader='" + (((Object)(object)val != (Object)null) ? ((Object)val).name : "<null>") + "' set=[" + string.Join(", ", list) + "] missing=[" + string.Join(", ", list2) + "] shaderProps=[" + string.Join(", ", list3) + "]")); if ((Object)(object)val == (Object)null || ((Object)val).name != "Custom/Piece") { Debug.LogWarning((object)("RoboticInbox: Cybercrate expected shader Custom/Piece, got " + (((Object)(object)val != (Object)null) ? ((Object)val).name : "null"))); } return val2; } internal static void UpdateGlow(Material mat = null) { //IL_0028: 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) mat = mat ?? _material; if ((Object)(object)mat != (Object)null && mat.HasProperty("_EmissionColor")) { mat.SetColor("_EmissionColor", Color.white * RoboticInboxPlugin.GlowIntensity.Value); } } private static void SetFloat(Material m, string p, float v, List<string> set, List<string> missing) { if (m.HasProperty(p)) { m.SetFloat(p, v); set.Add(p + "=" + v); } else { missing.Add(p); } } private unsafe static void SetColor(Material m, string p, Color v, List<string> set, List<string> missing) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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) if (m.HasProperty(p)) { m.SetColor(p, v); Color val = v; set.Add(p + "=" + ((object)(*(Color*)(&val))/*cast due to .constrained prefix*/).ToString()); } else { missing.Add(p); } } private static bool IsUnderAny(Transform t, List<GameObject> roots) { return roots.Exists((GameObject r) => t.IsChildOf(r.transform)); } private static bool Encapsulate(Transform space, Transform of, ref Bounds bounds) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_00a4: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) bool flag = false; MeshFilter[] componentsInChildren = ((Component)of).GetComponentsInChildren<MeshFilter>(true); Vector3 val2 = default(Vector3); foreach (MeshFilter val in componentsInChildren) { if ((Object)(object)val.sharedMesh == (Object)null || !ActiveWithin(((Component)val).transform, of)) { continue; } Bounds bounds2 = val.sharedMesh.bounds; for (int j = 0; j < 8; j++) { ((Vector3)(ref val2))..ctor(((j & 1) == 0) ? ((Bounds)(ref bounds2)).min.x : ((Bounds)(ref bounds2)).max.x, ((j & 2) == 0) ? ((Bounds)(ref bounds2)).min.y : ((Bounds)(ref bounds2)).max.y, ((j & 4) == 0) ? ((Bounds)(ref bounds2)).min.z : ((Bounds)(ref bounds2)).max.z); Vector3 val3 = space.InverseTransformPoint(((Component)val).transform.TransformPoint(val2)); if (!flag) { bounds = new Bounds(val3, Vector3.zero); flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val3); } } } return flag; } private static bool ActiveWithin(Transform t, Transform root) { while ((Object)(object)t != (Object)null) { if (!((Component)t).gameObject.activeSelf) { return false; } if ((Object)(object)t == (Object)(object)root) { return true; } t = t.parent; } return true; } } [BepInPlugin("com.darthjml.roboticinbox", "RoboticInbox", "1.2.0")] public class RoboticInboxPlugin : BaseUnityPlugin { public const string PluginGuid = "com.darthjml.roboticinbox"; public const string PluginName = "RoboticInbox"; public const string PluginVersion = "1.2.0"; public static ConfigEntry<float> ScanRadius; public static ConfigEntry<int> InboxWidth; public static ConfigEntry<int> InboxHeight; public static ConfigEntry<bool> DebugLog; public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> GlowIntensity; public static ConfigEntry<bool> RequireMod; private float _timer; private bool _errorLogged; public const string PrefabName = "RoboticInbox"; public static GameObject RoboticInboxPrefab; private static GameObject _prefabHolder; internal static readonly List<Container> Containers = new List<Container>(); internal static float? SyncedRadius; internal static int? SyncedWidth; internal static int? SyncedHeight; private static readonly FieldRef<Container, ZNetView> ContainerNView = AccessTools.FieldRefAccess<Container, ZNetView>("m_nview"); private static readonly FieldRef<Container, uint> ContainerLastRevision = AccessTools.FieldRefAccess<Container, uint>("m_lastRevision"); private static readonly Func<Container, long, bool> ContainerCheckAccess = AccessTools.MethodDelegate<Func<Container, long, bool>>(AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null), (object)null, true); internal static float Radius => SyncedRadius ?? ScanRadius.Value; internal static int Width => SyncedWidth ?? InboxWidth.Value; internal static int Height => SyncedHeight ?? InboxHeight.Value; private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) ScanRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ScanRadius", 20f, new ConfigDescription("How far (meters) the inbox looks for matching chests. One floor tile = 2 m. Server value is enforced on clients.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 64f), Array.Empty<object>())); InboxWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Inbox", "Columns", 8, new ConfigDescription("Inbox slot columns (wood chest = 5, max 8). Applies on world load; server value is enforced on clients.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>())); InboxHeight = ((BaseUnityPlugin)this).Config.Bind<int>("Inbox", "Rows", 4, new ConfigDescription("Inbox slot rows (wood chest = 2). Applies on world load; server value is enforced on clients.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>())); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Debug", false, "Enable debug logging."); Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable auto-dispersion."); GlowIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "GlowIntensity", 3f, new ConfigDescription("Brightness of the Cybercrate's cyan runes (0 = off). Client-only, applies live.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); GlowIntensity.SettingChanged += delegate { Cybercrate.UpdateGlow(); }; RequireMod = ((BaseUnityPlugin)this).Config.Bind<bool>("Server", "RequireMod", true, "Server/host only: disconnect players who don't have RoboticInbox or have a different version. If false, they may join and only a warning is logged."); new Harmony("com.darthjml.roboticinbox").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RoboticInbox v1.2.0 loaded."); } private void Update() { try { ConfigSync.Tick(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)ex); } if (!Enabled.Value) { return; } _timer += Time.deltaTime; if (_timer < 1f) { return; } _timer = 0f; try { ProcessInboxes(); } catch (Exception ex2) { if (DebugLog.Value || !_errorLogged) { ((BaseUnityPlugin)this).Logger.LogError((object)ex2); } _errorLogged = true; } } internal static void RegisterPrefab(ZNetScene zns) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown if ((Object)(object)RoboticInboxPrefab == (Object)null) { GameObject prefab = zns.GetPrefab("piece_chest_wood"); if ((Object)(object)prefab == (Object)null) { Debug.LogWarning((object)"RoboticInbox: could not find piece_chest_wood prefab."); return; } if ((Object)(object)_prefabHolder == (Object)null) { _prefabHolder = new GameObject("RoboticInbox_PrefabHolder"); _prefabHolder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_prefabHolder); } GameObject val = Object.Instantiate<GameObject>(prefab, _prefabHolder.transform, false); ((Object)val).name = "RoboticInbox"; Piece component = val.GetComponent<Piece>(); component.m_name = "Robotic Inbox"; component.m_description = "Storage box that automatically disperses items to nearby containers containing matching items."; component.m_enabled = true; component.m_category = (PieceCategory)0; component.m_craftingStation = null; List<Requirement> list = new List<Requirement>(); string[] array = new string[2] { "Wood", "Stone" }; foreach (string text in array) { GameObject prefab2 = zns.GetPrefab(text); ItemDrop val2 = ((prefab2 != null) ? prefab2.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null) { list.Add(new Requirement { m_resItem = val2, m_amount = 10, m_recover = true }); } else { Debug.LogWarning((object)("RoboticInbox: material not found: " + text)); } } component.m_resources = list.ToArray(); component.m_dlc = ""; Container component2 = val.GetComponent<Container>(); if ((Object)(object)component2 != (Object)null) { component2.m_name = "Robotic Inbox"; } try { Cybercrate.Apply(val); } catch (Exception ex) { Debug.LogError((object)("RoboticInbox: Cybercrate visual failed, keeping the wood chest look: " + ex)); } RoboticInboxPrefab = val; } ApplyInboxSize(); int stableHashCode = StringExtensionMethods.GetStableHashCode("RoboticInbox"); Dictionary<int, GameObject> dictionary = AccessTools.FieldRefAccess<ZNetScene, Dictionary<int, GameObject>>("m_namedPrefabs").Invoke(zns); if (!dictionary.ContainsKey(stableHashCode)) { zns.m_prefabs.Add(RoboticInboxPrefab); dictionary.Add(stableHashCode, RoboticInboxPrefab); } GameObject prefab3 = zns.GetPrefab("Hammer"); PieceTable val3 = ((!((Object)(object)prefab3 != (Object)null)) ? null : prefab3.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces); if ((Object)(object)val3 == (Object)null) { Debug.LogWarning((object)"RoboticInbox: hammer piece table not found."); return; } val3.m_pieces.RemoveAll((GameObject go) => (Object)(object)go == (Object)null); if (!val3.m_pieces.Contains(RoboticInboxPrefab)) { val3.m_pieces.Add(RoboticInboxPrefab); } Debug.Log((object)"RoboticInbox: prefab registered and added to hammer."); } internal static void ApplyInboxSize() { Container val = (((Object)(object)RoboticInboxPrefab != (Object)null) ? RoboticInboxPrefab.GetComponent<Container>() : null); if (!((Object)(object)val == (Object)null)) { val.m_width = Width; val.m_height = Height; } } private static bool IsInbox(Container c) { return ((Object)c).name.StartsWith("RoboticInbox", StringComparison.Ordinal); } private static bool CanWrite(Container c) { if (!c.IsOwner() || c.IsInUse() || c.GetInventory() == null) { return false; } ZNetView val = ContainerNView.Invoke(c); if ((Object)(object)val != (Object)null && val.IsValid()) { return ContainerLastRevision.Invoke(c) == val.GetZDO().DataRevision; } return false; } private void ProcessInboxes() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Containers.RemoveAll((Container c) => (Object)(object)c == (Object)null); float num = Radius * Radius; long playerID = localPlayer.GetPlayerID(); foreach (Container container in Containers) { if (!IsInbox(container) || !CanWrite(container)) { continue; } Inventory inventory = container.GetInventory(); if (inventory.NrOfItems() == 0) { continue; } Vector3 pos = ((Component)container).transform.position; List<Container> list = new List<Container>(); foreach (Container container2 in Containers) { if (!((Object)(object)container2 == (Object)(object)container) && !IsInbox(container2)) { Vector3 val = ((Component)container2).transform.position - pos; if (!(((Vector3)(ref val)).sqrMagnitude > num) && CanWrite(container2) && ContainerCheckAccess(container2, playerID) && !((Object)(object)((Component)container2).GetComponentInParent<TombStone>() != (Object)null)) { list.Add(container2); } } } if (list.Count == 0) { continue; } list.Sort(delegate(Container a, Container b) { //IL_0006: 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_0016: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Vector3 val3 = ((Component)a).transform.position - pos; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; val3 = ((Component)b).transform.position - pos; return sqrMagnitude.CompareTo(((Vector3)(ref val3)).sqrMagnitude); }); foreach (ItemData item in new List<ItemData>(inventory.GetAllItems())) { if (item == null || item.m_shared == null) { continue; } foreach (Container item2 in list) { Inventory inventory2 = item2.GetInventory(); if (!inventory2.ContainsItemByName(item.m_shared.m_name)) { continue; } int num2 = item.m_stack; if (!inventory2.CanAddItem(item, num2)) { num2 = inventory2.FindFreeStackSpace(item.m_shared.m_name, (float)item.m_worldLevel); if (num2 <= 0) { continue; } num2 = Math.Min(num2, item.m_stack); } string name = item.m_shared.m_name; int num3 = inventory2.CountItems(name, -1, false); ItemData val2 = item.Clone(); val2.m_stack = num2; inventory2.AddItem(val2); num2 = inventory2.CountItems(name, -1, false) - num3; if (num2 > 0) { inventory.RemoveItem(item, num2); if (DebugLog.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"RoboticInbox: moved {num2}x {item.m_shared.m_name} -> {((Object)item2).name}"); } if (item.m_stack <= 0 || !inventory.ContainsItem(item)) { break; } } } } } } } [HarmonyPatch(typeof(Container), "Awake")] public static class Container_Awake_Patch { private static void Postfix(Container __instance) { if (__instance.GetInventory() != null) { RoboticInboxPlugin.Containers.Add(__instance); } } } public static class ConfigSync { [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class OnNewConnection_Patch { private static void Postfix(ZNet __instance, ZNetPeer peer) { peer.m_rpc.Register<ZPackage>("RoboticInbox_Config", (Action<ZRpc, ZPackage>)RPC_Config); peer.m_rpc.Register<string>("RoboticInbox_Version", (Action<ZRpc, string>)RPC_Version); if (!__instance.IsServer()) { _serverVersion = null; _rejectMessage = null; _pendingHudWarning = null; } peer.m_rpc.Invoke("RoboticInbox_Version", new object[1] { Mine }); } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private static class RPC_PeerInfo_Patch { private static bool Prefix(ZNet __instance, ZRpc rpc, ref bool __state) { __state = true; try { if (!__instance.IsServer() || rpc == null) { return true; } PeerVersions.TryGetValue(rpc, out var value); PeerVersions.Remove(rpc); if (value == Mine) { return true; } string text = Endpoint(rpc); string text2 = ((value == null) ? ("client " + text + " does not have RoboticInbox (server has v" + Mine + ")") : ("client " + text + " has RoboticInbox v" + value + ", server has v" + Mine)); if (!RoboticInboxPlugin.RequireMod.Value) { Debug.LogWarning((object)("RoboticInbox: " + text2 + "; allowed because Server.RequireMod = false.")); return true; } Debug.LogWarning((object)("RoboticInbox: " + text2 + "; disconnecting (Server.RequireMod = true).")); rpc.Invoke("Error", new object[1] { 3 }); PendingKicks[rpc] = Time.time + 3f; __state = false; return false; } catch (Exception ex) { Debug.LogWarning((object)("RoboticInbox: version check failed, letting client in: " + ex)); return true; } } private static void Postfix(ZNet __instance, ZRpc rpc, bool __state) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if (!__state || rpc == null) { return; } if (!__instance.IsServer()) { if (_serverVersion == null) { Debug.Log((object)"RoboticInbox: this server does not run RoboticInbox. Sorting still works for you with your local settings; players without the mod won't see inboxes."); } return; } ZPackage val = new ZPackage(); val.Write(RoboticInboxPlugin.ScanRadius.Value); val.Write(RoboticInboxPlugin.InboxWidth.Value); val.Write(RoboticInboxPlugin.InboxHeight.Value); rpc.Invoke("RoboticInbox_Config", new object[1] { val }); } } [HarmonyPatch(typeof(ZNet), "Disconnect", new Type[] { typeof(ZNetPeer) })] private static class Disconnect_Patch { private static void Prefix(ZNetPeer peer) { if (peer?.m_rpc != null) { PeerVersions.Remove(peer.m_rpc); PendingKicks.Remove(peer.m_rpc); } } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] private static class ShowConnectError_Patch { private static void Postfix(FejdStartup __instance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if (_rejectMessage != null && (int)ZNet.GetConnectionStatus() == 3) { if ((Object)(object)__instance.m_connectionFailedError != (Object)null) { __instance.m_connectionFailedError.text = _rejectMessage; } _rejectMessage = null; } } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] private static class OnDestroy_Patch { private static void Postfix() { RoboticInboxPlugin.SyncedRadius = null; RoboticInboxPlugin.SyncedWidth = (RoboticInboxPlugin.SyncedHeight = null); RoboticInboxPlugin.ApplyInboxSize(); PeerVersions.Clear(); PendingKicks.Clear(); _serverVersion = null; _pendingHudWarning = null; } } private const string RpcName = "RoboticInbox_Config"; private const string VersionRpcName = "RoboticInbox_Version"; private const float KickDelay = 3f; private static readonly Dictionary<ZRpc, string> PeerVersions = new Dictionary<ZRpc, string>(); private static readonly Dictionary<ZRpc, float> PendingKicks = new Dictionary<ZRpc, float>(); private static string _serverVersion; private static string _rejectMessage; private static string _pendingHudWarning; private static readonly Func<ZNet, ZRpc, ZNetPeer> GetPeer = AccessTools.MethodDelegate<Func<ZNet, ZRpc, ZNetPeer>>(AccessTools.Method(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null), (object)null, true); private static string Mine => "1.2.0"; private static string Endpoint(ZRpc rpc) { try { ISocket socket = rpc.GetSocket(); return ((socket != null) ? socket.GetEndPointString() : null) ?? "?"; } catch { return "?"; } } private static void RPC_Version(ZRpc rpc, string version) { ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null || rpc == null) { return; } version = version ?? ""; if (instance.IsServer()) { PeerVersions[rpc] = version; if (version != Mine) { Debug.LogWarning((object)("RoboticInbox: client " + Endpoint(rpc) + " has RoboticInbox v" + version + ", server has v" + Mine + ".")); } return; } _serverVersion = version; if (version == Mine) { Debug.Log((object)("RoboticInbox: server runs RoboticInbox v" + version + " (same as ours).")); return; } Debug.LogWarning((object)("RoboticInbox: VERSION MISMATCH - server has RoboticInbox v" + version + ", you have v" + Mine + ".")); _rejectMessage = "This server requires Robotic Inbox v" + version + ".\nYou have v" + Mine + ".\n\nImport the server's r2modman profile code (or install Robotic Inbox v" + version + ") and try again."; _pendingHudWarning = "Robotic Inbox version mismatch!\nServer v" + version + ", you v" + Mine + ". Please update."; } internal static void Tick() { if (PendingKicks.Count > 0) { ZNet instance = ZNet.instance; foreach (ZRpc item in new List<ZRpc>(PendingKicks.Keys)) { if (!((Object)(object)instance != (Object)null) || !(Time.time < PendingKicks[item])) { PendingKicks.Remove(item); ZNetPeer val = (((Object)(object)instance != (Object)null) ? GetPeer(instance, item) : null); if (val != null) { Debug.Log((object)("RoboticInbox: disconnecting rejected client " + Endpoint(item) + ".")); instance.Disconnect(val); } } } } if (_pendingHudWarning != null && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, _pendingHudWarning, 0, (Sprite)null, false, true); _pendingHudWarning = null; } } private static void RPC_Config(ZRpc rpc, ZPackage pkg) { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { RoboticInboxPlugin.SyncedRadius = Mathf.Clamp(pkg.ReadSingle(), 1f, 64f); RoboticInboxPlugin.SyncedWidth = Mathf.Clamp(pkg.ReadInt(), 1, 8); RoboticInboxPlugin.SyncedHeight = Mathf.Clamp(pkg.ReadInt(), 1, 8); RoboticInboxPlugin.ApplyInboxSize(); Debug.Log((object)$"RoboticInbox: using server config radius={RoboticInboxPlugin.SyncedRadius} size={RoboticInboxPlugin.SyncedWidth}x{RoboticInboxPlugin.SyncedHeight}"); } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetScene_Awake_Patch { private static void Postfix(ZNetScene __instance) { try { RoboticInboxPlugin.RegisterPrefab(__instance); } catch (Exception ex) { Debug.LogWarning((object)("RoboticInbox: register failed " + ex)); } } } [HarmonyPatch(typeof(Player), "UpdateKnownRecipesList")] public static class Player_UpdateKnownRecipesList_Patch { private static string _lastState; private static readonly FieldRef<Player, HashSet<string>> KnownRecipes = AccessTools.FieldRefAccess<Player, HashSet<string>>("m_knownRecipes"); private static readonly MethodInfo UpdateAvailablePiecesList = AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null); private static void Postfix(Player __instance) { try { GameObject roboticInboxPrefab = RoboticInboxPlugin.RoboticInboxPrefab; if ((Object)(object)roboticInboxPrefab == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } Piece component = roboticInboxPrefab.GetComponent<Piece>(); HashSet<string> hashSet = KnownRecipes.Invoke(__instance); List<PieceTable> list = new List<PieceTable>(); ((Humanoid)__instance).GetInventory().GetAllPieceTables(list); int num = 0; int num2 = 0; foreach (PieceTable item in list) { if (!((Object)(object)item == (Object)null) && item.m_pieces != null && item.m_pieces.Exists((GameObject g) => (Object)(object)g != (Object)null && ((Object)g).name == "piece_chest_wood")) { num++; if (!item.m_pieces.Contains(roboticInboxPrefab)) { item.m_pieces.Add(roboticInboxPrefab); num2++; } } } bool flag = hashSet.Contains(component.m_name); if (num > 0 && !flag) { hashSet.Add(component.m_name); } if (num2 > 0 || (num > 0 && !flag)) { UpdateAvailablePiecesList.Invoke(__instance, null); } string text = $"tables={list.Count} hammerTables={num} added={num2} wasKnown={flag}"; if (text != _lastState) { _lastState = text; Debug.Log((object)("RoboticInbox: " + text)); } } catch (Exception ex) { Debug.LogWarning((object)("RoboticInbox: known-list patch failed: " + ex)); } } } }