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 SlipStream v1.0.15
SlipStream.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SlipStream")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("SlipStream")] [assembly: AssemblyFileVersion("1.0.15.0")] [assembly: AssemblyInformationalVersion("1.0.15+93e4786fd6da7213e58c36dcb338f01050b95c14")] [assembly: AssemblyProduct("SlipStream")] [assembly: AssemblyTitle("SlipStream")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.15.0")] [module: UnverifiableCode] [module: UnverifiableCode] namespace Slipstream; internal static class CoOp { private static bool _registered; private static object _console; private static MethodInfo _submit; private static readonly List<string> _pending = new List<string>(); public static void Register() { if (_registered) { if (_pending.Count > 0) { FlushPending(); } return; } Type type = Hook.Type("RoR2.Console"); if (type == null) { return; } _console = Hook.Get(Hook.Member(type, "instance", "_instance"), null); if (_console == null) { return; } _submit = Hook.Method(type, "SubmitCmd"); Type type2 = Hook.Type("RoR2.ConVarFlags") ?? type.GetNestedType("ConVarFlags", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); object flags = 1; if (type2 != null && type2.IsEnum) { try { flags = Enum.Parse(type2, "ExecuteOnServer"); } catch { flags = Enum.ToObject(type2, 1); } } bool num = AddCommand(type, "slipstream_t", flags, new Action<object>(OnToggle)) & AddCommand(type, "slipstream_item", flags, new Action<object>(OnItem)) & AddCommand(type, "slipstream_giveall", flags, new Action<object>(OnGiveAll)) & AddCommand(type, "slipstream_clear", flags, new Action<object>(OnClear)) & AddCommand(type, "slipstream_equip", flags, new Action<object>(OnEquip)) & AddCommand(type, "slipstream_money", flags, new Action<object>(OnMoney)) & AddCommand(type, "slipstream_void", flags, new Action<object>(OnVoid)) & AddCommand(type, "slipstream_lunar", flags, new Action<object>(OnLunar)) & AddCommand(type, "slipstream_revive", flags, new Action<object>(OnRevive)) & AddCommand(type, "slipstream_spawnas", flags, new Action<object>(OnSpawnAs)) & AddCommand(type, "slipstream_team", flags, new Action<object>(OnTeam)) & AddCommand(type, "slipstream_skin", flags, new Action<object>(OnSkin)); AddCommand(type, "slipstream_buff", flags, new Action<object>(OnBuff)); _registered = num; if (num) { Log.Info("Co-op host commands ready."); FlushPending(); ReplayLocalToggles(); } else { Log.Warn("Could not register co-op host commands. Clients cannot gift items or god themselves until the host has SlipStream and this registers."); } } public static void Submit(string command) { if (!string.IsNullOrEmpty(command)) { Register(); if (_submit == null || _console == null || !_registered) { _pending.Add(command); } else { Send(command); } } } public static bool AskHost(string command) { if (Game.IsServer) { return false; } Submit(command); return true; } private static void Send(string command) { object obj = Game.LocalActor()?.NetworkUser ?? Game.FirstLocalNetworkUser(); if (obj == null) { _pending.Add(command); return; } try { ParameterInfo[] parameters = _submit.GetParameters(); if (parameters.Length == 2) { _submit.Invoke(_console, new object[2] { obj, command }); } else if (parameters.Length >= 3) { _submit.Invoke(_console, new object[3] { obj, command, false }); } else { MethodInfo submit = _submit; object console = _console; object[] parameters2 = new string[1] { command }; submit.Invoke(console, parameters2); } } catch (Exception ex) { Log.Warn("Host command failed: " + ex.Message); _pending.Add(command); } } private static void FlushPending() { if (_pending.Count != 0) { string[] array = _pending.ToArray(); _pending.Clear(); string[] array2 = array; for (int i = 0; i < array2.Length; i++) { Send(array2[i]); } } } private static void ReplayLocalToggles() { if (!Game.IsServer && Session.LocalMods.Any) { Actor actor = Game.LocalActor(); if (actor != null) { Game.PushLocalToggles(actor); } } } private static bool AddCommand(Type consoleType, string name, object flags, Delegate raw) { IDictionary dictionary = Hook.Field(consoleType, "concommandCatalog", "_concommandCatalog")?.GetValue(_console) as IDictionary; Type type = ((dictionary != null) ? Nested(consoleType, "ConCommand") : null); Type type2 = Nested(consoleType, "ConCommandDelegate"); if (dictionary == null || type == null || type2 == null) { return TryRegisterMethod(consoleType, name, flags, raw); } try { Delegate obj = BindHandler(type2, raw.Method); if ((object)obj == null) { return TryRegisterMethod(consoleType, name, flags, raw); } object obj2; try { obj2 = Activator.CreateInstance(type); } catch { obj2 = Activator.CreateInstance(type, nonPublic: true); } FieldInfo fieldInfo = Hook.Field(type, "flags"); FieldInfo fieldInfo2 = Hook.Field(type, "action", "fn", "callback"); FieldInfo fieldInfo3 = Hook.Field(type, "helpText", "help"); if (fieldInfo != null) { fieldInfo.SetValue(obj2, Hook.Coerce(flags, fieldInfo.FieldType)); } if (fieldInfo2 != null) { fieldInfo2.SetValue(obj2, obj); } if (fieldInfo3 != null && fieldInfo3.FieldType == typeof(string)) { fieldInfo3.SetValue(obj2, ""); } dictionary[name] = obj2; return true; } catch (Exception ex) { Log.Warn("Could not add " + name + ": " + ex.Message); return TryRegisterMethod(consoleType, name, flags, raw); } } private static bool TryRegisterMethod(Type consoleType, string name, object flags, Delegate raw) { MethodInfo[] methods = consoleType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name.IndexOf("RegisterConCommand", StringComparison.OrdinalIgnoreCase) < 0) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); try { if (parameters.Length == 4) { Delegate obj = BindHandler(parameters[3].ParameterType, raw.Method); if ((object)obj != null) { methodInfo.Invoke(_console, new object[4] { name, flags, "", obj }); return true; } } } catch { } } return false; } private static Delegate BindHandler(Type delType, MethodInfo handler) { if (delType == null || handler == null) { return null; } ParameterInfo[] array = delType.GetMethod("Invoke")?.GetParameters(); if (array == null || array.Length != 1) { return null; } try { ParameterExpression parameterExpression = Expression.Parameter(array[0].ParameterType, "args"); MethodCallExpression body = Expression.Call(handler, Expression.Convert(parameterExpression, typeof(object))); return Expression.Lambda(delType, body, parameterExpression).Compile(); } catch { return null; } } private static Type Nested(Type type, string name) { Type type2 = type; while (type2 != null) { Type nestedType = type2.GetNestedType(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (nestedType != null) { return nestedType; } type2 = type2.BaseType; } return Hook.Type(type.FullName + "+" + name); } private static Actor Sender(object args) { if (args == null) { return null; } object obj = Hook.Get(Hook.Member(args.GetType(), "sender"), args); if (obj == null) { return null; } foreach (Actor item in Game.Players()) { if (item.NetworkUser != null && item.NetworkUser == obj) { return item; } } uint num = Game.NetIdOf(obj); Actor actor = ((num != 0) ? Game.FindByNetId(num) : null); if (actor != null) { return actor; } uint num2 = Game.NetIdOf(Hook.Get(Hook.Member(obj.GetType(), "masterObject", "master"), obj)); if (num2 == 0) { return null; } return Game.FindByNetId(num2); } private static string[] Tokens(object args) { if (args == null) { return Array.Empty<string>(); } Type type = args.GetType(); if (Hook.Get(Hook.Member(type, "userArgs", "args", "userTokenList"), args) is IList { Count: >0 } list) { string[] array = new string[list.Count]; for (int i = 0; i < list.Count; i++) { array[i] = list[i]?.ToString() ?? ""; } return array; } MethodInfo methodInfo = Hook.Method(type, "GetArgString") ?? Hook.Method(type, "GetArg"); MemberInfo memberInfo = Hook.Member(type, "Count", "count"); object obj = ((memberInfo != null) ? Hook.Get(memberInfo, args) : null); if (methodInfo != null && obj != null) { int num = Convert.ToInt32(obj); if (num > 0) { string[] array2 = new string[num]; for (int j = 0; j < num; j++) { try { array2[j] = methodInfo.Invoke(args, new object[1] { j })?.ToString() ?? ""; } catch { array2[j] = ""; } } return array2; } } MethodInfo method = type.GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(int) }, null); if (method != null && obj != null) { int num2 = Convert.ToInt32(obj); string[] array3 = new string[num2]; for (int k = 0; k < num2; k++) { try { array3[k] = method.Invoke(args, new object[1] { k })?.ToString() ?? ""; } catch { array3[k] = ""; } } return array3; } return Array.Empty<string>(); } private static uint UIntAt(string[] tokens, int i) { if (tokens == null || i < 0 || i >= tokens.Length) { return 0u; } uint.TryParse(tokens[i], out var result); return result; } private static int IntAt(string[] tokens, int i) { if (tokens == null || i < 0 || i >= tokens.Length) { return 0; } int.TryParse(tokens[i], out var result); return result; } private static void OnToggle(object args) { if (!Game.IsServer) { return; } string[] array = Tokens(args); if (array.Length < 2) { return; } uint num = UIntAt(array, 0); int num2 = IntAt(array, 1); if (num == 0) { return; } Actor actor = Game.FindByNetId(num); if (actor == null || actor.IsLocal) { return; } ActorMods actorMods = Session.RemoteModsFor(num); if (actorMods != null) { actorMods.God = (num2 & 1) != 0; actorMods.InfiniteSprint = (num2 & 2) != 0; actorMods.InfiniteSkills = (num2 & 4) != 0; actorMods.Noclip = (num2 & 8) != 0; Game.SetGod(actor, actorMods.God); if (!actorMods.Noclip) { Ticker.RestoreNoclip(actor); } } } private static void OnItem(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.GiveItemLocal(actor, IntAt(tokens, 1), IntAt(tokens, 2)); } } } private static void OnGiveAll(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.GiveAllItemsLocal(actor, IntAt(tokens, 1)); } } } private static void OnClear(object args) { if (Game.IsServer) { Actor actor = Game.FindByNetId(UIntAt(Tokens(args), 0)); if (actor != null) { Game.ClearInventoryLocal(actor); } } } private static void OnEquip(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.SetEquipmentLocal(actor, IntAt(tokens, 1)); } } } private static void OnMoney(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.SetMoney(actor, UIntAt(tokens, 1)); } } } private static void OnVoid(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.SetVoidCoins(actor, UIntAt(tokens, 1)); } } } private static void OnLunar(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.AwardLunar(actor, UIntAt(tokens, 1)); } } } private static void OnRevive(object args) { if (Game.IsServer) { Actor actor = Game.FindByNetId(UIntAt(Tokens(args), 0)); if (actor != null) { Game.Revive(actor); } } } private static void OnSpawnAs(object args) { if (Game.IsServer) { string[] array = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(array, 0)); string bodyName = ((array != null && array.Length > 1) ? array[1] : null); if (actor != null) { Game.SpawnAsNamed(actor, bodyName); } } } private static void OnTeam(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.ApplyTeamLocal(actor, IntAt(tokens, 1)); } } } private static void OnBuff(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.SetBuffLocal(actor, IntAt(tokens, 1), IntAt(tokens, 2)); } } } private static void OnSkin(object args) { if (Game.IsServer) { string[] tokens = Tokens(args); Actor actor = Game.FindByNetId(UIntAt(tokens, 0)); if (actor != null) { Game.ApplySkin(actor, IntAt(tokens, 1)); } } } } internal static class Esp { private struct Mark { public Vector3 World; public string Label; public Color Color; } private static readonly List<Mark> Marks = new List<Mark>(128); private static float _nextRefresh; private static GUIStyle _style; public static void Draw() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) if (!Session.EspAny || (Object)(object)Camera.main == (Object)null) { return; } if (Time.unscaledTime >= _nextRefresh) { Rebuild(); _nextRefresh = Time.unscaledTime + 0.35f; } if (_style == null) { _style = new GUIStyle(GUI.skin.label) { fontSize = 12, fontStyle = (FontStyle)1, alignment = (TextAnchor)4, richText = false }; _style.normal.textColor = Color.white; } Camera main = Camera.main; int height = Screen.height; int num = ((Marks.Count < 96) ? Marks.Count : 96); for (int i = 0; i < num; i++) { Mark mark = Marks[i]; Vector3 val = main.WorldToScreenPoint(mark.World); if (!(val.z <= 0f)) { float x = val.x; float num2 = (float)height - val.y; _style.normal.textColor = mark.Color; string label = mark.Label; Vector2 val2 = _style.CalcSize(new GUIContent(label)); GUI.Label(new Rect(x - val2.x * 0.5f, num2 - 8f, val2.x + 4f, val2.y), label, _style); } } } private static void Rebuild() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) Marks.Clear(); Actor actor = Game.LocalActor(); Vector3 origin = (((Object)(object)actor?.Transform != (Object)null) ? actor.Transform.position : Vector3.zero); if (Session.EspTeleporter) { AddTracked("RoR2.TeleporterInteraction", "TP", new Color(1f, 0.55f, 0.2f), origin, 280f); } if (Session.EspChests) { AddTracked("RoR2.ChestBehavior", "Chest", new Color(0.95f, 0.85f, 0.35f), origin, 280f); AddNamed("chest", "Chest", new Color(0.95f, 0.85f, 0.35f), origin, 280f); } if (Session.EspShops) { AddTracked("RoR2.ShopTerminalBehavior", "Shop", new Color(0.55f, 0.75f, 1f), origin, 280f); } if (Session.EspBarrels) { AddTracked("RoR2.BarrelInteraction", "Barrel", new Color(0.7f, 0.55f, 0.3f), origin, 280f); } if (Session.EspScrappers) { AddTracked("RoR2.ScrapperController", "Scrapper", new Color(0.4f, 0.9f, 0.55f), origin, 280f); } if (Session.EspSecrets) { AddTracked("RoR2.PressurePlateController", "Plate", new Color(0.85f, 0.4f, 0.9f), origin, 280f); AddNamed("pressureplate", "Secret", new Color(0.85f, 0.4f, 0.9f), origin, 280f); } if (Session.EspPrinters) { AddTracked("RoR2.PurchaseInteraction", "Printer", new Color(0.4f, 0.85f, 1f), origin, 280f, "duplicator", "printer"); AddNamed("duplicator", "Printer", new Color(0.4f, 0.85f, 1f), origin, 280f); } if (Session.EspNewt) { AddNamed("newt", "Newt", new Color(0.45f, 0.55f, 1f), origin, 280f); AddNamed("bazaar", "Newt", new Color(0.45f, 0.55f, 1f), origin, 280f); } if (Session.EspDrones) { AddTracked("RoR2.SummonMasterBehavior", "Drone", new Color(0.7f, 0.7f, 0.75f), origin, 280f); AddNamed("drone", "Drone", new Color(0.7f, 0.7f, 0.75f), origin, 280f); } if (Session.EspShrines) { AddNamed("shrine", "Shrine", new Color(0.95f, 0.45f, 0.45f), origin, 280f); AddTracked("RoR2.ShrineChanceBehavior", "Shrine", new Color(0.95f, 0.45f, 0.45f), origin, 280f); AddTracked("RoR2.ShrineBossBehavior", "Mountain", new Color(0.95f, 0.45f, 0.45f), origin, 280f); AddTracked("RoR2.ShrineBloodBehavior", "Blood", new Color(0.95f, 0.45f, 0.45f), origin, 280f); AddTracked("RoR2.ShrineCombatBehavior", "Combat", new Color(0.95f, 0.45f, 0.45f), origin, 280f); AddTracked("RoR2.ShrineRestackBehavior", "Order", new Color(0.95f, 0.45f, 0.45f), origin, 280f); AddTracked("RoR2.ShrineHealingBehavior", "Woods", new Color(0.95f, 0.45f, 0.45f), origin, 280f); } if (!Session.EspPlayers) { return; } foreach (Actor item in Game.Players()) { if (!((Object)(object)item.Transform == (Object)null)) { Add(item.Transform.position + Vector3.up * 2f, item.Name, new Color(0.45f, 1f, 0.55f), origin, 400f); } } } private static void AddTracked(string typeName, string label, Color color, Vector3 origin, float maxDist, params string[] nameContains) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) Type type = Hook.Type(typeName); IList list = Game.Tracked(type); if (list != null) { foreach (object item in list) { Transform val = Hook.TransformOf(item); if (!((Object)(object)val == (Object)null) && (nameContains == null || nameContains.Length == 0 || NameMatches(((Object)((Component)val).gameObject).name, nameContains))) { Add(val.position, LabelFor(((Object)((Component)val).gameObject).name, label), color, origin, maxDist); } } return; } if (type == null) { return; } Object[] array = Object.FindObjectsOfType(type); for (int i = 0; i < array.Length; i++) { Transform val2 = Hook.TransformOf(array[i]); if (!((Object)(object)val2 == (Object)null) && (nameContains == null || nameContains.Length == 0 || NameMatches(((Object)((Component)val2).gameObject).name, nameContains))) { Add(val2.position, LabelFor(((Object)((Component)val2).gameObject).name, label), color, origin, maxDist); } } } private static void AddNamed(string fragment, string label, Color color, Vector3 origin, float maxDist) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Type type = Hook.Type("RoR2.PurchaseInteraction") ?? Hook.Type("RoR2.GenericInteraction"); if (type == null) { return; } IEnumerable enumerable = Game.Tracked(type); if (enumerable == null) { enumerable = Object.FindObjectsOfType(type); } foreach (object item in enumerable) { Transform val = Hook.TransformOf(item); if (!((Object)(object)val == (Object)null) && ((Object)((Component)val).gameObject).name.IndexOf(fragment, StringComparison.OrdinalIgnoreCase) >= 0) { Add(val.position, LabelFor(((Object)((Component)val).gameObject).name, label), color, origin, maxDist); } } } private static bool NameMatches(string name, string[] fragments) { foreach (string value in fragments) { if (name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static string LabelFor(string objectName, string fallback) { if (!Session.EspAdvanced) { return fallback; } string text = objectName.Replace("(Clone)", "").Trim(); if (text.Length <= 22) { return text; } return text.Substring(0, 22); } private static void Add(Vector3 world, string label, Color color, Vector3 origin, float maxDist) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0027: 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_0037: Unknown result type (might be due to invalid IL or missing references) Vector3 val = world - origin; if (!(((Vector3)(ref val)).sqrMagnitude > maxDist * maxDist)) { Marks.Add(new Mark { World = world, Label = label, Color = color }); } } } internal sealed class Actor { public int Id; public string Name; public bool IsLocal; public object NetworkUser; public object Master; public object Body; public object Motor; public object Health; public object Inventory; public object InputBank; public object Team; public object Direction; public Transform Transform; } internal sealed class CatalogItem { public int Index; public string Name; public string Pickup; public bool Hidden; public object Def; public Texture Icon; public Rect IconUv = new Rect(0f, 0f, 1f, 1f); public Color IconColor = new Color(0.18f, 0.22f, 0.26f, 1f); public bool IconResolved; } internal static class Game { private struct PendingGive { public int ActorId; public uint NetId; public int ItemIndex; public int Count; } public static bool Ready; public static Harmony Harmony; public static Type TCharacterBody; public static Type TCharacterMaster; public static Type THealthComponent; public static Type TCharacterMotor; public static Type TInventory; public static Type TNetworkUser; public static Type TPlayerCharacterMasterController; public static Type TLocalUserManager; public static Type TTeamComponent; public static Type TInputBank; public static Type TCharacterDirection; public static Type TSkillLocator; public static Type TGenericSkill; public static Type TItemCatalog; public static Type TItemDef; public static Type TEquipmentCatalog; public static Type TEquipmentDef; public static Type TBuffCatalog; public static Type TBuffDef; public static Type TSurvivorCatalog; public static Type TSurvivorDef; public static Type TBodyCatalog; public static Type TMasterCatalog; public static Type TEliteCatalog; public static Type TEliteDef; public static Type TSceneCatalog; public static Type TSceneDef; public static Type TRun; public static Type TTeamManager; public static Type TTeleporterInteraction; public static Type THoldoutZoneController; public static Type TCombatDirector; public static Type TLanguage; public static Type TNetworkServer; public static Type TInstanceTracker; public static Type TTeleportHelper; public static Type TDirectorSpawnRequest; public static Type TDirectorPlacementRule; public static Type TSpawnCard; public static Type TInteractableSpawnCard; public static Type TCharacterSpawnCard; public static Type TRoR2Application; public static Type TNetworkManagerSystem; public static Type TMapZone; public static Type TBaseAI; public static Type TKinematicMotor; public static Type TItemIndex; public static Type TEquipmentIndex; public static Type TBuffIndex; public static Type TTeamIndex; public static Type THurtBox; public static Type TPickupIndex; public static Type TGenericPickupController; public static Type TSkinDef; public static Type TModelLocator; public static Type TModelSkinController; public static Type TBodyIndex; private static MemberInfo _bodyInstances; private static MemberInfo _playerInstances; private static MemberInfo _networkUsers; private static MemberInfo _localUsers; private static MemberInfo _runInstance; private static MemberInfo _teamManagerInstance; private static MemberInfo _teleporterInstance; private static MethodInfo _languageGet; private static MethodInfo _giveItem; private static MethodInfo _removeItem; private static MethodInfo _getItemCount; private static MethodInfo _onInventoryChanged; private static FieldInfo _itemStacks; private static MethodInfo _setEquipment; private static MethodInfo _getEquipment; private static MethodInfo _suicide; private static MethodInfo _respawn; private static MethodInfo _respawnAt; private static MethodInfo _getBody; private static MethodInfo _setBuffCount; private static MethodInfo _getBuffCount; private static MethodInfo _addTimedBuff; private static MethodInfo _clearTimedBuffs; private static MethodInfo _awardLunar; private static MethodInfo _advanceStage; private static MethodInfo _getSceneDef; private static MethodInfo _findSceneDef; private static MethodInfo _allSceneDefs; private static MethodInfo _itemCount; private static MethodInfo _getItemDef; private static MethodInfo _equipCount; private static MethodInfo _getEquipDef; private static MethodInfo _buffCount; private static MethodInfo _getBuffDef; private static MethodInfo _allSurvivors; private static MethodInfo _getBodyPrefab; private static MethodInfo _findBodyPrefab; private static MethodInfo _findBodyIndex; private static MethodInfo _transformBody; private static MethodInfo _getMasterPrefab; private static MethodInfo _bodyCount; private static MethodInfo _masterCount; private static MethodInfo _eliteCount; private static MethodInfo _getEliteDef; private static MethodInfo _instanceTrackerGet; private static MethodInfo _teleportBody; private static MethodInfo _spawnCardDoSpawn; private static MethodInfo _networkServerSpawn; private static MethodInfo _networkServerActive; private static MethodInfo _serverKick; private static MethodInfo _serverBan; private static MethodInfo _giveTeamMoney; private static MethodInfo _giveTeamExp; private static MethodInfo _getBodySkins; private static MethodInfo _applySkin; private static MethodInfo _applySkinAsync; private static MethodInfo _skinDefApply; private static MethodInfo _setLoadoutServer; private static MethodInfo _setSkinIndex; private static FieldInfo _directorCombatDisableField; private static MemberInfo _masterGod; private static MemberInfo _healthGod; private static MemberInfo _masterMoney; private static MemberInfo _voidCoins; private static MemberInfo _lunarCoins; private static MemberInfo _bodyMaster; private static MemberInfo _bodyHealth; private static MemberInfo _bodyMotor; private static MemberInfo _bodyInventory; private static MemberInfo _bodyInput; private static MemberInfo _bodyTeam; private static MemberInfo _bodySkill; private static MemberInfo _bodyDirection; private static MemberInfo _bodySprinting; private static MemberInfo _masterInventory; private static MemberInfo _masterBodyPrefab; private static MemberInfo _masterPcmc; private static MemberInfo _pcmcMaster; private static MemberInfo _nuMaster; private static MemberInfo _nuUserName; private static MemberInfo _motorGravity; private static MemberInfo _motorVelocity; private static FieldInfo _tpShop; private static FieldInfo _tpGold; private static FieldInfo _tpCelestial; private static FieldInfo _tpHoldout; private static FieldInfo _tpShrineStacks; private static FieldInfo _holdoutCharge; private static MemberInfo _kcmLayers; private static FieldInfo _itemNameToken; private static FieldInfo _itemHidden; private static FieldInfo _itemTier; private static MemberInfo _itemPickupToken; private static MemberInfo _itemDescToken; private static FieldInfo _equipNameToken; private static FieldInfo _buffNameToken; private static FieldInfo _survivorNameToken; private static MemberInfo _survivorBodyPrefab; private static FieldInfo _sceneNameToken; private static FieldInfo _sceneCachedName; private static FieldInfo _eliteNameToken; private static FieldInfo _eliteEquipment; private static MemberInfo _bodyNameToken; private static MemberInfo _allBodyPrefabs; private static MemberInfo _bodyIndex; private static MemberInfo _bodySkinIndex; private static FieldInfo _modelTransform; private static FieldInfo _mscSkins; private static MemberInfo _mscCurrentSkin; private static FieldInfo _skinNameToken; private static FieldInfo _catalogSkins; private static MemberInfo _masterLoadout; private static FieldInfo _loadoutBodyManager; private static FieldInfo _masterBodyPrefabField; private static PropertyInfo _inputMove; private static PropertyInfo _inputAim; private static FieldInfo _placementMode; private static FieldInfo _placementPosition; private static FieldInfo _spawnRequestTeam; private static FieldInfo _spawnRequestIgnoreLimit; private static object _directPlacementMode; private static FieldInfo[] _mouseSkillFields; private static FieldInfo _buttonDown; private static FieldInfo _buttonWasDown; private static bool _loggedMissing; public static string LastActionMessage; private static readonly List<Action> _pendingPlayer = new List<Action>(); private static readonly List<PendingGive> _pendingGives = new List<PendingGive>(); private static bool _skinBusy; private static float _skinBusyUntil; public static bool IsServer { get { try { if (_networkServerActive != null) { return (bool)_networkServerActive.Invoke(null, null); } } catch { } try { object obj2 = LocalActor()?.Master; Component val = (Component)((obj2 is Component) ? obj2 : null); if (Object.op_Implicit((Object)(object)val)) { PropertyInfo propertyInfo = Hook.Prop(((object)val).GetType(), "isServer") ?? Hook.Prop(Hook.Type("UnityEngine.Networking.NetworkBehaviour"), "isServer"); if (propertyInfo != null) { return (bool)propertyInfo.GetValue(val, null); } } } catch { } return false; } } public static object RunInstance { get { if (!(_runInstance == null)) { return Hook.Get(_runInstance, null); } return null; } } public static bool SkinBusy { get { if (_skinBusy) { return Time.unscaledTime < _skinBusyUntil; } return false; } } public static void Init(Harmony harmony) { Harmony = harmony; try { Resolve(); if (Ready) { Patches.Apply(harmony); CoOp.Register(); } } catch (Exception message) { Log.Error(message); Ready = TCharacterBody != null; } } public static void Resolve() { if (Ready) { return; } TCharacterBody = Hook.Type("RoR2.CharacterBody"); if (TCharacterBody == null) { if (!_loggedMissing) { Log.Warn("RoR2 types not loaded yet."); _loggedMissing = true; } return; } TCharacterMaster = Hook.Type("RoR2.CharacterMaster"); THealthComponent = Hook.Type("RoR2.HealthComponent"); TCharacterMotor = Hook.Type("RoR2.CharacterMotor"); TInventory = Hook.Type("RoR2.Inventory"); TNetworkUser = Hook.Type("RoR2.NetworkUser"); TPlayerCharacterMasterController = Hook.Type("RoR2.PlayerCharacterMasterController"); TLocalUserManager = Hook.Type("RoR2.LocalUserManager"); TTeamComponent = Hook.Type("RoR2.TeamComponent"); TInputBank = Hook.Type("RoR2.InputBankTest") ?? Hook.Type("RoR2.InputBank"); TCharacterDirection = Hook.Type("RoR2.CharacterDirection"); TSkillLocator = Hook.Type("RoR2.SkillLocator"); TGenericSkill = Hook.Type("RoR2.GenericSkill"); TItemCatalog = Hook.Type("RoR2.ItemCatalog"); TItemDef = Hook.Type("RoR2.ItemDef"); TEquipmentCatalog = Hook.Type("RoR2.EquipmentCatalog"); TEquipmentDef = Hook.Type("RoR2.EquipmentDef"); TBuffCatalog = Hook.Type("RoR2.BuffCatalog"); TBuffDef = Hook.Type("RoR2.BuffDef"); TSurvivorCatalog = Hook.Type("RoR2.SurvivorCatalog"); TSurvivorDef = Hook.Type("RoR2.SurvivorDef"); TBodyCatalog = Hook.Type("RoR2.BodyCatalog"); TMasterCatalog = Hook.Type("RoR2.MasterCatalog"); TEliteCatalog = Hook.Type("RoR2.EliteCatalog"); TEliteDef = Hook.Type("RoR2.EliteDef"); TSceneCatalog = Hook.Type("RoR2.SceneCatalog"); TSceneDef = Hook.Type("RoR2.SceneDef"); TRun = Hook.Type("RoR2.Run"); TTeamManager = Hook.Type("RoR2.TeamManager"); TTeleporterInteraction = Hook.Type("RoR2.TeleporterInteraction"); THoldoutZoneController = Hook.Type("RoR2.HoldoutZoneController"); TCombatDirector = Hook.Type("RoR2.CombatDirector"); TLanguage = Hook.Type("RoR2.Language"); TNetworkServer = Hook.Type("UnityEngine.Networking.NetworkServer") ?? Hook.Type("RoR2.NetworkServer"); TInstanceTracker = Hook.Type("RoR2.InstanceTracker"); TTeleportHelper = Hook.Type("RoR2.TeleportHelper"); TDirectorSpawnRequest = Hook.Type("RoR2.DirectorSpawnRequest"); TDirectorPlacementRule = Hook.Type("RoR2.DirectorPlacementRule"); TSpawnCard = Hook.Type("RoR2.SpawnCard"); TInteractableSpawnCard = Hook.Type("RoR2.InteractableSpawnCard"); TCharacterSpawnCard = Hook.Type("RoR2.CharacterSpawnCard"); TRoR2Application = Hook.Type("RoR2.RoR2Application"); TNetworkManagerSystem = Hook.Type("RoR2.Networking.NetworkManagerSystem") ?? Hook.Type("RoR2.NetworkManagerSystem"); TMapZone = Hook.Type("RoR2.MapZone"); TBaseAI = Hook.Type("RoR2.CharacterAI.BaseAI"); TKinematicMotor = Hook.Type("KinematicCharacterController.KinematicCharacterMotor"); TItemIndex = Hook.Type("RoR2.ItemIndex"); TEquipmentIndex = Hook.Type("RoR2.EquipmentIndex"); TBuffIndex = Hook.Type("RoR2.BuffIndex"); TTeamIndex = Hook.Type("RoR2.TeamIndex"); THurtBox = Hook.Type("RoR2.HurtBox"); TPickupIndex = Hook.Type("RoR2.PickupIndex"); TGenericPickupController = Hook.Type("RoR2.GenericPickupController"); TSkinDef = Hook.Type("RoR2.SkinDef"); TModelLocator = Hook.Type("RoR2.ModelLocator"); TModelSkinController = Hook.Type("RoR2.ModelSkinController"); TBodyIndex = Hook.Type("RoR2.BodyIndex"); _bodyInstances = Hook.Member(TCharacterBody, "readOnlyInstancesList", "instancesList", "instances"); _playerInstances = Hook.Member(TPlayerCharacterMasterController, "instances", "_instances", "instancesList", "readOnlyInstancesList"); _networkUsers = Hook.Member(TNetworkUser, "readOnlyInstancesList", "instances", "instancesList"); _localUsers = Hook.Member(TLocalUserManager, "readOnlyLocalUsersList") ?? Hook.Method(TLocalUserManager, "GetFirstLocalUser"); _runInstance = Hook.Member(TRun, "instance", "_instance"); _teamManagerInstance = Hook.Member(TTeamManager, "instance"); _teleporterInstance = Hook.Member(TTeleporterInteraction, "instance"); _directorCombatDisableField = Hook.Field(TCombatDirector, "cvDirectorCombatDisable"); _languageGet = Hook.Method(TLanguage, "GetString", typeof(string)) ?? Hook.Method(TLanguage, "GetLocalizedStringByToken", typeof(string)); _giveItem = FindMethod(TInventory, "GiveItem", 2) ?? FindMethod(TInventory, "GiveItem", 3) ?? FindMethod(TInventory, "GiveItem", 1) ?? Hook.Method(TInventory, "GiveItem"); _removeItem = FindMethod(TInventory, "RemoveItem", 2) ?? Hook.Method(TInventory, "RemoveItem"); _getItemCount = FindMethod(TInventory, "GetItemCount", 1) ?? Hook.Method(TInventory, "GetItemCount"); _onInventoryChanged = Hook.Method(TInventory, "OnInventoryChanged"); _itemStacks = Hook.Field(TInventory, "itemStacks", "_itemStacks"); _setEquipment = FindMethod(TInventory, "SetEquipmentIndex", 1) ?? FindMethod(TInventory, "SetEquipmentIndex", 2); _getEquipment = Hook.Method(TInventory, "GetEquipmentIndex") ?? Hook.Prop(TInventory, "currentEquipmentIndex")?.GetGetMethod(); _suicide = FindMethod(THealthComponent, "Suicide", 3) ?? FindMethod(THealthComponent, "Suicide", 0) ?? Hook.Method(THealthComponent, "Suicide"); _respawn = Hook.Method(TCharacterMaster, "RespawnExtraLife") ?? Hook.Method(TCharacterMaster, "RespawnExtraLifeVoid"); _respawnAt = FindMethod(TCharacterMaster, "Respawn", 2) ?? FindMethod(TCharacterMaster, "Respawn", 3); _getBody = Hook.Method(TCharacterMaster, "GetBody"); _setBuffCount = FindMethod(TCharacterBody, "SetBuffCount", 2); _getBuffCount = FindMethod(TCharacterBody, "GetBuffCount", 1); _addTimedBuff = FindMethod(TCharacterBody, "AddTimedBuff", 2) ?? FindMethod(TCharacterBody, "AddTimedBuff", 3); _clearTimedBuffs = FindMethod(TCharacterBody, "ClearTimedBuffs", 1); _awardLunar = Hook.Method(TNetworkUser, "AwardLunarCoins") ?? FindMethod(TNetworkUser, "AwardLunarCoins", 1); _advanceStage = FindMethod(TRun, "AdvanceStage", 1); _getSceneDef = Hook.Method(TSceneCatalog, "GetSceneDefForCurrentScene"); _findSceneDef = Hook.Method(TSceneCatalog, "FindSceneDef", typeof(string)) ?? Hook.Method(TSceneCatalog, "GetSceneDefFromSceneName", typeof(string)); _allSceneDefs = Hook.Prop(TSceneCatalog, "allSceneDefs")?.GetGetMethod() ?? Hook.Method(TSceneCatalog, "GetAllSceneDefs"); _itemCount = Hook.Prop(TItemCatalog, "itemCount")?.GetGetMethod(); _getItemDef = Hook.Method(TItemCatalog, "GetItemDef"); _equipCount = Hook.Prop(TEquipmentCatalog, "equipmentCount")?.GetGetMethod(); _getEquipDef = Hook.Method(TEquipmentCatalog, "GetEquipmentDef"); _buffCount = Hook.Prop(TBuffCatalog, "buffCount")?.GetGetMethod(); _getBuffDef = Hook.Method(TBuffCatalog, "GetBuffDef"); _allSurvivors = Hook.Prop(TSurvivorCatalog, "allSurvivorDefs")?.GetGetMethod(); _getBodyPrefab = Hook.Method(TBodyCatalog, "GetBodyPrefab"); _findBodyPrefab = Hook.Method(TBodyCatalog, "FindBodyPrefab", typeof(string)) ?? Hook.Method(TBodyCatalog, "FindBodyPrefab"); _findBodyIndex = Hook.Method(TBodyCatalog, "FindBodyIndex", typeof(string)) ?? Hook.Method(TBodyCatalog, "FindBodyIndex"); _transformBody = FindMethod(TCharacterMaster, "TransformBody", 1) ?? Hook.Method(TCharacterMaster, "TransformBody"); _getMasterPrefab = Hook.Method(TMasterCatalog, "GetMasterPrefab"); _bodyCount = Hook.Prop(TBodyCatalog, "bodyCount")?.GetGetMethod(); _masterCount = Hook.Prop(TMasterCatalog, "masterCount")?.GetGetMethod(); _eliteCount = Hook.Prop(TEliteCatalog, "eliteCount")?.GetGetMethod(); _getEliteDef = Hook.Method(TEliteCatalog, "GetEliteDef"); _teleportBody = FindMethod(TTeleportHelper, "TeleportBody", 2); _spawnCardDoSpawn = FindMethod(TSpawnCard, "DoSpawn", 3); _networkServerSpawn = Hook.Method(TNetworkServer, "Spawn", typeof(GameObject)); _networkServerActive = Hook.Prop(TNetworkServer, "active")?.GetGetMethod() ?? Hook.Method(TNetworkServer, "get_active"); _serverKick = FindMethod(TNetworkManagerSystem, "ServerKickClient", 2) ?? FindMethod(TNetworkManagerSystem, "ServerKickClient", 1); _serverBan = FindMethod(TNetworkManagerSystem, "ServerBanClient", 1); _giveTeamMoney = FindMethod(TTeamManager, "GiveTeamMoney", 2); _giveTeamExp = FindMethod(TTeamManager, "GiveTeamExperience", 2) ?? FindMethod(TTeamManager, "GiveTeamExperience", 3); _getBodySkins = Hook.Method(TBodyCatalog, "GetBodySkins") ?? Hook.Method(Hook.Type("RoR2.SkinCatalog"), "GetBodySkins"); _applySkin = FindMethod(TModelSkinController, "ApplySkin", 1) ?? Hook.Method(TModelSkinController, "ApplySkin"); _applySkinAsync = FindMethod(TModelSkinController, "ApplySkinAsync", 1) ?? Hook.Method(TModelSkinController, "ApplySkinAsync"); _skinDefApply = FindMethod(TSkinDef, "Apply", 1) ?? Hook.Method(TSkinDef, "Apply"); _setLoadoutServer = Hook.Method(TCharacterMaster, "SetLoadoutServer"); _catalogSkins = Hook.Field(TBodyCatalog, "skins"); _masterGod = Hook.Member(TCharacterMaster, "godMode"); _healthGod = Hook.Member(THealthComponent, "godMode"); _masterMoney = Hook.Member(TCharacterMaster, "money"); _voidCoins = Hook.Member(TCharacterMaster, "voidCoins", "voidCoin"); _lunarCoins = Hook.Member(TNetworkUser, "lunarCoins"); _bodyMaster = Hook.Member(TCharacterBody, "master", "_master"); _bodyHealth = Hook.Member(TCharacterBody, "healthComponent", "_healthComponent"); _bodyMotor = Hook.Member(TCharacterBody, "characterMotor", "_characterMotor"); _bodyInventory = Hook.Member(TCharacterBody, "inventory", "_inventory"); _bodyInput = Hook.Member(TCharacterBody, "inputBank", "_inputBank"); _bodyTeam = Hook.Member(TCharacterBody, "teamComponent", "_teamComponent"); _bodySkill = Hook.Member(TCharacterBody, "skillLocator", "_skillLocator"); _bodyDirection = Hook.Member(TCharacterBody, "characterDirection", "_characterDirection"); _bodySprinting = Hook.Member(TCharacterBody, "isSprinting", "sprinting"); _masterInventory = Hook.Member(TCharacterMaster, "inventory", "_inventory"); _masterBodyPrefab = Hook.Member(TCharacterMaster, "bodyPrefab", "_bodyPrefab"); _masterPcmc = Hook.Member(TCharacterMaster, "playerCharacterMasterController"); _pcmcMaster = Hook.Member(TPlayerCharacterMasterController, "master"); _nuMaster = Hook.Member(TNetworkUser, "master"); _nuUserName = Hook.Member(TNetworkUser, "userName"); _motorGravity = Hook.Member(TCharacterMotor, "useGravity"); _motorVelocity = Hook.Member(TCharacterMotor, "velocity", "Velocity", "BaseVelocity"); _tpShop = Hook.Field(TTeleporterInteraction, "shouldAttemptToSpawnShopPortal"); _tpGold = Hook.Field(TTeleporterInteraction, "shouldAttemptToSpawnGoldshoresPortal"); _tpCelestial = Hook.Field(TTeleporterInteraction, "shouldAttemptToSpawnMSPortal"); _tpHoldout = Hook.Field(TTeleporterInteraction, "holdoutZoneController"); _tpShrineStacks = Hook.Field(TTeleporterInteraction, "shrineBonusStacks", "bossShrineBonus"); _holdoutCharge = Hook.Field(THoldoutZoneController, "_charge", "charge"); _kcmLayers = Hook.Member(TKinematicMotor, "CollidableLayers", "collidableLayers"); _itemNameToken = Hook.Field(TItemDef, "nameToken"); _itemHidden = Hook.Field(TItemDef, "hidden"); _itemTier = Hook.Field(TItemDef, "tier"); _itemPickupToken = Hook.Member(TItemDef, "pickupToken", "descriptionToken"); _itemDescToken = Hook.Member(TItemDef, "descriptionToken", "pickupToken"); _equipNameToken = Hook.Field(TEquipmentDef, "nameToken"); _buffNameToken = Hook.Field(TBuffDef, "nameToken", "eliteNameToken"); _survivorNameToken = Hook.Field(TSurvivorDef, "displayNameToken"); _survivorBodyPrefab = Hook.Member(TSurvivorDef, "bodyPrefab", "_bodyPrefab"); _sceneNameToken = Hook.Field(TSceneDef, "nameToken"); _sceneCachedName = Hook.Field(TSceneDef, "cachedName", "baseSceneName"); _eliteNameToken = Hook.Field(TEliteDef, "modifierToken", "eliteNameToken"); _eliteEquipment = Hook.Field(TEliteDef, "eliteEquipmentDef"); _bodyNameToken = Hook.Member(TCharacterBody, "baseNameToken"); _allBodyPrefabs = Hook.Member(TBodyCatalog, "allBodyPrefabs", "bodyPrefabs"); _bodyIndex = Hook.Member(TCharacterBody, "bodyIndex"); _bodySkinIndex = Hook.Member(TCharacterBody, "skinIndex"); _modelTransform = Hook.Field(TModelLocator, "modelTransform", "_modelTransform"); _mscSkins = Hook.Field(TModelSkinController, "skins"); _mscCurrentSkin = Hook.Member(TModelSkinController, "currentSkinIndex", "skinIndex"); _skinNameToken = Hook.Field(TSkinDef, "nameToken"); _masterLoadout = Hook.Member(TCharacterMaster, "loadout", "_loadout"); Type type = Hook.Type("RoR2.Loadout"); Type type2 = type?.GetNestedType("BodyLoadoutManager") ?? Hook.Type("RoR2.Loadout+BodyLoadoutManager"); _loadoutBodyManager = Hook.Field(type, "bodyLoadoutManager"); _setSkinIndex = Hook.Method(type2, "SetSkinIndex"); _masterBodyPrefabField = Hook.Field(Hook.Type("RoR2.CharacterMaster"), "bodyPrefab"); _inputMove = Hook.Prop(TInputBank, "moveVector"); _inputAim = Hook.Prop(TInputBank, "aimDirection"); _placementMode = Hook.Field(TDirectorPlacementRule, "placementMode"); _placementPosition = Hook.Field(TDirectorPlacementRule, "position"); _spawnRequestTeam = Hook.Field(TDirectorSpawnRequest, "teamIndexOverride"); _spawnRequestIgnoreLimit = Hook.Field(TDirectorSpawnRequest, "ignoreTeamMemberLimit"); if (TDirectorPlacementRule != null) { Type nestedType = TDirectorPlacementRule.GetNestedType("PlacementMode"); if (nestedType != null && nestedType.IsEnum) { try { _directPlacementMode = Enum.Parse(nestedType, "Direct"); } catch { _directPlacementMode = Enum.ToObject(nestedType, 0); } } } Ready = true; Log.Info("RoR2 bridge ready. GiveItem=" + ((_giveItem != null) ? _giveItem.ToString() : "missing") + " itemStacks=" + (_itemStacks != null) + " money=" + (_masterMoney != null) + " motor=" + (_bodyMotor != null) + " sprint=" + (_bodySprinting != null) + " team=" + (_bodyTeam != null) + " applySkinAsync=" + ((_applySkinAsync != null) ? _applySkinAsync.ToString() : "missing") + " findBodyPrefab=" + (_findBodyPrefab != null) + " transformBody=" + ((_transformBody != null) ? _transformBody.ToString() : "missing")); } private static MethodInfo FindMethod(Type type, string name, int argc) { if (type == null) { return null; } MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == name && methodInfo.GetParameters().Length == argc && !methodInfo.IsGenericMethod) { return methodInfo; } } return null; } public static string Localize(string token) { if (string.IsNullOrEmpty(token)) { return token; } if (_languageGet == null) { return token; } try { string text = _languageGet.Invoke(null, new object[1] { token }) as string; return string.IsNullOrEmpty(text) ? token : text; } catch { return token; } } public static List<Actor> Players() { List<Actor> list = new List<Actor>(); HashSet<int> hashSet = new HashSet<int>(); object obj = LocalBody(); IEnumerable enumerable = ((_playerInstances != null) ? (Hook.Get(_playerInstances, null) as IEnumerable) : null); if (enumerable != null) { foreach (object item in enumerable) { if (item != null) { Actor actor = FromMaster((_pcmcMaster != null) ? Hook.Get(_pcmcMaster, item) : null, obj); if (actor != null && hashSet.Add(actor.Id)) { list.Add(actor); } } } } IEnumerable enumerable2 = ((_networkUsers != null) ? (Hook.Get(_networkUsers, null) as IEnumerable) : null); if (enumerable2 != null) { foreach (object item2 in enumerable2) { if (item2 != null) { Actor actor2 = FromMaster((_nuMaster != null) ? Hook.Get(_nuMaster, item2) : null, obj); if (actor2 != null && hashSet.Add(actor2.Id)) { actor2.NetworkUser = item2; list.Add(actor2); } } } } if (list.Count == 0 && obj != null) { Actor actor3 = FromBody(obj, obj); if (actor3 != null) { list.Add(actor3); } } return list; } public static Actor FindPlayer(int id) { foreach (Actor item in Players()) { if (item.Id == id) { return item; } } return null; } public static object LocalBody() { try { MethodInfo methodInfo = Hook.Method(TLocalUserManager, "GetFirstLocalUser"); object obj = ((methodInfo != null) ? methodInfo.Invoke(null, null) : null); if (obj == null) { return null; } MemberInfo memberInfo = Hook.Member(obj.GetType(), "cachedBody"); object obj2 = ((memberInfo != null) ? Hook.Get(memberInfo, obj) : null); if (obj2 != null) { return obj2; } MemberInfo memberInfo2 = Hook.Member(obj.GetType(), "cachedMaster", "cachedMasterController"); object obj3 = ((memberInfo2 != null) ? Hook.Get(memberInfo2, obj) : null); if (obj3 != null && _getBody != null) { return _getBody.Invoke(obj3, null); } } catch { } return null; } public static Actor LocalActor() { object obj = LocalBody(); if (obj != null) { return FromBody(obj, obj); } return null; } private static Actor FromMaster(object master, object localBody) { if (master == null) { return null; } object obj = null; try { obj = _getBody?.Invoke(master, null); } catch { } if (obj == null) { return FromMasterOnly(master, localBody); } return FromBody(obj, localBody); } private static Actor FromMasterOnly(object master, object localBody) { Actor obj = new Actor { Master = master, Name = "Player", Id = StableId(master, (Component)((master is Component) ? master : null)) }; obj.Inventory = InventoryOf(obj); FillNetworkUser(obj); return obj; } public static Actor FromBody(object body, object localBody) { if (body == null) { return null; } Component val = (Component)((body is Component) ? body : null); object obj = ((_bodyMaster != null) ? Hook.Get(_bodyMaster, body) : null); if (!UnityAlive(obj)) { obj = ComponentOf(Bind(body, "masterObject", "_masterObject"), TCharacterMaster); } Actor actor = new Actor { Body = body, Master = obj, Health = ((_bodyHealth != null) ? Hook.Get(_bodyHealth, body) : null), Motor = ((_bodyMotor != null) ? Hook.Get(_bodyMotor, body) : null), InputBank = ((_bodyInput != null) ? Hook.Get(_bodyInput, body) : null), Team = ((_bodyTeam != null) ? Hook.Get(_bodyTeam, body) : null), Direction = ((_bodyDirection != null) ? Hook.Get(_bodyDirection, body) : null), Transform = (Object.op_Implicit((Object)(object)val) ? val.transform : null), Id = StableId(obj, val), IsLocal = (localBody != null && body == localBody) }; if (!UnityAlive(actor.Health) && Object.op_Implicit((Object)(object)val) && THealthComponent != null) { actor.Health = val.GetComponent(THealthComponent); } if (!UnityAlive(actor.Motor) && Object.op_Implicit((Object)(object)val) && TCharacterMotor != null) { actor.Motor = val.GetComponent(TCharacterMotor); } if (!UnityAlive(actor.InputBank) && Object.op_Implicit((Object)(object)val) && TInputBank != null) { actor.InputBank = val.GetComponent(TInputBank); } if (!UnityAlive(actor.Team) && Object.op_Implicit((Object)(object)val) && TTeamComponent != null) { actor.Team = val.GetComponent(TTeamComponent); } actor.Inventory = InventoryOf(actor); FillNetworkUser(actor); if (string.IsNullOrEmpty(actor.Name)) { actor.Name = (Object.op_Implicit((Object)(object)val) ? ((Object)val.gameObject).name : "Body"); } return actor; } private static void FillNetworkUser(Actor actor) { object obj = ((actor.Master != null && _masterPcmc != null) ? Hook.Get(_masterPcmc, actor.Master) : null); if (!UnityAlive(obj)) { obj = ComponentOf(actor.Master, TPlayerCharacterMasterController); } if (UnityAlive(obj)) { MethodInfo methodInfo = Hook.Method(obj.GetType(), "GetDisplayName"); if (methodInfo != null) { actor.Name = (methodInfo.Invoke(obj, null) as string) ?? actor.Name; } object obj2 = Bind(obj, "networkUser"); if (UnityAlive(obj2)) { actor.NetworkUser = obj2; } } if (actor.NetworkUser != null && string.IsNullOrEmpty(actor.Name) && _nuUserName != null) { actor.Name = Hook.Get(_nuUserName, actor.NetworkUser) as string; } if (string.IsNullOrEmpty(actor.Name)) { actor.Name = "Player"; } } private static object Bind(object target, params string[] names) { if (target == null || names == null || names.Length == 0) { return null; } MemberInfo memberInfo = Hook.Member(target.GetType(), names); if (!(memberInfo == null)) { return Hook.Get(memberInfo, target); } return null; } private static object ComponentOf(object host, Type type) { if (host == null || type == null) { return null; } Component val = (Component)((host is Component) ? host : null); if (val != null && Object.op_Implicit((Object)(object)val)) { return val.GetComponent(type); } GameObject val2 = (GameObject)((host is GameObject) ? host : null); if (val2 != null && Object.op_Implicit((Object)(object)val2)) { return val2.GetComponent(type); } return null; } private static bool UnityAlive(object obj) { if (obj == null) { return false; } Object val = (Object)((obj is Object) ? obj : null); if (val != null) { return Object.op_Implicit(val); } return true; } private static int StableId(object master, Component fallback) { Component val = (Component)((master is Component) ? master : null); if (val != null && Object.op_Implicit((Object)(object)val)) { return ((Object)val).GetInstanceID(); } if (Object.op_Implicit((Object)(object)fallback)) { return ((Object)fallback).GetInstanceID(); } return master?.GetHashCode() ?? 0; } public static object FirstLocalNetworkUser() { try { MethodInfo methodInfo = Hook.Method(TLocalUserManager, "GetFirstLocalUser"); object obj = ((methodInfo != null) ? methodInfo.Invoke(null, null) : null); if (obj == null) { return null; } return Hook.Get(Hook.Member(obj.GetType(), "currentNetworkUser", "networkUser"), obj); } catch { return null; } } public static uint NetId(Actor actor) { uint num = NetIdOf(actor?.Master); if (num != 0) { return num; } uint num2 = NetIdOf(actor?.NetworkUser); if (num2 != 0) { return num2; } return NetIdOf(actor?.Body); } public static uint NetIdOf(object component) { Component val = (Component)((component is Component) ? component : null); if (!Object.op_Implicit((Object)(object)val)) { return 0u; } Type type = Hook.Type("UnityEngine.Networking.NetworkIdentity"); if (type == null) { return 0u; } Component val2 = val.GetComponent(type) ?? val.GetComponentInParent(type); if (!Object.op_Implicit((Object)(object)val2)) { return 0u; } object obj = Hook.Get(Hook.Member(((object)val2).GetType(), "netId"), val2); if (obj == null) { return 0u; } object obj2 = Hook.Get(Hook.Member(obj.GetType(), "Value", "value"), obj); try { return Convert.ToUInt32(obj2 ?? ((object)0)); } catch { return 0u; } } public static Actor FindByNetId(uint netId) { if (netId == 0) { return null; } foreach (Actor item in Players()) { if (NetIdOf(item.Master) == netId) { return item; } if (NetIdOf(item.NetworkUser) == netId) { return item; } if (NetIdOf(item.Body) == netId) { return item; } } return null; } public static IEnumerable Bodies() { IEnumerable enumerable = ((_bodyInstances != null) ? (Hook.Get(_bodyInstances, null) as IEnumerable) : null); return enumerable ?? Array.Empty<object>(); } public static int TeamOf(object body) { if (body == null) { return 0; } object obj = ((_bodyTeam != null) ? Hook.Get(_bodyTeam, body) : null); if (!UnityAlive(obj)) { Component val = (Component)((body is Component) ? body : null); if (val != null && TTeamComponent != null) { obj = val.GetComponent(TTeamComponent); } } if (!UnityAlive(obj)) { return 0; } return IndexValue.ToInt(Hook.Get(Hook.Prop(obj.GetType(), "teamIndex") ?? Hook.Member(obj.GetType(), "teamIndex", "_teamIndex"), obj)); } public static void SetTeam(Actor actor, int teamIndex) { if (actor != null) { if (actor.IsLocal) { Session.ForcedTeam = teamIndex; } if (!CoOp.AskHost("slipstream_team " + NetId(actor) + " " + teamIndex)) { ApplyTeamLocal(actor, teamIndex); } } } public static void ApplyTeamLocal(Actor actor, int teamIndex) { if (actor == null) { return; } object teamEnum = ((TTeamIndex != null) ? IndexValue.FromInt(TTeamIndex, teamIndex) : ((object)teamIndex)); object obj = actor.Team; if (!UnityAlive(obj)) { object body = actor.Body; Component val = (Component)((body is Component) ? body : null); if (val != null && TTeamComponent != null) { obj = val.GetComponent(TTeamComponent) ?? val.GetComponentInChildren(TTeamComponent, true); } } actor.Team = obj; WriteTeamIndex(obj, teamEnum); WriteTeamIndex(actor.Master, teamEnum); WriteTeamIndex(actor.Body, teamEnum); WriteHurtBoxes(actor.Body, teamEnum); LastActionMessage = "Team: " + TeamName(teamIndex) + ". Allies on that team will not attack you."; Log.Info(LastActionMessage + " value=" + teamIndex + " on " + actor.Name); } public static void HoldForcedTeam(Actor actor) { if (actor != null && actor.Body != null && Session.ForcedTeam != int.MinValue && TeamOf(actor.Body) != Session.ForcedTeam) { ApplyTeamLocal(actor, Session.ForcedTeam); } } private static string TeamName(int teamIndex) { return teamIndex switch { 0 => "Neutral", 1 => "Player", 2 => "Monster", 3 => "Lunar", 4 => "Void", _ => "Team " + teamIndex, }; } private static void WriteTeamIndex(object target, object teamEnum) { if (target == null || teamEnum == null) { return; } Type type = target.GetType(); string[] array = new string[4] { "set_teamIndex", "SetTeamIndex", "SwitchTeam", "ChangeTeam" }; foreach (string name in array) { MethodInfo methodInfo = Hook.Method(type, name); if (!(methodInfo == null)) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1) { Hook.Call(methodInfo, target, Hook.Coerce(teamEnum, parameters[0].ParameterType)); return; } } } PropertyInfo propertyInfo = Hook.Prop(type, "teamIndex"); if (propertyInfo != null && propertyInfo.CanWrite) { Hook.Set(propertyInfo, target, teamEnum); return; } Hook.Set(Hook.Member(type, "teamIndex", "_teamIndex"), target, teamEnum); } private static void WriteHurtBoxes(object body, object teamEnum) { Component val = (Component)((body is Component) ? body : null); if (!Object.op_Implicit((Object)(object)val) || teamEnum == null) { return; } Type type = THurtBox ?? Hook.Type("RoR2.HurtBox"); if (type != null) { Component[] componentsInChildren = val.GetComponentsInChildren(type, true); for (int i = 0; i < componentsInChildren.Length; i++) { WriteTeamIndex(componentsInChildren[i], teamEnum); } } Type type2 = Hook.Type("RoR2.TeamFilter"); if (type2 != null) { WriteTeamIndex(val.GetComponent(type2) ?? val.GetComponentInChildren(type2, true), teamEnum); } } public static void PushLocalToggles(Actor self) { if (self != null) { SetGod(self, Session.LocalMods.God); if (!IsServer) { CoOp.Submit("slipstream_t " + NetId(self) + " " + PackToggles(Session.LocalMods)); } } } public static int PackToggles(ActorMods mods) { if (mods == null) { return 0; } int num = 0; if (mods.God) { num |= 1; } if (mods.InfiniteSprint) { num |= 2; } if (mods.InfiniteSkills) { num |= 4; } if (mods.Noclip) { num |= 8; } return num; } public static void SetGod(Actor actor, bool enabled) { if (actor != null) { if (actor.Master != null && _masterGod != null) { Hook.Set(_masterGod, actor.Master, enabled); } if (actor.Health != null && _healthGod != null) { Hook.Set(_healthGod, actor.Health, enabled); } } } public static void SetSprinting(Actor actor, bool enabled) { if (actor != null && actor.Body != null && !(_bodySprinting == null)) { Hook.Set(_bodySprinting, actor.Body, enabled); } } public static void SetMotorGravity(Actor actor, bool useGravity) { if (actor != null && actor.Motor != null && !(_motorGravity == null)) { Hook.Set(_motorGravity, actor.Motor, useGravity); } } public static void SetMotorVelocity(Actor actor, Vector3 velocity) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (actor != null && actor.Motor != null && !(_motorVelocity == null)) { Hook.Set(_motorVelocity, actor.Motor, velocity); } } public static Vector3 MotorVelocity(Actor actor) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (actor == null || actor.Motor == null || _motorVelocity == null) { return Vector3.zero; } object obj = Hook.Get(_motorVelocity, actor.Motor); if (obj is Vector3) { return (Vector3)obj; } return Vector3.zero; } public static void SetCollidable(Actor actor, bool enabled) { object obj = actor?.Body; Component val = (Component)((obj is Component) ? obj : null); if (val != null && TKinematicMotor != null) { Component component = val.GetComponent(TKinematicMotor); if ((Object)(object)component != (Object)null && _kcmLayers != null) { Hook.Set(_kcmLayers, component, enabled ? (-1) : 0); } } if ((Object)(object)actor?.Transform != (Object)null) { Collider component2 = ((Component)actor.Transform).GetComponent<Collider>(); if ((Object)(object)component2 != (Object)null) { component2.enabled = enabled; } } } public static Vector3 MoveVector(Actor actor) { //IL_0018: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (actor == null || actor.InputBank == null || _inputMove == null) { return Vector3.zero; } object value = _inputMove.GetValue(actor.InputBank, null); if (value is Vector3) { return (Vector3)value; } return Vector3.zero; } public static Vector3 AimDirection(Actor actor) { //IL_0031: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (actor == null || actor.InputBank == null || _inputAim == null) { if (!Object.op_Implicit((Object)(object)actor.Transform)) { return Vector3.forward; } return actor.Transform.forward; } object value = _inputAim.GetValue(actor.InputBank, null); if (value is Vector3) { return (Vector3)value; } return Vector3.forward; } public static void SetAim(Actor actor, Vector3 direction) { //IL_0072: 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) if (actor != null && actor.InputBank != null && _inputAim != null && _inputAim.CanWrite) { _inputAim.SetValue(actor.InputBank, ((Vector3)(ref direction)).normalized, null); } if (actor != null && actor.Direction != null) { Hook.Set(Hook.Member(actor.Direction.GetType(), "forward"), actor.Direction, ((Vector3)(ref direction)).normalized); } } public static void RefillSkills(Actor actor) { if (actor == null || actor.Body == null || _bodySkill == null) { return; } object obj = Hook.Get(_bodySkill, actor.Body); if (obj == null) { return; } string[] array = new string[4] { "primary", "secondary", "utility", "special" }; foreach (string text in array) { MemberInfo memberInfo = Hook.Member(obj.GetType(), text); object obj2 = ((memberInfo != null) ? Hook.Get(memberInfo, obj) : null); if (obj2 != null) { MemberInfo memberInfo2 = Hook.Member(obj2.GetType(), "maxStock"); MemberInfo member = Hook.Member(obj2.GetType(), "stock"); FieldInfo fieldInfo = Hook.Field(obj2.GetType(), "rechargeStopwatch", "finalRechargeStopwatch"); object value = ((memberInfo2 != null) ? Hook.Get(memberInfo2, obj2) : ((object)1)); Hook.Set(member, obj2, value); if (fieldInfo != null) { fieldInfo.SetValue(obj2, 0f); } } } } public static uint GetMoney(Actor actor) { if (actor == null || actor.Master == null || _masterMoney == null) { return 0u; } try { return Convert.ToUInt32(Hook.Get(_masterMoney, actor.Master) ?? ((object)0)); } catch { return 0u; } } public static void SetMoney(Actor actor, uint amount) { if (actor != null && actor.Master != null && !CoOp.AskHost("slipstream_money " + NetId(actor) + " " + amount)) { if (_masterMoney == null) { LastActionMessage = "Could not find CharacterMaster.money."; Log.Warn(LastActionMessage); return; } Hook.Set(_masterMoney, actor.Master, amount); LastActionMessage = "Set money to " + amount + " for " + actor.Name + "."; Log.Info(LastActionMessage); } } public static uint GetVoidCoins(Actor actor) { if (actor == null || actor.Master == null || _voidCoins == null) { return 0u; } try { return Convert.ToUInt32(Hook.Get(_voidCoins, actor.Master) ?? ((object)0)); } catch { return 0u; } } public static void SetVoidCoins(Actor actor, uint amount) { if (actor != null && actor.Master != null && !(_voidCoins == null) && !CoOp.AskHost("slipstream_void " + NetId(actor) + " " + amount)) { Hook.Set(_voidCoins, actor.Master, amount); LastActionMessage = "Set Void coins to " + amount + " for " + actor.Name + "."; } } public static uint GetLunar(Actor actor) { if (actor == null || actor.NetworkUser == null || _lunarCoins == null) { return 0u; } try { return Convert.ToUInt32(Hook.Get(_lunarCoins, actor.NetworkUser) ?? ((object)0)); } catch { return 0u; } } public static void AwardLunar(Actor actor, uint amount) { if (actor != null && actor.NetworkUser != null && !CoOp.AskHost("slipstream_lunar " + NetId(actor) + " " + amount)) { if (_awardLunar != null) { Hook.Call(_awardLunar, actor.NetworkUser, amount); } else if (_lunarCoins != null) { uint lunar = GetLunar(actor); Hook.Set(_lunarCoins, actor.NetworkUser, lunar + amount); } LastActionMessage = "Awarded " + amount + " lunar coins to " + actor.Name + "."; } } public static void GiveExperience(uint amount) { object obj = ((_teamManagerInstance != null) ? Hook.Get(_teamManagerInstance, null) : null); if (obj == null || _giveTeamExp == null) { LastActionMessage = "Team XP could not be applied (TeamManager missing)."; return; } if (_giveTeamExp.GetParameters().Length == 2) { Hook.Call(_giveTeamExp, obj, IndexValue.FromInt(TTeamIndex, 1), amount); } else { Hook.Call(_giveTeamExp, obj, IndexValue.FromInt(TTeamIndex, 1), (ulong)amount, true); } LastActionMessage = "Gave " + amount + " team XP."; } public static void QueuePlayer(Action action) { if (action != null) { _pendingPlayer.Add(action); } } public static void DrainPendingPlayer() { if (_pendingPlayer.Count == 0) { return; } Action[] array = _pendingPlayer.ToArray(); _pendingPlayer.Clear(); Action[] array2 = array; foreach (Action action in array2) { try { action(); } catch (Exception ex) { LastActionMessage = "Player action failed: " + ex.Message; Log.Warn(LastActionMessage); } } } public static void QueueGive(Actor actor, int itemIndex, int count) { if (actor != null && count != 0) { _pendingGives.Add(new PendingGive { ActorId = actor.Id, NetId = NetId(actor), ItemIndex = itemIndex, Count = count }); } } public static void DrainPendingGive() { if (_pendingGives.Count == 0) { return; } PendingGive[] array = _pendingGives.ToArray(); _pendingGives.Clear(); PendingGive[] array2 = array; for (int i = 0; i < array2.Length; i++) { PendingGive pendingGive = array2[i]; Actor actor = FindPlayer(pendingGive.ActorId) ?? FindByNetId(pendingGive.NetId); if (actor == null && pendingGive.NetId == 0) { actor = LocalActor(); } GiveItem(actor, pendingGive.ItemIndex, pendingGive.Count); } } public static void GiveItem(Actor actor, int itemIndex, int count) { if (actor == null || count == 0) { return; } if (!IsServer) { uint num = NetId(actor); if (num != 0) { CoOp.Submit("slipstream_item " + num + " " + itemIndex + " " + count); LastActionMessage = "Asked the host to grant ×" + count + "."; return; } if (!actor.IsLocal) { LastActionMessage = "Could not reach that player. Need a netId and the host running SlipStream."; return; } } GiveItemLocal(actor, itemIndex, count); } public static void GiveItemLocal(Actor actor, int itemIndex, int count) { object obj = InventoryOf(actor); if (obj == null) { LastActionMessage = "No inventory on " + (actor?.Name ?? "that player") + "."; Log.Warn(LastActionMessage + " master=" + UnityAlive(actor?.Master) + " body=" + UnityAlive(actor?.Body) + " TInventory=" + (TInventory != null)); } else if (count != 0) { object index = IndexValue.FromInt(TItemIndex, itemIndex); bool flag = false; if (count > 0) { flag = InvokeInventory(obj, _giveItem, index, count); } else if (_removeItem != null) { flag = InvokeInventory(obj, _removeItem, index, -count); } if (!flag) { flag = TryWriteStacks(obj, itemIndex, count); } if (flag) { Hook.Call(_onInventoryChanged, obj); LastActionMessage = ((count > 0) ? "Gave ×" : "Removed ×") + Math.Abs(count) + " to " + actor.Name + "."; Log.Info(LastActionMessage + " itemIndex=" + itemIndex); } else { LastActionMessage = "Could not change inventory (GiveItem missing)."; Log.Warn(LastActionMessage + " GiveItem=" + (_giveItem != null) + " stacks=" + (_itemStacks != null)); } } } private static object InventoryOf(Actor actor) { if (actor == null) { return null; } if (UnityAlive(actor.Inventory)) { return actor.Inventory; } object obj = null; if (UnityAlive(actor.Master)) { if (_masterInventory != null) { obj = Hook.Get(_masterInventory, actor.Master); } if (!UnityAlive(obj)) { obj = Bind(actor.Master, "inventory", "_inventory"); } if (!UnityAlive(obj)) { obj = ComponentOf(actor.Master, TInventory); } } if (!UnityAlive(obj) && UnityAlive(actor.Body)) { if (_bodyInventory != null) { obj = Hook.Get(_bodyInventory, actor.Body); } if (!UnityAlive(obj)) { obj = Bind(actor.Body, "inventory", "_inventory"); } if (!UnityAlive(obj)) { obj = ComponentOf(actor.Body, TInventory); } } if (!UnityAlive(obj) && UnityAlive(actor.Body) && !UnityAlive(actor.Master)) { object obj2 = (actor.Master = Bind(actor.Body, "master", "_master") ?? ComponentOf(Bind(actor.Body, "masterObject", "_masterObject"), TCharacterMaster)); if (UnityAlive(obj2)) { obj = Bind(obj2, "inventory", "_inventory") ?? ComponentOf(obj2, TInventory); } } actor.Inventory = (UnityAlive(obj) ? obj : null); return actor.Inventory; } private static bool InvokeInventory(object inv, MethodInfo method, object index, int count) { if (inv == null || method == null) { return false; } try { ParameterInfo[] parameters = method.GetParameters(); object obj = index; if (TItemDef != null && parameters.Length != 0 && parameters[0].ParameterType == TItemDef && _getItemDef != null) { obj = _getItemDef.Invoke(null, new object[1] { index }); } else if (parameters.Length != 0) { obj = Hook.Coerce(index, parameters[0].ParameterType); } if (parameters.Length == 1) { method.Invoke(inv, new object[1] { obj }); } else if (parameters.Length == 2) { method.Invoke(inv, new object[2] { obj, Hook.Coerce(count, parameters[1].ParameterType) }); } else { if (parameters.Length < 3) { return false; } object obj2 = null; if (parameters[2].ParameterType == typeof(bool) || parameters[2].ParameterType == typeof(bool?)) { obj2 = false; } else if (parameters[2].ParameterType.IsValueType) { obj2 = Activator.CreateInstance(parameters[2].ParameterType); } method.Invoke(inv, new object[3] { obj, Hook.Coerce(count, parameters[1].ParameterType), obj2 }); } return true; } catch (Exception ex) { Log.Warn(method.Name + " failed: " + (ex.InnerException ?? ex).Message); return false; } } private static bool TryWriteStacks(object inv, int itemIndex, int count) { if (inv == null || _itemStacks == null || itemIndex < 0) { return false; } object value = _itemStacks.GetValue(inv); if (value is int[] array) { if (itemIndex >= array.Length) { return false; } array[itemIndex] = Math.Max(0, array[itemIndex] + count); _itemStacks.SetValue(inv, array); return true; } if (value is Array array2 && itemIndex < array2.Length) { int num = Convert.ToInt32(array2.GetValue(itemIndex)); array2.SetValue(Math.Max(0, num + count), itemIndex); return true; } return false; } public static int ItemCount(Actor actor, int itemIndex) { object obj = InventoryOf(actor); if (obj == null || _getItemCount == null) { return 0; } object obj2 = Hook.Call(_getItemCount, obj, IndexValue.FromInt(TItemIndex, itemIndex)); if (obj2 != null) { return Convert.ToInt32(obj2); } return 0; } public static void ClearInventory(Actor actor) { if (actor != null && !CoOp.AskHost("slipstream_clear " + NetId(actor))) { ClearInventoryLocal(actor); } } public static void ClearInventoryLocal(Actor actor) { object obj = InventoryOf(actor); if (obj == null) { return; } foreach (CatalogItem item in Items()) { int num = ItemCount(actor, item.Index); if (num > 0 && _removeItem != null) { Hook.Call(_removeItem, obj, IndexValue.FromInt(TItemIndex, item.Index), num); } } LastActionMessage = "Cleared inventory for " + actor.Name + "."; } public static void GiveAllItems(Actor actor, int stacks) { if (actor != null && !CoOp.AskHost("slipstream_giveall " + NetId(actor) + " " + stacks)) { GiveAllItemsLocal(actor, stacks); } } public static void GiveAllItemsLocal(Actor actor, int stacks) { bool flag = default(bool); foreach (CatalogItem item in Items()) { int num; if (item.Def != null && _itemHidden != null) { object value = _itemHidden.GetValue(item.Def); if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) == 0) { GiveItemLocal(actor, item.Index, stacks); } } LastActionMessage = "Gave all items ×" + stacks + " to " + actor.Name + "."; } public static void SetEquipment(Actor actor, int equipmentIndex) { if (actor != null && !CoOp.AskHost("slipstream_equip " + NetId(actor) + " " + equipmentIndex)) { SetEquipmentLocal(actor, equipmentIndex); } } public static void SetEquipmentLocal(Actor actor, int equipmentIndex) { object obj = InventoryOf(actor); if (obj != null && !(_setEquipment == null)) { object obj2 = IndexValue.FromInt(TEquipmentIndex, equipmentIndex); if (_setEquipment.GetParameters().Length == 1) { Hook.Call(_setEquipment, obj, obj2); } else { Hook.Call(_setEquipment, obj, obj2, false); } } } public static void SetBuff(Actor actor, int buffIndex, int count) { if (actor != null && !CoOp.AskHost("slipstream_buff " + NetId(actor) + " " + buffIndex + " " + count)) { SetBuffLocal(actor, buffIndex, count); } } public static void SetBuffLocal(Actor actor, int buffIndex, int count) { if (actor == null || actor.Body == null) { return; } object obj = IndexValue.FromInt(TBuffIndex, buffIndex); if (_setBuffCount != null) { Hook.Call(_setBuffCount, actor.Body, obj, count); } else if (count > 0 && _addTimedBuff != null) { if (_addTimedBuff.GetParameters().Length == 2) { Hook.Call(_addTimedBuff, actor.Body, obj, 60f); } else { Hook.Call(_addTimedBuff, actor.Body, obj, count, 60f); } } } public static void Kill(object body) { if (body == null) { return; } object obj = ((_bodyHealth != null) ? Hook.Get(_bodyHealth, body) : null); if (obj == null) { Component val = (Component)((body is Component) ? body : null); if (val != null && THealthComponent != null) { obj = val.GetComponent(THealthComponent); } } if (obj != null && _suicide != null) { if (_suicide.GetParameters().Length == 0) { Hook.Call(_suicide, obj); } else { Hook.Call(_suicide, obj, null, null, null); } } } public static void KillAllMobs() { int num = 0; foreach (object item in Bodies()) { if (TeamOf(item) != 1) { Kill(item); num++; } } LastActionMessage = "Killed " + num + " non-player bodies."; Log.Info(LastActionMessage); } public static void Revive(Actor actor) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_00cf: 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) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if (actor == null || actor.Master == null || CoOp.AskHost("slipstream_revive " + NetId(actor))) { return; } Vector3 val = (Object.op_Implicit((Object)(object)actor.Transform) ? actor.Transform.position : Vector3.zero); Quaternion val2 = (Object.op_Implicit((Object)(object)actor.Transform) ? actor.Transform.rotation : Quaternion.identity); if (_respawnAt != null) { if (_respawnAt.GetParameters().Length == 2) { Hook.Call(_respawnAt, actor.Master, val, val2); } else { Hook.Call(_respawnAt, actor.Master, val, val2, true); } } else if (_respawn != null) { Hook.Call(_respawn, actor.Master); } LastActionMessage = "Revived " + actor.Name + "."; } public static void Teleport(Actor actor, Vector3 position) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (actor != null && actor.Body != null) { if (_teleportBody != null) { Hook.Call(_teleportBody, actor.Body, position); } else if (Object.op_Implicit((Object)(object)actor.Transform)) { actor.Transform.position = position; } } } public static void SpawnAs(Actor actor, GameObject bodyPrefab) { SpawnAsBody(actor, bodyPrefab); } public static void SpawnAsSurvivor(Actor actor, object survivorDef) { GameObject val = BodyPrefabOf(survivorDef); if (!Object.op_Implicit((Object)(object)val)) { object obj = ((survivorDef is Object) ? survivorDef : null); LastActionMessage = "Could not resolve a body prefab for " + (((obj != null) ? ((Object)obj).name : null) ?? "that survivor") + "."; Log.Warn(LastActionMessage); } else { SpawnAsBody(actor, val); } } public static void SpawnAsNamed(Actor actor, string bodyName) { SpawnAsBody(actor, FindBodyPrefab(bodyName)); } private static void SpawnAsBody(Actor actor, GameObject prefab) { if (actor == null || actor.Master == null) { LastActionMessage = "No player master to spawn as."; Log.Warn(LastActionMessage); } else if (!Object.op_Implicit((Object)(object)prefab)) { LastActionMessage = "Body prefab was null."; Log.Warn(LastActionMessage); } else { if (CoOp.AskHost("slipstream_spawnas " + NetId(actor) + " " + ((Object)prefab).name)) { return; } Log.Info("Spawn as " + ((Object)prefab).name + " on " + actor.Name + "."); bool flag = false; if (_transformBody != null) { try { ParameterInfo[] parameters = _transformBody.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string)) { Hook.Call(_transformBody, actor.Master, ((Object)prefab).name); flag = true; } else if (parameters.Length == 1) { Hook.Call(_transformBody, actor.Master, Hook.Coerce(prefab, parameters[0].ParameterType)); flag = true; } } catch (Exception ex) { Log.Warn("TransformBody failed: " + (ex.InnerException ?? ex).Message); } } if (!flag) { if (_masterBodyPrefab != null) { Hook.Set(_masterBodyPrefab, actor.Master, prefab); } else if (_masterBodyPrefabField != null) { _masterBodyPrefabField.SetValue(actor.Master, prefab); } Revive(actor); } LastActionMessage = "Spawning as " + ((Object)prefab).name + "."; if (Session.ForcedTeam != int.MinValue) { ApplyTeamLocal(actor.IsLocal ? (LocalActor() ?? actor) : actor, Session.ForcedTeam); } } } public static string BodyDisplayName(Actor actor) { if (actor == null || actor.Body == null) { return null; } string text = ((_bodyNameToken != null) ? (Hook.Get(_bodyNameToken, actor.Body) as string) : null); string text2 = Localize(text); if (string.IsNullOrEmpty(text2) || text2 == text) { object body = actor.Body; object obj = ((body is Component) ? body : null); text2 = ((obj != null) ? ((Object)obj).name : null); } if (!string.IsNullOrEmpty(text2)) { return text2; } return actor.Name; } public static int CurrentSkinIndex(Actor actor) { if (actor == null || actor.Body == null) { return -1; } Component val = ModelSkinOf(actor); if ((Object)(object)val != (Object)null && _mscCurrentSkin != null) { return IndexValue.ToInt(Hook.Get(_mscCurrentSkin, val)); } if (_bodySkinIndex != null) { return IndexValue.ToInt(Hook.Get(_bodySkinIndex, actor.Body)); } return -1; } public static List<CatalogItem> SkinsFor(Actor actor) { List<CatalogItem> list = new List<CatalogItem>(); Array array = SkinArray(actor); if (array == null) { return list; } for (int i = 0; i < array.Length; i++) { object obj = null; try { obj = array.GetValue(i); } catch { continue; } if (obj != null) { list.Add(new CatalogItem { Index = i, Def = obj, Name = SkinDisplayName(obj, i) }); } } return list; } public static void QueueSkin(Actor actor, int skinIndex) { if (actor != null && actor.Body != null && skinIndex >= 0) { Session.PendingSkinActorId = actor.Id; Session.PendingSkinIndex = skinIndex; } } public static void DrainPendingSkin() { if (Session.PendingSkinIndex >= 0 && !SkinBusy) { int pendingSkinActorId = Session.PendingSkinActorId; int pendingSkinIndex = Session.PendingSkinIndex; Session.PendingSkinIndex = -1; ApplySkin(FindPlayer(pendingSkinActorId) ?? LocalActor(), pendingSkinIndex); } } public static void ApplySkin(Actor actor, int skinIndex) { if (actor == null || actor.Body == null || skinIndex < 0 || SkinBusy) { return; } Array array = SkinArray(actor); if (array == null || skinIndex >= array.Length) { Log.Warn("No skins array for this body."); return; } Component val = ModelSkinOf(actor); if ((Object)(object)val == (Object)null) { Log.Warn("No ModelSkinController on this body."); return; } _skinBusy = true; _skinBusyUntil = Time.unscaledTime + 12f; Log.Info("Applying skin " + skinIndex + " on " + actor.Name + "."); SlipstreamPlugin.Run(ApplySkinRoutine(actor, skinIndex, val)); } private static IEnumerator ApplySkinRoutine(Actor actor, int skinIndex, object msc) { yield return null; object started = null; try { started = InvokeApplySkinAsync(msc, skinIndex); } catch (Exception ex) { Log.Warn("ApplySkinAsync threw: " + (ex.InnerException ?? ex).Message); } if (started == null) { Log.Warn("ApplySkinAsync did not start. SkinDef.Apply was not used."); _skinBusy = false; yield break; } Log.Info("ApplySkinAsync started for skin " + skinIndex + " (" + started.GetType().Name + ")."); if (started is IEnumerator routine) { float until = Time.unscaledTime + 12f; while (routine.MoveNext() && !(Time.unscaledTime > until)) { yield return routine.Current; } } else { IEnumerator pump = UniTaskToCoroutine(started); float until = Time.unscaledTime + 10f; if (pump != null) { while (pump.MoveNext() && !(Time.unscaledTime > until)) { yield return pump.Current; } } else { ForgetUniTask(started); while (Time.unscaledTime < until && !UniTaskCompleted(started)) { yield return null; } } } WriteSkinLoadout(actor, skinIndex); if (IsServer) { PushLoadout(actor); } else { CoOp.Submit("slipstream_skin " + NetId(actor) + " " + skinIndex); } _skinBusy = false; Log.Info("Skin " + skinIndex + " apply finished."); } private static void PushLoadout(Actor actor) { if (actor == null || actor.Master == null || _setLoadoutServer == null) { return; } try { object obj = ((_masterLoadout != null) ? Hook.Get(_masterLoadout, actor.Master) : Bind(actor.Master, "loadout", "_loadout")); if (obj != null) { Hook.Call(_setLoadoutServer, actor.Master, obj); } } catch (Exception ex) { Log.Warn("SetLoadoutServer skipped: " + ex.Message); } } private static object InvokeApplySkinAsync(object msc, int skinIndex) { if (msc == null || TModelSkinController == null) { return null; } MethodInfo methodInfo = null; MethodInfo methodInfo2 = null; MethodInfo[] methods = TModelSkinController.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo3 in methods) { if (methodInfo3.Name != "ApplySkinAsync" || methodInfo3.IsGenericMethod) { continue; } ParameterInfo[] parameters = methodInfo3.GetParameters(); if (parameters.Length >= 1 && parameters.Length <= 2) { if (typeof(IEnumerator).IsAssignableFrom(methodInfo3.ReturnType)) { methodInfo = methodInfo3; } else { methodInfo2 = methodInfo3; } } } MethodInfo methodInfo4 = methodInfo ?? methodInfo2 ?? _applySkinAsync; if (methodInfo4 == null) { return null; } try { object[] array = ArgsForApplySkinAsync(methodInfo4, skinIndex); if (array == null) { return null; } Log.Info("Invoking " + methodInfo4); return methodInfo4.Invoke(msc, array); } catch (Exception ex) { Log.Warn("ApplySkinAsync failed: " + (ex.InnerException ?? ex).Message); return null; } } private static object[] ArgsForApplySkinAsync(MethodInfo method, int skinIndex) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length < 1 || parameters.Length > 2) { return null; } object[] array = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; if (parameterType == typeof(int) || parameterType == typeof(uint) || (parameterType.IsEnum && parameterType.Name.IndexOf("Unload", StringComparison.OrdinalIgnoreCase) < 0)) { array[i] = Hook.Coerce(skinIndex, parameterType); } else if (parameterType.IsEnum) { array[i] = ParseNamedEnum(parameterType, "OnRunEnd", "AtWill", "OnSceneUnload"); } else if (parameterType.IsValueType) { array[i] = Activator.CreateInstance(parameterType); } else { array[i] = null; } } return array; } private static object ParseNamedEnum(Type type, params string[] names) { if (type == null || !type.IsEnum) { return null; } foreach (string value in names) { try { return Enum.Parse(type, value); } catch { } } return Enum.ToObject(type, 0); } private static void ForgetUniTask(object task) { if (task == null) { return; } Type type = task.GetType(); string[] array = new string[2] { "Cysharp.Threading.Tasks.UniTaskExtensions", "Cysharp.Threading.Tasks.UniTask" }; for (int i = 0; i < array.Length; i++) { Type type2 = Hook.Type(array[i]); if (type2 == null) { continue; } MethodInfo[] methods = type2.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "Forget") { continue; } try { MethodInfo methodInfo2 = (methodInfo.IsGenericMethod ? methodInfo.MakeGenericMethod(type) : methodInfo); if (methodInfo2.GetParameters().Length == 1) { methodInfo2.Invoke(null, new object[1] { task }); return; } } catch { } } } } private static IEnumerator UniTaskToCoroutine(object task) { if (task == null) { yield break; } IEnumerator inner = null; Type type = task.GetType(); Type type2 = Hook.Type("Cysharp.Threading.Tasks.UniTaskExtensions"); if (type2 != null) { MethodInfo[] methods = type2.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "ToCoroutine" || methodInfo.GetParameters().Length != 1) { continue; } try { MethodInfo methodInfo2 = methodInfo; if (!methodInfo.IsGenericMethod) { goto IL_00b6; } if (!type.IsGenericType) { continue; } methodInfo2 = methodInfo.MakeGenericMethod(type.GetGenericArguments()); goto IL_00b6; IL_00b6: if (methodInfo2.Invoke(null, new object[1] { task }) is IEnumerator enumerator) { inner = enumerator; break; } } catch (Exception ex) { Log.Warn("ToCoroutine skipped: " + (ex.InnerException ?? ex).Message); } } } if (inner != null) { while (inner.MoveNext()) { yield return inner.Current; } yield break; } ForgetUniTask(task); float until = Time.unscaledTime + 10f; while (Time.unscaledTime < until && !UniTaskCompleted(task)) { yield return null; } } private static bool UniTaskCompleted(object task) { if (task == null) { return true; } object obj = Hook.Get(Hook.Member(task.GetType(), "Status", "status"), task); if (obj == null) { return false; } try { return Convert.ToInt32(obj) != 0; } catch { return false; } } private static string SkinDisplayName(object def, int index) { string text = ((_skinNameToken != null) ? (_skinNameToken.GetValue(def) as string) : null); string text2 = Localize(text); if (string.IsNullOrEmpty(text2) || text2 == text) { object obj = ((def is Object) ? def : null); text2 = ((obj != null) ? ((Object)obj).name : null); } if (!string.IsNullOrEmpty(text2)) { return text2; } return "Skin " + index; } private static object BodyIndexOf(Actor actor) { if (actor == null || actor.Body == null || _bodyIndex == null) { return null; } return Hook.Get(_bodyIndex, actor.Body); } private static Component ModelSkinOf(Actor actor) { object obj = actor?.Body; Component val = (Component)((obj is Component) ? obj : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } if (TModelLocator != null) { Component component = val.GetComponent(TModelLocator); if (Object.op_Implicit((Object)(object)component)) { object obj2 = Bind(component, "modelTransform", "_modelTransform"); Transform val2 = (Transform)((obj2 is Transform) ? obj2 : null); if (Object.op_Implicit((Object)(object)val2) && TModelSkinController != null) { Component component2 = ((Component)val2).GetComponent(TModelSkinController); if (Object.op_Implicit((Object)(object)component2)) { return component2; } } } } if (TModelSkinController != null) { Component componentInChildren = val.GetComponentInChildren(TModelSkinController, true); if (Object.op_Implicit((Object)(object)componentInChildren)) { return componentInChildren; } } return null; } private static Array SkinArray(Actor actor) { Component val = ModelSkinOf(actor); if ((Object)(object)val != (Object)null && _mscSkins != null && _mscSkins.GetValue(val) is Array { Length: >0 } array) { return array; } object obj = BodyIndexOf(actor); if (obj == null) { return null; } if (_getBodySkins != null) { try { ParameterInfo[] parameters = _getBodySkins.GetParameters(); object obj2 = obj; if (parameters.Length == 1) { obj2 = Hook.Coerce(obj, parameters[0].ParameterType); } if (_getBodySkins.Invoke(null, new object[1] { obj2 }) is Array { Length: >0 } array2) { return array2; } } catch { } } if (_catalogSkins?.GetValue(null) is Array array3) { try { int num = IndexValue.ToInt(obj); if (num >= 0 && num < array3.Length && array3.GetValue(num) is Array { Length: >0 } array4) { return array4; } } catch { } } return null; } private static void WriteSkinLoadout(Actor actor, int skinIndex) { if (actor.Master == null) { return; } try { object obj = ((_masterLoadout != null) ? Hook.Get(_masterLoadout, actor.Master) : Bind(actor.Master, "loadout", "_loadout")); object obj2 = ((obj != null && _loadoutBodyManager != null) ? _loadoutBodyManager.GetValue(obj) : null); object obj3 = BodyIndexOf(actor