using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.Warehouse;
using LabFusion.Entities;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.Utilities;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using SpawnLogger;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: MelonInfo(typeof(SpawnLoggerMod), "Spawn Logger", "2.3.1", "Local Utility", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : System.Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(/*Could not decode attribute arguments.*/)]
internal sealed class RefSafetyRulesAttribute : System.Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SpawnLogger
{
public sealed class SpawnLoggerMod : MelonMod
{
private sealed class Identity
{
public byte SmallId;
public ulong PlatformId;
public string Name;
}
private sealed class SpawnSnapshot
{
public Identity ClaimedOwner;
public Identity TransportSender;
public float CapturedAt;
public string AlertReason;
}
private sealed class PlayerHistory
{
public Page Page;
public readonly List<string> Entries = new List<string>();
}
private sealed class FeedItem
{
public ulong PlatformId;
public string Text;
}
[CompilerGenerated]
private static class <>O
{
public static PlayerUpdate <0>__OnPlayerJoined;
public static PlayerUpdate <1>__OnPlayerLeft;
public static UpdateEvent <2>__OnLevelLoaded;
public static Action <3>__ClearLogs;
}
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Action<bool> <>9__26_0;
public static Action<bool> <>9__26_1;
public static Action <>9__49_0;
public static Action <>9__49_1;
public static Action <>9__50_0;
public static Action <>9__50_1;
internal void <CreateMenu>b__26_0(bool value)
{
SavePreference(_clearOnLeave, value);
}
internal void <CreateMenu>b__26_1(bool value)
{
SavePreference(_logSlzContent, value);
}
internal void <RenderFeed>b__49_0()
{
}
internal void <RenderFeed>b__49_1()
{
}
internal void <RenderEntries>b__50_0()
{
}
internal void <RenderEntries>b__50_1()
{
}
}
private const int MaxEntries = 30;
private const float LevelSettleSeconds = 5f;
private const float SnapshotLifetimeSeconds = 120f;
private const float CleanupIntervalSeconds = 5f;
private static readonly Dictionary<ushort, SpawnSnapshot> PendingSpawns = new Dictionary<ushort, SpawnSnapshot>();
private static readonly HashSet<ushort> SeenEntityIds = new HashSet<ushort>();
private static readonly Dictionary<ulong, PlayerHistory> PlayerHistories = new Dictionary<ulong, PlayerHistory>();
private static readonly List<FeedItem> SpawnFeed = new List<FeedItem>();
private static readonly List<FeedItem> AlertFeed = new List<FeedItem>();
private static MelonPreferences_Entry<bool> _clearOnLeave;
private static MelonPreferences_Entry<bool> _logSlzContent;
private static Page _spawnPage;
private static Page _playersPage;
private static Page _alertPage;
private static bool _menuCreated;
private static float _loggingReadyAt = 1f / 0f;
private static float _nextCleanupAt;
public override void OnInitializeMelon()
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Expected O, but got Unknown
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
MelonPreferences_Category val = MelonPreferences.CreateCategory("SpawnLogger");
_clearOnLeave = val.CreateEntry<bool>("AutoClearOnPlayerLeave", true, "Auto-Clear On Player Leave", "Remove a disconnected player's entries from the in-game log.", false, false, (ValueValidator)null, (string)null);
_logSlzContent = val.CreateEntry<bool>("LogSlzContent", false, "Log SLZ Content", "Include SLZ-authored and internal-pallet spawns. Magazines are always excluded.", false, false, (ValueValidator)null, (string)null);
Hooking.OnUIRigCreated += new Action(CreateMenu);
object obj = <>O.<0>__OnPlayerJoined;
if (obj == null)
{
PlayerUpdate val2 = OnPlayerJoined;
<>O.<0>__OnPlayerJoined = val2;
obj = (object)val2;
}
MultiplayerHooking.OnPlayerJoined += (PlayerUpdate)obj;
object obj2 = <>O.<1>__OnPlayerLeft;
if (obj2 == null)
{
PlayerUpdate val3 = OnPlayerLeft;
<>O.<1>__OnPlayerLeft = val3;
obj2 = (object)val3;
}
MultiplayerHooking.OnPlayerLeft += (PlayerUpdate)obj2;
object obj3 = <>O.<2>__OnLevelLoaded;
if (obj3 == null)
{
UpdateEvent val4 = OnLevelLoaded;
<>O.<2>__OnLevelLoaded = val4;
obj3 = (object)val4;
}
MultiplayerHooking.OnTargetLevelLoaded += (UpdateEvent)obj3;
}
public override void OnDeinitializeMelon()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
//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_004f: Expected O, but got Unknown
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
Hooking.OnUIRigCreated -= new Action(CreateMenu);
object obj = <>O.<0>__OnPlayerJoined;
if (obj == null)
{
PlayerUpdate val = OnPlayerJoined;
<>O.<0>__OnPlayerJoined = val;
obj = (object)val;
}
MultiplayerHooking.OnPlayerJoined -= (PlayerUpdate)obj;
object obj2 = <>O.<1>__OnPlayerLeft;
if (obj2 == null)
{
PlayerUpdate val2 = OnPlayerLeft;
<>O.<1>__OnPlayerLeft = val2;
obj2 = (object)val2;
}
MultiplayerHooking.OnPlayerLeft -= (PlayerUpdate)obj2;
object obj3 = <>O.<2>__OnLevelLoaded;
if (obj3 == null)
{
UpdateEvent val3 = OnLevelLoaded;
<>O.<2>__OnLevelLoaded = val3;
obj3 = (object)val3;
}
MultiplayerHooking.OnTargetLevelLoaded -= (UpdateEvent)obj3;
ResetLevelState();
}
public override void OnUpdate()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: 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_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
float realtimeSinceStartup = Time.realtimeSinceStartup;
if (realtimeSinceStartup < _nextCleanupAt || PendingSpawns.Count == 0)
{
return;
}
_nextCleanupAt = realtimeSinceStartup + 5f;
List<ushort> val = new List<ushort>();
Enumerator<ushort, SpawnSnapshot> enumerator = PendingSpawns.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
KeyValuePair<ushort, SpawnSnapshot> current = enumerator.Current;
if (realtimeSinceStartup - current.Value.CapturedAt > 120f)
{
val.Add(current.Key);
}
}
}
finally
{
((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
}
Enumerator<ushort> enumerator2 = val.GetEnumerator();
try
{
while (enumerator2.MoveNext())
{
ushort current2 = enumerator2.Current;
PendingSpawns.Remove(current2);
}
}
finally
{
((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
}
}
private static void OnLevelLoaded()
{
ResetLevelState();
_loggingReadyAt = Time.realtimeSinceStartup + 5f;
}
private static void ResetLevelState()
{
PendingSpawns.Clear();
SeenEntityIds.Clear();
_nextCleanupAt = 0f;
}
private void CreateMenu()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
//IL_0092: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
if (_menuCreated)
{
return;
}
Page val = Page.Root.CreatePage("Spawn Logger", Color.yellow, 0, true);
Color red = Color.red;
object obj = <>O.<3>__ClearLogs;
if (obj == null)
{
Action val2 = ClearLogs;
<>O.<3>__ClearLogs = val2;
obj = (object)val2;
}
val.CreateFunction("Clear All Logs", red, (Action)obj);
val.CreateBool("Auto-Clear On Leave", Color.yellow, _clearOnLeave.Value, (Action<bool>)delegate(bool value)
{
SavePreference(_clearOnLeave, value);
});
val.CreateBool("Log SLZ Content", Color.yellow, _logSlzContent.Value, (Action<bool>)delegate(bool value)
{
SavePreference(_logSlzContent, value);
});
_spawnPage = val.CreatePage("All Spawns", Color.yellow, 0, true);
_playersPage = val.CreatePage("Players", Color.yellow, 0, true);
_alertPage = val.CreatePage("Suspicious", Color.red, 0, true);
_menuCreated = true;
Enumerator<PlayerID> enumerator = PlayerIDManager.PlayerIDs.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
PlayerID current = enumerator.Current;
RefreshHistory(GetOrCreateHistory(CreateIdentity(current, 0)));
}
}
finally
{
((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
}
RefreshMainPages();
}
private static void SavePreference(MelonPreferences_Entry<bool> preference, bool value)
{
preference.Value = value;
MelonPreferences.Save();
}
private static void OnPlayerJoined(PlayerID player)
{
if (player != null)
{
RefreshHistory(GetOrCreateHistory(CreateIdentity(player, 0)));
}
}
private static void OnPlayerLeft(PlayerID player)
{
if (player == null)
{
return;
}
PreserveDepartingIdentity(player);
if (_clearOnLeave != null && _clearOnLeave.Value)
{
RemovePlayerHistory(player.PlatformID);
SpawnFeed.RemoveAll((Predicate<FeedItem>)((FeedItem item) => item.PlatformId == player.PlatformID));
AlertFeed.RemoveAll((Predicate<FeedItem>)((FeedItem item) => item.PlatformId == player.PlatformID));
RefreshMainPages();
}
}
private static void PreserveDepartingIdentity(PlayerID player)
{
//IL_0014: 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)
Identity claimedOwner = CreateIdentity(player, 0);
Enumerator<ushort, SpawnSnapshot> enumerator = PendingSpawns.Values.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
SpawnSnapshot current = enumerator.Current;
if (current.ClaimedOwner.SmallId == player.SmallID && current.ClaimedOwner.PlatformId == 0)
{
current.ClaimedOwner = claimedOwner;
}
}
}
finally
{
((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
}
}
private static void RemovePlayerHistory(ulong platformId)
{
PlayerHistory playerHistory = default(PlayerHistory);
if (!PlayerHistories.TryGetValue(platformId, ref playerHistory))
{
return;
}
PlayerHistories.Remove(platformId);
if (playerHistory.Page != null)
{
Page playersPage = _playersPage;
if (playersPage != null)
{
playersPage.RemovePage(playerHistory.Page);
}
}
}
private static Identity CreateIdentity(PlayerID player, byte fallbackSmallId = 0)
{
if (player == null)
{
return new Identity
{
SmallId = fallbackSmallId,
Name = $"Unknown (ID {fallbackSmallId})"
};
}
string text = default(string);
return new Identity
{
SmallId = player.SmallID,
PlatformId = player.PlatformID,
Name = ((MetadataHelper.TryGetDisplayName(player, ref text) && !string.IsNullOrWhiteSpace(text)) ? text : $"Player {player.SmallID}")
};
}
internal static void CaptureResponse(SpawnResponseData data, ReceivedMessage message)
{
if (data?.SpawnData != null)
{
ulong valueOrDefault = ((ReceivedMessage)(ref message)).PlatformID.GetValueOrDefault();
Identity identity = ((valueOrDefault == 0L) ? null : CreateIdentity(PlayerIDManager.GetPlayerID(valueOrDefault), 0));
if (identity != null && identity.PlatformId == 0)
{
identity.PlatformId = valueOrDefault;
}
PendingSpawns[data.EntityID] = new SpawnSnapshot
{
ClaimedOwner = CreateIdentity(PlayerIDManager.GetPlayerID(data.OwnerID), data.OwnerID),
TransportSender = identity,
CapturedAt = Time.realtimeSinceStartup,
AlertReason = BuildAlertReason(data, identity)
};
}
}
private static string BuildAlertReason(SpawnResponseData data, Identity transportSender)
{
PlayerID hostID = PlayerIDManager.GetHostID();
bool flag = hostID != null && transportSender != null && transportSender.PlatformId != hostID.PlatformID;
bool flag2 = NetworkEntityManager.IDManager.RegisteredEntities.GetEntity(data.EntityID) != null;
if (!flag && !flag2)
{
return null;
}
string text = (flag ? "spawn response came directly from a non-host client" : string.Empty);
if (flag && transportSender.SmallId != data.OwnerID)
{
text += $"; payload claimed owner ID {data.OwnerID}";
}
if (flag2)
{
text = text + ((text.Length == 0) ? string.Empty : "; ") + "entity ID was already registered";
}
return text;
}
internal static void CompleteSpawn(SpawnResponseData data, Poolee poolee)
{
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Invalid comparison between Unknown and I4
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
if (data?.SpawnData == null)
{
return;
}
SpawnSnapshot spawnSnapshot = default(SpawnSnapshot);
PendingSpawns.TryGetValue(data.EntityID, ref spawnSnapshot);
PendingSpawns.Remove(data.EntityID);
if (Time.realtimeSinceStartup < _loggingReadyAt || !SeenEntityIds.Add(data.EntityID))
{
return;
}
string barcode = data.SpawnData.Barcode;
if (string.IsNullOrWhiteSpace(barcode))
{
return;
}
TryResolveCrate(barcode, out var crate);
if (!IsMagazine(poolee, crate, barcode) && !ShouldExcludeSlz(crate, barcode))
{
spawnSnapshot = spawnSnapshot ?? new SpawnSnapshot
{
ClaimedOwner = CreateIdentity(PlayerIDManager.GetPlayerID(data.OwnerID), data.OwnerID)
};
string itemName = (string.IsNullOrWhiteSpace((crate != null) ? ((Scannable)crate).Title : null) ? barcode : ((Scannable)crate).Title);
if (!string.IsNullOrEmpty(spawnSnapshot.AlertReason))
{
AddAlert(spawnSnapshot, data.SpawnData.SpawnSource, itemName);
}
else if ((int)data.SpawnData.SpawnSource != 1)
{
AddNormalSpawn(spawnSnapshot.ClaimedOwner, itemName);
}
}
}
private static bool TryResolveCrate(string barcode, out Crate crate)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
crate = null;
AssetWarehouse instance = AssetWarehouse.Instance;
return instance != null && instance.TryGetCrate(new Barcode(barcode), ref crate) && (Object)(object)crate != (Object)null;
}
private static bool ShouldExcludeSlz(Crate crate, string barcode)
{
return (_logSlzContent == null || !_logSlzContent.Value) && IsSlzContent(crate, barcode);
}
private static bool IsSlzContent(Crate crate, string barcode)
{
if (barcode.StartsWith("SLZ.", (StringComparison)5))
{
return true;
}
Pallet val = ((crate != null) ? crate.Pallet : null);
if ((Object)(object)val == (Object)null)
{
return false;
}
if (val.Internal)
{
return true;
}
string text = val.Author?.Trim();
return string.Equals(text, "SLZ", (StringComparison)5) || string.Equals(text, "Stress Level Zero", (StringComparison)5) || string.Equals(text, "StressLevelZero", (StringComparison)5);
}
private static bool IsMagazine(Poolee poolee, Crate crate, string barcode)
{
if ((Object)(object)poolee != (Object)null && (Object)(object)((Component)poolee).gameObject.GetComponentInChildren<Magazine>(true) != (Object)null)
{
return true;
}
string text = ((crate != null) ? ((Scannable)crate).Title : null) ?? string.Empty;
return text.IndexOf("magazine", (StringComparison)5) >= 0 || text.IndexOf(" ammo mag", (StringComparison)5) >= 0 || barcode.IndexOf(".Magazine.", (StringComparison)5) >= 0 || barcode.EndsWith(".Magazine", (StringComparison)5);
}
private static void AddNormalSpawn(Identity owner, string itemName)
{
string text = $"[{System.DateTime.Now:HH:mm:ss}] {owner.Name}: {itemName}";
AddToFeed(SpawnFeed, owner.PlatformId, text);
PlayerHistory orCreateHistory = GetOrCreateHistory(owner);
InsertNewest(orCreateHistory.Entries, text);
RefreshHistory(orCreateHistory);
RefreshSpawnPage();
MelonLogger.Msg(text);
}
private static void AddAlert(SpawnSnapshot snapshot, EntitySource source, string itemName)
{
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
Identity transportSender = snapshot.TransportSender;
string text = transportSender?.Name ?? "Unresolved sender";
string text2 = $"[{System.DateTime.Now:HH:mm:ss}] ALERT: {text} -> {itemName} (claimed {snapshot.ClaimedOwner.Name}; source {source}; {snapshot.AlertReason})";
AddToFeed(AlertFeed, transportSender?.PlatformId ?? 0, text2);
RefreshAlertPage();
MelonLogger.Warning(text2);
}
private static void AddToFeed(List<FeedItem> feed, ulong platformId, string text)
{
feed.Insert(0, new FeedItem
{
PlatformId = platformId,
Text = text
});
Trim<FeedItem>(feed);
}
private static PlayerHistory GetOrCreateHistory(Identity identity)
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
ulong num = ((identity.PlatformId != 0L) ? identity.PlatformId : (18446744073709551615uL - (ulong)identity.SmallId));
PlayerHistory playerHistory = default(PlayerHistory);
if (!PlayerHistories.TryGetValue(num, ref playerHistory))
{
playerHistory = new PlayerHistory();
PlayerHistories.Add(num, playerHistory);
}
if (playerHistory.Page == null && _playersPage != null)
{
playerHistory.Page = _playersPage.CreatePage(identity.Name, Color.white, 0, true);
}
if (playerHistory.Page != null)
{
playerHistory.Page.Name = identity.Name;
}
return playerHistory;
}
private static void RefreshHistory(PlayerHistory history)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
RenderEntries(history.Page, history.Entries, "No spawns logged yet", Color.white);
}
private static void ClearLogs()
{
//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)
SpawnFeed.Clear();
AlertFeed.Clear();
Enumerator<ulong, PlayerHistory> enumerator = PlayerHistories.Values.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
PlayerHistory current = enumerator.Current;
current.Entries.Clear();
RefreshHistory(current);
}
}
finally
{
((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
}
RefreshMainPages();
}
private static void RefreshMainPages()
{
RefreshSpawnPage();
RefreshAlertPage();
}
private static void RefreshSpawnPage()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
RenderFeed(_spawnPage, SpawnFeed, "No spawns logged yet", Color.white);
}
private static void RefreshAlertPage()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
RenderFeed(_alertPage, AlertFeed, "No suspicious spawns detected", Color.red);
}
private static void RenderFeed(Page page, List<FeedItem> feed, string emptyText, Color color)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: 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_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: 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_008a: Expected O, but got Unknown
if (page == null)
{
return;
}
page.RemoveAll();
if (feed.Count == 0)
{
Color gray = Color.gray;
object obj = <>c.<>9__49_0;
if (obj == null)
{
Action val = delegate
{
};
<>c.<>9__49_0 = val;
obj = (object)val;
}
page.CreateFunction(emptyText, gray, (Action)obj);
return;
}
Enumerator<FeedItem> enumerator = feed.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
FeedItem current = enumerator.Current;
string text = current.Text;
object obj2 = <>c.<>9__49_1;
if (obj2 == null)
{
Action val2 = delegate
{
};
<>c.<>9__49_1 = val2;
obj2 = (object)val2;
}
page.CreateFunction(text, color, (Action)obj2);
}
}
finally
{
((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
}
}
private static void RenderEntries(Page page, List<string> entries, string emptyText, Color color)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: 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_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
if (page == null)
{
return;
}
page.RemoveAll();
if (entries.Count == 0)
{
Color gray = Color.gray;
object obj = <>c.<>9__50_0;
if (obj == null)
{
Action val = delegate
{
};
<>c.<>9__50_0 = val;
obj = (object)val;
}
page.CreateFunction(emptyText, gray, (Action)obj);
return;
}
Enumerator<string> enumerator = entries.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
string current = enumerator.Current;
object obj2 = <>c.<>9__50_1;
if (obj2 == null)
{
Action val2 = delegate
{
};
<>c.<>9__50_1 = val2;
obj2 = (object)val2;
}
page.CreateFunction(current, color, (Action)obj2);
}
}
finally
{
((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
}
}
private static void InsertNewest<T>(List<T> entries, T item)
{
entries.Insert(0, item);
Trim<T>(entries);
}
private static void Trim<T>(List<T> entries)
{
if (entries.Count > 30)
{
entries.RemoveRange(30, entries.Count - 30);
}
}
}
[HarmonyPatch(typeof(SpawnResponseMessage), "OnHandleMessage")]
internal static class SpawnResponseReceivedPatch
{
private static void Prefix(ReceivedMessage received)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
try
{
SpawnLoggerMod.CaptureResponse(((ReceivedMessage)(ref received)).ReadData<SpawnResponseData>(), received);
}
catch (System.Exception ex)
{
MelonLogger.Warning("Spawn Logger could not inspect a response: " + ex.Message);
}
}
}
[HarmonyPatch(typeof(SpawnResponseMessage), "OnSpawnFinished")]
internal static class SpawnFinishedPatch
{
private static void Postfix(SpawnResponseData data, Poolee poolee)
{
try
{
SpawnLoggerMod.CompleteSpawn(data, poolee);
}
catch (System.Exception ex)
{
MelonLogger.Error($"Spawn Logger failed to inspect a spawn: {ex}");
}
}
}
}