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 BonekiniBottom v1.0.1
CustomizerT2D.dll
Decompiled 7 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using HarmonyLib; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("CustomizerT2DOnly")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CustomizerT2DOnly")] [assembly: AssemblyTitle("CustomizerT2DOnly")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace CustomizerT2DOnly; [BepInPlugin("com.yourname.customizer.t2donly", "CustomizerT2DOnly", "2.0.0")] public class CustomizerT2DOnly : BaseUnityPlugin { [HarmonyPatch(typeof(Material), "set_mainTexture")] internal static class H_Material_Setters { private static void Postfix(Material __instance, Texture value) { Texture2D val = (Texture2D)(object)((value is Texture2D) ? value : null); if (val != null) { Instance?.TrySwap(val); } } [HarmonyPatch(typeof(Material), "SetTexture", new Type[] { typeof(string), typeof(Texture) })] [HarmonyPostfix] private static void SetTexture_Postfix(Material __instance, string name, Texture value) { Texture2D val = (Texture2D)(object)((value is Texture2D) ? value : null); if (val != null) { Instance?.TrySwap(val); } } } [HarmonyPatch(typeof(SpriteRenderer), "set_sprite")] internal static class H_SpriteRenderer_SetSprite { private static void Postfix(Sprite value) { Texture2D val = (Object.op_Implicit((Object)(object)value) ? value.texture : null); if (Object.op_Implicit((Object)(object)val)) { Instance?.TrySwap(val); } } } internal static class H_UI_Image_SetSprite { public static void Postfix(object __instance, Sprite value) { if (Object.op_Implicit((Object)(object)value)) { Texture2D texture = value.texture; if (Object.op_Implicit((Object)(object)texture)) { Instance?.TrySwap(texture); } } } } [CompilerGenerated] private sealed class <AdaptiveWatcher>d__41 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CustomizerT2DOnly <>4__this; private Stopwatch <sw>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AdaptiveWatcher>d__41(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <sw>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown int num = <>1__state; CustomizerT2DOnly customizerT2DOnly = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; <sw>5__2 = new Stopwatch(); } if (customizerT2DOnly._keys != null && customizerT2DOnly._satisfiedKeys.Count < customizerT2DOnly._keys.Count) { if (customizerT2DOnly._scanSnapshot == null || customizerT2DOnly._scanIndex >= customizerT2DOnly._scanSnapshot.Length) { customizerT2DOnly._scanSnapshot = Resources.FindObjectsOfTypeAll<Texture2D>(); customizerT2DOnly._scanIndex = 0; } <sw>5__2.Restart(); while (customizerT2DOnly._scanIndex < customizerT2DOnly._scanSnapshot.Length && <sw>5__2.Elapsed.TotalMilliseconds < 3.0) { Texture2D val = customizerT2DOnly._scanSnapshot[customizerT2DOnly._scanIndex++]; if (Object.op_Implicit((Object)(object)val)) { customizerT2DOnly.TrySwap(val); } } <sw>5__2.Stop(); } else { customizerT2DOnly._scanSnapshot = null; customizerT2DOnly._scanIndex = 0; } <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WatchRoutine>d__34 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CustomizerT2DOnly <>4__this; private float <elapsed>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WatchRoutine>d__34(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown int num = <>1__state; CustomizerT2DOnly customizerT2DOnly = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <elapsed>5__2 = 0f; break; case 1: <>1__state = -1; <elapsed>5__2 += 0.5f; break; } if (<elapsed>5__2 < 4f) { customizerT2DOnly.ApplyOverridesPass(); if (customizerT2DOnly._satisfiedKeys.Count < customizerT2DOnly._keys.Count) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } } customizerT2DOnly._watchRoutine = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float MENU_DELAY = 0.6f; private const float GAMEPLAY_DELAY = 0.5f; private const float WATCH_WINDOW_SECONDS = 4f; private const float WATCH_TICK_SECONDS = 0.5f; private const float ADAPTIVE_TICK = 0.1f; private const double ADAPTIVE_BUDGET_MS = 3.0; private static readonly string[] MENU_SCENE_PATTERNS = new string[3] { "menu", "mainmenu", "title" }; private static MethodInfo _miLoadImageBool; private static MethodInfo _miLoadImage; private static MethodInfo _miTexLoadImage; private Dictionary<string, (byte[] bytes, int w, int h)> _map; private HashSet<string> _keys; private readonly HashSet<int> _replacedIds = new HashSet<int>(); private readonly HashSet<int> _notOurTex = new HashSet<int>(); private readonly HashSet<string> _satisfiedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private bool _armedForGameplayOnce; private Coroutine _watchRoutine; private Coroutine _adaptiveRoutine; private Type _typeSpriteAtlas; private Type _typeSpriteAtlasManager; private EventInfo _evAtlasRegistered; private MethodInfo _miGetSprites_Array; private Delegate _atlasCallbackDelegate; private Texture2D[] _scanSnapshot; private int _scanIndex; private Harmony _harmony; private static CustomizerT2DOnly Instance { get { GameObject managerObject = Chainloader.ManagerObject; if (managerObject == null) { return null; } return managerObject.GetComponent<CustomizerT2DOnly>(); } } private void OnEnable() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _harmony = new Harmony("com.yourname.customizer.t2donly.setters"); try { _harmony.PatchAll(typeof(H_Material_Setters)); _harmony.PatchAll(typeof(H_SpriteRenderer_SetSprite)); TryPatchUIImageSetter(_harmony); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"[T2D] Harmony setters failed: {arg}"); } TryHookSpriteAtlasRegistered(); SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; if (_watchRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_watchRoutine); } if (_adaptiveRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_adaptiveRoutine); } TryUnhookSpriteAtlasRegistered(); try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } } private void Awake() { CacheLoadImageMethods(); } private void Start() { //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_003c: Unknown result type (might be due to invalid IL or missing references) BuildOverrideMap(); if (_keys != null && _keys.Count > 0 && _adaptiveRoutine == null) { _adaptiveRoutine = ((MonoBehaviour)this).StartCoroutine(AdaptiveWatcher()); } Scene activeScene = SceneManager.GetActiveScene(); if (IsMenu(activeScene)) { _armedForGameplayOnce = true; ((MonoBehaviour)this).Invoke("ApplyOnMenu", 0.6f); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (IsMenu(scene)) { _armedForGameplayOnce = true; ((MonoBehaviour)this).Invoke("ApplyOnMenu", 0.6f); } else if (_armedForGameplayOnce) { _armedForGameplayOnce = false; ((MonoBehaviour)this).Invoke("StartGameplayWatch", 0.5f); } } private static bool IsMenu(Scene scene) { string text = ((Scene)(ref scene)).name ?? string.Empty; string[] mENU_SCENE_PATTERNS = MENU_SCENE_PATTERNS; foreach (string value in mENU_SCENE_PATTERNS) { if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private void ApplyOnMenu() { _satisfiedKeys.Clear(); ApplyOverridesPass(); } private void StartGameplayWatch() { if (_watchRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_watchRoutine); } _watchRoutine = ((MonoBehaviour)this).StartCoroutine(WatchRoutine()); } [IteratorStateMachine(typeof(<WatchRoutine>d__34))] private IEnumerator WatchRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WatchRoutine>d__34(0) { <>4__this = this }; } private void CacheLoadImageMethods() { try { Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule", throwOnError: false); if (type != null) { _miLoadImageBool = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, null); if (_miLoadImageBool == null) { _miLoadImage = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(Texture2D), typeof(byte[]) }, null); } } _miTexLoadImage = typeof(Texture2D).GetMethod("LoadImage", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(byte[]) }, null); } catch { } } private bool LoadImageCompat(Texture2D tex, byte[] data, bool makeNoLongerReadable) { try { if ((Object)(object)tex == (Object)null || data == null) { return false; } if (_miLoadImageBool != null) { return (bool)_miLoadImageBool.Invoke(null, new object[3] { tex, data, makeNoLongerReadable }); } if (_miLoadImage != null) { return (bool)_miLoadImage.Invoke(null, new object[2] { tex, data }); } if (_miTexLoadImage != null) { return (bool)_miTexLoadImage.Invoke(tex, new object[1] { data }); } return false; } catch { return false; } } private static string NormalizeName(string name) { if (string.IsNullOrEmpty(name)) { return name; } if (name.StartsWith("sactx-", StringComparison.OrdinalIgnoreCase)) { int num = name.LastIndexOf('-'); if (num > 0 && num < name.Length - 1) { int num2 = name.Length - (num + 1); if (num2 >= 6 && num2 <= 10) { bool flag = true; for (int i = num + 1; i < name.Length; i++) { char c = name[i]; if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F')) { flag = false; break; } } if (flag) { return name.Substring(0, num); } } } } return name; } private void BuildOverrideMap() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown _map = new Dictionary<string, (byte[], int, int)>(StringComparer.OrdinalIgnoreCase); try { string path = Path.Combine(Application.dataPath, "Mods", "Customizer"); if (!Directory.Exists(path)) { return; } string[] directories = Directory.GetDirectories(path); foreach (string path2 in directories) { string path3 = Path.Combine(path2, "Texture2D"); if (!Directory.Exists(path3)) { continue; } foreach (string item in Directory.EnumerateFiles(path3, "*.png", SearchOption.TopDirectoryOnly)) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item); string key = NormalizeName(fileNameWithoutExtension); try { byte[] array = File.ReadAllBytes(item); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (LoadImageCompat(val, array, makeNoLongerReadable: false)) { _map[key] = (array, ((Texture)val).width, ((Texture)val).height); } Object.Destroy((Object)(object)val); } catch { } } } _keys = new HashSet<string>(_map.Keys, StringComparer.OrdinalIgnoreCase); } catch { } } private void ApplyOverridesPass() { if (_map != null && _map.Count != 0) { Texture2D[] array = Resources.FindObjectsOfTypeAll<Texture2D>(); for (int i = 0; i < array.Length; i++) { TrySwap(array[i]); } } } private bool TrySwap(Texture2D tex) { if (!Object.op_Implicit((Object)(object)tex)) { return false; } int instanceID = ((Object)tex).GetInstanceID(); if (_replacedIds.Contains(instanceID) || _notOurTex.Contains(instanceID)) { return false; } string text = NormalizeName(((Object)tex).name); if (!_keys.Contains(text)) { _notOurTex.Add(instanceID); return false; } (byte[], int, int) tuple = _map[text]; if (((Texture)tex).width != tuple.Item2 || ((Texture)tex).height != tuple.Item3) { _notOurTex.Add(instanceID); return false; } if (LoadImageCompat(tex, tuple.Item1, makeNoLongerReadable: false)) { _replacedIds.Add(instanceID); _satisfiedKeys.Add(text); if (_replacedIds.Count > 16384 || _notOurTex.Count > 16384) { _replacedIds.Clear(); _notOurTex.Clear(); } return true; } _notOurTex.Add(instanceID); return false; } [IteratorStateMachine(typeof(<AdaptiveWatcher>d__41))] private IEnumerator AdaptiveWatcher() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AdaptiveWatcher>d__41(0) { <>4__this = this }; } private void TryHookSpriteAtlasRegistered() { try { _typeSpriteAtlas = Type.GetType("UnityEngine.U2D.SpriteAtlas, UnityEngine.U2DModule", throwOnError: false); _typeSpriteAtlasManager = Type.GetType("UnityEngine.U2D.SpriteAtlasManager, UnityEngine.U2DModule", throwOnError: false); if (!(_typeSpriteAtlas == null) && !(_typeSpriteAtlasManager == null)) { _evAtlasRegistered = _typeSpriteAtlasManager.GetEvent("atlasRegistered", BindingFlags.Static | BindingFlags.Public); _miGetSprites_Array = _typeSpriteAtlas.GetMethod("GetSprites", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(Sprite[]) }, null); if (!(_evAtlasRegistered == null) && !(_miGetSprites_Array == null)) { MethodInfo method = typeof(CustomizerT2DOnly).GetMethod("OnAtlasRegisteredHandler", BindingFlags.Instance | BindingFlags.NonPublic); Type type = typeof(Action<>).MakeGenericType(_typeSpriteAtlas); _atlasCallbackDelegate = Delegate.CreateDelegate(type, this, method); _evAtlasRegistered.GetAddMethod().Invoke(null, new object[1] { _atlasCallbackDelegate }); } } } catch { } } private void TryUnhookSpriteAtlasRegistered() { try { if (_evAtlasRegistered != null && (object)_atlasCallbackDelegate != null) { _evAtlasRegistered.GetRemoveMethod().Invoke(null, new object[1] { _atlasCallbackDelegate }); } } catch { } finally { _atlasCallbackDelegate = null; _evAtlasRegistered = null; _miGetSprites_Array = null; _typeSpriteAtlas = null; _typeSpriteAtlasManager = null; } } private void OnAtlasRegisteredHandler(object atlasObj) { try { if (atlasObj == null || _miGetSprites_Array == null || _map == null || _map.Count == 0) { return; } Sprite[] array = (Sprite[])(object)new Sprite[1024]; int num = (int)_miGetSprites_Array.Invoke(atlasObj, new object[1] { array }); if (num <= 0) { return; } for (int i = 0; i < num && i < array.Length; i++) { Sprite val = array[i]; if (Object.op_Implicit((Object)(object)val)) { Texture2D texture = val.texture; if (Object.op_Implicit((Object)(object)texture)) { TrySwap(texture); } } } } catch { } } private void TryPatchUIImageSetter(Harmony h) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown try { Type type = Type.GetType("UnityEngine.UI.Image, UnityEngine.UI", throwOnError: false) ?? Type.GetType("UnityEngine.UI.Image, UnityEngine.UIModule", throwOnError: false); if (!(type == null)) { MethodInfo methodInfo = AccessTools.Property(type, "sprite")?.GetSetMethod(); if (!(methodInfo == null)) { HarmonyMethod val = new HarmonyMethod(typeof(H_UI_Image_SetSprite).GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[T2D] Patched UI.Image.set_sprite"); } } } catch { } } }