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 SearchableBuildMenu v1.0.4
SearchableBuildMenu.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using SearchableBuildMenu.Utilities; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("SearchableBuildMenu")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Azumatt")] [assembly: AssemblyProduct("SearchableBuildMenu")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("1.0.4")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.4.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace SearchableBuildMenu { [HarmonyPatch(typeof(Hud), "Awake")] internal static class HudAwakePatch { private static void Postfix(Hud __instance) { //IL_0098: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_0111: Unknown result type (might be due to invalid IL or missing references) SearchableBuildMenuPlugin.BuildSearchBox = Object.Instantiate<GameObject>(SearchableBuildMenuPlugin.Asset.LoadAsset<GameObject>("BuildPieceSearch"), __instance.m_pieceSelectionWindow.transform); ((Object)SearchableBuildMenuPlugin.BuildSearchBox).name = "BuildPieceSearchBox"; DragWindowCntrl.ApplyDragWindowCntrl(SearchableBuildMenuPlugin.BuildSearchBox); SearchableBuildMenuPlugin.BuildSearchInputField = SearchableBuildMenuPlugin.BuildSearchBox.GetComponentInChildren<TMP_InputField>(); TMP_FontAsset font = ((Component)__instance.m_pieceDescription).GetComponentInChildren<TMP_Text>().font; SearchableBuildMenuPlugin.BuildSearchInputField.textComponent.font = font; ((Component)SearchableBuildMenuPlugin.BuildSearchInputField.placeholder).GetComponentInChildren<TMP_Text>().font = font; RectTransform component = SearchableBuildMenuPlugin.BuildSearchBox.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); if (PlayerPrefs.HasKey("SearchableBuildMenuSearchBoxPosition")) { Vector2 anchoredPosition = StringToVector2(PlayerPrefs.GetString("SearchableBuildMenuSearchBoxPosition")); component.anchoredPosition = anchoredPosition; } else { component.anchoredPosition = new Vector2(-10f, 35f); } component.sizeDelta = new Vector2(200f, 30f); ((UnityEvent<string>)(object)SearchableBuildMenuPlugin.BuildSearchInputField.onValueChanged).AddListener((UnityAction<string>)PieceTableUpdateAvailablePatch.OnSearchValueChanged); } internal static Vector2 StringToVector2(string s) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(s)) { throw new ArgumentException("SearchableBuildMenuSearchBoxPosition Input string is null or empty."); } string[] array = s.Substring(1, s.Length - 2).Split(new char[1] { ',' }); if (array.Length != 2) { throw new FormatException("SearchableBuildMenuSearchBoxPosition Input string was not in a correct format."); } return new Vector2(float.Parse(array[0]), float.Parse(array[1])); } } [HarmonyPatch(typeof(PieceTable), "UpdateAvailable")] internal static class PieceTableUpdateAvailablePatch { private static void Postfix(PieceTable __instance) { if ((Object)(object)SearchableBuildMenuPlugin.BuildSearchInputField == (Object)null) { return; } string searchText = SearchableBuildMenuPlugin.BuildSearchInputField.text.ToLower(); if (string.IsNullOrEmpty(searchText)) { return; } if (searchText.StartsWith("@", StringComparison.Ordinal)) { string modIdentifier = searchText.Substring(1).ToLower(); for (int i = 0; i < __instance.m_availablePieces.Count; i++) { __instance.m_availablePieces[i] = __instance.m_availablePieces[i].Where(delegate(Piece piece) { Assembly assemblyForPrefab = AssetLoadTracker.GetAssemblyForPrefab(((Object)((Component)piece).gameObject).name.ToLowerInvariant()); return assemblyForPrefab != null && assemblyForPrefab.GetName().Name.ToLowerInvariant().Contains(modIdentifier); }).ToList(); } return; } if (searchText.StartsWith("!", StringComparison.Ordinal)) { string searchQuery = searchText.Substring(1).ToLower(); for (int j = 0; j < __instance.m_availablePieces.Count; j++) { __instance.m_availablePieces[j] = __instance.m_availablePieces[j].Where((Piece piece) => piece.m_resources.Any((Requirement resource) => Localization.instance.Localize(resource.m_resItem?.m_itemData?.m_shared?.m_name).ToLower().Contains(searchQuery))).ToList(); } return; } for (int k = 0; k < __instance.m_availablePieces.Count; k++) { __instance.m_availablePieces[k] = __instance.m_availablePieces[k].Where((Piece piece) => piece.m_name.ToLower().Contains(searchText) || piece.m_description.ToLower().Contains(searchText) || Localization.instance.Localize(piece.m_name).ToLower().Contains(searchText) || Localization.instance.Localize(piece.m_description).ToLower().Contains(searchText)).ToList(); } } internal static void OnSearchValueChanged(string searchText) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { if (!string.IsNullOrEmpty(searchText)) { localPlayer.UpdateAvailablePiecesList(); } else if (((Humanoid)localPlayer).m_rightItem != null && Object.op_Implicit((Object)(object)((Humanoid)localPlayer).m_rightItem.m_shared.m_buildPieces)) { ((Humanoid)localPlayer).SetPlaceMode(((Humanoid)localPlayer).m_rightItem.m_shared.m_buildPieces); } else { ((Humanoid)localPlayer).SetPlaceMode((PieceTable)null); } } } } [HarmonyPatch(typeof(TextInput), "IsVisible")] internal static class TextInputIsVisiblePatch { private static void Postfix(TextInput __instance, ref bool __result) { if (SearchableBuildMenuPlugin.BuildSearchInputField.isFocused) { __result = true; } } } [HarmonyPatch(typeof(Player), "CopyPiece")] internal static class ClearSearchInputOnCopy { private static void Prefix(Player __instance) { if (!((Object)(object)SearchableBuildMenuPlugin.BuildSearchInputField == (Object)null)) { SearchableBuildMenuPlugin.BuildSearchInputField.text = string.Empty; ((UnityEvent<string>)(object)SearchableBuildMenuPlugin.BuildSearchInputField.onValueChanged).Invoke(SearchableBuildMenuPlugin.BuildSearchInputField.text); } } } [BepInPlugin("Azumatt.SearchableBuildMenu", "SearchableBuildMenu", "1.0.4")] public class SearchableBuildMenuPlugin : BaseUnityPlugin { public enum Toggle { On = 1, Off = 0 } internal const string ModName = "SearchableBuildMenu"; internal const string ModVersion = "1.0.4"; internal const string Author = "Azumatt"; private const string ModGUID = "Azumatt.SearchableBuildMenu"; private readonly Harmony _harmony = new Harmony("Azumatt.SearchableBuildMenu"); public static readonly ManualLogSource SearchableBuildMenuLogger = Logger.CreateLogSource("SearchableBuildMenu"); internal static AssetBundle Asset = null; internal static GameObject BuildSearchBox = null; internal static TMP_InputField BuildSearchInputField = null; public void Awake() { LoadAssets(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); } private static AssetBundle GetAssetBundleFromResources(string filename) { string filename2 = filename; Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename2)); using Stream stream = executingAssembly.GetManifestResourceStream(name); return AssetBundle.LoadFromStream(stream); } public static void LoadAssets() { Asset = GetAssetBundleFromResources("buildpiecesearch"); } private void Start() { AssetLoadTracker.MapPrefabsToBundles(); AssetLoadTracker.MapBundlesToAssemblies(); } } } namespace SearchableBuildMenu.Utilities { public class AssetLoadTracker { private static readonly Dictionary<string, string> PrefabToBundleMapping = new Dictionary<string, string>(); private static readonly Dictionary<string, Assembly> BundleToAssemblyMapping = new Dictionary<string, Assembly>(); internal static void MapPrefabsToBundles() { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { foreach (string item in from name in allLoadedAssetBundle.GetAllAssetNames() where name.EndsWith(".prefab") select name) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item); PrefabToBundleMapping[fileNameWithoutExtension] = ((Object)allLoadedAssetBundle).name; } } } internal static void MapBundlesToAssemblies() { List<Assembly> list = Chainloader.PluginInfos.Select((KeyValuePair<string, PluginInfo> keyValuePair) => ((object)keyValuePair.Value.Instance).GetType().Assembly).ToList(); foreach (string bundleName in PrefabToBundleMapping.Values.Distinct()) { foreach (Assembly item in list) { try { if (item.GetManifestResourceNames().Any((string resourceName) => resourceName.EndsWith(bundleName))) { BundleToAssemblyMapping[bundleName] = item; break; } } catch (Exception arg) { SearchableBuildMenuPlugin.SearchableBuildMenuLogger.LogError((object)$"Error while getting manifest resource names for assembly {item.GetName().Name}: {arg}"); } } } } public static Assembly? GetAssemblyForPrefab(string prefabName) { if (PrefabToBundleMapping.TryGetValue(prefabName, out string value) && BundleToAssemblyMapping.TryGetValue(value, out Assembly value2)) { return value2; } return null; } public static string GetBundleForPrefab(string prefabName) { if (!PrefabToBundleMapping.TryGetValue(prefabName, out string value)) { return ""; } return value; } } public class DragWindowCntrl : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler { private float size; private float _scale = 1f; private RectTransform _window; private Vector2 _delta; private Image draggingImage; public static void ApplyDragWindowCntrl(GameObject go) { go.AddComponent<DragWindowCntrl>(); } private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown _window = (RectTransform)((Component)this).transform; Transform obj = Utils.FindChild(((Component)this).transform, "DraggingImage", (IterativeSearchType)0); draggingImage = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null); if (!((Object)(object)draggingImage == (Object)null)) { ((Behaviour)draggingImage).enabled = false; } } private void Start() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_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_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_0060: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); if (PlayerPrefs.HasKey("SearchableBuildMenuSearchBoxPosition")) { val = HudAwakePatch.StringToVector2(PlayerPrefs.GetString("SearchableBuildMenuSearchBoxPosition")); } else { ((Vector2)(ref val))..ctor(-10f, 35f); } val = GetCorrectedPositionIfOffScreen(val); _window.anchoredPosition = val; size = _window.sizeDelta.x; _scale = ((Transform)_window).localScale.x; } private void Update() { ((Selectable)SearchableBuildMenuPlugin.BuildSearchInputField).interactable = !Input.GetKey((KeyCode)306); if ((Object)(object)draggingImage != (Object)null) { ((Behaviour)draggingImage).enabled = Input.GetKey((KeyCode)306); } } public void OnBeginDrag(PointerEventData eventData) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_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_0036: Unknown result type (might be due to invalid IL or missing references) Transform parent = ((Transform)_window).parent; Vector2 val = default(Vector2); RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((parent is RectTransform) ? parent : null), eventData.position, eventData.pressEventCamera, ref val); _delta = val - _window.anchoredPosition; } public void OnDrag(PointerEventData eventData) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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) Transform parent = ((Transform)_window).parent; Vector2 val = default(Vector2); if (RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((parent is RectTransform) ? parent : null), eventData.position, eventData.pressEventCamera, ref val)) { Vector2 anchoredPosition = val - _delta; _window.anchoredPosition = anchoredPosition; } } public void OnEndDrag(PointerEventData eventData) { //IL_0007: 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_0011: 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) Vector2 correctedPositionIfOffScreen = GetCorrectedPositionIfOffScreen(_window.anchoredPosition); _window.anchoredPosition = correctedPositionIfOffScreen; PlayerPrefs.SetString("SearchableBuildMenuSearchBoxPosition", ((object)(Vector2)(ref correctedPositionIfOffScreen)).ToString()); PlayerPrefs.Save(); } private Vector2 GetCorrectedPositionIfOffScreen(Vector2 position) { //IL_0028: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) CanvasScaler val = Object.FindObjectOfType<CanvasScaler>(); float num = (float)Screen.width / val.scaleFactor; float num2 = (float)Screen.height / val.scaleFactor; Rect rect = _window.rect; float num3 = ((Rect)(ref rect)).width / 2f; float num4 = ((Rect)(ref rect)).height / 2f; Vector2 result = default(Vector2); ((Vector2)(ref result))..ctor(-10f, 35f); if (!(position.x + num3 < 0f) && !(position.x - num3 > num) && !(position.y + num4 < 0f) && !(position.y - num4 > num2)) { return position; } return result; } } }