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 RepoCommandConsole v2.0.0
RepoCommandConsole.dll
Decompiled 6 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.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Pipes; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Photon.Pun; using Photon.Realtime; using REPOLib.Modules; using RepoLiveControl.Commands; using RepoLiveControl.Networking; using RepoLiveControl.Runtime; using UnityEngine; using UnityEngine.AI; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [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("RepoCommandConsole")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Host-authoritative R.E.P.O. command console with fuzzy autocomplete and delegated client permissions.")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0+a45269048a6bbb6b3902670edb7323a8d213f586")] [assembly: AssemblyProduct("RepoCommandConsole")] [assembly: AssemblyTitle("RepoCommandConsole")] [assembly: AssemblyVersion("2.0.0.0")] namespace RepoLiveControl { internal sealed class CommandConsoleRuntime : IDisposable { private const string InputControlName = "RepoCommandConsole.Input"; private const int WindowId = 198042; private const int SuggestionLimit = 8; private readonly Plugin plugin; private readonly ConfigEntry<KeyCode> toggleKey; private readonly ConfigEntry<int> networkEventCode; private readonly List<string> history = new List<string>(); private readonly ConsoleInputGate inputGate = new ConsoleInputGate(); private Rect windowRect; private string input = "/"; private string result = "Ready. Type /help or use fuzzy autocomplete."; private IReadOnlyList<CompletionItem> suggestions = Array.AsReadOnly(new CompletionItem[0]); private CompletionCatalog catalog = CompletionCatalog.Empty; private int selectedSuggestion; private int pendingCaretPosition = -1; private int completionCaretPosition = 1; private bool open; private bool focusInput; private bool releaseGuiFocus; private bool stylesReady; private bool localPermissionKnown; private bool localPermissionGranted; private long observedPermissionSessionRevision; private float catalogRefreshAt; private GUIStyle windowStyle; private GUIStyle titleStyle; private GUIStyle hintStyle; private GUIStyle inputStyle; private GUIStyle suggestionStyle; private GUIStyle selectedSuggestionStyle; private GUIStyle resultStyle; private Texture2D windowBackground; private Texture2D selectedBackground; internal PermissionService Permissions { get; private set; } internal CommandNetworkRouter Network { get; private set; } internal string ToggleKeyLabel => ((object)toggleKey.Value/*cast due to .constrained prefix*/).ToString(); internal CommandConsoleRuntime(Plugin plugin) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) this.plugin = plugin; toggleKey = ((BaseUnityPlugin)plugin).Config.Bind<KeyCode>("Console", "ToggleKey", (KeyCode)283, "Key used to open and close the independent in-game command console."); networkEventCode = ((BaseUnityPlugin)plugin).Config.Bind<int>("Networking", "PhotonEventCode", 198, "Fixed Photon custom event code shared by all clients (3-199). Change only if another mod collides."); int num = Mathf.Clamp(networkEventCode.Value, 3, 199); if (num != networkEventCode.Value) { networkEventCode.Value = num; ((BaseUnityPlugin)plugin).Config.Save(); } Permissions = new PermissionService(); observedPermissionSessionRevision = Permissions.SessionRevision; Network = new CommandNetworkRouter((byte)num, Permissions, SetResult); windowRect = new Rect(0f, 90f, 860f, 510f); } internal void Update() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Network.Update(IsNetworkSessionSceneActive()); Bridge.PublishPermissionSessionRevision(Permissions.SessionRevision); if (observedPermissionSessionRevision != Permissions.SessionRevision) { observedPermissionSessionRevision = Permissions.SessionRevision; localPermissionKnown = false; localPermissionGranted = false; } if (inputGate.TryAccept(ConsoleInputAction.Toggle, Time.frameCount, Input.GetKeyDown(toggleKey.Value), IsInputSystemKeyPressedThisFrame(toggleKey.Value), guiPressedThisFrame: false)) { SetOpen(!open); } else { if (!open) { return; } if (TryAcceptInputAction(ConsoleInputAction.Close, (KeyCode)27, (KeyCode)0)) { SetOpen(value: false); return; } if (TryAcceptInputAction(ConsoleInputAction.AcceptCompletion, (KeyCode)9, (KeyCode)0)) { AcceptSelectedSuggestion(appendSpace: true); } else if (TryAcceptInputAction(ConsoleInputAction.SelectPrevious, (KeyCode)273, (KeyCode)0) && suggestions.Count > 0) { selectedSuggestion = (selectedSuggestion - 1 + suggestions.Count) % suggestions.Count; } else if (TryAcceptInputAction(ConsoleInputAction.SelectNext, (KeyCode)274, (KeyCode)0) && suggestions.Count > 0) { selectedSuggestion = (selectedSuggestion + 1) % suggestions.Count; } else if (TryAcceptInputAction(ConsoleInputAction.Submit, (KeyCode)13, (KeyCode)271)) { SubmitInput(); } try { SemiFunc.InputDisableMovement(); SemiFunc.InputDisableAiming(); SemiFunc.CursorUnlock(0.1f); if ((Object)(object)MenuManager.instance != (Object)null) { MenuManager.instance.TextInputActive(); } if ((Object)(object)PlayerController.instance != (Object)null) { PlayerController.instance.InputDisable(0.1f); } } catch { } if (Time.realtimeSinceStartup >= catalogRefreshAt) { RefreshCatalog(); catalogRefreshAt = Time.realtimeSinceStartup + 1f; } } } internal void OnGUI() { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_014f: 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) ReleaseGuiFocusIfRequested(); if (open) { EnsureStyles(); float num = Mathf.Min(900f, Mathf.Max(540f, (float)Screen.width - 40f)); ((Rect)(ref windowRect)).width = num; ((Rect)(ref windowRect)).height = Mathf.Min(600f, Mathf.Max(440f, (float)Screen.height - 120f)); ((Rect)(ref windowRect)).x = Mathf.Clamp(((Rect)(ref windowRect)).x, 10f, Mathf.Max(10f, (float)Screen.width - num - 10f)); ((Rect)(ref windowRect)).y = Mathf.Clamp(((Rect)(ref windowRect)).y, 10f, Mathf.Max(10f, (float)Screen.height - ((Rect)(ref windowRect)).height - 10f)); if (((Rect)(ref windowRect)).x <= 0f) { ((Rect)(ref windowRect)).x = ((float)Screen.width - num) * 0.5f; } HandleKeyboardEvent(Event.current); if (!open) { ReleaseGuiFocusIfRequested(); } else { windowRect = GUI.Window(198042, windowRect, new WindowFunction(DrawWindow), string.Empty, windowStyle); } } } private void DrawWindow(int windowId) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Invalid comparison between Unknown and I4 //IL_03ec: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Label("REPO COMMAND CONSOLE • " + RoleLabel(), titleStyle, Array.Empty<GUILayoutOption>()); GUILayout.Label(ToggleKeyLabel + " / Esc closes • ↑↓ selects • Tab accepts • Enter runs", hintStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); GUI.SetNextControlName("RepoCommandConsole.Input"); string a = GUILayout.TextField(input, inputStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(38f) }); bool num = !string.Equals(a, input, StringComparison.Ordinal); if (num) { input = a; } if (focusInput) { GUI.FocusControl("RepoCommandConsole.Input"); focusInput = false; } TextEditor focusedInputEditor = GetFocusedInputEditor(); if (pendingCaretPosition >= 0 && focusedInputEditor != null && (int)Event.current.type == 7) { int selectIndex = (focusedInputEditor.cursorIndex = Mathf.Clamp(pendingCaretPosition, 0, input.Length)); focusedInputEditor.selectIndex = selectIndex; pendingCaretPosition = -1; } int num3 = ((pendingCaretPosition >= 0) ? Mathf.Clamp(pendingCaretPosition, 0, input.Length) : ((focusedInputEditor != null) ? Mathf.Clamp(focusedInputEditor.cursorIndex, 0, input.Length) : Mathf.Clamp(completionCaretPosition, 0, input.Length))); bool flag = num3 != completionCaretPosition; completionCaretPosition = num3; if (num || flag) { selectedSuggestion = 0; RefreshSuggestions(); } GUILayout.Space(6f); GUILayout.Label("FUZZY AUTOCOMPLETE", hintStyle, Array.Empty<GUILayoutOption>()); if (suggestions.Count == 0) { GUILayout.Label("No completion for the active argument.", hintStyle, Array.Empty<GUILayoutOption>()); } else { for (int i = 0; i < suggestions.Count; i++) { CompletionItem completionItem = suggestions[i]; string obj = ((i == selectedSuggestion) ? "▶ " : " "); GUIStyle val = ((i == selectedSuggestion) ? selectedSuggestionStyle : suggestionStyle); if (GUILayout.Button(obj + completionItem.Value, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { selectedSuggestion = i; AcceptSelectedSuggestion(appendSpace: true); } } } GUILayout.FlexibleSpace(); GUILayout.Label("RESULT", hintStyle, Array.Empty<GUILayoutOption>()); GUILayout.Label(result, resultStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinHeight(48f), GUILayout.MaxHeight(72f) }); if (history.Count > 0) { GUILayout.Label(string.Join("\n", history.ToArray()), hintStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxHeight(72f) }); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Help", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { input = "/help"; SubmitInput(); } if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { input = "/"; completionCaretPosition = input.Length; result = "Ready."; history.Clear(); RefreshSuggestions(); focusInput = true; } if (GUILayout.Button("Run", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { SubmitInput(); } if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { SetOpen(value: false); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref windowRect)).width, 44f)); } private void HandleKeyboardEvent(Event current) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Invalid comparison between Unknown and I4 //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Invalid comparison between Unknown and I4 //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Invalid comparison between Unknown and I4 //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Invalid comparison between Unknown and I4 if (current == null || (int)current.type != 4) { return; } if (current.keyCode == toggleKey.Value) { if (inputGate.TryAccept(ConsoleInputAction.Toggle, Time.frameCount, legacyPressedThisFrame: false, inputSystemPressedThisFrame: false, guiPressedThisFrame: true)) { SetOpen(!open); } current.Use(); } else if ((int)current.keyCode == 27) { if (AcceptGuiInput(ConsoleInputAction.Close)) { SetOpen(value: false); } current.Use(); } else if ((int)current.keyCode == 9) { if (AcceptGuiInput(ConsoleInputAction.AcceptCompletion)) { AcceptSelectedSuggestion(appendSpace: true); } current.Use(); } else if ((int)current.keyCode == 273 && suggestions.Count > 0) { if (AcceptGuiInput(ConsoleInputAction.SelectPrevious)) { selectedSuggestion = (selectedSuggestion - 1 + suggestions.Count) % suggestions.Count; } current.Use(); } else if ((int)current.keyCode == 274 && suggestions.Count > 0) { if (AcceptGuiInput(ConsoleInputAction.SelectNext)) { selectedSuggestion = (selectedSuggestion + 1) % suggestions.Count; } current.Use(); } else if ((int)current.keyCode == 13 || (int)current.keyCode == 271) { if (AcceptGuiInput(ConsoleInputAction.Submit)) { SubmitInput(); } current.Use(); } } private static bool IsNetworkSessionSceneActive() { RunManager instance = RunManager.instance; if ((Object)(object)instance == (Object)null) { return NetworkSessionSceneActivationPolicy.ShouldActivate(managerAvailable: false, currentLevelAvailable: false, isLobby: false, isGameplay: false, isShop: false, isArena: false); } Level levelCurrent = instance.levelCurrent; if ((Object)(object)levelCurrent == (Object)null) { return NetworkSessionSceneActivationPolicy.ShouldActivate(managerAvailable: true, currentLevelAvailable: false, isLobby: false, isGameplay: false, isShop: false, isArena: false); } return NetworkSessionSceneActivationPolicy.ShouldActivate(managerAvailable: true, currentLevelAvailable: true, (Object)(object)levelCurrent == (Object)(object)instance.levelLobby, ContainsLevel(instance.levels, levelCurrent), ContainsLevel(instance.levelShop, levelCurrent), ContainsLevel(instance.levelArena, levelCurrent)); } private static bool ContainsLevel(IList<Level> levels, Level current) { return levels?.Contains(current) ?? false; } private bool TryAcceptInputAction(ConsoleInputAction action, KeyCode primaryKey, KeyCode secondaryKey = (KeyCode)0) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) bool legacyPressedThisFrame = Input.GetKeyDown(primaryKey) || ((int)secondaryKey != 0 && Input.GetKeyDown(secondaryKey)); bool inputSystemPressedThisFrame = IsInputSystemKeyPressedThisFrame(primaryKey) || ((int)secondaryKey != 0 && IsInputSystemKeyPressedThisFrame(secondaryKey)); return inputGate.TryAccept(action, Time.frameCount, legacyPressedThisFrame, inputSystemPressedThisFrame, guiPressedThisFrame: false); } private bool AcceptGuiInput(ConsoleInputAction action) { return inputGate.TryAccept(action, Time.frameCount, legacyPressedThisFrame: false, inputSystemPressedThisFrame: false, guiPressedThisFrame: true); } private void SubmitInput() { string text = (input ?? string.Empty).Trim(); CommandParseResult commandParseResult = SlashCommandParser.Parse(text); if (!commandParseResult.Success) { SetResult("ERROR " + commandParseResult.ErrorMessage); focusInput = true; return; } AddHistory("> " + text); result = "PENDING Sending command to " + ((!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) ? "host executor..." : "lobby host..."); try { if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { int requesterActorNumber = ((PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1)); long requiredSessionRevision = Permissions.SessionRevision; Bridge.Enqueue(new ControlRequest(text, CommandRequestSource.LocalConsole, requesterActorNumber, SetResult, requiredSessionRevision, () => Permissions.SessionRevision == requiredSessionRevision)); } else { Network.SendRequest(text); } } catch (Exception ex) { SetResult("ERROR " + ex.Message); } focusInput = true; } private void SetResult(string value) { result = (string.IsNullOrWhiteSpace(value) ? "ERROR Empty command response." : value); AddHistory(result); if (result.IndexOf("granted you", StringComparison.OrdinalIgnoreCase) >= 0) { localPermissionKnown = true; localPermissionGranted = true; } else if (result.IndexOf("revoked your", StringComparison.OrdinalIgnoreCase) >= 0 || result.IndexOf("has not granted", StringComparison.OrdinalIgnoreCase) >= 0) { localPermissionKnown = true; localPermissionGranted = false; } if (Plugin.Log != null) { Plugin.Log.LogInfo((object)("Console result: " + result)); } } private void AddHistory(string value) { if (!string.IsNullOrWhiteSpace(value)) { history.Insert(0, (value.Length > 140) ? (value.Substring(0, 140) + "…") : value); while (history.Count > 3) { history.RemoveAt(history.Count - 1); } } } private void AcceptSelectedSuggestion(bool appendSpace) { if (suggestions.Count != 0) { selectedSuggestion = Mathf.Clamp(selectedSuggestion, 0, suggestions.Count - 1); CompletionApplication completionApplication = CommandCompletionEngine.ApplyCompletion(input, suggestions[selectedSuggestion], appendSpace); input = completionApplication.Text; pendingCaretPosition = completionApplication.CaretPosition; completionCaretPosition = completionApplication.CaretPosition; selectedSuggestion = 0; RefreshSuggestions(); focusInput = true; } } private void RefreshCatalog() { List<string> list = new List<string>(); List<string> list2 = new List<string>(); bool flag = !PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient; if (flag) { list.AddRange(Permissions.GetGrantCandidates()); list2.AddRange(Permissions.GetRevokeCandidates()); } catalog = new CompletionCatalog(RuntimeTargetCatalog.GetSelectors(includeAll: true), list, list2, flag); RefreshSuggestions(); } private void RefreshSuggestions() { try { suggestions = CommandCompletionEngine.GetCompletions(input, Mathf.Clamp(completionCaretPosition, 0, (input != null) ? input.Length : 0), catalog, 8); } catch (Exception ex) { suggestions = Array.AsReadOnly(new CompletionItem[0]); if (Plugin.Log != null) { Plugin.Log.LogWarning((object)("Could not refresh command suggestions: " + ex.Message)); } } if (selectedSuggestion >= suggestions.Count) { selectedSuggestion = 0; } } private string RoleLabel() { if (!PhotonNetwork.InRoom) { return "LOCAL HOST"; } if (PhotonNetwork.IsMasterClient) { return "LOBBY HOST"; } if (!localPermissionKnown) { return "CLIENT • PERMISSION UNKNOWN"; } if (!localPermissionGranted) { return "CLIENT • NOT GRANTED"; } return "CLIENT • PERMISSION GRANTED"; } private void SetOpen(bool value) { open = value; if (open) { if (string.IsNullOrWhiteSpace(input)) { input = "/"; } ((Rect)(ref windowRect)).x = ((float)Screen.width - ((Rect)(ref windowRect)).width) * 0.5f; ((Rect)(ref windowRect)).y = Mathf.Max(20f, (float)Screen.height * 0.08f); focusInput = true; pendingCaretPosition = input.Length; completionCaretPosition = input.Length; releaseGuiFocus = false; RefreshCatalog(); result = "Ready. Chat is not required; this console uses its own input path."; } else { releaseGuiFocus = true; } if (Plugin.Log != null) { Plugin.Log.LogInfo((object)("Command console " + (open ? "opened." : "closed."))); } } private static TextEditor GetFocusedInputEditor() { if (!string.Equals(GUI.GetNameOfFocusedControl(), "RepoCommandConsole.Input", StringComparison.Ordinal)) { return null; } object stateObject = GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl); return (TextEditor)((stateObject is TextEditor) ? stateObject : null); } private unsafe static bool IsInputSystemKeyPressedThisFrame(KeyCode keyCode) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current == null) { return false; } if (!Enum.TryParse<Key>(ConsoleToggleKeyMapping.ToInputSystemKeyName(((object)(*(KeyCode*)(&keyCode))/*cast due to .constrained prefix*/).ToString()), ignoreCase: true, out Key val) || (int)val == 0) { return false; } if (current[val] != null) { return ((ButtonControl)current[val]).wasPressedThisFrame; } return false; } private void ReleaseGuiFocusIfRequested() { if (releaseGuiFocus) { GUI.FocusControl((string)null); releaseGuiFocus = false; } } private void EnsureStyles() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Expected O, but got Unknown //IL_02a5: Unknown result type (might be due to invalid IL or missing references) if (!stylesReady) { stylesReady = true; windowBackground = MakeTexture(new Color(0.035f, 0.045f, 0.055f, 0.97f)); selectedBackground = MakeTexture(new Color(0.16f, 0.24f, 0.19f, 0.98f)); windowStyle = new GUIStyle(GUI.skin.window); windowStyle.normal.background = windowBackground; windowStyle.padding = new RectOffset(20, 20, 16, 18); titleStyle = new GUIStyle(GUI.skin.label); titleStyle.fontSize = 22; titleStyle.fontStyle = (FontStyle)1; titleStyle.normal.textColor = new Color(1f, 0.86f, 0.12f); hintStyle = new GUIStyle(GUI.skin.label); hintStyle.fontSize = 13; hintStyle.wordWrap = true; hintStyle.normal.textColor = new Color(0.72f, 0.78f, 0.8f); inputStyle = new GUIStyle(GUI.skin.textField); inputStyle.fontSize = 20; inputStyle.padding = new RectOffset(10, 10, 7, 6); inputStyle.normal.textColor = Color.white; inputStyle.focused.textColor = Color.white; suggestionStyle = new GUIStyle(GUI.skin.button); suggestionStyle.alignment = (TextAnchor)3; suggestionStyle.fontSize = 15; suggestionStyle.normal.textColor = new Color(0.86f, 0.9f, 0.91f); selectedSuggestionStyle = new GUIStyle(suggestionStyle); selectedSuggestionStyle.normal.background = selectedBackground; selectedSuggestionStyle.normal.textColor = new Color(0.35f, 1f, 0.56f); selectedSuggestionStyle.fontStyle = (FontStyle)1; resultStyle = new GUIStyle(GUI.skin.box); resultStyle.alignment = (TextAnchor)0; resultStyle.fontSize = 14; resultStyle.wordWrap = true; resultStyle.padding = new RectOffset(10, 10, 8, 8); resultStyle.normal.textColor = Color.white; } } private static Texture2D MakeTexture(Color color) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false); val.SetPixel(0, 0, color); val.Apply(); return val; } public void Dispose() { Network.Dispose(); Permissions.Reset(); if ((Object)(object)windowBackground != (Object)null) { Object.Destroy((Object)(object)windowBackground); } if ((Object)(object)selectedBackground != (Object)null) { Object.Destroy((Object)(object)selectedBackground); } } } [BepInPlugin("com.jameskieley.repo.commandconsole", "REPO Command Console", "2.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal const string PluginGuid = "com.jameskieley.repo.commandconsole"; internal const string PluginName = "REPO Command Console"; internal const string PluginVersion = "2.0.0"; private CommandConsoleRuntime commandConsole; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal CommandConsoleRuntime CommandConsole => commandConsole; private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; commandConsole = new CommandConsoleRuntime(this); Bridge.PublishPermissionSessionRevision(commandConsole.Permissions.SessionRevision); Bridge.Start(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("REPO Command Console 2.0.0 loaded. Press " + commandConsole.ToggleKeyLabel + " to open the command console.")); } private void Update() { if (commandConsole != null) { commandConsole.Update(); } } private void OnGUI() { if (commandConsole != null) { commandConsole.OnGUI(); } } private void OnDestroy() { if (commandConsole != null) { commandConsole.Dispose(); } commandConsole = null; Instance = null; } } public static class Loader { public static void Load() { Bridge.Start(); } } internal sealed class ControlRequest { internal readonly string Command; internal readonly CommandRequestSource Source; internal readonly int RequesterActorNumber; internal readonly Action<string> CompletionCallback; internal readonly long? RequiredSessionRevision; internal readonly Func<bool> AuthorizationValidator; internal readonly ManualResetEventSlim Completed = new ManualResetEventSlim(initialState: false); internal string Result = "ERROR No result was produced."; internal bool ExecutionContextBound; internal bool ExecutionStartedInRoom; internal object ExecutionRoomIdentity; internal int ExecutionMasterActorNumber = -1; internal long ExecutionSessionRevision = -1L; private int completionState; private int cancellationState; internal bool IsCancelled => Volatile.Read(in cancellationState) != 0; internal ControlRequest(string command) : this(command, CommandRequestSource.NamedPipe, -1, null, CapturePublishedSessionRevision(), null) { } internal ControlRequest(string command, CommandRequestSource source, int requesterActorNumber, Action<string> completionCallback) : this(command, source, requesterActorNumber, completionCallback, null, null) { } internal ControlRequest(string command, CommandRequestSource source, int requesterActorNumber, Action<string> completionCallback, long? requiredSessionRevision, Func<bool> authorizationValidator) { Command = command; Source = source; RequesterActorNumber = requesterActorNumber; CompletionCallback = completionCallback; RequiredSessionRevision = requiredSessionRevision; AuthorizationValidator = authorizationValidator; } internal void Complete(string result) { if (Interlocked.Exchange(ref completionState, 1) != 0) { return; } Result = result; Completed.Set(); if (CompletionCallback == null) { return; } try { CompletionCallback(result); } catch (Exception ex) { if (Plugin.Log != null) { Plugin.Log.LogError((object)("Command completion callback failed: " + ex)); } } } internal void Cancel(string result) { Interlocked.Exchange(ref cancellationState, 1); if (Interlocked.Exchange(ref completionState, 1) == 0) { Result = result; Completed.Set(); } } private static long? CapturePublishedSessionRevision() { long publishedPermissionSessionRevision = Bridge.GetPublishedPermissionSessionRevision(); if (publishedPermissionSessionRevision < 0) { return null; } return publishedPermissionSessionRevision; } } internal enum CommandRequestSource { NamedPipe, LocalConsole, RemoteClient } internal enum SpawnKind { Enemy, Loot, Item, Cart } internal sealed class EnemyPlacementReservation { internal readonly Vector3 Position; internal readonly float HorizontalRadius; internal EnemyPlacementReservation(Vector3 position, float horizontalRadius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) Position = position; HorizontalRadius = horizontalRadius; } } internal sealed class EnemyClearanceVolume { internal readonly Vector3 CenterOffset; internal readonly Vector3 HalfExtents; internal readonly float HorizontalRadius; internal EnemyClearanceVolume(Vector3 centerOffset, Vector3 halfExtents, float horizontalRadius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) CenterOffset = centerOffset; HalfExtents = halfExtents; HorizontalRadius = horizontalRadius; } } internal sealed class SpawnJob { internal readonly ControlRequest Request; internal readonly SpawnKind Kind; internal readonly string Selector; internal readonly string Placement; internal readonly int Requested; internal readonly Vector3 Anchor; internal readonly List<Vector3> ReservedPositions = new List<Vector3>(); internal readonly List<EnemyPlacementReservation> EnemyReservations = new List<EnemyPlacementReservation>(); internal int Spawned; internal bool Finished; internal readonly SpawnNameSummary NameSummary = new SpawnNameSummary(); internal SpawnJob(ControlRequest request, SpawnKind kind, string selector, string placement, int requested, Vector3 anchor) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) Request = request; Kind = kind; Selector = selector; Placement = placement; Requested = requested; Anchor = anchor; } } internal sealed class SpawnedObjectRecord { internal GameObject Instance; internal string Name; internal SpawnKind Kind; internal bool IsWeapon; } internal sealed class DuplicateLootJob { internal readonly ControlRequest Request; internal readonly List<PrefabRef> Prefabs; internal readonly Vector3 Anchor; internal readonly List<Vector3> Positions = new List<Vector3>(); internal int Spawned; internal bool Finished; internal DuplicateLootJob(ControlRequest request, List<PrefabRef> prefabs, Vector3 anchor) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Request = request; Prefabs = prefabs; Anchor = anchor; } } internal sealed class ItemBatchJob { internal readonly ControlRequest Request; internal readonly List<Item> Items; internal readonly List<string> TypeNames; internal readonly string Placement; internal readonly int CountPerType; internal readonly Vector3 Anchor; internal readonly List<Vector3> ReservedPositions = new List<Vector3>(); internal int Spawned; internal bool Finished; internal ItemBatchJob(ControlRequest request, List<Item> items, List<string> typeNames, string placement, int countPerType, Vector3 anchor) { //IL_0037: 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) Request = request; Items = items; TypeNames = typeNames; Placement = placement; CountPerType = countPerType; Anchor = anchor; } } internal sealed class BalancedItemJob { internal readonly ControlRequest Request; internal readonly List<Item> Items; internal readonly List<string> TypeNames; internal readonly Dictionary<string, int> TypeCounts; internal readonly string Placement; internal readonly Vector3 Anchor; internal readonly List<Vector3> ReservedPositions = new List<Vector3>(); internal int Spawned; internal bool Finished; internal BalancedItemJob(ControlRequest request, List<Item> items, List<string> typeNames, Dictionary<string, int> typeCounts, string placement, Vector3 anchor) { //IL_0037: 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) Request = request; Items = items; TypeNames = typeNames; TypeCounts = typeCounts; Placement = placement; Anchor = anchor; } } internal static class Bridge { internal const string PipeName = "CodexRepoCommandConsoleV2"; private const string HarmonyId = "com.jameskieley.repo.commandconsole.harmony"; private static readonly ConcurrentQueue<ControlRequest> Requests = new ConcurrentQueue<ControlRequest>(); private static readonly List<SpawnedObjectRecord> SpawnedObjects = new List<SpawnedObjectRecord>(); private static readonly FieldInfo EnemyFirstSpawnPointField = AccessTools.Field(typeof(EnemyParent), "firstSpawnPoint"); private static readonly FieldInfo EnemyFirstSpawnPointsField = AccessTools.Field(typeof(EnemyDirector), "enemyFirstSpawnPoints"); private static readonly string[] ExpensiveLootNames = new string[5] { "Diamond Display", "Griffin Statue", "Dragon Skull", "GoldTooth", "Server Rack" }; private static readonly string[] WeaponTerms = new string[28] { "weapon", "melee", "ranged", "gun", "pistol", "rifle", "shotgun", "revolver", "blaster", "cannon", "launcher", "sword", "blade", "knife", "dagger", "axe", "hatchet", "bat", "hammer", "mace", "spear", "bow", "crossbow", "grenade", "mine", "bomb", "pan", "taser" }; private static int started; private static long publishedPermissionSessionRevision = -1L; private static SpawnJob activeJob; private static DuplicateLootJob activeDuplicateLootJob; private static ItemBatchJob activeItemBatchJob; private static BalancedItemJob activeBalancedItemJob; internal static void Start() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (Interlocked.Exchange(ref started, 1) == 0) { Harmony.UnpatchID("Codex.REPO.SpawnBridge"); Harmony.UnpatchID("Codex.REPO.SpawnBridge.V2"); Harmony.UnpatchID("Codex.REPO.ControlBridge"); Harmony.UnpatchID("Codex.REPO.LiveControl"); Harmony.UnpatchID("Codex.REPO.LiveControl.V2"); Harmony.UnpatchID("Codex.REPO.LiveControl.V3"); Harmony.UnpatchID("Codex.REPO.LiveControl.V4"); Harmony.UnpatchID("Codex.REPO.LiveControl.V5"); Harmony.UnpatchID("Codex.REPO.LiveControl.V6"); Harmony.UnpatchID("Codex.REPO.LiveControl.V7"); Harmony.UnpatchID("Codex.REPO.LiveControl.V8"); Harmony.UnpatchID("Codex.REPO.LiveControl.V9"); Harmony.UnpatchID("Codex.REPO.LiveControl.V10"); Harmony.UnpatchID("Codex.REPO.LiveControl.V11"); Harmony.UnpatchID("Codex.REPO.LiveControl.V12"); Harmony.UnpatchID("Codex.REPO.LiveControl.V13"); Harmony.UnpatchID("com.jameskieley.repo.commandconsole.harmony"); new Harmony("com.jameskieley.repo.commandconsole.harmony").PatchAll(typeof(Bridge).Assembly); Thread thread = new Thread(ListenForRequests); thread.IsBackground = true; thread.Name = "Codex REPO Live Control"; thread.Start(); } } internal static void Enqueue(ControlRequest request) { if (request == null) { throw new ArgumentNullException("request"); } Requests.Enqueue(request); } internal static void PublishPermissionSessionRevision(long revision) { Interlocked.Exchange(ref publishedPermissionSessionRevision, revision); } internal static long GetPublishedPermissionSessionRevision() { return Interlocked.Read(in publishedPermissionSessionRevision); } private static void ListenForRequests() { while (true) { try { using NamedPipeServerStream namedPipeServerStream = new NamedPipeServerStream("CodexRepoCommandConsoleV2", PipeDirection.InOut, 1); namedPipeServerStream.WaitForConnection(); string text; using (StreamReader streamReader = new StreamReader(namedPipeServerStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), detectEncodingFromByteOrderMarks: false, 1024, leaveOpen: true)) { text = streamReader.ReadLine(); } string text2; if (string.IsNullOrWhiteSpace(text)) { text2 = "ERROR Empty command."; } else { ControlRequest controlRequest = new ControlRequest(text); Requests.Enqueue(controlRequest); if (controlRequest.Completed.Wait(TimeSpan.FromSeconds(30.0))) { text2 = controlRequest.Result; } else { text2 = "ERROR Command timed out waiting for the game thread; the queued request was cancelled."; controlRequest.Cancel(text2); } } using StreamWriter streamWriter = new StreamWriter(namedPipeServerStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), 1024, leaveOpen: true); streamWriter.AutoFlush = true; streamWriter.WriteLine(text2); } catch (Exception ex) { try { File.AppendAllText(Path.Combine(Path.GetTempPath(), "RepoLiveControl-pipe.log"), DateTime.UtcNow.ToString("O") + " " + ex?.ToString() + Environment.NewLine); } catch { } Thread.Sleep(250); } } } internal static void ProcessFrame() { if (HasActiveJob()) { RefreshPermissionSession(); if (AbortActiveJobsIfAuthorityLost()) { return; } } if (activeBalancedItemJob != null) { ProcessBalancedItemJob(activeBalancedItemJob); if (activeBalancedItemJob.Finished) { activeBalancedItemJob = null; } } else if (activeItemBatchJob != null) { ProcessItemBatchJob(activeItemBatchJob); if (activeItemBatchJob.Finished) { activeItemBatchJob = null; } } else if (activeDuplicateLootJob != null) { ProcessDuplicateLootJob(activeDuplicateLootJob); if (activeDuplicateLootJob.Finished) { activeDuplicateLootJob = null; } } else if (activeJob != null) { ProcessSpawnJob(activeJob); if (activeJob.Finished) { activeJob = null; } } else { if (!Requests.TryDequeue(out var result) || result.IsCancelled) { return; } try { RefreshPermissionSession(); BindExecutionContext(result); string invalidExecutionReason = GetInvalidExecutionReason(result); if (invalidExecutionReason != null) { throw new InvalidOperationException(invalidExecutionReason); } Dispatch(result); } catch (Exception ex) { Complete(result, "ERROR " + ex.Message); } } } private static bool AbortActiveJobsIfAuthorityLost() { bool result = false; if (activeBalancedItemJob != null) { string invalidExecutionReason = GetInvalidExecutionReason(activeBalancedItemJob.Request); if (!activeBalancedItemJob.Finished && invalidExecutionReason != null) { activeBalancedItemJob.Finished = true; activeBalancedItemJob.ReservedPositions.Clear(); Complete(activeBalancedItemJob.Request, string.Format("ERROR {2} Balanced item spread stopped after {0}/{1}.", activeBalancedItemJob.Spawned, activeBalancedItemJob.Items.Count, invalidExecutionReason)); result = true; } if (activeBalancedItemJob.Finished) { activeBalancedItemJob = null; } } if (activeItemBatchJob != null) { string invalidExecutionReason2 = GetInvalidExecutionReason(activeItemBatchJob.Request); if (!activeItemBatchJob.Finished && invalidExecutionReason2 != null) { activeItemBatchJob.Finished = true; activeItemBatchJob.ReservedPositions.Clear(); Complete(activeItemBatchJob.Request, string.Format("ERROR {2} Item batch stopped after {0}/{1}.", activeItemBatchJob.Spawned, activeItemBatchJob.Items.Count, invalidExecutionReason2)); result = true; } if (activeItemBatchJob.Finished) { activeItemBatchJob = null; } } if (activeDuplicateLootJob != null) { string invalidExecutionReason3 = GetInvalidExecutionReason(activeDuplicateLootJob.Request); if (!activeDuplicateLootJob.Finished && invalidExecutionReason3 != null) { activeDuplicateLootJob.Finished = true; activeDuplicateLootJob.Positions.Clear(); Complete(activeDuplicateLootJob.Request, string.Format("ERROR {2} Loot duplication stopped after {0}/{1}.", activeDuplicateLootJob.Spawned, activeDuplicateLootJob.Prefabs.Count, invalidExecutionReason3)); result = true; } if (activeDuplicateLootJob.Finished) { activeDuplicateLootJob = null; } } if (activeJob != null) { string invalidExecutionReason4 = GetInvalidExecutionReason(activeJob.Request); if (!activeJob.Finished && invalidExecutionReason4 != null) { activeJob.Finished = true; activeJob.ReservedPositions.Clear(); activeJob.EnemyReservations.Clear(); Complete(activeJob.Request, string.Format("ERROR {2} Spawn stopped after {0}/{1}.", activeJob.Spawned, activeJob.Requested, invalidExecutionReason4)); result = true; } if (activeJob.Finished) { activeJob = null; } } return result; } private static void RefreshPermissionSession() { PermissionService permissionService = GetPermissionService(); if (permissionService != null) { permissionService.UpdateSession(); PublishPermissionSessionRevision(permissionService.SessionRevision); } } private static bool HasActiveJob() { if (activeBalancedItemJob == null && activeItemBatchJob == null && activeDuplicateLootJob == null) { return activeJob != null; } return true; } private static PermissionService GetPermissionService() { if (!((Object)(object)Plugin.Instance != (Object)null) || Plugin.Instance.CommandConsole == null) { return null; } return Plugin.Instance.CommandConsole.Permissions; } private static void BindExecutionContext(ControlRequest request) { if (!request.ExecutionContextBound) { PermissionService permissionService = GetPermissionService(); request.ExecutionStartedInRoom = PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null; request.ExecutionRoomIdentity = PhotonNetwork.CurrentRoom; request.ExecutionMasterActorNumber = ((PhotonNetwork.MasterClient == null) ? (-1) : PhotonNetwork.MasterClient.ActorNumber); request.ExecutionSessionRevision = permissionService?.SessionRevision ?? (-1); request.ExecutionContextBound = true; } } private static string GetInvalidExecutionReason(ControlRequest request) { if (request == null || !request.ExecutionContextBound) { return "The command has no valid execution session."; } PermissionService permissionService = GetPermissionService(); string text = CommandIngressSessionPolicy.Validate(request.IsCancelled, request.RequiredSessionRevision, permissionService?.SessionRevision); if (text != null) { return text; } if (request.AuthorizationValidator != null) { bool flag; try { flag = request.AuthorizationValidator(); } catch { flag = false; } if (!flag) { return "The requester is no longer authorized in this lobby."; } } if (request.ExecutionStartedInRoom) { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return "The original multiplayer room closed."; } if (request.ExecutionRoomIdentity != PhotonNetwork.CurrentRoom) { return "The multiplayer room changed."; } if (!PhotonNetwork.IsMasterClient) { return "Host authority was lost."; } if (((PhotonNetwork.MasterClient == null) ? (-1) : PhotonNetwork.MasterClient.ActorNumber) != request.ExecutionMasterActorNumber) { return "The lobby host changed."; } if (permissionService != null && request.ExecutionSessionRevision != permissionService.SessionRevision) { return "The multiplayer session changed."; } } else { if (request.Source == CommandRequestSource.RemoteClient) { return "Remote commands require their original multiplayer room."; } if (PhotonNetwork.InRoom) { return "The multiplayer session changed after the command began."; } } return null; } private static void Dispatch(ControlRequest request) { string translatedCommand = request.Command; if (!translatedCommand.StartsWith("/", StringComparison.Ordinal) || SlashCommandRuntime.TryTranslateOrComplete(request, translatedCommand, out translatedCommand)) { string[] parts = translatedCommand.Split('|'); string text = Part(parts, 0, string.Empty).ToLowerInvariant(); switch (text) { case "enemy": BeginSpawn(request, SpawnKind.Enemy, parts, 500, "near-player"); break; case "loot": BeginSpawn(request, SpawnKind.Loot, parts, 500, "safe"); break; case "item": BeginSpawn(request, SpawnKind.Item, parts, 500, "safe"); break; case "cart": BeginSpawn(request, SpawnKind.Cart, parts, 20, "at-player"); break; case "itemeach": BeginItemEach(request, parts); break; case "itemspread": BeginBalancedItems(request, parts); break; case "despawn": DespawnEnemies(request, Part(parts, 1, "all"), ParseInt(parts, 2, 0)); break; case "despawnitem": DespawnItems(request, Part(parts, 1, "all")); break; case "despawnspawned": DespawnSpawnedObjects(request, Part(parts, 1, "all"), Part(parts, 2, "all"), ParseInt(parts, 3, -1)); break; case "auto": SetAutomaticEnemies(request, Part(parts, 1, "on")); break; case "unstick": UnstickLoot(request); break; case "duplicate": DuplicateLoot(request, Part(parts, 1, "loot")); break; case "topup3": TopUpLootAfterOneDuplicate(request, Part(parts, 1, "loot")); break; case "inspect": InspectLoot(request, Part(parts, 1, "loot")); break; case "status": ReportStatus(request); break; default: throw new InvalidOperationException("Unknown action '" + text + "'."); } } } private static void BeginItemEach(ControlRequest request, string[] parts) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) string text = Part(parts, 1, "upgrade"); int num = Mathf.Clamp(ParseInt(parts, 2, 1), 1, 50); string placement = Part(parts, 3, "safe").ToLowerInvariant(); PlayerAvatar val = RequireRequestPlayer(request); List<Item> list = new List<Item>(); List<string> list2 = new List<string>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (Item allItem in Items.AllItems) { if (!((Object)(object)allItem == (Object)null) && !string.IsNullOrWhiteSpace(allItem.itemName) && allItem.itemName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0 && hashSet.Add(allItem.itemName)) { list2.Add(allItem.itemName); for (int i = 0; i < num; i++) { list.Add(allItem); } } } if (list.Count == 0) { throw new InvalidOperationException("No item types match '" + text + "'."); } activeItemBatchJob = new ItemBatchJob(request, list, list2, placement, num, ((Component)val).transform.position); ProcessItemBatchJob(activeItemBatchJob); } private static void BeginBalancedItems(ControlRequest request, string[] parts) { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) string text = Part(parts, 1, "upgrade"); int num = Mathf.Clamp(ParseInt(parts, 2, 1), 1, 500); string placement = Part(parts, 3, "safe").ToLowerInvariant(); PlayerAvatar val = RequireRequestPlayer(request); List<Item> list = new List<Item>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); bool flag = text.Equals("weapon", StringComparison.OrdinalIgnoreCase) || text.Equals("weapons", StringComparison.OrdinalIgnoreCase); foreach (Item allItem in Items.AllItems) { if (!((Object)(object)allItem == (Object)null) && !string.IsNullOrWhiteSpace(allItem.itemName) && (flag ? IsWeaponItem(allItem) : (allItem.itemName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)) && hashSet.Add(allItem.itemName)) { list.Add(allItem); } } if (list.Count == 0) { throw new InvalidOperationException("No item types match '" + text + "'."); } Shuffle(list); List<Item> list2 = new List<Item>(num); List<string> list3 = new List<string>(); Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); for (int i = 0; i < num; i++) { Item val2 = list[i % list.Count]; list2.Add(val2); if (!dictionary.ContainsKey(val2.itemName)) { list3.Add(val2.itemName); } dictionary[val2.itemName] = ((!dictionary.ContainsKey(val2.itemName)) ? 1 : (dictionary[val2.itemName] + 1)); } activeBalancedItemJob = new BalancedItemJob(request, list2, list3, dictionary, placement, ((Component)val).transform.position); ProcessBalancedItemJob(activeBalancedItemJob); } private static void ProcessItemBatchJob(ItemBatchJob job) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) try { int num = 0; while (!job.Finished && num < 10) { Item val = job.Items[job.Spawned]; Vector3 placement = GetPlacement(job.Placement, job.Anchor, job.ReservedPositions); GameObject val2 = Items.SpawnItem(val, placement, Quaternion.identity); if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("REPOLib returned no spawned item object for '" + val.itemName + "'."); } SpawnedObjects.Add(new SpawnedObjectRecord { Instance = val2, Name = val.itemName, Kind = SpawnKind.Item, IsWeapon = IsWeaponItem(val) }); job.Spawned++; num++; if (job.Spawned >= job.Items.Count) { job.Finished = true; Complete(job.Request, string.Format("OK Spawned {0} item object(s): {1} each of {2} matching type(s): {3}.", job.Spawned, job.CountPerType, job.TypeNames.Count, string.Join(", ", job.TypeNames.ToArray()))); } } } catch (Exception ex) { job.Finished = true; Complete(job.Request, $"ERROR Item batch stopped after {job.Spawned}/{job.Items.Count}: {ex.Message}"); } } private static void ProcessBalancedItemJob(BalancedItemJob job) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) try { int num = 0; while (!job.Finished && num < 10) { Item val = job.Items[job.Spawned]; Vector3 placement = GetPlacement(job.Placement, job.Anchor, job.ReservedPositions); GameObject val2 = Items.SpawnItem(val, placement, Quaternion.identity); if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("REPOLib returned no spawned item object for '" + val.itemName + "'."); } SpawnedObjects.Add(new SpawnedObjectRecord { Instance = val2, Name = val.itemName, Kind = SpawnKind.Item, IsWeapon = IsWeaponItem(val) }); job.Spawned++; num++; if (job.Spawned < job.Items.Count) { continue; } job.Finished = true; List<string> list = new List<string>(); foreach (string typeName in job.TypeNames) { list.Add(typeName + " x" + job.TypeCounts[typeName]); } Complete(job.Request, string.Format("OK Spawned {0} balanced item object(s) across {1} type(s): {2}.", job.Spawned, job.TypeNames.Count, string.Join(", ", list.ToArray()))); } } catch (Exception ex) { job.Finished = true; Complete(job.Request, $"ERROR Balanced item spread stopped after {job.Spawned}/{job.Items.Count}: {ex.Message}"); } } private static void InspectLoot(ControlRequest request, string target) { if (!target.Equals("loot", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Inspect target must be loot."); } IList obj = (GetField(ValuableDirector.instance, "valuableList") as IList) ?? throw new InvalidOperationException("The tracked loot list is unavailable."); List<string> list = new List<string>(); foreach (object item in obj) { ValuableObject val = (ValuableObject)((item is ValuableObject) ? item : null); if ((Object)(object)val != (Object)null && !list.Contains(((Object)((Component)val).gameObject).name)) { list.Add(((Object)((Component)val).gameObject).name); } } List<string> list2 = new List<string>(); foreach (PrefabRef allValuable in Valuables.AllValuables) { if ((Object)(object)((PrefabRef<GameObject>)(object)allValuable).Prefab != (Object)null) { list2.Add(((Object)((PrefabRef<GameObject>)(object)allValuable).Prefab).name); } } Complete(request, "OK Loot inspection: tracked=[" + string.Join(", ", list.ToArray()) + "]; registered=[" + string.Join(", ", list2.ToArray()) + "]."); } private static void DuplicateLoot(ControlRequest request, string target) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (!target.Equals("loot", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Duplicate target must be loot."); } IList obj = (GetField(ValuableDirector.instance, "valuableList") as IList) ?? throw new InvalidOperationException("The tracked loot list is unavailable."); List<PrefabRef> list = new List<PrefabRef>(); foreach (object item in obj) { ValuableObject val = (ValuableObject)((item is ValuableObject) ? item : null); if (!((Object)(object)val == (Object)null)) { PrefabRef val2 = FindValuablePrefab(val); if (val2 == null) { throw new InvalidOperationException("No registered valuable prefab matches existing loot '" + ((Object)((Component)val).gameObject).name + "'. No copies were spawned."); } list.Add(val2); } } if (list.Count == 0) { Complete(request, "OK Duplicated 0 loot object(s); the map had no tracked loot."); return; } PlayerAvatar val3 = RequireRequestPlayer(request); Shuffle(list); activeDuplicateLootJob = new DuplicateLootJob(request, list, ((Component)val3).transform.position); ProcessDuplicateLootJob(activeDuplicateLootJob); } private static void TopUpLootAfterOneDuplicate(ControlRequest request, string target) { //IL_0188: Unknown result type (might be due to invalid IL or missing references) if (!target.Equals("loot", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Top-up target must be loot."); } IList obj = (GetField(ValuableDirector.instance, "valuableList") as IList) ?? throw new InvalidOperationException("The tracked loot list is unavailable."); List<PrefabRef> list = new List<PrefabRef>(); List<int> list2 = new List<int>(); foreach (object item in obj) { ValuableObject val = (ValuableObject)((item is ValuableObject) ? item : null); if ((Object)(object)val == (Object)null) { continue; } PrefabRef val2 = FindValuablePrefab(val); if (val2 == null) { throw new InvalidOperationException("No registered valuable prefab matches existing loot '" + ((Object)((Component)val).gameObject).name + "'. No copies were spawned."); } int num = -1; for (int i = 0; i < list.Count; i++) { if (list[i] == val2) { num = i; break; } } if (num < 0) { list.Add(val2); list2.Add(1); } else { list2[num]++; } } List<PrefabRef> list3 = new List<PrefabRef>(); for (int j = 0; j < list.Count; j++) { int num2 = list2[j] / 2; for (int k = 0; k < num2; k++) { list3.Add(list[j]); } } if (list3.Count == 0) { Complete(request, "OK Added 0 loot object(s); no complete duplicated pairs were found."); return; } PlayerAvatar val3 = RequireRequestPlayer(request); Shuffle(list3); activeDuplicateLootJob = new DuplicateLootJob(request, list3, ((Component)val3).transform.position); ProcessDuplicateLootJob(activeDuplicateLootJob); } private static void ProcessDuplicateLootJob(DuplicateLootJob job) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) try { int num = 0; while (!job.Finished && num < 10) { if (job.Positions.Count < job.Prefabs.Count) { if (!TryFindClearPosition(job.Anchor, job.Positions, out var result)) { throw new InvalidOperationException("Could not reserve collision-free locations for all copies. No copies were spawned."); } job.Positions.Add(result); } else { PrefabRef val = job.Prefabs[job.Spawned]; GameObject val2 = Valuables.SpawnValuable(val, job.Positions[job.Spawned], Quaternion.identity); if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("REPOLib returned no spawned loot object for '" + ((Object)((PrefabRef<GameObject>)(object)val).Prefab).name + "'."); } SpawnedObjects.Add(new SpawnedObjectRecord { Instance = val2, Name = ((Object)((PrefabRef<GameObject>)(object)val).Prefab).name, Kind = SpawnKind.Loot, IsWeapon = false }); job.Spawned++; if (job.Spawned >= job.Prefabs.Count) { job.Finished = true; Complete(job.Request, $"OK Duplicated {job.Spawned} loot object(s) into distinct collision-free random locations."); } } num++; } } catch (Exception ex) { job.Finished = true; Complete(job.Request, $"ERROR Loot duplication stopped after {job.Spawned}/{job.Prefabs.Count}: {ex.Message}"); } } private static void BeginSpawn(ControlRequest request, SpawnKind kind, string[] parts, int maximum, string defaultPlacement) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar val = RequireRequestPlayer(request); string selector = Part(parts, 1, "random"); int requested = Mathf.Clamp(ParseInt(parts, 2, 1), 1, maximum); string placement = Part(parts, 3, defaultPlacement).ToLowerInvariant(); activeJob = new SpawnJob(request, kind, selector, placement, requested, ((Component)val).transform.position); ProcessSpawnJob(activeJob); } private static void ProcessSpawnJob(SpawnJob job) { try { int num = 0; while (!job.Finished && num < 10) { switch (job.Kind) { case SpawnKind.Enemy: SpawnEnemyStep(job); break; case SpawnKind.Loot: SpawnLootStep(job); break; case SpawnKind.Item: SpawnItemStep(job); break; case SpawnKind.Cart: SpawnCartStep(job); break; } num++; if (job.Spawned >= job.Requested) { job.Finished = true; string text = job.NameSummary.Format(); string result = string.Format("OK Spawned {0} {1} object(s){2}.", job.Spawned, job.Kind.ToString().ToLowerInvariant(), (text.Length == 0) ? string.Empty : (": " + text)); Complete(job.Request, result); } } } catch (Exception ex) { job.Finished = true; Complete(job.Request, $"ERROR Spawn stopped after {job.Spawned}/{job.Requested}: {ex.Message}"); } } private static void SpawnEnemyStep(SpawnJob job) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) EnemySetup val = FindEnemy(job.Selector); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("No enemy matches '" + job.Selector + "'."); } Vector3 result; if (job.Placement == "safe") { if (!TryFindClearEnemyPosition(job.Anchor, job.EnemyReservations, GetEnemyClearanceVolume(val), out result)) { throw new InvalidOperationException("No additional collision-free enemy placement was found."); } } else if (job.Placement == "at-player") { result = SemiFunc.EnemyRoamFindPoint(job.Anchor); } else { Vector3 val2 = Random.insideUnitSphere * 4f; val2.y = 0f; result = SemiFunc.EnemyRoamFindPoint(job.Anchor + val2); } List<EnemyParent> list = Enemies.SpawnEnemy(val, result, Quaternion.identity, false); if (list == null || list.Count == 0) { throw new InvalidOperationException("The enemy setup spawned no objects."); } List<EnemyParent> list2 = new List<EnemyParent>(); foreach (EnemyParent item in list) { if ((Object)(object)item != (Object)null) { list2.Add(item); } } if (list2.Count == 0) { throw new InvalidOperationException("The enemy setup returned no live objects."); } int num = CommandExecutionTranslation.AcceptedEnemyCountForSetup(job.Requested - job.Spawned, list2.Count, job.Placement == "safe"); EnemyDirector instance = EnemyDirector.instance; for (int i = num; i < list2.Count; i++) { DestroyEnemyInstance(list2[i], instance); } EnemyParent enemyParent = GetEnemyParent(val); string name = (((Object)(object)enemyParent == (Object)null) ? "unknown" : enemyParent.enemyName); for (int j = 0; j < num; j++) { EnemyParent val3 = list2[j]; SpawnedObjects.Add(new SpawnedObjectRecord { Instance = ((Component)val3).gameObject, Name = name, Kind = SpawnKind.Enemy, IsWeapon = false }); } AppendName(job, name, num); job.Spawned += num; } private static void DestroyEnemyInstance(EnemyParent enemy, EnemyDirector director) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)enemy == (Object)null) { return; } if ((Object)(object)director != (Object)null) { director.enemiesSpawned.Remove(enemy); LevelPoint val = ((EnemyFirstSpawnPointField == null) ? ((LevelPoint)null) : ((LevelPoint)EnemyFirstSpawnPointField.GetValue(enemy))); List<LevelPoint> list = ((EnemyFirstSpawnPointsField == null) ? null : ((List<LevelPoint>)EnemyFirstSpawnPointsField.GetValue(director))); if ((Object)(object)val != (Object)null) { list?.Remove(val); } } if (PhotonNetwork.InRoom) { PhotonNetwork.Destroy(((Component)enemy).gameObject); } else { Object.Destroy((Object)(object)((Component)enemy).gameObject); } } private static void SpawnLootStep(SpawnJob job) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) PrefabRef val = FindValuable(job.Selector, job.Spawned); if (val == null) { throw new InvalidOperationException("No loot matches '" + job.Selector + "'."); } Vector3 placement = GetPlacement(job); GameObject val2 = Valuables.SpawnValuable(val, placement, Quaternion.identity); if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("REPOLib returned no spawned loot object."); } SpawnedObjects.Add(new SpawnedObjectRecord { Instance = val2, Name = ((Object)((PrefabRef<GameObject>)(object)val).Prefab).name, Kind = SpawnKind.Loot, IsWeapon = false }); AppendName(job, ((Object)((PrefabRef<GameObject>)(object)val).Prefab).name, 1); job.Spawned++; } private static void SpawnItemStep(SpawnJob job) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) Item val = FindItem(job.Selector); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("No item matches '" + job.Selector + "'."); } Vector3 placement = GetPlacement(job); GameObject val2 = Items.SpawnItem(val, placement, Quaternion.identity); if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("REPOLib returned no spawned item object."); } SpawnedObjects.Add(new SpawnedObjectRecord { Instance = val2, Name = val.itemName, Kind = SpawnKind.Item, IsWeapon = IsWeaponItem(val) }); AppendName(job, val.itemName, 1); job.Spawned++; } private static void SpawnCartStep(SpawnJob job) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) string text = FindCartItemName(job.Selector); if (text == null) { throw new InvalidOperationException("No cart item matches '" + job.Selector + "'."); } Vector3 placement = GetPlacement(job); GameObject val = PhotonNetwork.InstantiateRoomObject("Items/" + text, placement, Quaternion.identity, (byte)0, (object[])null); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("Photon could not spawn the cart item '" + text + "'."); } SpawnedObjects.Add(new SpawnedObjectRecord { Instance = val, Name = text, Kind = SpawnKind.Cart, IsWeapon = false }); AppendName(job, text, 1); job.Spawned++; } private static Vector3 GetPlacement(SpawnJob job) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) return GetPlacement(job.Placement, job.Anchor, job.ReservedPositions); } private static Vector3 GetPlacement(string placement, Vector3 anchor, List<Vector3> reservedPositions) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (placement == "at-player") { return anchor + Vector3.up * 1.5f; } if (placement == "near-player") { Vector3 val = Random.insideUnitSphere * 3f; val.y = Math.Abs(val.y) + 1f; return anchor + val; } if (!TryFindClearPosition(anchor, reservedPositions, out var result)) { throw new InvalidOperationException("No additional collision-free placement was found."); } reservedPositions.Add(result); return result; } private static bool TryFindClearPosition(Vector3 origin, List<Vector3> reserved, out Vector3 result) { //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) LevelGenerator instance = LevelGenerator.Instance; List<LevelPoint> list = (((Object)(object)instance == (Object)null) ? null : instance.LevelPathPoints); int num = EnemyClearancePolicy.BuildGameplaySolidMask((Func<string, int>)LayerMask.NameToLayer); for (int i = 0; i < 500; i++) { Vector3 val; if (list != null && list.Count > 0 && i % 2 == 0) { val = ((Component)list[Random.Range(0, list.Count)]).transform.position; } else { float num2 = Random.Range(0f, MathF.PI * 2f); float num3 = Random.Range(4f, 30f); val = origin + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * num3; } Vector3 val2 = SemiFunc.EnemyRoamFindPoint(val) + Vector3.up * 1.75f; bool flag = false; foreach (Vector3 item in reserved) { if (Vector3.Distance(val2, item) < 4f) { flag = true; break; } } if (flag) { continue; } Collider[] array = Physics.OverlapBox(val2, new Vector3(1.35f, 1.25f, 1.35f), Quaternion.identity, num, (QueryTriggerInteraction)1); bool flag2 = false; Collider[] array2 = array; foreach (Collider val3 in array2) { if ((Object)(object)val3 != (Object)null && !val3.isTrigger) { flag2 = true; break; } } if (!flag2) { result = val2; return true; } } result = Vector3.zero; return false; } private static bool TryFindClearEnemyPosition(Vector3 origin, List<EnemyPlacementReservation> reserved, EnemyClearanceVolume clearance, out Vector3 result) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014f: 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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) LevelGenerator instance = LevelGenerator.Instance; List<LevelPoint> list = (((Object)(object)instance == (Object)null) ? null : instance.LevelPathPoints); int num = EnemyClearancePolicy.BuildGameplaySolidMask((Func<string, int>)LayerMask.NameToLayer); Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal); for (int i = 0; i < 500; i++) { Vector3 val; if (list != null && list.Count > 0 && i % 2 == 0) { val = ((Component)list[Random.Range(0, list.Count)]).transform.position; } else { float num2 = Random.Range(0f, MathF.PI * 2f); float num3 = Random.Range(4f, 30f); val = origin + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * num3; } Vector3 val2 = SemiFunc.EnemyRoamFindPoint(val); bool flag = false; foreach (EnemyPlacementReservation item in reserved) { float num4 = val2.x - item.Position.x; float num5 = val2.z - item.Position.z; float num6 = clearance.HorizontalRadius + item.HorizontalRadius + 0.5f; if (num4 * num4 + num5 * num5 < num6 * num6) { flag = true; break; } } if (flag) { continue; } Collider[] array = Physics.OverlapBox(val2 + clearance.CenterOffset, clearance.HalfExtents, Quaternion.identity, num, (QueryTriggerInteraction)1); bool flag2 = false; Collider[] array2 = array; foreach (Collider val3 in array2) { if ((Object)(object)val3 != (Object)null && !val3.isTrigger) { string text = LayerMask.LayerToName(((Component)val3).gameObject.layer); string key = (string.IsNullOrEmpty(text) ? ((Component)val3).gameObject.layer.ToString() : text) + ":" + ((Object)val3).name; dictionary.TryGetValue(key, out var value); dictionary[key] = value + 1; flag2 = true; break; } } if (!flag2) { reserved.Add(new EnemyPlacementReservation(val2, clearance.HorizontalRadius)); result = val2; return true; } } string text2 = string.Empty; int num7 = 0; foreach (KeyValuePair<string, int> item2 in dictionary) { if (num7 >= 8) { break; } if (text2.Length > 0) { text2 += ", "; } text2 = text2 + item2.Key + " x" + item2.Value; num7++; } Plugin.Log.LogWarning((object)$"Enemy clearance rejected all candidates. center={clearance.CenterOffset}, halfExtents={clearance.HalfExtents}, radius={clearance.HorizontalRadius:0.00}, mask={num}, blockers=[{text2}]"); result = Vector3.zero; return false; } private static EnemyClearanceVolume GetEnemyClearanceVolume(EnemySetup setup) { //IL_00e7: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_008e: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(-0.9f, 0.1f, -0.9f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0.9f, 2.4f, 0.9f); if ((Object)(object)setup != (Object)null && setup.spawnObjects != null) { foreach (PrefabRef spawnObject in setup.spawnObjects) { GameObject val3 = ((PrefabRef<GameObject>)(object)spawnObject)?.Prefab; if (!((Object)(object)val3 == (Object)null) && TryGetAggregatePrefabBounds(val3, out var aggregate)) { Vector3 position = val3.transform.position; val = Vector3.Min(val, ((Bounds)(ref aggregate)).min - position); val2 = Vector3.Max(val2, ((Bounds)(ref aggregate)).max - position); } } } Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(0.2f, 0.2f, 0.2f); val -= val4; val2 += val4; val.y = EnemyClearancePolicy.ClampProbeBottomOffset(val.y); Vector3 centerOffset = (val + val2) * 0.5f; Vector3 halfExtents = (val2 - val) * 0.5f; float num = Mathf.Max(Mathf.Abs(val.x), Mathf.Abs(val2.x)); float num2 = Mathf.Max(Mathf.Abs(val.z), Mathf.Abs(val2.z)); float horizontalRadius = Mathf.Sqrt(num * num + num2 * num2); return new EnemyClearanceVolume(centerOffset, halfExtents, horizontalRadius); } private static bool TryGetAggregatePrefabBounds(GameObject prefab, out Bounds aggregate) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) aggregate = default(Bounds); bool found = false; NavMeshAgent[] componentsInChildren = prefab.GetComponentsInChildren<NavMeshAgent>(true); Bounds candidate = default(Bounds); foreach (NavMeshAgent val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { Vector3 lossyScale = ((Component)val).transform.lossyScale; float num = Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.z)); float num2 = Mathf.Abs(lossyScale.y); if (EnemyClearancePolicy.IsNavigationEnvelopeUsable(val.radius, val.height, val.baseOffset, num, num2)) { float num3 = val.radius * num; float num4 = val.height * num2; float num5 = val.baseOffset * num2; ((Bounds)(ref candidate))..ctor(((Component)val).transform.position + Vector3.up * (num5 + num4 * 0.5f), new Vector3(num3 * 2f, num4, num3 * 2f)); EncapsulateBounds(ref aggregate, ref found, candidate); } } } if (found && HasUsableBounds(aggregate)) { return true; } aggregate = default(Bounds); found = false; Collider[] componentsInChildren2 = prefab.GetComponentsInChildren<Collider>(true); foreach (Collider val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && EnemyClearancePolicy.IsBodyGeometryEligible(val2.enabled, val2.isTrigger, IsActiveInPrefabHierarchy(((Component)val2).transform, prefab.transform), (Object)(object)val2.attachedRigidbody != (Object)null)) { Bounds bounds = val2.bounds; if (HasUsableBounds(bounds)) { EncapsulateBounds(ref aggregate, ref found, bounds); } } } if (found && !HasUsableBounds(aggregate)) { aggregate = default(Bounds); found = false; } if (!found) { Renderer[] componentsInChildren3 = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren3) { if (!((Object)(object)val3 == (Object)null) && EnemyClearancePolicy.IsBodyGeometryEligible(val3.enabled, isTrigger: false, IsActiveInPrefabHierarchy(((Component)val3).transform, prefab.transform), attachedToRigidbody: false)) { Bounds bounds2 = val3.bounds; if (HasUsableBounds(bounds2)) { EncapsulateBounds(ref aggregate, ref found, bounds2); } } } } if (found) { return HasUsableBounds(aggregate); } return false; } private static bool IsActiveInPrefabHierarchy(Transform componentTransform, Transform prefabRoot) { if ((Object)(object)componentTransform == (Object)null || (Object)(object)prefabRoot == (Object)null) { return false; } Transform val = componentTransform; while ((Object)(object)val != (Object)null) { if (!((Component)val).gameObject.activeSelf) { return false; } if ((Object)(object)val == (Object)(object)prefabRoot) { return true; } val = val.parent; } return false; } private static bool HasUsableBounds(Bounds candidate) { //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_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_004a: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) Vector3 center = ((Bounds)(ref candidate)).center; Vector3 size = ((Bounds)(ref candidate)).size; if (float.IsNaN(center.x) || float.IsInfinity(center.x) || float.IsNaN(center.y) || float.IsInfinity(center.y) || float.IsNaN(center.z) || float.IsInfinity(center.z) || float.IsNaN(size.x) || float.IsInfinity(size.x) || float.IsNaN(size.y) || float.IsInfinity(size.y) || float.IsNaN(size.z) || float.IsInfinity(size.z)) { return false; } return ((Vector3)(ref size)).sqrMagnitude > 1E-06f; } private static void EncapsulateBounds(ref Bounds aggregate, ref bool found, Bounds candidate) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!found) { aggregate = candidate; found = true; } else { ((Bounds)(ref aggregate)).Encapsulate(candidate); } } private static void DespawnEnemies(ControlRequest request, string selector, int keep) { EnemyDirector instance = EnemyDirector.instance; if ((Object)(object)instance == (Object)null) { throw new InvalidOperationException("The enemy director is unavailable."); } keep = Math.Max(0, keep); List<EnemyParent> list = new List<EnemyParent>(); EnemyParent[] array = instance.enemiesSpawned.ToArray(); foreach (EnemyParent val in array) { if (!((Object)(object)val == (Object)null) && (selector.Equals("all", StringComparison.OrdinalIgnoreCase) || val.enemyName.IndexOf(selector, StringComparison.OrdinalIgnoreCase) >= 0)) { list.Add(val); } } int num = 0; for (int j = keep; j < list.Count; j++) { EnemyParent val2 = list[j]; instance.enemiesSpawned.Remove(val2); PhotonNetwork.Destroy(((Component)val2).gameObject); num++; } Complete(request, $"OK Despawned {num} matching enemy object(s); kept {Math.Min(keep, list.Count)}."); } private static void DespawnItems(ControlRequest request, string selector) { if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { throw new InvalidOperationException("Only the host can despawn network items."); } bool flag = selector.Equals("weapon", StringComparison.OrdinalIgnoreCase) || selector.Equals("weapons", StringComparison.OrdinalIgnoreCase); int num = 0; for (int num2 = SpawnedObjects.Count - 1; num2 >= 0; num2--) { SpawnedObjectRecord spawnedObjectRecord = SpawnedObjects[num2]; if ((Object)(object)spawnedObjectRecord.Instance == (Object)null) { SpawnedObjects.RemoveAt(num2); continue; } if (spawnedObjectRecord.Kind != SpawnKind.Item && spawnedObjectRecord.Kind != SpawnKind.Cart) { continue; } bool num3; if (!flag) { if (selector.Equals("all", StringComparison.OrdinalIgnoreCase)) { goto IL_00bd; } num3 = spawnedObjectRecord.Name.IndexOf(selector, StringComparison.OrdinalIgnoreCase) >= 0; } else { num3 = spawnedObjectRecord.IsWeapon; } if (!num3) { continue; } goto IL_00bd; IL_00bd: DestroySpawnedObject(spawnedObjectRecord); SpawnedObjects.RemoveAt(num2); num++; } Complete(request, $"OK Despawned {num} matching bridge-spawned item object(s) for '{selector}'."); } private static void DespawnSpawnedObjects(ControlRequest request, string kindText, string selector, int requested) { SpawnKind? spawnKind = ParseSpawnKind(kindText); if (!spawnKind.HasValue && !kindText.Equals("all", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Unknown spawned-object kind '" + kindText + "'."); } int num = ((requested < 0) ? int.MaxValue : Mathf.Clamp(requested, 1, 500)); int num2 = 0; int num3 = SpawnedObjects.Count - 1; while (num3 >= 0 && num2 < num) { SpawnedObjectRecord spawnedObjectRecord = SpawnedObjects[num3]; if ((Object)(object)spawnedObjectRecord.Instance == (Object)null) { SpawnedObjects.RemoveAt(num3); } else { bool num4 = !spawnKind.HasValue || spawnedObjectRecord.Kind == spawnKind.Value || (spawnKind.Value == SpawnKind.Item && spawnedObjectRecord.Kind == SpawnKind.Cart); bool flag = selector.Equals("all", StringComparison.OrdinalIgnoreCase) || spawnedObjectRecord.Name.Equals(selector, StringComparison.OrdinalIgnoreCase); if (num4 && flag) { DestroySpawnedObject(spawnedObjectRecord); SpawnedObjects.RemoveAt(num3); num2++; } } num3--; } Complete(request, $"OK Despawned {num2} matching mod-spawned {kindText} object(s) for '{selector}'."); } private static SpawnKind? ParseSpawnKind(string value) { if (value.Equals("enemy", StringComparison.OrdinalIgnoreCase)) { return SpawnKind.Enemy; } if (value.Equals("valuable", StringComparison.OrdinalIgnoreCase) || value.Equals("loot", StringComparison.OrdinalIgnoreCase)) { return SpawnKind.Loot; } if (value.Equals("item", StringComparison.OrdinalIgnoreCase)) { return SpawnKind.Item; } if (value.Equals("cart", StringComparison.OrdinalIgnoreCase)) { return SpawnKind.Cart; } return null; } private static void DestroySpawnedObject(SpawnedObjectRecord record) { if (record == null || (Object)(object)record.Instance == (Object)null) { return; } if (record.Kind == SpawnKind.Enemy) { EnemyParent val = record.Instance.GetComponent<EnemyParent>() ?? record.Instance.GetComponentInChildren<EnemyParent>(); if ((Object)(object)val != (Object)null) { DestroyEnemyInstance(val, EnemyDirector.instance); return; } } else if (record.Kind == SpawnKind.Loot && (Object)(object)ValuableDirector.instance != (Object)null) { IList list = GetField(ValuableDirector.instance, "valuableList") as IList; ValuableObject val2 = record.Instance.GetComponent<ValuableObject>() ?? record.Instance.GetComponentInChildren<ValuableObject>(); if (list != null && (Object)(object)val2 != (Object)null) { list.Remove(val2); } } else if ((record.Kind == SpawnKind.Item || record.Kind == SpawnKind.Cart) && (Object)(object)ItemManager.instance != (Object)null) { ItemAttributes val3 = record.Instance.GetComponent<ItemAttributes>() ?? record.Instance.GetComponentInChildren<ItemAttributes>(); if ((Object)(object)val3 != (Object)null) { ItemManager.instance.spawnedItems.Remove(val3); } } if (PhotonNetwork.InRoom) { PhotonNetwork.Destroy(record.Instance); } else { Object.Destroy((Object)(object)record.Instance); } } private static void SetAutomaticEnemies(ControlRequest request, string setting) { EnemyDirector instance = EnemyDirector.instance; if ((Object)(object)instance == (Object)null) { throw new InvalidOperationException("The enemy director is unavailable."); } bool flag; if (setting.Equals("on", StringComparison.OrdinalIgnoreCase) || setting == "1" || setting.Equals("true", StringComparison.OrdinalIgnoreCase)) { flag = true; } else { if (!setting.Equals("off", StringComparison.OrdinalIgnoreCase) && !(setting == "0") && !setting.Equals("false", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Auto setting must be on or off."); } flag = false; } ((Behaviour)instance).enabled = flag; Complete(request, "OK Automatic enemy spawning is " + (flag ? "enabled." : "disabled.")); } private static void UnstickLoot(ControlRequest request) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) ValuableDirector instance = ValuableDirector.instance; PlayerAvatar val = RequireRequestPlayer(request); IList obj = (GetField(instance, "valuableList") as IList) ?? throw new InvalidOperationException("The tracked loot list is unavailable."); List<PhysGrabObject> list = new List<PhysGrabObject>(); foreach (object item in obj) { ValuableObject val2 = (ValuableObject)((item is ValuableObject) ? item : null); if (!((Object)(object)val2 == (Object)null)) { PhysGrabObject val3 = ((Component)val2).GetComponent<PhysGrabObject>() ?? ((Component)val2).GetComponentInParent<PhysGrabObject>(); if ((Object)(object)val3 != (Object)null && IsStuck(val3)) { list.Add(val3); } } } List<Vector3> list2 = new List<Vector3>(); int