diff --git a/src/Compatibility/DataCenterModLoader/GameAPI.cs b/src/Compatibility/DataCenterModLoader/GameAPI.cs index 42c6a5cc..1743fd7b 100644 --- a/src/Compatibility/DataCenterModLoader/GameAPI.cs +++ b/src/Compatibility/DataCenterModLoader/GameAPI.cs @@ -1390,23 +1390,60 @@ private ulong FindHandleByStableId(string targetId) { try { - foreach (var srv in UnityEngine.Resources.FindObjectsOfTypeAll()) + var nm = Il2Cpp.NetworkMap.instance; + if (nm != null && nm.servers != null) { - try + foreach (var kvp in nm.servers) { - if (srv.gameObject.scene.name == null) continue; - if ((srv.ServerID ?? "") == targetId) return (ulong)srv.Pointer.ToInt64(); + try + { + var srv = kvp.Value; + if (srv != null && srv.gameObject.scene.name != null) + { + if ((srv.ServerID ?? "") == targetId) return (ulong)srv.Pointer.ToInt64(); + } + } + catch { } } - catch { } } - foreach (var sw in UnityEngine.Resources.FindObjectsOfTypeAll()) + else { - try + foreach (var srv in UnityEngine.Resources.FindObjectsOfTypeAll()) { - if (sw.gameObject.scene.name == null) continue; - if ((sw.switchId ?? "") == targetId) return (ulong)sw.Pointer.ToInt64(); + try + { + if (srv.gameObject.scene.name == null) continue; + if ((srv.ServerID ?? "") == targetId) return (ulong)srv.Pointer.ToInt64(); + } + catch { } + } + } + if (nm != null && nm.switches != null) + { + foreach (var kvp in nm.switches) + { + try + { + var sw = kvp.Value; + if (sw != null && sw.gameObject.scene.name != null) + { + if ((sw.switchId ?? "") == targetId) return (ulong)sw.Pointer.ToInt64(); + } + } + catch { } + } + } + else + { + foreach (var sw in UnityEngine.Resources.FindObjectsOfTypeAll()) + { + try + { + if (sw.gameObject.scene.name == null) continue; + if ((sw.switchId ?? "") == targetId) return (ulong)sw.Pointer.ToInt64(); + } + catch { } } - catch { } } foreach (var pp in UnityEngine.Resources.FindObjectsOfTypeAll()) { @@ -2331,33 +2368,71 @@ uint ObjFindByTypeImpl(byte typeId, IntPtr outHandles, uint max) { case 0: // Server { - var all = UnityEngine.Resources.FindObjectsOfTypeAll(); - foreach (var srv in all) + var nm = Il2Cpp.NetworkMap.instance; + if (nm != null && nm.servers != null) { - try + foreach (var kvp in nm.servers) + { + try + { + var srv = kvp.Value; + if (srv == null || srv.gameObject.scene.name == null) continue; + if (count >= max) break; + Marshal.WriteInt64(outHandles, (int)(count * 8), srv.Pointer.ToInt64()); + count++; + } + catch { } + } + } + else + { + var all = UnityEngine.Resources.FindObjectsOfTypeAll(); + foreach (var srv in all) { - if (srv.gameObject.scene.name == null) continue; - if (count >= max) break; - Marshal.WriteInt64(outHandles, (int)(count * 8), srv.Pointer.ToInt64()); - count++; + try + { + if (srv.gameObject.scene.name == null) continue; + if (count >= max) break; + Marshal.WriteInt64(outHandles, (int)(count * 8), srv.Pointer.ToInt64()); + count++; + } + catch { } } - catch { } } break; } case 4: // NetworkSwitch { - var all = UnityEngine.Resources.FindObjectsOfTypeAll(); - foreach (var sw in all) + var nm = Il2Cpp.NetworkMap.instance; + if (nm != null && nm.switches != null) { - try + foreach (var kvp in nm.switches) { - if (sw.gameObject.scene.name == null) continue; - if (count >= max) break; - Marshal.WriteInt64(outHandles, (int)(count * 8), sw.Pointer.ToInt64()); - count++; + try + { + var sw = kvp.Value; + if (sw == null || sw.gameObject.scene.name == null) continue; + if (count >= max) break; + Marshal.WriteInt64(outHandles, (int)(count * 8), sw.Pointer.ToInt64()); + count++; + } + catch { } + } + } + else + { + var all = UnityEngine.Resources.FindObjectsOfTypeAll(); + foreach (var sw in all) + { + try + { + if (sw.gameObject.scene.name == null) continue; + if (count >= max) break; + Marshal.WriteInt64(outHandles, (int)(count * 8), sw.Pointer.ToInt64()); + count++; + } + catch { } } - catch { } } break; } @@ -2596,21 +2671,45 @@ ulong ObjFindByIdImpl(byte typeId, ushort fieldId, IntPtr id, uint idLen) { case 0: // Server { - foreach (var srv in UnityEngine.Resources.FindObjectsOfTypeAll()) + var nm = Il2Cpp.NetworkMap.instance; + if (nm != null && nm.servers != null) { - try + foreach (var kvp in nm.servers) { - if (srv.gameObject.scene.name == null) continue; - string val = fieldId switch + try { - 0 => srv.ServerID ?? "", - 2 => srv.rackPositionUID.ToString(), - 3 => srv.gameObject.name ?? "", - _ => "" - }; - if (val == targetId) return (ulong)srv.Pointer.ToInt64(); + var srv = kvp.Value; + if (srv == null || srv.gameObject.scene.name == null) continue; + string val = fieldId switch + { + 0 => srv.ServerID ?? "", + 2 => srv.rackPositionUID.ToString(), + 3 => srv.gameObject.name ?? "", + _ => "" + }; + if (val == targetId) return (ulong)srv.Pointer.ToInt64(); + } + catch { } + } + } + else + { + foreach (var srv in UnityEngine.Resources.FindObjectsOfTypeAll()) + { + try + { + if (srv.gameObject.scene.name == null) continue; + string val = fieldId switch + { + 0 => srv.ServerID ?? "", + 2 => srv.rackPositionUID.ToString(), + 3 => srv.gameObject.name ?? "", + _ => "" + }; + if (val == targetId) return (ulong)srv.Pointer.ToInt64(); + } + catch { } } - catch { } } // Lookup failed — dump all known servers so we can see if ID mismatch try @@ -2636,20 +2735,43 @@ ulong ObjFindByIdImpl(byte typeId, ushort fieldId, IntPtr id, uint idLen) } case 4: // NetworkSwitch { - foreach (var sw in UnityEngine.Resources.FindObjectsOfTypeAll()) + var nm = Il2Cpp.NetworkMap.instance; + if (nm != null && nm.switches != null) { - try + foreach (var kvp in nm.switches) { - if (sw.gameObject.scene.name == null) continue; - string val = fieldId switch + try { - 1 => sw.switchId ?? "", - 3 => sw.gameObject.name ?? "", - _ => "" - }; - if (val == targetId) return (ulong)sw.Pointer.ToInt64(); + var sw = kvp.Value; + if (sw == null || sw.gameObject.scene.name == null) continue; + string val = fieldId switch + { + 1 => sw.switchId ?? "", + 3 => sw.gameObject.name ?? "", + _ => "" + }; + if (val == targetId) return (ulong)sw.Pointer.ToInt64(); + } + catch { } + } + } + else + { + foreach (var sw in UnityEngine.Resources.FindObjectsOfTypeAll()) + { + try + { + if (sw.gameObject.scene.name == null) continue; + string val = fieldId switch + { + 1 => sw.switchId ?? "", + 3 => sw.gameObject.name ?? "", + _ => "" + }; + if (val == targetId) return (ulong)sw.Pointer.ToInt64(); + } + catch { } } - catch { } } try { diff --git a/src/GameLayer/Patches/Networking/CablePositionsPatch.cs b/src/GameLayer/Patches/Networking/CablePositionsPatch.cs index 84c3f50c..28acd2ec 100644 --- a/src/GameLayer/Patches/Networking/CablePositionsPatch.cs +++ b/src/GameLayer/Patches/Networking/CablePositionsPatch.cs @@ -35,28 +35,40 @@ private static bool CreateNewCablePrefix( __result = Interlocked.Increment(ref _nextCableId); - HookIntegration.Emit("greg.CABLE.Created", - new gregCore.Core.Models.EventPayload - { - HookName = "greg.CABLE.Created", - OccurredAtUtc = DateTime.UtcNow, - Data = new System.Collections.Generic.Dictionary - { - { "CableId", __result }, - { "Source", "PrefixBypass" } - } - }); + try { EmitCreate(__result); } catch { } return false; } catch (Exception ex) { - MelonLogger.Error($"[CablePatch] CreateNewCable failed: {ex.Message}"); + try { LogError(ex); } catch { } __result = Environment.TickCount & 0x7FFFFFFF; return false; } } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + private static void EmitCreate(int id) + { + HookIntegration.Emit("greg.CABLE.Created", + new gregCore.Core.Models.EventPayload + { + HookName = "greg.CABLE.Created", + OccurredAtUtc = DateTime.UtcNow, + Data = new System.Collections.Generic.Dictionary + { + { "CableId", id }, + { "Source", "PrefixBypass" } + } + }); + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + private static void LogError(Exception ex) + { + MelonLogger.Error($"[CablePatch] CreateNewCable failed: {ex.Message}"); + } + public static void SetBaseId(int baseId) { int current; @@ -67,8 +79,16 @@ public static void SetBaseId(int baseId) } while (Interlocked.CompareExchange(ref _nextCableId, baseId + 1, current) != current); + try { LogBaseIdSync(baseId); } catch { } + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + private static void LogBaseIdSync(int baseId) + { MelonLogger.Msg($"[CablePatch] Cable ID counter set to {baseId + 1}"); } public static int PeekNextId() => _nextCableId; + + } diff --git a/src/Infrastructure/Scripting/Lua/Modules/LuaServerModule.cs b/src/Infrastructure/Scripting/Lua/Modules/LuaServerModule.cs index 17bd8abb..fd1e74db 100644 --- a/src/Infrastructure/Scripting/Lua/Modules/LuaServerModule.cs +++ b/src/Infrastructure/Scripting/Lua/Modules/LuaServerModule.cs @@ -16,12 +16,32 @@ public static void Register(Table greg, Script script, string modId) { var serverTable = new Table(script); + // Helper for O(1) performance lookup via NetworkMap + System.Collections.Generic.IEnumerable GetServers() + { + try + { + var nm = Il2Cpp.NetworkMap.instance; + if (nm != null && nm.servers != null) + { + var list = new System.Collections.Generic.List(); + foreach (var kvp in nm.servers) + { + if (kvp.Value != null) list.Add(kvp.Value); + } + return list; + } + } + catch { } + return UnityEngine.Object.FindObjectsOfType() ?? new Il2Cpp.Server[0]; + } + // greg.server.get_all() → table of server info serverTable["get_all"] = (Func)(() => { try { - var servers = UnityEngine.Object.FindObjectsOfType(); + var servers = GetServers(); var result = new Table(script); int i = 1; foreach (var s in servers) @@ -80,7 +100,7 @@ public static void Register(Table greg, Script script, string modId) { try { - var servers = UnityEngine.Object.FindObjectsOfType(); + var servers = GetServers(); foreach (var s in servers) { try @@ -104,7 +124,7 @@ public static void Register(Table greg, Script script, string modId) try { int repaired = 0; - var servers = UnityEngine.Object.FindObjectsOfType(); + var servers = GetServers(); foreach (var s in servers) { try