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 CleanShip v1.0.2
CleanShip.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using GameNetcodeStuff; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CleanShip")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+25c99e96dc6d3a04909db71266aabd3b4f8db979")] [assembly: AssemblyProduct("CleanShip")] [assembly: AssemblyTitle("CleanShip")] [assembly: AssemblyVersion("1.0.0.0")] namespace CleanShip; public static class Setting { public static bool bMenu; public static bool bCleaning; } [Serializable] public class ItemLocationList { public float winWidth = 600f; public float winHeight = 800f; public int fontSize = 16; public bool onlySortCustom = false; public List<ItemData> items = new List<ItemData>(); } [Serializable] public class ItemData { public string itemName; public float x; public float y; public float z; } [BepInPlugin("me.cleanship.mod", "CleanShip", "1.0.2")] public class Plugin : BaseUnityPlugin { public static ManualLogSource Log; public static Plugin Instance; private Rect winRect; private bool isMenuOpen = false; private Vector2 configScrollPosition = Vector2.zero; private Vector2 shipItemsScrollPosition = Vector2.zero; private string searchKeyword = ""; private string configPath; public ItemLocationList customLocations = new ItemLocationList(); private List<string> detectedShipItemNames = new List<string>(); private InputAction menuKeyAction; private void Awake() { //IL_005f: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)">>> CleanShip 物品整理模组加载中... <<<"); configPath = Path.Combine(Paths.ConfigPath, "CleanShip_Items.json"); LoadCustomLocations(); winRect = new Rect(50f, 50f, customLocations.winWidth, customLocations.winHeight); menuKeyAction = new InputAction("OpenCleanShipMenu", (InputActionType)0, "<Keyboard>/equals", (string)null, (string)null, (string)null); menuKeyAction.performed += ToggleMenu; menuKeyAction.Enable(); } private void ToggleMenu(CallbackContext context) { isMenuOpen = !isMenuOpen; Setting.bMenu = isMenuOpen; if (isMenuOpen) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; RefreshShipItems(); } else { Cursor.visible = false; Cursor.lockState = (CursorLockMode)1; } } private void SaveCustomLocations() { string contents = JsonUtility.ToJson((object)customLocations, true); File.WriteAllText(configPath, contents); } private void LoadCustomLocations() { if (File.Exists(configPath)) { try { string text = File.ReadAllText(configPath); customLocations = JsonUtility.FromJson<ItemLocationList>(text); return; } catch { customLocations = new ItemLocationList(); return; } } customLocations = new ItemLocationList(); } private void OnGUI() { //IL_0141: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_0132: 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) if (!isMenuOpen) { return; } int fontSize = customLocations.fontSize; GUI.skin.label.fontSize = fontSize; GUI.skin.button.fontSize = fontSize; GUI.skin.textField.fontSize = fontSize; GUI.skin.box.fontSize = fontSize; GUI.skin.toggle.fontSize = fontSize; GUI.skin.window.fontSize = fontSize + 2; GUI.backgroundColor = Color.black; if (Mathf.Abs(((Rect)(ref winRect)).width - customLocations.winWidth) > 1f) { ((Rect)(ref winRect)).width = customLocations.winWidth; } if (Mathf.Abs(((Rect)(ref winRect)).height - customLocations.winHeight) > 1f) { ((Rect)(ref winRect)).height = customLocations.winHeight; } try { winRect = GUILayout.Window(9999, winRect, new WindowFunction(WindowFunction), "CleanShip 物品整理控制台", Array.Empty<GUILayoutOption>()); } catch { GUI.color = Color.white; GUI.backgroundColor = Color.white; } } private void WindowFunction(int id) { //IL_0035: 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_00b3: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: 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_0355: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_05b8: Unknown result type (might be due to invalid IL or missing references) //IL_07a8: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Label("--- 基础操作 ---", Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.backgroundColor = (Setting.bCleaning ? Color.green : Color.white); if (GUILayout.Button(Setting.bCleaning ? "停止整理" : "整理飞船", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) })) { if (!Setting.bCleaning) { ((MonoBehaviour)this).StartCoroutine(SortCoroutine()); } else { Setting.bCleaning = false; ((MonoBehaviour)this).StopAllCoroutines(); } } GUI.backgroundColor = (customLocations.onlySortCustom ? Color.cyan : Color.gray); if (GUILayout.Button(customLocations.onlySortCustom ? "模式: 仅自定义" : "模式: 全部整理", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) })) { customLocations.onlySortCustom = !customLocations.onlySortCustom; SaveCustomLocations(); } GUI.backgroundColor = Color.white; GUILayout.EndHorizontal(); GUILayout.Space(15f); GUI.color = Color.cyan; GUILayout.Label("--- 飞船内物品扫描 ---", Array.Empty<GUILayoutOption>()); GUI.color = Color.white; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("刷新", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) })) { RefreshShipItems(); } GUILayout.Label("搜:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); searchKeyword = GUILayout.TextField(searchKeyword, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); shipItemsScrollPosition = GUILayout.BeginScrollView(shipItemsScrollPosition, GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(180f) }); List<string> list = detectedShipItemNames.Where((string n) => n?.ToLower().Contains(searchKeyword.ToLower()) ?? false).ToList(); if (list.Count == 0) { GUILayout.Label("无匹配物品", Array.Empty<GUILayoutOption>()); } else { foreach (string itemName in list) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.color = (customLocations.items.Any((ItemData x) => x != null && x.itemName == itemName) ? Color.green : Color.white); GUILayout.Label(itemName, Array.Empty<GUILayoutOption>()); GUI.color = Color.white; if (GUILayout.Button("设为脚下", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { RecordItemByName(itemName); } GUILayout.EndHorizontal(); } } GUILayout.EndScrollView(); GUILayout.Space(15f); GUI.color = Color.yellow; GUILayout.Label($"--- 已保存配置 ({customLocations.items.Count}) ---", Array.Empty<GUILayoutOption>()); GUI.color = Color.white; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("记录手持", Array.Empty<GUILayoutOption>())) { RecordCurrentItem(); } if (GUILayout.Button("保存配置", Array.Empty<GUILayoutOption>())) { SaveCustomLocations(); Log.LogInfo((object)"配置已保存!"); } GUILayout.EndHorizontal(); configScrollPosition = GUILayout.BeginScrollView(configScrollPosition, GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(200f) }); for (int i = 0; i < customLocations.items.Count; i++) { ItemData itemData = customLocations.items[i]; if (itemData != null) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(itemData.itemName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }); itemData.x = (float.TryParse(GUILayout.TextField(itemData.x.ToString("F1"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }), out var result) ? result : itemData.x); itemData.y = (float.TryParse(GUILayout.TextField(itemData.y.ToString("F1"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }), out var result2) ? result2 : itemData.y); itemData.z = (float.TryParse(GUILayout.TextField(itemData.z.ToString("F1"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }), out var result3) ? result3 : itemData.z); GUI.backgroundColor = Color.red; if (GUILayout.Button("X", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) })) { customLocations.items.RemoveAt(i); SaveCustomLocations(); } GUI.backgroundColor = Color.white; GUILayout.EndHorizontal(); } } GUILayout.EndScrollView(); GUILayout.Space(15f); GUI.color = Color.magenta; GUILayout.Label("--- 界面设置 ---", Array.Empty<GUILayoutOption>()); GUI.color = Color.white; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"字体: {customLocations.fontSize}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); int num = (int)GUILayout.HorizontalSlider((float)customLocations.fontSize, 10f, 30f, Array.Empty<GUILayoutOption>()); if (num != customLocations.fontSize) { customLocations.fontSize = num; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"宽: {(int)customLocations.winWidth}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); float num2 = GUILayout.HorizontalSlider(customLocations.winWidth, 400f, 1000f, Array.Empty<GUILayoutOption>()); if (Mathf.Abs(num2 - customLocations.winWidth) > 1f) { customLocations.winWidth = num2; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"高: {(int)customLocations.winHeight}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); float num3 = GUILayout.HorizontalSlider(customLocations.winHeight, 600f, 1300f, Array.Empty<GUILayoutOption>()); if (Mathf.Abs(num3 - customLocations.winHeight) > 1f) { customLocations.winHeight = num3; } GUILayout.EndHorizontal(); if (GUILayout.Button("保存界面设置", Array.Empty<GUILayoutOption>())) { SaveCustomLocations(); } GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, customLocations.winWidth, 30f)); } private T GetPrivateField<T>(object instance, string fieldName) { FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return (T)field.GetValue(instance); } return default(T); } private void SetPrivateField(object instance, string fieldName, object value) { FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(instance, value); } } private void CallPrivateMethod(object instance, string methodName, params object[] args) { MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(instance, args); } } private IEnumerator SortCoroutine() { Setting.bCleaning = true; PlayerControllerB player = GameNetworkManager.Instance?.localPlayerController; Transform shipTransform = StartOfRound.Instance?.elevatorTransform; if ((Object)(object)shipTransform == (Object)null || (Object)(object)player == (Object)null) { Setting.bCleaning = false; yield break; } GrabbableObject[] items = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0); GrabbableObject[] array = items; foreach (GrabbableObject item in array) { if (!Setting.bCleaning || player.isPlayerDead || !player.isPlayerControlled || !StartOfRound.Instance.inShipPhase) { break; } if ((Object)(object)item == (Object)null || (Object)(object)item.itemProperties == (Object)null) { continue; } bool isPhysicallyInShip = Vector3.Distance(((Component)item).transform.position, shipTransform.position) < 18f; if (item.isHeld || item.heldByPlayerOnServer || (!item.isInShipRoom && !isPhysicallyInShip)) { continue; } ItemData customData = customLocations.items.FirstOrDefault((ItemData x) => x != null && x.itemName == item.itemProperties.itemName); if (customLocations.onlySortCustom && customData == null) { continue; } Vector3 targetPos = new Vector3(-3.3f, 0.5f, -12.7f); if (customData != null) { targetPos = new Vector3(customData.x, customData.y, customData.z); } if (Vector3.Distance(((Component)item).transform.position, targetPos) > 0.2f) { yield return (object)new WaitUntil((Func<bool>)(() => player.isPlayerDead || !GetPrivateField<bool>(player, "isThrowingObject"))); if (player.isPlayerDead) { break; } NetworkObjectReference netObjRef = new NetworkObjectReference(((NetworkBehaviour)item).NetworkObject); SetPrivateField(player, "currentlyGrabbingObject", item); CallPrivateMethod(player, "GrabObjectServerRpc", netObjRef); float waitTimer = 0f; yield return (object)new WaitUntil((Func<bool>)delegate { waitTimer += Time.deltaTime; return player.isPlayerDead || (Object)(object)player.currentlyHeldObjectServer == (Object)(object)item || waitTimer > 1f; }); if (!player.isPlayerDead && !((Object)(object)player.currentlyHeldObjectServer != (Object)(object)item)) { player.DiscardHeldObject(true, (NetworkObject)null, targetPos, false); ((Component)item).transform.rotation = Quaternion.Euler(0f, 0f, 0f); yield return (object)new WaitForSeconds(0.1f); } } else if (Quaternion.Angle(((Component)item).transform.rotation, Quaternion.Euler(0f, 0f, 0f)) > 5f) { ((Component)item).transform.rotation = Quaternion.Euler(0f, 0f, 0f); } } Setting.bCleaning = false; } private void RefreshShipItems() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) detectedShipItemNames.Clear(); if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.elevatorTransform == (Object)null) { return; } Transform elevatorTransform = StartOfRound.Instance.elevatorTransform; GrabbableObject[] array = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0); GrabbableObject[] array2 = array; foreach (GrabbableObject val in array2) { if (!val.isHeld && !val.heldByPlayerOnServer && !(Vector3.Distance(((Component)val).transform.position, elevatorTransform.position) > 20f)) { string text = val.itemProperties?.itemName; if (text != null && !detectedShipItemNames.Contains(text)) { detectedShipItemNames.Add(text); } } } detectedShipItemNames.Sort(); } private void RecordItemByName(string itemName) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00c3: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null)) { Vector3 position = ((Component)val).transform.position; ItemData itemData = customLocations.items.FirstOrDefault((ItemData x) => x != null && x.itemName == itemName); if (itemData != null) { itemData.x = position.x; itemData.y = position.y; itemData.z = position.z; } else { customLocations.items.Add(new ItemData { itemName = itemName, x = position.x, y = position.y, z = position.z }); } SaveCustomLocations(); } } private void RecordCurrentItem() { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.currentlyHeldObjectServer == (Object)null) && !((Object)(object)val.currentlyHeldObjectServer.itemProperties == (Object)null)) { RecordItemByName(val.currentlyHeldObjectServer.itemProperties.itemName); } } }