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 Module Spawner and Delete v1.5.0
ModuleUI.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("EmptyChildMod")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("EmptyChildMod")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("eb22faed-b405-4d38-9eb8-cae6b316dbed")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace ModuleEditor; [BepInPlugin("com.yourname.moduleeditor", "Module Editor UI", "1.2.0")] public class ModuleEditorPlugin : BaseUnityPlugin { private void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if ((Object)(object)GameObject.Find("ModuleEditorUI_Runner") == (Object)null) { GameObject val = new GameObject("ModuleEditorUI_Runner"); val.AddComponent<ModuleEditorUI>(); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Module Editor v1.2 Loaded. Press 'Insert' to open."); } } public class ModuleEditorUI : MonoBehaviour { public class ModuleInstanceInfo { public Module Module; public string Name; } public class PrefabInfo { public PrefabRef PrefabRef; public string Name; } private bool showUI = false; private Rect windowRect = new Rect(50f, 50f, 900f, 650f); private List<ModuleInstanceInfo> currentModules = new List<ModuleInstanceInfo>(); private List<PrefabInfo> availablePrefabs = new List<PrefabInfo>(); private ModuleInstanceInfo selectedModule = null; private string searchString = ""; private List<ModuleInstanceInfo> selectedModules = new List<ModuleInstanceInfo>(); private Vector2 scrollCurrent; private Vector2 scrollPrefabs; private GUIStyle windowStyle; private GUIStyle boxStyle; private GUIStyle labelStyle; private GUIStyle selectedStyle; private GUIStyle boldLabelStyle; private GUIStyle searchStyle; private GUIStyle deleteButtonStyle; private GUIStyle buttonStyle; private bool stylesInit = false; private static FieldInfo f_GridX = typeof(Module).GetField("GridX", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static FieldInfo f_GridY = typeof(Module).GetField("GridY", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static FieldInfo f_Top = typeof(Module).GetField("ConnectingTop", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static FieldInfo f_Bottom = typeof(Module).GetField("ConnectingBottom", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static FieldInfo f_Left = typeof(Module).GetField("ConnectingLeft", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static FieldInfo f_Right = typeof(Module).GetField("ConnectingRight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static FieldInfo f_First = typeof(Module).GetField("First", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Update() { if (!IsSafeToModify()) { Debug.LogWarning((object)"ModuleEditor: Cannot cleanup doors while level is loading!"); } else if (Input.GetKeyDown((KeyCode)127)) { showUI = !showUI; if (showUI) { RefreshModuleList(); LoadAllPrefabs(); Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } else { Cursor.visible = false; Cursor.lockState = (CursorLockMode)1; } } } private void OnGUI() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (showUI) { if (!stylesInit) { InitStyles(); } windowRect = GUI.Window(9912, windowRect, new WindowFunction(DrawWindow), "MODULE BROWSER & EDITOR", windowStyle); } } private void DrawWindow(int windowID) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) GUI.DragWindow(new Rect(0f, 0f, 900f, 30f)); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) }); GUILayout.Label($"<b>CURRENT LEVEL MODULES</b> ({selectedModules.Count} Selected)", boldLabelStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("REFRESH / CLEAR", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) })) { RefreshModuleList(); selectedModules.Clear(); GUIUtility.ExitGUI(); } GUI.backgroundColor = new Color(1f, 0.5f, 0f); if (GUILayout.Button("DESTROY ALL DOORS", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) })) { ExecuteDoorCleanup(); GUIUtility.ExitGUI(); } GUI.backgroundColor = Color.white; GUILayout.EndHorizontal(); scrollCurrent = GUILayout.BeginScrollView(scrollCurrent, boxStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(480f) }); for (int i = 0; i < currentModules.Count; i++) { ModuleInstanceInfo moduleInstanceInfo = currentModules[i]; if (moduleInstanceInfo == null || (Object)(object)moduleInstanceInfo.Module == (Object)null) { continue; } bool flag = selectedModules.Contains(moduleInstanceInfo); float num = ((selectedModules.Count == 0 || flag) ? 1f : 0.3f); GUI.color = new Color(1f, 1f, 1f, num); GUILayout.BeginVertical(flag ? selectedStyle : GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.Label("<b>" + moduleInstanceInfo.Name + "</b>", new GUIStyle(labelStyle) { richText = true }, Array.Empty<GUILayoutOption>()); if (GUILayout.Button(flag ? "DESELECT" : "SELECT", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) })) { if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) { if (flag) { selectedModules.Remove(moduleInstanceInfo); } else { selectedModules.Add(moduleInstanceInfo); } } else { selectedModules.Clear(); selectedModules.Add(moduleInstanceInfo); } GUIUtility.ExitGUI(); } GUILayout.EndVertical(); GUILayout.Space(2f); } GUI.color = Color.white; GUILayout.EndScrollView(); if (selectedModules.Count > 0) { GUI.backgroundColor = new Color(1f, 0.2f, 0.2f); if (GUILayout.Button($"DELETE SELECTED ({selectedModules.Count})", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { ExecuteBatchDelete(); GUIUtility.ExitGUI(); } GUI.backgroundColor = Color.white; } GUILayout.EndVertical(); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(450f) }); GUILayout.Label("<b>REPLACEMENT & SPAWNING</b>", boldLabelStyle, Array.Empty<GUILayoutOption>()); searchString = GUILayout.TextField(searchString, searchStyle, Array.Empty<GUILayoutOption>()); scrollPrefabs = GUILayout.BeginScrollView(scrollPrefabs, boxStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(451f) }); List<PrefabInfo> list = availablePrefabs.Where((PrefabInfo p) => string.IsNullOrEmpty(searchString) || p.Name.ToLower().Contains(searchString.ToLower())).ToList(); foreach (PrefabInfo item in list) { GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.Label("<b>" + item.Name + "</b>", new GUIStyle(labelStyle) { richText = true }, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.enabled = selectedModules.Count > 0; if (GUILayout.Button((selectedModules.Count > 1) ? $"REPLACE ({selectedModules.Count})" : "REPLACE", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) })) { List<ModuleInstanceInfo> list2 = new List<ModuleInstanceInfo>(selectedModules); foreach (ModuleInstanceInfo item2 in list2) { ExecuteReplace(item2, item); } selectedModules.Clear(); RefreshModuleList(); GUIUtility.ExitGUI(); } GUI.enabled = true; GUI.backgroundColor = Color.cyan; if (GUILayout.Button("SPAWN AT ME", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(25f) })) { SpawnAtPlayer(item); RefreshModuleList(); GUIUtility.ExitGUI(); } GUI.backgroundColor = Color.white; GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.Space(2f); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.EndHorizontal(); } private void ExecuteBatchDelete() { List<ModuleInstanceInfo> list = new List<ModuleInstanceInfo>(selectedModules); foreach (ModuleInstanceInfo item in list) { if (!((Object)(object)item.Module == (Object)null)) { if (SemiFunc.IsMultiplayer()) { PhotonNetwork.Destroy(((Component)item.Module).gameObject); } else { Object.Destroy((Object)(object)((Component)item.Module).gameObject); } } } selectedModules.Clear(); ((MonoBehaviour)this).Invoke("RefreshModuleList", 0.1f); } private void ExecuteDoorCleanup() { if (!IsSafeToModify()) { Debug.LogWarning((object)"ModuleEditor: Cannot cleanup doors while level is loading!"); return; } string pattern = "^(Door|Arctic Door|Museum Storage Door|Manor Door|Wizard Door|Museum Door)(\\s*\\(.*\\))?(\\s*\\d+)?"; GameObject[] array = Object.FindObjectsOfType<GameObject>(); int num = 0; GameObject[] array2 = array; foreach (GameObject val in array2) { string text = ((Object)val).name.ToLower(); if ((!text.Contains("truck") || !text.Contains("door")) && Regex.IsMatch(((Object)val).name, pattern)) { if (SemiFunc.IsMultiplayer()) { PhotonNetwork.Destroy(val); } else { Object.Destroy((Object)(object)val); } num++; } } Debug.Log((object)$"Door Cleanup: Removed {num} doors."); RefreshModuleList(); } private void SpawnAtPlayer(PrefabInfo p) { //IL_003d: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00ad: Unknown result type (might be due to invalid IL or missing references) if (!IsSafeToModify()) { Debug.LogWarning((object)"ModuleEditor: Cannot cleanup doors while level is loading!"); } else { if (p.PrefabRef == null) { return; } Vector3 position = ((Component)PlayerController.instance).transform.position; float num = 15f; position.x = Mathf.Round(position.x / num) * num; position.z = Mathf.Round(position.z / num) * num; position.y = Mathf.Round(position.y / 2.5f) * 2.5f; GameObject val = null; val = ((!SemiFunc.IsMultiplayer()) ? Object.Instantiate<GameObject>(p.PrefabRef.Prefab, position, Quaternion.identity) : PhotonNetwork.InstantiateRoomObject(p.PrefabRef.ResourcePath, position, Quaternion.identity, (byte)0, (object[])null)); if ((Object)(object)val != (Object)null && (Object)(object)LevelGenerator.Instance?.LevelParent != (Object)null) { if ((Object)(object)val != (Object)null && (Object)(object)LevelGenerator.Instance?.LevelParent != (Object)null) { val.transform.parent = LevelGenerator.Instance.LevelParent.transform; ((Object)val).name = p.Name; } ((Object)val).name = p.Name; } } } private void ExecuteReplace(ModuleInstanceInfo oldInfo, PrefabInfo newPrefab) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) if (!IsSafeToModify()) { Debug.LogWarning((object)"ModuleEditor: Cannot cleanup doors while level is loading!"); return; } Vector3 position = ((Component)oldInfo.Module).transform.position; Quaternion rotation = ((Component)oldInfo.Module).transform.rotation; Transform parent = ((Component)oldInfo.Module).transform.parent; int num = (int)f_GridX.GetValue(oldInfo.Module); int num2 = (int)f_GridY.GetValue(oldInfo.Module); bool flag = (bool)f_Top.GetValue(oldInfo.Module); bool flag2 = (bool)f_Bottom.GetValue(oldInfo.Module); bool flag3 = (bool)f_Left.GetValue(oldInfo.Module); bool flag4 = (bool)f_Right.GetValue(oldInfo.Module); bool flag5 = (bool)f_First.GetValue(oldInfo.Module); if (SemiFunc.IsMultiplayer()) { PhotonNetwork.Destroy(((Component)oldInfo.Module).gameObject); } else { Object.Destroy((Object)(object)((Component)oldInfo.Module).gameObject); } GameObject val = null; val = ((!SemiFunc.IsMultiplayer()) ? Object.Instantiate<GameObject>(newPrefab.PrefabRef.Prefab, position, rotation) : PhotonNetwork.InstantiateRoomObject(newPrefab.PrefabRef.ResourcePath, position, rotation, (byte)0, (object[])null)); if ((Object)(object)val != (Object)null) { val.transform.parent = parent; Module component = val.GetComponent<Module>(); if ((Object)(object)component != (Object)null) { f_GridX.SetValue(component, num); f_GridY.SetValue(component, num2); component.ModuleConnectionSet(flag, flag2, flag4, flag3, flag5); } } } private void ExecuteCloneReplace(ModuleInstanceInfo oldInfo, Module sourceModule) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0022: 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) Vector3 position = ((Component)oldInfo.Module).transform.position; Quaternion rotation = ((Component)oldInfo.Module).transform.rotation; Transform parent = ((Component)oldInfo.Module).transform.parent; int num = (int)f_GridX.GetValue(oldInfo.Module); int num2 = (int)f_GridY.GetValue(oldInfo.Module); bool flag = (bool)f_Top.GetValue(oldInfo.Module); bool flag2 = (bool)f_Bottom.GetValue(oldInfo.Module); bool flag3 = (bool)f_Left.GetValue(oldInfo.Module); bool flag4 = (bool)f_Right.GetValue(oldInfo.Module); bool flag5 = (bool)f_First.GetValue(oldInfo.Module); if (SemiFunc.IsMultiplayer()) { PhotonNetwork.Destroy(((Component)oldInfo.Module).gameObject); } else { Object.Destroy((Object)(object)((Component)oldInfo.Module).gameObject); } GameObject val = Object.Instantiate<GameObject>(((Component)sourceModule).gameObject, position, rotation); if ((Object)(object)val != (Object)null) { val.transform.parent = parent; ((Object)val).name = ((Object)sourceModule).name; Module component = val.GetComponent<Module>(); if ((Object)(object)component != (Object)null) { f_GridX.SetValue(component, num); f_GridY.SetValue(component, num2); component.ModuleConnectionSet(flag, flag2, flag4, flag3, flag5); } } } private void RefreshModuleList() { currentModules.Clear(); if (!((Object)(object)LevelGenerator.Instance?.LevelParent == (Object)null)) { Module[] componentsInChildren = LevelGenerator.Instance.LevelParent.GetComponentsInChildren<Module>(true); foreach (Module val in componentsInChildren) { currentModules.Add(new ModuleInstanceInfo { Module = val, Name = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "") }); } } } private void LoadAllPrefabs() { if (availablePrefabs.Count > 0) { return; } Level[] array = Resources.FindObjectsOfTypeAll<Level>(); Level[] array2 = array; foreach (Level val in array2) { if ((Object)(object)val == (Object)null) { continue; } List<List<PrefabRef>> list = new List<List<PrefabRef>> { val.ModulesNormal1, val.ModulesNormal2, val.ModulesNormal3, val.ModulesPassage1, val.ModulesPassage2, val.ModulesPassage3, val.ModulesDeadEnd1, val.ModulesDeadEnd2, val.ModulesDeadEnd3, val.ModulesExtraction1, val.ModulesExtraction2, val.ModulesExtraction3, val.StartRooms }; foreach (List<PrefabRef> item in list) { if (item == null) { continue; } foreach (PrefabRef r in item) { if (r != null && !string.IsNullOrEmpty(r.PrefabName) && !availablePrefabs.Any((PrefabInfo x) => x.Name == r.PrefabName)) { availablePrefabs.Add(new PrefabInfo { PrefabRef = r, Name = r.PrefabName }); } } } } } private bool IsSafeToModify() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 if ((Object)(object)GameDirector.instance == (Object)null) { return false; } gameState currentState = GameDirector.instance.currentState; if ((int)currentState == 0 || (int)currentState == 4 || (int)currentState == 5 || (int)currentState == 1) { return false; } return true; } private void InitStyles() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0051: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_00b5: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown windowStyle = new GUIStyle(GUI.skin.window); boxStyle = new GUIStyle(GUI.skin.box); GUIStyle val = new GUIStyle(GUI.skin.label); val.normal.textColor = Color.white; labelStyle = val; boldLabelStyle = new GUIStyle(labelStyle) { fontStyle = (FontStyle)1, fontSize = 14 }; GUIStyle val2 = new GUIStyle(GUI.skin.box); val2.normal.background = MakeTex(2, 2, new Color(0.2f, 0.6f, 0.2f, 1f)); selectedStyle = val2; searchStyle = new GUIStyle(GUI.skin.textField); buttonStyle = new GUIStyle(GUI.skin.button) { fontSize = 11 }; stylesInit = true; } private Texture2D MakeTex(int w, int h, Color c) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Color[] array = (Color[])(object)new Color[w * h]; for (int i = 0; i < array.Length; i++) { array[i] = c; } Texture2D val = new Texture2D(w, h); val.SetPixels(array); val.Apply(); return val; } }