using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using ChuxiaDebug;
using GameNetcodeStuff;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ChuxiaDebug")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ChuxiaDebug")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("60d2b7e4-0b76-440e-98cb-261563a44ec3")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("ChuxiaDebug", "chuxia.ChuxiaDebug", "1.0.6")]
public class ChuxiaDebugPlugin : BaseUnityPlugin
{
public static ConfigEntry<bool> EnableColor;
public static ConfigEntry<string> OpenTabs;
public void Awake()
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
EnableColor = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableColor", false, "Enable color.");
OpenTabs = ((BaseUnityPlugin)this).Config.Bind<string>("General", "OpenTabs", "", "");
Harmony val = new Harmony("chuxia.ChuxiaDebug");
val.PatchAll(typeof(Patches));
}
}
public static class Patches
{
private static GameObject ChuxiaDebugMono { get; set; }
[HarmonyPostfix]
[HarmonyPatch(typeof(MenuManager), "Awake")]
public static void ConnectClientToPlayerObjectPostfix(PlayerControllerB __instance)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
if ((Object)(object)ChuxiaDebugMono == (Object)null)
{
ChuxiaDebugMono = new GameObject("ChuxiaDebugMono");
ChuxiaDebugMono chuxiaDebugMono = ChuxiaDebugMono.AddComponent<ChuxiaDebugMono>();
Object.DontDestroyOnLoad((Object)(object)ChuxiaDebugMono);
}
}
}
namespace ChuxiaDebug;
internal class ChuxiaDebugMono : MonoBehaviour
{
private class DebugTab
{
public string Name;
public Action DrawAction;
public bool IsClosable;
public DebugTab(string name, Action drawAction, bool isClosable = true)
{
Name = name;
DrawAction = drawAction;
IsClosable = isClosable;
}
}
private enum MemberType
{
Field,
Property,
Method
}
private class MemberAccessor
{
public string Name;
public MemberType Type;
public Func<object, object> Getter;
public Action<object> MethodInvoker;
public MethodInfo MethodInfo;
public string TypeName { get; set; }
public string TypeNamespace { get; set; }
public string DeclaringName { get; set; }
}
private List<DebugTab> openedTabs = new List<DebugTab>();
private int selectedTabIndex = -1;
public static ChuxiaDebugMono Instance;
private Dictionary<string, Action> tabFuncs = new Dictionary<string, Action>();
private float lastFieldUpdateTime = 0f;
private bool realtimeUpdate = true;
private List<(MemberAccessor accessor, object value)> cachedFieldValues = new List<(MemberAccessor, object)>();
private string searchFieldText = "";
private Stack<object> objectStack = new Stack<object>();
private Vector2 scrollPosition = Vector2.zero;
private Dictionary<Type, Object> cachedObjects = new Dictionary<Type, Object>();
private List<Type> allTypes;
private string searchInput = "";
private List<Type> searchResults = new List<Type>();
private Vector2 searchScroll;
private Vector2 tabScrollPos = Vector2.zero;
private object pendingPushObject = null;
private string pendingCollectionBackLabel = "";
private static Dictionary<Type, List<MemberAccessor>> memberCache = new Dictionary<Type, List<MemberAccessor>>();
private static bool Gui { get; set; }
private void AddTab(string tabName)
{
if (!openedTabs.Any((DebugTab t) => t.Name == tabName) && tabFuncs.TryGetValue(tabName, out var value))
{
openedTabs.Add(new DebugTab(tabName, value));
selectedTabIndex = openedTabs.Count - 1;
}
}
public void SetCurrentObject(object obj)
{
objectStack.Clear();
if (obj != null)
{
objectStack.Push(obj);
}
}
private Object GetCachedObject(Type type)
{
if (!cachedObjects.TryGetValue(type, out var value) || value == (Object)null)
{
value = Object.FindAnyObjectByType(type);
cachedObjects[type] = value;
}
return value;
}
private T GetCachedObject<T>() where T : Object
{
Type typeFromHandle = typeof(T);
if (!cachedObjects.TryGetValue(typeFromHandle, out var value) || value == (Object)null)
{
value = (Object)(object)Object.FindAnyObjectByType<T>();
cachedObjects[typeFromHandle] = value;
}
return (T)(object)value;
}
private void Awake()
{
allTypes = (from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly assembly)
{
try
{
return assembly.GetTypes();
}
catch
{
return Array.Empty<Type>();
}
})
where t.IsClass && !t.IsAbstract && typeof(Object).IsAssignableFrom(t)
select t).ToList();
tabFuncs = new Dictionary<string, Action>();
tabFuncs["RoundManager"] = delegate
{
DrawSingleObjectTab(RoundManager.Instance);
};
tabFuncs["GameNetworkManager"] = delegate
{
DrawSingleObjectTab(GameNetworkManager.Instance);
};
tabFuncs["HUDManager"] = delegate
{
DrawSingleObjectTab(HUDManager.Instance);
};
tabFuncs["ShipBuildModeManager"] = delegate
{
DrawSingleObjectTab(ShipBuildModeManager.Instance);
};
tabFuncs["SoundManager"] = delegate
{
DrawSingleObjectTab(SoundManager.Instance);
};
tabFuncs["MenuManager"] = delegate
{
DrawSingleObjectTab(GetCachedObject<MenuManager>());
};
tabFuncs["QuickMenuManager"] = delegate
{
DrawSingleObjectTab(GetCachedObject<QuickMenuManager>());
};
tabFuncs["StartOfRound"] = delegate
{
DrawSingleObjectTab(StartOfRound.Instance);
};
tabFuncs["TimeOfDay"] = delegate
{
DrawSingleObjectTab(TimeOfDay.Instance);
};
tabFuncs["StartMatchLever"] = delegate
{
DrawSingleObjectTab(GetCachedObject<StartMatchLever>());
};
tabFuncs["Terminal"] = delegate
{
DrawSingleObjectTab(GetCachedObject<Terminal>());
};
tabFuncs["MapScreen"] = delegate
{
DrawSingleObjectTab(StartOfRound.Instance?.mapScreen);
};
openedTabs.Add(new DebugTab("Default", DrawDefaultTab, isClosable: false));
openedTabs.Add(new DebugTab("Search", DrawSearchTab, isClosable: false));
string[] array = ChuxiaDebugPlugin.OpenTabs?.Value?.Split(new char[1] { ',' });
if (array != null)
{
string[] array2 = array;
foreach (string tabName in array2)
{
if (tabFuncs.TryGetValue(tabName, out var value))
{
openedTabs.Add(new DebugTab(tabName, value));
continue;
}
Type type = allTypes.FirstOrDefault((Type t) => t.Name == tabName);
if (!(type != null))
{
continue;
}
Object instance = GetCachedObject(type);
if (instance != (Object)null)
{
openedTabs.Add(new DebugTab(tabName, delegate
{
DrawSingleObjectTab(instance);
}));
}
}
}
selectedTabIndex = 0;
Instance = this;
}
private void UpdateSavedOpenTabs()
{
IEnumerable<string> values = from t in openedTabs
where t.IsClosable
select t.Name;
ChuxiaDebugPlugin.OpenTabs.Value = string.Join(",", values);
}
private void DrawDefaultTab()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
ChuxiaDebugPlugin.EnableColor.Value = GUILayout.Toggle(ChuxiaDebugPlugin.EnableColor.Value, "EnableColor", Array.Empty<GUILayoutOption>());
scrollPosition = GUILayout.BeginScrollView(scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(500f) });
foreach (KeyValuePair<string, Action> kvp in tabFuncs)
{
if (!openedTabs.Any((DebugTab t) => t.Name == kvp.Key) && GUILayout.Button(kvp.Key ?? "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
{
openedTabs.Add(new DebugTab(kvp.Key, kvp.Value));
selectedTabIndex = openedTabs.Count - 1;
UpdateSavedOpenTabs();
break;
}
}
GUILayout.EndScrollView();
}
private void DrawSearchTab()
{
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
GUILayout.Label("Search Type:", Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
searchInput = GUILayout.TextField(searchInput, Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Search", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
{
if (!string.IsNullOrWhiteSpace(searchInput))
{
string lowerInput = searchInput.ToLowerInvariant();
searchResults = (from t in allTypes
where t.Name.ToLowerInvariant().Contains(lowerInput)
orderby t.Name
select t).ToList();
}
else
{
searchResults.Clear();
}
}
GUILayout.EndHorizontal();
if (searchResults.Count == 0)
{
return;
}
searchScroll = GUILayout.BeginScrollView(searchScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(500f) });
foreach (Type searchResult in searchResults)
{
Object[] array = Object.FindObjectsByType(searchResult, (FindObjectsSortMode)1);
foreach (Object item in array)
{
if (GUILayout.Button(searchResult.Name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) }))
{
openedTabs.Add(new DebugTab(searchResult.Name, delegate
{
DrawSingleObjectTab(item);
}));
selectedTabIndex = openedTabs.Count - 1;
UpdateSavedOpenTabs();
}
}
}
GUILayout.EndScrollView();
}
public static void String(string text, GUIStyle style, float yPos)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Expected O, but got Unknown
//IL_000f: 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_0016: 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_002c: 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)
float num = Screen.width;
Vector2 val = style.CalcSize(new GUIContent(text));
float num2 = (num - val.x) / 2f;
GUI.Label(new Rect(num2, yPos, val.x, val.y), text, style);
}
public void Update()
{
if (UnityInput.Current.GetKeyDown((KeyCode)291))
{
Gui = !Gui;
if (Cursor.visible && !Gui)
{
Cursor.visible = false;
Cursor.lockState = (CursorLockMode)1;
}
}
if (!Cursor.visible && Gui)
{
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
}
}
public void OnGUI()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: 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_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: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
Scene activeScene = SceneManager.GetActiveScene();
Color backgroundColor = default(Color);
((Color)(ref backgroundColor))..ctor(0.09019608f, 0.09019608f, 0.09019608f, 1f);
GUI.backgroundColor = backgroundColor;
GUI.contentColor = Color.white;
GUIStyle val = new GUIStyle(GUI.skin.label);
val.normal.textColor = Color.white;
val.fontStyle = (FontStyle)1;
GUIStyle style = val;
if (!Gui)
{
String("ChuxiaDebug Press F10", style, 10f);
}
else
{
ShowMenu();
}
}
private void DrawDebugWindow(int windowId)
{
//IL_0010: 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_0071: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
try
{
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
try
{
tabScrollPos = GUILayout.BeginScrollView(tabScrollPos, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(40f),
GUILayout.ExpandWidth(true)
});
try
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
try
{
for (int i = 0; i < openedTabs.Count; i++)
{
DebugTab debugTab = openedTabs[i];
GUI.backgroundColor = ((i == selectedTabIndex) ? Color.green : Color.white);
if (GUILayout.Button(debugTab.Name, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Width(150f),
GUILayout.Height(30f)
}))
{
selectedTabIndex = i;
scrollPosition = Vector2.zero;
searchFieldText = "";
objectStack.Clear();
cachedFieldValues.Clear();
}
GUI.backgroundColor = Color.white;
if (debugTab.IsClosable && GUILayout.Button("x", (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Width(20f),
GUILayout.Height(30f)
}))
{
openedTabs.RemoveAt(i);
if (selectedTabIndex >= i)
{
selectedTabIndex = Mathf.Max(0, selectedTabIndex - 1);
}
UpdateSavedOpenTabs();
break;
}
}
}
finally
{
GUILayout.EndHorizontal();
}
}
finally
{
GUILayout.EndScrollView();
}
GUILayout.Space(10f);
if (selectedTabIndex >= 0 && selectedTabIndex < openedTabs.Count)
{
openedTabs[selectedTabIndex].DrawAction?.Invoke();
}
}
finally
{
GUILayout.EndVertical();
}
GUI.DragWindow();
}
catch (Exception arg)
{
Debug.LogError((object)$"ChuxiaDebug: Error in DrawDebugWindow. GUI may be broken.\n{arg}");
}
}
public void ShowMenu()
{
//IL_0025: 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_0040: Expected O, but got Unknown
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
float num = (float)(Screen.width - 1500) / 2f;
GUI.Window(0, new Rect(num, 10f, 1500f, 600f), new WindowFunction(DrawDebugWindow), "ChuxiaDebug");
}
public void DrawSingleObjectTab(object obj)
{
//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)
if (obj != null)
{
if (objectStack.Count == 0)
{
objectStack.Push(obj);
scrollPosition = Vector2.zero;
searchFieldText = "";
}
DrawObjectFields();
}
}
private void PushOrExpandObject(object obj, string fallbackLabel = "Back")
{
//IL_009f: 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_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)
if (obj is IEnumerable source && !(obj is string))
{
Debug.Log((object)203);
List<object> item = source.Cast<object>().ToList();
objectStack.Clear();
cachedFieldValues.Clear();
objectStack.Push(item);
pendingCollectionBackLabel = fallbackLabel;
scrollPosition = Vector2.zero;
searchFieldText = "";
}
else
{
Debug.Log((object)218);
objectStack.Push(obj);
scrollPosition = Vector2.zero;
searchFieldText = "";
}
}
public void DrawObjectListTab<T>(IEnumerable<T> items, Func<T, string> getName, string backButtonLabel)
{
//IL_0019: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: 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_0097: Unknown result type (might be due to invalid IL or missing references)
if (objectStack.Count == 0)
{
scrollPosition = GUILayout.BeginScrollView(scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(500f) });
foreach (T item in items)
{
string text = getName(item);
if (GUILayout.Button(text, Array.Empty<GUILayoutOption>()))
{
objectStack.Clear();
cachedFieldValues.Clear();
objectStack.Push(item);
scrollPosition = Vector2.zero;
searchFieldText = "";
}
}
GUILayout.EndScrollView();
}
else if (GUILayout.Button("← " + backButtonLabel, Array.Empty<GUILayoutOption>()))
{
objectStack.Clear();
cachedFieldValues.Clear();
scrollPosition = Vector2.zero;
searchFieldText = "";
}
else
{
DrawObjectFields();
}
}
public void PlayerTab()
{
DrawObjectListTab(StartOfRound.Instance.allPlayerScripts, (PlayerControllerB player) => player.playerUsername, "Back To allPlayerScripts");
}
public void ItemListTab()
{
DrawObjectListTab(StartOfRound.Instance.allItemsList.itemsList, (Item item) => item.itemName, "Back To ItemList");
}
private string ObjectToName(object obj)
{
if (obj == null && ChuxiaDebugPlugin.EnableColor.Value)
{
return "<color=grey>null</color>";
}
if (obj == null)
{
return "null";
}
if (obj is IList list && list != null)
{
return $"[{list.Count}] ";
}
if (obj is ICollection collection && collection != null)
{
return $"[{collection.Count}] ";
}
if (obj is IDictionary dictionary && dictionary != null)
{
return $"[{dictionary.Count}] ";
}
PlayerControllerB val = (PlayerControllerB)((obj is PlayerControllerB) ? obj : null);
if (val != null)
{
return $"{val.playerUsername}({val.playerClientId})";
}
UnlockableItem val2 = (UnlockableItem)((obj is UnlockableItem) ? obj : null);
if (val2 != null)
{
return val2.unlockableName ?? "";
}
GrabbableObject val3 = (GrabbableObject)((obj is GrabbableObject) ? obj : null);
if (val3 != null)
{
return val3?.itemProperties.itemName ?? "";
}
WeatherEffect val4 = (WeatherEffect)((obj is WeatherEffect) ? obj : null);
if (val4 != null)
{
return val4.name ?? "";
}
TextMeshProUGUI val5 = (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null);
if (val5 != null)
{
return ((val5 != null) ? ((TMP_Text)val5).text : null) ?? "null";
}
Slider val6 = (Slider)((obj is Slider) ? obj : null);
if (val6 != null)
{
return $"{((val6 != null) ? new float?(val6.value) : null):F2}";
}
GameObject val7 = (GameObject)((obj is GameObject) ? obj : null);
if (val7 != null)
{
return "\"" + ((val7 != null) ? ((Object)val7).name : null) + "\" ";
}
if (obj is string && ChuxiaDebugPlugin.EnableColor.Value)
{
return $"<color=#C57160>\"{obj}\"</color>";
}
if (obj is string)
{
return $"\"{obj}\"";
}
if ((obj is bool || obj is bool) && ChuxiaDebugPlugin.EnableColor.Value)
{
return $"<color=#3599D0>{obj}</color>";
}
if (obj is bool || obj is bool)
{
return $"{obj}";
}
Object val8 = (Object)((obj is Object) ? obj : null);
if (val8 != null)
{
if (val8 == (Object)null)
{
return "null";
}
return "\"" + ((val8 != null) ? val8.name : null) + "\"";
}
return obj?.ToString() ?? "null";
}
private void DrawObjectFields()
{
//IL_0466: 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_0475: Expected O, but got Unknown
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Unknown result type (might be due to invalid IL or missing references)
//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
if (objectStack.Count == 0 || objectStack.Peek() == null)
{
return;
}
object obj = objectStack.Peek();
Object val = (Object)((obj is Object) ? obj : null);
if (val != null && val == (Object)null)
{
objectStack.Pop();
objectStack.Push(null);
return;
}
if (obj is IList items && !(obj is string))
{
DrawObjectListTab(items, (object o) => ObjectToName(o) ?? "null", pendingCollectionBackLabel);
return;
}
Type type = obj.GetType();
List<MemberAccessor> memberAccessors = GetMemberAccessors(type);
if ((realtimeUpdate && Time.unscaledTime - lastFieldUpdateTime > 0.1f) || cachedFieldValues.Count == 0)
{
cachedFieldValues.Clear();
foreach (MemberAccessor item in memberAccessors)
{
object obj2 = null;
try
{
obj2 = ((item.Type == MemberType.Method) ? "<Func>" : item.Getter(obj));
Transform val2 = (Transform)((obj2 is Transform) ? obj2 : null);
if (val2 != null)
{
obj2 = $"({val2.position.x:F2}, {val2.position.y:F2}, {val2.position.z:F2})";
}
}
catch
{
obj2 = "<Fail>";
}
cachedFieldValues.Add((item, obj2));
}
lastFieldUpdateTime = Time.unscaledTime;
}
GUILayout.Space(10f);
if (objectStack.Count > 1 && GUILayout.Button("← Back", Array.Empty<GUILayoutOption>()))
{
objectStack.Pop();
scrollPosition = Vector2.zero;
searchFieldText = "";
return;
}
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label(ObjectToName(obj) ?? "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
realtimeUpdate = GUILayout.Toggle(realtimeUpdate, "Auto-Update", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
GUILayout.EndHorizontal();
GUILayout.Space(5f);
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label("Search: ", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) });
string text = GUILayout.TextField(searchFieldText, Array.Empty<GUILayoutOption>());
GUILayout.EndHorizontal();
if (text != searchFieldText)
{
searchFieldText = text;
}
List<(MemberAccessor, object)> list = cachedFieldValues.Where(((MemberAccessor accessor, object value) kv) => string.IsNullOrEmpty(searchFieldText) || kv.accessor.Name.IndexOf(searchFieldText, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
int count = list.Count;
int num = Mathf.CeilToInt(16.666666f);
int num2 = Mathf.Clamp(Mathf.FloorToInt(scrollPosition.y / 30f), 0, Math.Max(0, count - 1));
int num3 = Mathf.Clamp(num2 + num + 2, 0, count);
scrollPosition.y = Mathf.Clamp(scrollPosition.y, 0f, Mathf.Max(0f, (float)count * 30f - 500f));
scrollPosition = GUILayout.BeginScrollView(scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(500f) });
GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
if (count == 0)
{
GUILayout.Label("No Fields", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
}
else
{
GUILayout.Space((float)num2 * 30f);
for (int i = num2; i < num3; i++)
{
var (memberAccessor, obj4) = list[i];
GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
GUIStyle val3 = new GUIStyle(GUI.skin.label)
{
wordWrap = false
};
if (ChuxiaDebugPlugin.EnableColor.Value)
{
string text2 = "";
switch (memberAccessor.Type)
{
case MemberType.Field:
text2 = "#3C8372";
break;
case MemberType.Property:
text2 = "#673688";
break;
case MemberType.Method:
text2 = "#884404";
break;
}
val3.richText = true;
string text3 = "<color=#27C890>" + memberAccessor.DeclaringName + "<color=white>.</color></color><color=" + text2 + ">" + memberAccessor.Name + "</color>";
GUILayout.Label(text3, val3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) });
}
else
{
GUILayout.Label(memberAccessor.DeclaringName + "." + memberAccessor.Name, val3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) });
}
string text4 = ObjectToName(obj4) ?? "NULL";
text4 = ((!ChuxiaDebugPlugin.EnableColor.Value) ? (text4 + " (" + memberAccessor.TypeNamespace + "." + memberAccessor.TypeName + ")") : (text4 + " (<color=grey>" + memberAccessor.TypeNamespace + "</color>.<color=#179932>" + memberAccessor.TypeName + "</color>)"));
GUILayout.Label(text4.Replace("\n", "\\n"), val3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
if (memberAccessor.Type != MemberType.Method && GUILayout.Button("Copy", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
GUIUtility.systemCopyBuffer = obj4?.ToString() ?? "";
}
if (memberAccessor.Type == MemberType.Method)
{
if (GUILayout.Button("Invoke", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
try
{
memberAccessor.MethodInvoker?.Invoke(obj);
Debug.Log((object)("调用方法成功: " + memberAccessor.Name));
}
catch (Exception arg)
{
Debug.LogError((object)$"调用方法失败: {memberAccessor.Name}, 异常: {arg}");
}
}
GUILayout.Space(60f);
}
else if (obj4 != null && obj4 != obj)
{
if (GUILayout.Button("Inject", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
pendingPushObject = obj4;
pendingCollectionBackLabel = "Back To " + ObjectToName(obj);
}
}
else
{
GUILayout.Space(60f);
}
GUILayout.EndHorizontal();
}
float num4 = Mathf.Max(0f, (float)(count - num3) * 30f);
GUILayout.Space(Mathf.Max(0f, num4));
}
GUILayout.EndVertical();
GUILayout.EndScrollView();
if (pendingPushObject != null)
{
PushOrExpandObject(pendingPushObject, pendingCollectionBackLabel);
pendingPushObject = null;
}
}
public void DrawObjectListTab(IList items, Func<object, string> getName, string backButtonLabel)
{
//IL_007f: 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_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_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
if (objectStack.Count == 0 || !(objectStack.Peek() is IList))
{
return;
}
if (GUILayout.Button("← " + backButtonLabel, Array.Empty<GUILayoutOption>()))
{
objectStack.Clear();
cachedFieldValues.Clear();
scrollPosition = Vector2.zero;
searchFieldText = "";
return;
}
scrollPosition = GUILayout.BeginScrollView(scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(500f) });
for (int i = 0; i < items.Count; i++)
{
object obj = items[i];
string text = $"[{i}] {getName(obj)}";
if (GUILayout.Button(text, Array.Empty<GUILayoutOption>()))
{
objectStack.Push(obj);
cachedFieldValues.Clear();
scrollPosition = Vector2.zero;
searchFieldText = "";
break;
}
}
GUILayout.EndScrollView();
}
private List<MemberAccessor> GetMemberAccessors(Type type)
{
if (memberCache.TryGetValue(type, out var value))
{
return value;
}
List<MemberAccessor> list = new List<MemberAccessor>();
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo[] fields = type.GetFields(bindingAttr);
foreach (FieldInfo fieldInfo in fields)
{
Func<object, object> getter = CreateGetter(fieldInfo);
list.Add(new MemberAccessor
{
Name = fieldInfo.Name,
Type = MemberType.Field,
TypeNamespace = fieldInfo.FieldType.Namespace,
TypeName = fieldInfo.FieldType.Name,
DeclaringName = fieldInfo.DeclaringType.Name,
Getter = getter,
MethodInvoker = null
});
}
PropertyInfo[] properties = type.GetProperties(bindingAttr);
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.CanRead && propertyInfo.GetIndexParameters().Length == 0)
{
Func<object, object> getter2 = CreateGetter(propertyInfo);
list.Add(new MemberAccessor
{
Name = propertyInfo.Name,
Type = MemberType.Property,
TypeNamespace = propertyInfo.DeclaringType.Namespace,
TypeName = propertyInfo.DeclaringType.Name,
DeclaringName = propertyInfo.DeclaringType.Name,
Getter = getter2,
MethodInvoker = null
});
}
}
memberCache[type] = list;
return list;
}
private Func<object, object> CreateGetter(FieldInfo field)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance");
MemberExpression expression = Expression.Field(Expression.Convert(parameterExpression, field.DeclaringType), field);
UnaryExpression body = Expression.Convert(expression, typeof(object));
return Expression.Lambda<Func<object, object>>(body, new ParameterExpression[1] { parameterExpression }).Compile();
}
private Func<object, object> CreateGetter(PropertyInfo prop)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance");
MemberExpression expression = Expression.Property(Expression.Convert(parameterExpression, prop.DeclaringType), prop);
UnaryExpression body = Expression.Convert(expression, typeof(object));
return Expression.Lambda<Func<object, object>>(body, new ParameterExpression[1] { parameterExpression }).Compile();
}
private Action<object> CreateMethodInvoker(MethodInfo method)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance");
MethodCallExpression body = Expression.Call(Expression.Convert(parameterExpression, method.DeclaringType), method);
return Expression.Lambda<Action<object>>(body, new ParameterExpression[1] { parameterExpression }).Compile();
}
}