using 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 System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Logging; using Discord; using HarmonyLib; using Sandbox; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("TexturePatcher")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("TexturePatcher")] [assembly: AssemblyTitle("TexturePatcher")] [assembly: AssemblyVersion("1.0.0.0")] namespace TexturePatcher { public static class Cheats { private class TextData { public string KeepEnabled = "Mantener activo"; public string SpawnerArm = "Brazo Spawner"; public string TeleportMenuCheat = "Teletransporte"; public string FullBright = "Brillo al máximo"; public string Invincibility = "Invencibilidad"; public string Noclip = "Noclip"; public string Flight = "Volar"; public string InfiniteWallJumps = "Saltos de pared infinitos"; public string NoWeaponCooldown = "Sin enfriamiento de arma"; public string InfinitePowerUps = "Potenciadores infinitos"; public string BlindEnemies = "Enemigos ciegos"; public string EnemiesHateEnemies = "Los enemigos se atacan entre sí"; public string EnemiesIgnorePlayer = "Los enemigos ignoran al jugador"; public string DisableEnemySpawns = "Desactivar spawn enemigo"; public string InvincibleEnemies = "Enemigos invencibles"; public string KillAllEnemies = "Matar a todos los enemigos"; public string QuickSave = "Guardado rápido"; public string QuickLoad = "Carga rápida"; public string SaveMenu = "Organizar saves"; public string Clear = "Limpiar"; public string RebuildNav = "Navegación enemigo"; public string Snapping = "Chasquido"; public string Physics = "Física"; public string CrashMode = "Modo Clash"; public string HideWeapons = "Ocultar armas"; public string HideUI = "Ocultar UI"; public string GhostDroneMode = "Drones embrujados"; } private static readonly TextData Text = new TextData(); public static string GetCheatName(string cheat) { return cheat switch { "ultrakill.keep-enabled" => Text.KeepEnabled, "ultrakill.spawner-arm" => Text.SpawnerArm, "ultrakill.teleport-menu" => Text.TeleportMenuCheat, "ultrakill.full-bright" => Text.FullBright, "ultrakill.invincibility" => Text.Invincibility, "ultrakill.noclip" => Text.Noclip, "ultrakill.flight" => Text.Flight, "ultrakill.infinite-wall-jumps" => Text.InfiniteWallJumps, "ultrakill.no-weapon-cooldown" => Text.NoWeaponCooldown, "ultrakill.infinite-power-ups" => Text.InfinitePowerUps, "ultrakill.blind-enemies" => Text.BlindEnemies, "ultrakill.enemy-hate-enemy" => Text.EnemiesHateEnemies, "ultrakill.enemy-ignore-player" => Text.EnemiesIgnorePlayer, "ultrakill.disable-enemy-spawns" => Text.DisableEnemySpawns, "ultrakill.invincible-enemies" => Text.InvincibleEnemies, "ultrakill.kill-all-enemies" => Text.KillAllEnemies, "ultrakill.sandbox.quick-save" => Text.QuickSave, "ultrakill.sandbox.quick-load" => Text.QuickLoad, "ultrakill.sandbox.save-menu" => Text.SaveMenu, "ultrakill.sandbox.clear" => Text.Clear, "ultrakill.sandbox.rebuild-nav" => Text.RebuildNav, "ultrakill.sandbox.snapping" => Text.Snapping, "ultrakill.sandbox.physics" => Text.Physics, "ultrakill.clash-mode" => Text.CrashMode, "ultrakill.hide-weapons" => Text.HideWeapons, "ultrakill.hide-ui" => Text.HideUI, "ultrakill.ghost-drone-mode" => Text.GhostDroneMode, _ => cheat, }; } } [HarmonyPatch(typeof(CheatsManager))] public static class CheatsManagerPatch { private static readonly string Navmesh1 = "NAVMESH DESACTUALIZADO"; private static readonly string Navmesh2 = "(Reconstruir la navegación en el menú de trucos)"; [HarmonyPatch("RebuildMenu")] [HarmonyPostfix] public static void RebuildMenu_Postfix() { GameObject val = GameObject.Find("Canvas"); if (!((Object)(object)val == (Object)null)) { Transform obj = val.transform.Find("Cheat Menu/Cheats Manager/Scroll View/Viewport"); GameObject val2 = ((obj != null) ? ((Component)obj).gameObject : null); if (!((Object)(object)val2 == (Object)null)) { CheatMenuItem[] componentsInChildren = val2.GetComponentsInChildren(true); } } } [HarmonyPatch("RenderCheatsInfo")] [HarmonyPrefix] public static bool RenderCheatsInfo_MyPatch(CheatsManager __instance, Dictionary> ___allRegisteredCheats) { StringBuilder stringBuilder = new StringBuilder(); if (Object.op_Implicit((Object)(object)MonoSingleton.Instance) && MonoSingleton.Instance.isDirty) { stringBuilder.AppendLine("" + Navmesh1 + "\n" + Navmesh2 + "\n"); } if (__instance.GetCheatState("ultrakill.spawner-arm")) { stringBuilder.AppendLine("Brazo spawner en el slot 6\n"); } foreach (KeyValuePair> ___allRegisteredCheat in ___allRegisteredCheats) { foreach (ICheat item in ___allRegisteredCheat.Value) { if (item.IsActive) { string text = MonoSingleton.Instance.ResolveCheatKey(item.Identifier); stringBuilder.Append("[" + ((text != null) ? text.ToUpper() : " ") + "] "); stringBuilder.Append("" + Cheats.GetCheatName(item.Identifier) + "\n"); } } } MonoSingleton.Instance.cheatsInfo.text = stringBuilder.ToString(); return false; } } public static class Core { private static bool _hudPatched; public static void HandleSceneSwitch(Scene scene, ref GameObject canvas) { string name = ((Scene)(ref scene)).name; if (!(name == "Intro") && !(name == "Bootstrap")) { _hudPatched = false; GameObject inactiveRootObject = GetInactiveRootObject("Canvas"); if (!Object.op_Implicit((Object)(object)inactiveRootObject)) { Debug.LogWarning((object)"[TexturePatcher] Canvas no encontrado, reintentando..."); PostInitPatches(); } else if (name == "Main Menu") { PatchFrontEnd(inactiveRootObject); } else { PostInitPatches(); } } } public static async void PostInitPatches() { await Task.Delay(300); if (_hudPatched) { return; } GameObject canvasObj = GetInactiveRootObject("Canvas"); if (!Object.op_Implicit((Object)(object)canvasObj)) { Debug.LogWarning((object)"[TexturePatcher] Canvas aún no existe (PostInit)"); return; } try { Debug.Log((object)"[TexturePatcher] Aplicando MiscHUDPatch"); MiscHUDPatch.PatchMisc(canvasObj); _hudPatched = true; } catch (Exception ex) { Debug.LogError((object)("[TexturePatcher] Error parcheando HUD:\n" + ex)); } } public static void PatchFrontEnd(GameObject frontEnd) { } private static GameObject GetInactiveRootObject(string objectName) { GameObject[] array = Resources.FindObjectsOfTypeAll(); GameObject[] array2 = array; foreach (GameObject val in array2) { if (((Object)val).name == objectName) { return val; } } return null; } public static GameObject GetGameObjectChild(GameObject parent, string childName) { if ((Object)(object)parent == (Object)null) { return null; } Transform val = parent.transform.Find(childName); return Object.op_Implicit((Object)(object)val) ? ((Component)val).gameObject : null; } public static TextMeshProUGUI GetTextMeshProUGUI(GameObject obj) { if ((Object)(object)obj == (Object)null) { return null; } return obj.GetComponent(); } public static string GetCurrentSceneName() { return SceneHelper.CurrentScene; } } [HarmonyPatch(typeof(DiscordController), "SendActivity")] public static class PatchDiscordActivity { public static class LevelNames { public static string GetDiscordLevelName(string missionName) { if (string.IsNullOrEmpty(missionName)) { return "Desconocido"; } missionName = missionName.ToLowerInvariant(); if (missionName.Contains("main menu")) { return "MENÚ PRINCIPAL"; } if (missionName.Contains("tutorial")) { return "TUTORIAL"; } if (missionName.Contains("endless")) { return "THE CYBER GRIND"; } if (missionName.Contains("uk_construct")) { return "SANDBOX"; } if (missionName.Contains("creditsmuseum2")) { return "SALON DE LA FAMA: LOS DEVS DE ULTRAKILL"; } if (missionName.Contains("0-1")) { return "0-1: EN EL FUEGO"; } if (missionName.Contains("0-2")) { return "0-2: LA PICADORA DE CARNE"; } if (missionName.Contains("0-3")) { return "0-3: MÁS ABAJO"; } if (missionName.Contains("0-4")) { return "0-4: EJÉRCITO DE UNA MÁQUINA"; } if (missionName.Contains("0-5")) { return "0-5: CERBERO"; } if (missionName.Contains("0-S")) { return "0-S: ALGO MALO"; } if (missionName.Contains("1-1")) { return "1-1: CORAZÓN DEL AMANECER"; } if (missionName.Contains("1-2")) { return "1-2: EL MUNDO EN LLAMAS"; } if (missionName.Contains("1-3")) { return "1-3: SALONES DE RESTOS SAGRADOS"; } if (missionName.Contains("1-4")) { return "1-4: CLAIR DE LUNE"; } if (missionName.Contains("1-S")) { return "1-S: EL INGENIO"; } if (missionName.Contains("2-1")) { return "2-1: EL CORTA LAZOS"; } if (missionName.Contains("2-2")) { return "2-2: MUERTE A 20,000 VOLTIOS"; } if (missionName.Contains("2-3")) { return "2-3: CERTERO ATAQUE AL CORAZÓN"; } if (missionName.Contains("2-4")) { return "2-4: LA CORTE DEL REY CADÁVER"; } if (missionName.Contains("2-S")) { return "2-S: UNA CANCIÓN DE AMOR TOTALMENTE IMPERFECTA"; } if (missionName.Contains("3-1")) { return "3-1: EL VIENTRE DE LA BESTIA"; } if (missionName.Contains("3-2")) { return "3-2: EN CARNE Y HUESO"; } if (missionName.Contains("4-1")) { return "4-1: ESCLAVOS DE PODER"; } if (missionName.Contains("4-2")) { return "4-2: MALDITO SEA EL SOL"; } if (missionName.Contains("4-3")) { return "4-3: UN DISPARO A CIEGAS"; } if (missionName.Contains("4-4")) { return "4-4: CLAIR DE SOLEIL"; } if (missionName.Contains("4-S")) { return "4-S: LUCHA DE BRANDICOOTS"; } if (missionName.Contains("5-1")) { return "5-1: EN EL DESPERTAR DE POSEIDÓN"; } if (missionName.Contains("5-2")) { return "5-2: OLAS DE UN MAR SIN ESTRELLAS"; } if (missionName.Contains("5-3")) { return "5-3: BARCO DE NECIOS"; } if (missionName.Contains("5-4")) { return "5-4: LEVIATÁN"; } if (missionName.Contains("5-S")) { return "5-S: SÓLO DIGO MAÑANA"; } if (missionName.Contains("6-1")) { return "6-1: LLANTO DEL LLORÓN"; } if (missionName.Contains("6-2")) { return "6-2: ESTÉTICAS DEL ODIO"; } if (missionName.Contains("7-1")) { return "7-1: JARDÍN DE SENDEROS BIFURCADOS"; } if (missionName.Contains("7-2")) { return "7-2: ILUMINA LA NOCHE"; } if (missionName.Contains("7-3")) { return "7-3: SIN SONIDO, SIN MEMORIA"; } if (missionName.Contains("7-4")) { return "7-4: ...COMO ANTENAS HACIA EL CIELO"; } if (missionName.Contains("7-S")) { return "7-S: EL INFIERNO NO TIENE FURIA"; } if (missionName.Contains("8-1")) { return "8-1: MARAVILLAS DEL DESGARRO"; } if (missionName.Contains("8-2")) { return "8-2: A TRAVÉS DEL ESPEJO"; } if (missionName.Contains("8-3")) { return "8-3: BUCLE DE DESINTEGRACIÓN"; } if (missionName.Contains("8-4")) { return "8-4: VUELO FINAL"; } if (missionName.Contains("P-1")) { return "P-1: ESPÍRITU DE SUPERVIVIENTE"; } if (missionName.Contains("P-2")) { return "P-2: EL ESPERAR DEL MUNDO"; } if (missionName.Contains("P-3")) { return "P-3: ???"; } if (missionName.Contains("9-1")) { return "9-1: ???"; } if (missionName.Contains("9-2")) { return "9-2: ???"; } if (missionName.Contains("0-E")) { return "0-E: ESTE CALOR, UN CALOR MALIGNO"; } if (missionName.Contains("1-E")) { return "1-E: ...Y CAYERON LAS CENIZAS"; } if (missionName.Contains("2-E")) { return "2-E: ???"; } if (missionName.Contains("3-E")) { return "3-E: ???"; } if (missionName.Contains("4-E")) { return "4-E: ???"; } if (missionName.Contains("5-E")) { return "5-E: ???"; } if (missionName.Contains("6-E")) { return "6-E: ???"; } if (missionName.Contains("7-E")) { return "7-E: ???"; } if (missionName.Contains("8-E")) { return "8-E: ???"; } if (missionName.Contains("9-E")) { return "9-E: ???"; } if (missionName.Contains("Intermission") || missionName.Contains("EarlyAccessEnd")) { return "???"; } return missionName; } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UpdateActivityHandler <>9__0_0; internal void b__0_0(Result result) { } } [HarmonyPrefix] public static bool SendActivity_MyPatch(DiscordController __instance, Activity ___cachedActivity, RankIcon[] ___rankIcons, ActivityManager ___activityManager) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Expected O, but got Unknown if (___activityManager == null) { return false; } try { Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (GetCurrentSceneName() != "endless") { string[] array = ___cachedActivity.Details.Split(new char[1] { ' ' }); if (array.Length > 1) { if (array[0] == "STYLE:") { ___cachedActivity.Details = "ESTILO: " + array[1]; } else if (array[0] == "WAVE:") { ___cachedActivity.Details = "OLEADA: " + array[1]; } } } else { ___cachedActivity.Details = ""; } if (GetCurrentSceneName() == "Main Menu") { ___cachedActivity.State = "MENÚ PRINCIPAL"; } else { string text = MonoSingleton.Instance.diffNames[MonoSingleton.Instance.GetInt("difficulty", 0)]; switch (text) { case "HARMLESS": text = "INOFENSIVO"; break; case "LENIENT": text = "INDULGENTE"; break; case "STANDARD": text = "ESTÁNDAR"; break; case "VIOLENT": text = "VIOLENTO"; break; case "BRUTAL": text = "BRUTAL"; break; case "ULTRAKILL MUST DIE": text = "ULTRAKILL DEBE MORIR"; break; } ___cachedActivity.State = "DIFICULTAD: " + text; } switch (___cachedActivity.Assets.SmallText) { case "Destructive": ___cachedActivity.Assets.SmallText = "DESTRUCTIVO"; break; case "Chaotic": ___cachedActivity.Assets.SmallText = "CAÓTICO"; break; case "Brutal": ___cachedActivity.Assets.SmallText = "BRUTAL"; break; case "Anarchic": ___cachedActivity.Assets.SmallText = "ANÁRQUICO"; break; case "Supreme": ___cachedActivity.Assets.SmallText = "SUPREMO"; break; case "SSadistic": ___cachedActivity.Assets.SmallText = "SSÁDICO"; break; case "SSShitstorm": ___cachedActivity.Assets.SmallText = "SSSUBLIME"; break; case "ULTRAKILL": ___cachedActivity.Assets.SmallText = "ULTRAKILL"; break; } ___cachedActivity.Assets.LargeText = LevelNames.GetDiscordLevelName(GetCurrentSceneName()); Activity val = ___cachedActivity; object obj = <>c.<>9__0_0; if (obj == null) { UpdateActivityHandler val2 = delegate { }; <>c.<>9__0_0 = val2; obj = (object)val2; } ___activityManager.UpdateActivity(val, (UpdateActivityHandler)obj); return false; } catch (Exception ex) { Debug.LogWarning((object)("Error en PatchDiscordActivity: " + ex)); return false; } } public static string GetCurrentSceneName() { return SceneHelper.CurrentScene; } } [HarmonyPatch(typeof(FinalRank), "SetInfo")] public static class LocalizeFinalRankInfo { [HarmonyPrefix] public static bool SetInfo_MyPatch(int restarts, bool damage, bool majorUsed, bool cheatsUsed, FinalRank __instance, bool ___noRestarts, bool ___majorAssists, bool ___noDamage) { __instance.extraInfo.text = ""; int num = 1; if (!damage) { num++; } if (majorUsed) { num++; } if (cheatsUsed) { num++; } if (cheatsUsed) { TMP_Text extraInfo = __instance.extraInfo; extraInfo.text += "- TRUCOS USADOS\n"; } if (majorUsed) { TMP_Text extraInfo2 = __instance.extraInfo; extraInfo2.text += "- AYUDAS MAYORES USADAS\n"; ___majorAssists = true; } if (restarts == 0) { if (num >= 3) { TMP_Text extraInfo3 = __instance.extraInfo; extraInfo3.text += "+ SIN REINICIOS\n"; } else { TMP_Text extraInfo4 = __instance.extraInfo; extraInfo4.text += "+ SIN REINICIOS\n (+500P)\n"; } ___noRestarts = true; } else { TMP_Text extraInfo5 = __instance.extraInfo; extraInfo5.text = $"- {restarts} REINICIOS\n"; } if (!damage) { if (num >= 3) { TMP_Text extraInfo6 = __instance.extraInfo; extraInfo6.text += "+ SIN DAÑOS\n"; } else { TMP_Text extraInfo7 = __instance.extraInfo; extraInfo7.text += "+ SIN DAÑOS\n (+5,000P)\n"; } ___noDamage = true; } return false; } } [HarmonyPatch(typeof(CrateCounter), "CoinsToPoints")] public static class LocalizeCoinTranslation { [HarmonyPrefix] public static bool CoinsToPoints_MyPatch(CrateCounter __instance, int ___savedCoins) { //IL_0001: 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) Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name == "388594c020ef7c240afc673f062e6425") { int num = ___savedCoins * 100; GameProgressSaver.AddMoney(num); MonoSingleton.Instance.SendHudMessage($"TRANSACCIÓN COMPLETA: {___savedCoins} MONEDAS => {StatsManager.DivideMoney(num)}P", "", "", 0, false, false, true); ___savedCoins = 0; } return false; } } internal static class LocalText { public static string StyleMultiplier = "MULTIPLICADOR"; public static string Classic_Health = "SALUD"; public static string Classic_Stamina = "ESTAMINA"; public static string Classic_Weapon = "ARMA"; public static string Classic_Arm = "BRAZO"; public static string Classic_Rail = "CARGA"; public static string Classic_Speed = "VELOCIDAD"; } public static class HUDMessagesSimple { public static string Translate(string message) { if (message.Contains("V-Rank")) { return message; } if (message.Contains("Altered")) { return "Entidad alterada destruida"; } return message; } } [HarmonyPatch(typeof(SceneManager), "Internal_SceneLoaded")] public static class SceneLoadedPatch { [HarmonyPostfix] public static void Postfix(Scene scene) { MiscHUDPatch.Reset(); MiscHUDPatch.TryPatchHUD(); } } [HarmonyPatch(typeof(HudMessage), "PlayMessage")] public static class LocalizeHudMessagePatch { [HarmonyPostfix] public static void Patch(HudMessage __instance) { try { TMP_Text componentInChildren = ((Component)__instance).GetComponentInChildren(); if (!((Object)(object)componentInChildren == (Object)null)) { string text = HUDMessagesSimple.Translate(__instance.message); text = text.Replace('$', '\n'); componentInChildren.text = text; } } catch (Exception ex) { Debug.LogError((object)("[TexturePatcher] HudMessage error: " + ex)); } } } public static class MiscHUDPatch { private static bool _patched; public static void Reset() { _patched = false; } public static void TryPatchHUD() { if (!_patched) { GameObject val = GameObject.Find("Canvas"); GameObject val2 = GameObject.Find("Player"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { DelayedRetry(); return; } PatchMisc(val); _patched = true; Debug.Log((object)"[TexturePatcher] HUD parcheado correctamente"); } } private static async void DelayedRetry() { await Task.Delay(100); TryPatchHUD(); } public static void PatchMisc(GameObject canvasObj) { GameObject val = GameObject.Find("Player"); if (!((Object)(object)val == (Object)null)) { GameObject child = GetChild(GetChild(GetChild(GetChild(GetChild(GetChild(GetChild(GetChild(val, "Main Camera"), "HUD Camera"), "HUD"), "StyleCanvas"), "Panel (1)"), "Panel"), "Text (1)"), "Text"); SetTMP(child, LocalText.StyleMultiplier); GameObject child2 = GetChild(GetChild(GetChild(canvasObj, "Crosshair Filler"), "AltHud"), "Filler"); GameObject child3 = GetChild(GetChild(GetChild(canvasObj, "Crosshair Filler"), "AltHud (2)"), "Filler"); SetTitle(child2, "Health", LocalText.Classic_Health); SetTitle(child3, "Health (1)", LocalText.Classic_Health); SetTitle(child2, "Stamina", LocalText.Classic_Stamina); SetTitle(child3, "Stamina (1)", LocalText.Classic_Stamina); SetTitle(child2, "Weapon", LocalText.Classic_Weapon); SetTitle(child3, "Weapon (1)", LocalText.Classic_Weapon); SetTitle(child2, "Arm", LocalText.Classic_Arm); SetTitle(child3, "Arm (1)", LocalText.Classic_Arm); SetTitle(child2, "RailcannonMeter (1)", LocalText.Classic_Rail); SetTitle(child3, "RailcannonMeter (2)", LocalText.Classic_Rail); SetTitle(child2, "Speedometer", LocalText.Classic_Speed); SetTitle(child3, "Speedometer", LocalText.Classic_Speed); } } private static void SetTitle(GameObject root, string child, string text) { if (!((Object)(object)root == (Object)null)) { SetTMP(GetChild(GetChild(root, child), "Title"), text); } } private static void SetTMP(GameObject obj, string text) { if (!((Object)(object)obj == (Object)null)) { TextMeshProUGUI component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { ((TMP_Text)component).text = text; } } } private static GameObject GetChild(GameObject parent, string name) { if ((Object)(object)parent == (Object)null) { return null; } Transform val = parent.transform.Find(name); return Object.op_Implicit((Object)(object)val) ? ((Component)val).gameObject : null; } } [BepInPlugin("com.lukah.texturepatcher", "Texture Patcher", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource LoggerInstance; private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown LoggerInstance = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[TexturePatcher] Plugin iniciado correctamente."); Harmony val = new Harmony("com.lukah.texturepatcher"); val.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[TexturePatcher] Parcheos aplicados exitosamente."); } } [HarmonyPatch(typeof(StatsDisplay), "UpdateDisplay")] public static class StatsPatchclass { [HarmonyPostfix] public static void StatsPostfix(StatsDisplay __instance, TMP_Text ___textContent) { if (!((Object)(object)SteamController.Instance == (Object)null)) { SandboxStats sandboxStats = SteamController.Instance.GetSandboxStats(); string arg = "TOTAL DE CAJAS CONSTRUIDAS"; string arg2 = "TOTAL DE ACCESORIOS COLOCADOS"; string arg3 = "TOTAL DE ENEMIGOS GENERADOS"; string arg4 = "TIEMPO TOTAL EN SANDBOX"; ___textContent.text = $"{sandboxStats.brushesBuilt} - {arg}\n" + $"{sandboxStats.propsSpawned} - {arg2}\n" + $"{sandboxStats.enemiesSpawned} - {arg3}\n" + $"{sandboxStats.hoursSpend:F1}h - {arg4}\n"; } } } public static class LevelNames { [HarmonyPatch(typeof(SaveSlotMenu))] public static class SlotLevelAndDifficultyPatch { [HarmonyPatch("UpdateSlotState")] [HarmonyPostfix] public static void UpdateSlotState_Postfix(SlotRowPanel targetPanel, SlotData data) { targetPanel.stateLabel.text = BuildSlotText(data.exists, data.highestLvlNumber, data.highestDifficulty); } private static string BuildSlotText(bool exists, int highestLvlNumber, int highestDifficulty) { if (!exists) { return "SLOT VACÍO"; } string text = MonoSingleton.Instance.diffNames[highestDifficulty] switch { "HARMLESS" => "INOFENSIVO", "LENIENT" => "INDULGENTE", "STANDARD" => "ESTÁNDAR", "VIOLENT" => "VIOLENTO", "BRUTAL" => "BRUTAL", "ULTRAKILL MUST DIE" => "ULTRAKILL DEBE MORIR", _ => "DIFICULTAD DESCONOCIDA", }; return GetLevelName(highestLvlNumber) + " " + ((highestLvlNumber <= 0) ? string.Empty : ("(" + text + ")")); } } public static string GetLevelName(int missionNum, string levelname = "None") { return missionNum switch { 0 => "MENÚ PRINCIPAL", 1 => "0-1: EN EL FUEGO", 2 => "0-2: LA PICADORA DE CARNE", 3 => "0-3: MÁS ABAJO", 4 => "0-4: EJÉRCITO DE UNA MÁQUINA", 5 => "0-5: CERBERO", 6 => "1-1: CORAZÓN DEL AMANECER", 7 => "1-2: EL MUNDO EN LLAMAS", 8 => "1-3: SALONES DE RESTOS SAGRADOS", 9 => "1-4: CLAIR DE LUNE", 10 => "2-1: EL CORTA LAZOS", 11 => "2-2: MUERTE A 20,000 VOLTIOS", 12 => "2-3: CERTERO ATAQUE AL CORAZÓN", 13 => "2-4: LA CORTE DEL REY CADÁVER", 14 => "3-1: EL VIENTRE DE LA BESTIA", 15 => "3-2: EN CARNE Y HUESO", 16 => "4-1: ESCLAVOS DE PODER", 17 => "4-2: MALDITO SEA EL SOL", 18 => "4-3: UN DISPARO A CIEGAS", 19 => "4-4: CLAIR DE SOLEIL", 20 => "5-1: EN EL DESPERTAR DE POSEIDÓN", 21 => "5-2: OLAS DE UN MAR SIN ESTRELLAS", 22 => "5-3: BARCO DE NECIOS", 23 => "5-4: LEVIATÁN", 24 => "6-1: LLANTO DEL LLORÓN", 25 => "6-2: ESTÉTICAS DEL ODIO", 26 => "7-1: JARDÍN DE SENDEROS BIFURCADOS", 27 => "7-2: ILUMINA LA NOCHE", 28 => "7-3: SIN SONIDO, SIN MEMORIA", 29 => "7-4: ...COMO ANTENAS HACIA EL CIELO", 30 => "8-1: MARAVILLAS DEL DESGARRO", 31 => "8-2: A TRAVÉS DEL ESPEJO", 32 => "8-3: BUCLE DE DESINTEGRACIÓN", 33 => "8-4: VUELO FINAL", 34 => "9-1: ???", 35 => "9-2: ???", 100 => "0-E: ESTE CALOR, UN CALOR MALIGNO", 101 => "1-E: ...Y CAYERON LAS CENIZAS", 102 => "2-E: ???", 103 => "3-E: ???", 104 => "4-E: ???", 105 => "5-E: ???", 106 => "6-E: ???", 107 => "7-E: ???", 108 => "8-E: ???", 109 => "9-E: ???", 666 => "P-1: ESPÍRITU DE SUPERVIVIENTE", 667 => "P-2: EL ESPERAR DEL MUNDO", 668 => "P-3: ???", _ => levelname, }; } } [HarmonyPatch(typeof(GunColorTypeGetter), "OnEnable")] public static class GunColorTypeShopPatch { [HarmonyPostfix] public static void OnEnablePostfix(GunColorTypeGetter __instance, TMP_Text[] ___templateTexts) { for (int i = 1; i < 5; i++) { if (GameProgressSaver.GetTotalSecretsFound() < GunColorController.requiredSecrets[i]) { ___templateTexts[i].text = "ORBES DE ALMA: " + GameProgressSaver.GetTotalSecretsFound() + " / " + GunColorController.requiredSecrets[i]; } } } } [HarmonyPatch(typeof(Speedometer), "FixedUpdate")] public static class SpeedometerPatch { [HarmonyPrefix] public static bool FixedUpdate_Prefix(TimeSince ___lastUpdate, bool ___classicVersion, TextMeshProUGUI ___textMesh, int ___type) { //IL_0045: 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_0062: 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_0071: 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) //IL_00a1: 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_00d7: Unknown result type (might be due to invalid IL or missing references) float num = 0f; string arg = ""; if (!___classicVersion) { Vector3 val; switch (___type) { case 0: return false; case 1: val = MonoSingleton.Instance.GetPlayerVelocity(true); num = ((Vector3)(ref val)).magnitude; arg = "u"; break; case 2: val = Vector3.ProjectOnPlane(MonoSingleton.Instance.GetPlayerVelocity(true), Vector3.up); num = ((Vector3)(ref val)).magnitude; arg = "hu"; break; case 3: num = Mathf.Abs(MonoSingleton.Instance.GetPlayerVelocity(true).y); arg = "vu"; break; } if (TimeSince.op_Implicit(___lastUpdate) > 0.064f) { ((TMP_Text)___textMesh).text = $"VELOCIDAD: {num:0.00} {arg}/s"; ___lastUpdate = TimeSince.op_Implicit(0f); } return false; } return true; } } public static class StyleBonusStrings { private static Dictionary BonusDictionary; private static HashSet HiddenBonuses; private static Dictionary DynamicTranslations; static StyleBonusStrings() { BonusDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "ultrakill.airslam", "GOLPE AÉREO" }, { "ultrakill.airshot", "DISPARO AÉREO" }, { "ultrakill.attripator", "ATRACTIVO" }, { "ultrakill.arsenal", "ARSENAL" }, { "ultrakill.bigheadshot", "GRAN HEADSHOT" }, { "ultrakill.bigkill", "GRAN MUERTE" }, { "ultrakill.bigfistkill", "GRAN GOLPE" }, { "ultrakill.bipolar", "BIPOLAR" }, { "ultrakill.cannonballed", "BOLA DE CAÑÓN" }, { "ultrakill.cannonballedfrombounce", "REBOTE DE CAÑÓN" }, { "ultrakill.cannonboost", "IMPULSO DE CAÑÓN" }, { "ultrakill.catapulted", "CATAPULTADO" }, { "ultrakill.chargeback", "CONTRACARGA" }, { "ultrakill.compressed", "COMPRIMIDO" }, { "ultrakill.criticalpunch", "GOLPE CRÍTICO" }, { "ultrakill.disrespect", "FALTA DE RESPETO" }, { "ultrakill.doublekill", "DOBLE MUERTE" }, { "ultrakill.downtosize", "A LA MEDIDA" }, { "ultrakill.drillpunch", "GOLPE AL TALADRO" }, { "ultrakill.drillpunchkill", "MUERTE DE TALADRO" }, { "ultrakill.enraged", "ENFURECIDO" }, { "ultrakill.exploded", "EXPLOTADO" }, { "ultrakill.finishedoff", "ACABADO" }, { "ultrakill.fireworks", "FUEGOS ARTIFICIALES" }, { "ultrakill.fireworksweak", "MALABARES" }, { "ultrakill.fistfullofdollar", "GOLPE DE DÓLAR" }, { "ultrakill.fried", "FRITO" }, { "ultrakill.friendlyfire", "FUEGO AMIGO" }, { "ultrakill.groundslam", "PISOTÓN" }, { "ultrakill.halfoff", "DESCUENTO" }, { "ultrakill.hammerhitgreen", "FUERZA BRUTA" }, { "ultrakill.hammerhitheavy", "GRAN PISTONAZO" }, { "ultrakill.hammerhitred", "IMPACTO PURO" }, { "ultrakill.hammerhityellow", "GOLPE DE PISTÓN" }, { "ultrakill.headshot", "HEADSHOT" }, { "ultrakill.headshotcombo", "COMBO DE HEADSHOTS" }, { "ultrakill.homerun", "HOMERUN" }, { "ultrakill.iconoclasm", "ROMPE ÍDOLOS" }, { "ultrakill.heartbreak", "ROMPE CORAZONES" }, { "ultrakill.instakill", "MUERTE INSTANTÁNEA" }, { "ultrakill.insurrknockdown", "TIEMPO FUERA" }, { "ultrakill.interruption", "INTERRUPCIÓN" }, { "ultrakill.kill", "MUERTE" }, { "ultrakill.landyours", "TIERRA SUYA" }, { "ultrakill.lightningbolt", "MONTAR EL RAYO" }, { "ultrakill.limbhit", "GOLPE DE MIEMBROS" }, { "ultrakill.mauriced", "MAURICIDIO" }, { "ultrakill.multikill", "MUERTE MÚLTIPLE" }, { "ultrakill.nailbombed", "BOMBA DE CLAVOS" }, { "ultrakill.nailbombedalive", "BOMBA DE CLAVOS" }, { "ultrakill.overkill", "EXAGERAR" }, { "ultrakill.parry", "PARRY" }, { "ultrakill.projectileboost", "IMPULSO DE PROYECTIL" }, { "ultrakill.quickdraw", "DESENFUNDADO RÁPIDO" }, { "ultrakill.ricoshot", "RICOSHOT" }, { "ultrakill.secret", "SECRETO" }, { "ultrakill.serve", "SERVIDO" }, { "ultrakill.strike", "STRIKE!" }, { "ultrakill.splattered", "SALPICADERO" }, { "ultrakill.triplekill", "MUERTE TRIPLE" }, { "ultrakill.rocketreturn", "REGRESO DE COHETE" }, { "ultrakill.roundtrip", "IDA Y VUELTA" }, { "ultrakill.terminalvelocity", "VELOCIDAD TERMINAL" }, { "ultrakill.insurrstomp", "PISOTEADO" } }; HiddenBonuses = new HashSet(StringComparer.OrdinalIgnoreCase) { "ultrakill.drillhit", "ultrakill.hammerhit", "ultrakill.firehit", "ultrakill.shotgunhit", "ultrakill.nailhit", "ultrakill.explosionhit", "ultrakill.zapperhit" }; DynamicTranslations = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "CONDUCTOR", "CONDUCTOR" }, { "CRUSHED", "APLASTADO" }, { "FALL", "CAÍDA" }, { "FRIED", "FRITO" }, { "GROOVY", "REBANADO" }, { "GUARD BREAK", "GUARDIA ROTA" }, { "HEAVY LIGHT", "LUZ PESADA" }, { "MINCED", "PICADO" }, { "NO-NO", "YO-YO" }, { "OUT OF BOUNDS", "FUERA DE LOS LÍMITES" }, { "RE-NO-NO", "RE YO-YO" }, { "PANCAKED", "PANQUEQUE" }, { "RICOSHOT", "RICOSHOT" }, { "ROADKILL", "MUERTE EN LA CARRETERA" }, { "SCREWED", "TORCIDO" }, { "SHREDDED", "TRITURADO" }, { "SLIPPED", "DESPLAZADO" }, { "TRAMPLED", "TRAMPADO" }, { "UNCHAINEDSAW", "MOTOSIERRA LOCA" }, { "OSHA VIOLATION", "VIOLACIÓN DE CÓDIGO" }, { "why are you even using this weapon", "¿Por qué estás usando esta arma?" }, { "why are you even spawning enemies here", "¿Por qué estás generando enemigos aquí?" }, { "BOILED", "HERVIDO" }, { "FOR THEE", "PARA ÉL" }, { "LOST", "PERDIDO" }, { "LONG WAY DOWN", "LARGO CAMINO HACIA ABAJO" }, { "M.A.D.", "L.O.C.O." }, { "TRASHED", "BASURA" }, { "ENVIROKILL", "MUERTE AMBIENTAL" }, { "SCRONGLED", "LICUADO" }, { "SCRONGBONGLED", "BATIDO" }, { "SCRINDONGULODED", "ZUMO" }, { "ZAPPED", "ELECTROCUTADO" }, { "BISHOP CAPTURE", "ALFIL CAPTURADO" }, { "BISHOP PROMOTION", "ASCENSO A ALFIL" }, { "BLACK WINS", "PIEZAS NEGRAS GANAN" }, { "BONGCLOUD", "BONGCLOUD" }, { "CASTLED", "CASTILLADO" }, { "EN PASSANT", "EN PASSANT" }, { "FOOLS MATE", "JAQUE AL TONTO" }, { "KNIGHT CAPTURE", "CABALLO CAPTURADO" }, { "KNIGHT PROMOTION", "ASCENSO A CABALLO" }, { "PAWN CAPTURE", "PEÓN CAPTURADO" }, { "QUEEN CAPTURE", "REINA CAPTURADA" }, { "QUEEN PROMOTION", "ASCENSO A REINA" }, { "ROOK CAPTURE", "TORRE CAPTURADA" }, { "ROOK PROMOTION", "ASCENSO A TORRE" }, { "STOP HITTING YOURSELF", "DEJA DE GOLPEARTE" }, { "ULTRAVICTORY", "ULTRAVICTORIA" }, { "WHITE WINS", "PIEZAS BLANCAS GANAN" }, { "STARSTRUCK", "IMPACTO ESTELAR" }, { "LOST IN SPACE", "PERDIDO EN EL ESPACIO" }, { "GONE SWIMMING", "A NADAR" }, { "RAISON D'ETRE", "RAISON D'ETRE" } }; } public static string TranslateBonus(string inputBonus) { if (string.IsNullOrEmpty(inputBonus)) { return string.Empty; } if (HiddenBonuses.Contains(inputBonus)) { return string.Empty; } string text = inputBonus; text = text.Replace("ULTRA", "ULTRA ").Replace("COUNTER", "CONTRA "); string key = Regex.Replace(text, "<[^>]*>", ""); if (BonusDictionary.TryGetValue(key, out var value)) { text = value; } else if (DynamicTranslations.TryGetValue(key, out value)) { text = value; } return text; } } [HarmonyPatch(typeof(StyleHUD), "GetLocalizedName")] public static class LocalizeStyleHud { [HarmonyPrefix] public static bool GetLocalizedName_MyPatch(string id, StyleHUD __instance, Dictionary ___idNameDict, ref string __result) { string text2 = (___idNameDict[id] = StyleBonusStrings.TranslateBonus(id)); __result = text2; return false; } } [HarmonyPatch(typeof(StyleHUD), "AscendRank")] public static class StyleHUD_AscendRankPatch { [HarmonyPrefix] public static void Prefix(StyleHUD __instance) { try { int num = Mathf.Clamp(__instance.rankIndex, 0, 7); int num2 = Mathf.Clamp(__instance.rankIndex + 1, 0, 7); if (num != num2) { } } catch (Exception ex) { Debug.Log((object)("[TexturePatcher] Error en AscendRankPatch: " + ex.Message)); } } } [HarmonyPatch(typeof(StyleHUD), "DescendRank")] public static class StyleHUD_DescendRankPatch { [HarmonyPrefix] public static void Prefix(StyleHUD __instance) { try { int num = Mathf.Clamp(__instance.rankIndex, 0, 7); int num2 = Mathf.Clamp(__instance.rankIndex - 1, 0, 7); if (num != num2) { } } catch (Exception ex) { Debug.Log((object)("[TexturePatcher] Error en DescendRankPatch: " + ex.Message)); } } } [HarmonyPatch] public static class TexturesPatch { private class DummyMonoBehaviour : MonoBehaviour { private void OnDestroy() { cancellationTokenSource?.Cancel(); currentLevel = null; currentReplacements = null; textureCache.Clear(); Plugin.LoggerInstance.LogInfo((object)"[TexturePatcher] Coroutine destroyed and cache cleared"); } } [CompilerGenerated] private sealed class <>c__DisplayClass29_0 { public Texture2D loaded; internal void b__0(Texture2D tex) { loaded = tex; } } [CompilerGenerated] private sealed class <>c__DisplayClass39_0 { public byte[] fileData; public string fullPath; public Exception error; public bool isDone; internal void b__0(object _) { try { if (!cancellationTokenSource.IsCancellationRequested) { fileData = File.ReadAllBytes(fullPath); } } catch (Exception ex) { error = ex; } finally { isDone = true; } } } [CompilerGenerated] private sealed class d__30 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__30(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; if (currentReplacements != null && currentReplacements.Count > 0) { <>2__current = ReplaceTexturesInScene(isInitialPass: false); <>1__state = 2; return true; } break; case 2: <>1__state = -1; break; } if (!cancellationTokenSource.IsCancellationRequested && !string.IsNullOrEmpty(currentLevel)) { 5__1 = GetSceneCheckDelay(currentLevel); <>2__current = (object)new WaitForSeconds(5__1); <>1__state = 1; return true; } Plugin.LoggerInstance.LogInfo((object)"[TexturePatcher] Background texture check ended."); 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(); } } [CompilerGenerated] private sealed class d__39 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string filename; public Action callback; private <>c__DisplayClass39_0 <>8__1; private Texture2D 5__2; private Texture2D 5__3; private bool 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__39(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass39_0(); if (cancellationTokenSource.IsCancellationRequested) { callback(null); return false; } if (textureCache.TryGetValue(filename, out 5__2)) { callback(5__2); return false; } <>8__1.fullPath = FindTextureFile(filename); if (string.IsNullOrEmpty(<>8__1.fullPath)) { Plugin.LoggerInstance.LogWarning((object)("[TexturePatcher] File not found: " + filename)); callback(null); return false; } <>8__1.fileData = null; <>8__1.error = null; <>8__1.isDone = false; ThreadPool.QueueUserWorkItem(delegate { try { if (!cancellationTokenSource.IsCancellationRequested) { <>8__1.fileData = File.ReadAllBytes(<>8__1.fullPath); } } catch (Exception error) { <>8__1.error = error; } finally { <>8__1.isDone = true; } }); break; case 1: <>1__state = -1; break; } if (!<>8__1.isDone && !cancellationTokenSource.IsCancellationRequested) { <>2__current = null; <>1__state = 1; return true; } if (cancellationTokenSource.IsCancellationRequested) { callback(null); return false; } if (<>8__1.error != null) { Plugin.LoggerInstance.LogWarning((object)("[TexturePatcher] Error loading '" + filename + "': " + <>8__1.error.Message)); callback(null); return false; } if (<>8__1.fileData == null || <>8__1.fileData.Length == 0) { Plugin.LoggerInstance.LogWarning((object)("[TexturePatcher] Empty or unreadable file: " + filename)); callback(null); return false; } 5__3 = new Texture2D(2, 2, (TextureFormat)4, false) { name = Path.GetFileNameWithoutExtension(<>8__1.fullPath), filterMode = (FilterMode)0, anisoLevel = 0 }; 5__4 = ImageConversion.LoadImage(5__3, <>8__1.fileData, false); if (!5__4) { Plugin.LoggerInstance.LogWarning((object)("[TexturePatcher] Failed to decode image: " + filename)); callback(null); return false; } textureCache[filename] = 5__3; callback(5__3); 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(); } } [CompilerGenerated] private sealed class d__29 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Dictionary textureMap; private Dictionary.Enumerator <>s__1; private KeyValuePair 5__2; private <>c__DisplayClass29_0 <>8__3; private string 5__4; private string 5__5; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>s__1 = default(Dictionary.Enumerator); 5__2 = default(KeyValuePair); <>8__3 = null; 5__4 = null; 5__5 = null; <>1__state = -2; } private bool MoveNext() { bool result; try { switch (<>1__state) { default: result = false; goto end_IL_0000; case 0: <>1__state = -1; <>s__1 = textureMap.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; if ((Object)(object)<>8__3.loaded == (Object)null) { Plugin.LoggerInstance.LogWarning((object)("[TexturePatcher] Failed to load texture: " + 5__5)); break; } ((Texture)<>8__3.loaded).filterMode = (FilterMode)0; currentReplacements[5__4] = <>8__3.loaded; Plugin.LoggerInstance.LogInfo((object)("[TexturePatcher] Loaded texture '" + 5__5 + "' as '" + 5__4 + "'")); <>8__3 = null; 5__4 = null; 5__5 = null; 5__2 = default(KeyValuePair); break; } while (true) { if (<>s__1.MoveNext()) { 5__2 = <>s__1.Current; <>8__3 = new <>c__DisplayClass29_0(); if (cancellationTokenSource.IsCancellationRequested) { result = false; <>m__Finally1(); break; } 5__4 = 5__2.Key; 5__5 = 5__2.Value.filename; if (currentReplacements.ContainsKey(5__4)) { continue; } <>8__3.loaded = null; <>2__current = coroutineStarter.StartCoroutine(LoadTexture(5__5, delegate(Texture2D tex) { <>8__3.loaded = tex; })); <>1__state = 1; result = true; break; } <>m__Finally1(); <>s__1 = default(Dictionary.Enumerator); result = false; break; } end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__24 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string sceneName; private Dictionary 5__1; private Texture2D 5__2; private Dictionary.Enumerator <>s__3; private KeyValuePair 5__4; private string 5__5; private Rect 5__6; private Texture2D 5__7; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__1 = null; 5__2 = null; <>s__3 = default(Dictionary.Enumerator); 5__4 = default(KeyValuePair); 5__5 = null; 5__7 = null; <>1__state = -2; } private bool MoveNext() { //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_00ef: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!manualBatchRegions.TryGetValue(sceneName, out 5__1)) { return false; } 5__2 = FindBatchTexture(sceneName); if ((Object)(object)5__2 == (Object)null) { return false; } <>s__3 = 5__1.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; 5__5 = null; 5__7 = null; 5__4 = default(KeyValuePair); break; } while (<>s__3.MoveNext()) { 5__4 = <>s__3.Current; 5__5 = 5__4.Key; 5__6 = 5__4.Value; if (!currentReplacements.TryGetValue(5__5, out 5__7)) { continue; } ReplaceTextureRegion(5__2, 5__6, 5__7); <>2__current = null; <>1__state = 1; return true; } <>m__Finally1(); <>s__3 = default(Dictionary.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__3).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__23 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private string 5__1; private Dictionary 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__23(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_005e: 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) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; if (isProcessing) { return false; } isProcessing = true; Scene activeScene = SceneManager.GetActiveScene(); 5__1 = ((Scene)(ref activeScene)).name; if (string.IsNullOrEmpty(5__1) || cancellationTokenSource.IsCancellationRequested) { Plugin.LoggerInstance.LogInfo((object)"[TexturePatcher] Scene loading aborted"); ResetInternalState(); return false; } if (ShouldIgnoreScene(5__1)) { Plugin.LoggerInstance.LogInfo((object)("[TexturePatcher] Ignoring scene: " + 5__1)); ResetInternalState(); return false; } if (!initialized) { Plugin.LoggerInstance.LogWarning((object)"[TexturePatcher] Not initialized"); ResetInternalState(); return false; } Plugin.LoggerInstance.LogInfo((object)("[TexturePatcher] Processing scene: " + 5__1)); <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; if (currentLevel != 5__1) { ResetInternalState(); currentLevel = 5__1; } currentReplacements = new Dictionary(); <>2__current = LoadTextures(globalTextureReplacements); <>1__state = 2; return true; case 2: { <>1__state = -1; 5__2 = GetLevelSpecificTextures(5__1); Dictionary dictionary = 5__2; if (dictionary != null && dictionary.Count > 0) { <>2__current = LoadTextures(5__2); <>1__state = 3; return true; } goto IL_01d5; } case 3: <>1__state = -1; goto IL_01d5; case 4: <>1__state = -1; <>2__current = ProcessBatchTextures(5__1); <>1__state = 5; return true; case 5: { <>1__state = -1; if (backgroundChecker != null) { coroutineStarter.StopCoroutine(backgroundChecker); } backgroundChecker = coroutineStarter.StartCoroutine(BackgroundTextureCheck()); isProcessing = false; return false; } IL_01d5: if (currentReplacements.Count == 0) { Plugin.LoggerInstance.LogWarning((object)"[TexturePatcher] No textures were loaded, skipping patching"); isProcessing = false; return false; } <>2__current = ReplaceTexturesInScene(isInitialPass: true); <>1__state = 4; 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 d__34 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public bool isInitialPass; private Camera 5__1; private int 5__2; private int 5__3; private int 5__4; private Renderer[] 5__5; private Renderer[] <>s__6; private int <>s__7; private Renderer 5__8; private int 5__9; private Material[] 5__10; private MaterialPropertyBlock 5__11; private int 5__12; private Material 5__13; private bool 5__14; private int

5__15; private int 5__16; private Texture2D 5__17; private Texture2D 5__18; private RawImage[] <>s__19; private int <>s__20; private RawImage 5__21; private int 5__22; private Texture2D 5__23; private Texture2D 5__24; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__34(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__5 = null; <>s__6 = null; 5__8 = null; 5__10 = null; 5__11 = null; 5__13 = null; 5__17 = null; 5__18 = null; <>s__19 = null; 5__21 = null; 5__23 = null; 5__24 = null; <>1__state = -2; } private bool MoveNext() { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (currentReplacements == null || cancellationTokenSource.IsCancellationRequested) { return false; } 5__1 = Camera.main; 5__2 = 0; 5__3 = 0; 5__4 = 0; 5__5 = Object.FindObjectsOfType(); <>s__6 = 5__5; <>s__7 = 0; goto IL_0374; case 1: <>1__state = -1; goto IL_0281; case 2: <>1__state = -1; goto IL_0350; case 3: { <>1__state = -1; goto IL_04dc; } IL_04dc: 5__23 = null; 5__24 = null; 5__21 = null; goto IL_04f2; IL_0374: if (<>s__7 < <>s__6.Length) { 5__8 = <>s__6[<>s__7]; if (IsValidRenderer(5__8, 5__1) && !IsInIgnoredPath(((Component)5__8).gameObject)) { 5__9 = ((Object)5__8).GetInstanceID(); if (processedObjectIds.Add(5__9)) { 5__10 = 5__8.sharedMaterials; 5__11 = new MaterialPropertyBlock(); 5__12 = 0; goto IL_02fa; } } goto IL_0366; } <>s__6 = null; <>s__19 = Object.FindObjectsOfType(); <>s__20 = 0; goto IL_0500; IL_04f2: <>s__20++; goto IL_0500; IL_0500: if (<>s__20 < <>s__19.Length) { 5__21 = <>s__19[<>s__20]; if (IsValidRawImage(5__21) && !IsInIgnoredPath(((Component)5__21).gameObject)) { 5__22 = ((Object)5__21).GetInstanceID(); if (processedRawImages.Add(5__22)) { ref Texture2D reference = ref 5__23; Texture texture = 5__21.texture; reference = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (!((Object)(object)5__23 == (Object)null)) { if (TryGetReplacement(((Object)5__23).name, out 5__24)) { 5__21.texture = (Texture)(object)5__24; 5__2++; } 5__4++; if (5__2 >= 8 || 5__4 % 60 == 0) { 5__2 = 0; <>2__current = null; <>1__state = 3; return true; } goto IL_04dc; } } } goto IL_04f2; } <>s__19 = null; return false; IL_02a2: if (

5__15 < TexturePropIDs.Length) { 5__16 = TexturePropIDs[

5__15]; if (5__13.HasProperty(5__16)) { ref Texture2D reference2 = ref 5__17; Texture texture2 = 5__13.GetTexture(5__16); reference2 = (Texture2D)(object)((texture2 is Texture2D) ? texture2 : null); if (!((Object)(object)5__17 == (Object)null)) { if (TryGetReplacement(((Object)5__17).name, out 5__18)) { 5__11.SetTexture(5__16, (Texture)(object)5__18); 5__14 = true; 5__2++; } if (5__2 >= 8) { 5__2 = 0; <>2__current = null; <>1__state = 1; return true; } goto IL_0281; } } goto IL_0290; } if (5__14) { 5__8.SetPropertyBlock(5__11, 5__12); } 5__13 = null; goto IL_02e8; IL_02fa: if (5__12 < 5__10.Length) { 5__13 = 5__10[5__12]; if ((Object)(object)5__13 == (Object)null) { goto IL_02e8; } 5__14 = false; 5__11.Clear(); 5__8.GetPropertyBlock(5__11, 5__12);

5__15 = 0; goto IL_02a2; } 5__3++; if (5__3 % 60 == 0) { <>2__current = null; <>1__state = 2; return true; } goto IL_0350; IL_0290:

5__15++; goto IL_02a2; IL_02e8: 5__12++; goto IL_02fa; IL_0350: 5__10 = null; 5__11 = null; 5__8 = null; goto IL_0366; IL_0366: <>s__7++; goto IL_0374; IL_0281: 5__17 = null; 5__18 = null; goto IL_0290; } } 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 static bool initialized = false; private static Dictionary> levelTextureMappings; private static Dictionary textureCache = new Dictionary(); private static MonoBehaviour coroutineStarter; private static Dictionary currentReplacements; private static string currentLevel = string.Empty; private static bool isProcessing = false; private static CancellationTokenSource cancellationTokenSource; private static readonly HashSet processedObjectIds = new HashSet(); private static readonly HashSet processedRawImages = new HashSet(); private static Coroutine backgroundChecker; private static readonly Dictionary batchTextureCache = new Dictionary(); private static readonly Dictionary batchRegionCache = new Dictionary(); private static readonly Dictionary> manualBatchRegions = new Dictionary> { { "45addc6c3730dae418321e00af1116c5", new Dictionary { { "VendingMachine", new Rect(0f, 0f, 256f, 256f) }, { "ad_fox_1", new Rect(0f, 0f, 256f, 256f) }, { "ad_clothes_1", new Rect(0f, 0f, 256f, 256f) }, { "ad_wing_1", new Rect(0f, 0f, 256f, 256f) } } } }; private static readonly List IgnoredPathPatterns = new List { "Leaderboard" }; private static readonly Dictionary globalTextureReplacements = new Dictionary { { "checkpoint", ("Checkpoint", "texture") }, { "spawnpoint", ("spawnpoint", "texture") }, { "T_ShopTerminal", ("T_ShopTerminal", "texture") }, { "T_ShopTerminal_Emission", ("T_ShopTerminal_Emission", "texture") }, { "T_Gabe_SpledorJustice", ("T_Gabe_SpledorJustice", "texture") }, { "bombtexture4", ("bombtexture4", "texture") }, { "bombtexture5", ("bombtexture5", "texture") } }; private static readonly HashSet ignoredScenes = new HashSet { "Bootstrap", "Intro", "Loading" }; private static readonly string[] TextureProps = new string[6] { "_MainTex", "_BaseMap", "_DetailAlbedoMap", "_Texture", "_MainTexture", "_EmissiveTex" }; private static readonly int[] TexturePropIDs = ((IEnumerable)TextureProps).Select((Func)Shader.PropertyToID).ToArray(); private static string texturesFolder { get { string text = Path.Combine(Paths.PluginPath, "ESP_TEAM-ULTRAKILL_IN_SPANISH"); char directorySeparatorChar = Path.DirectorySeparatorChar; return text + directorySeparatorChar; } } private static void EnsureTexturesFolderExists() { if (!Directory.Exists(texturesFolder)) { Directory.CreateDirectory(texturesFolder); Plugin.LoggerInstance.LogInfo((object)("[TexturePatcher] Created texture folder: " + texturesFolder)); } } [HarmonyPrepare] private static void Prepare() { cancellationTokenSource = new CancellationTokenSource(); EnsureTexturesFolderExists(); InitializeTextureMappings(); Plugin.LoggerInstance.LogInfo((object)"[TexturePatcher] Module initialized"); } private static void InitializeTextureMappings() { if (!initialized) { levelTextureMappings = new Dictionary> { { "4f8ecffaa98c2614f89922daf31fa22d", new Dictionary { { "", ("Batch Tutorial", "texture") } } }, { "eb57c9574cb2e624799753de0f8ffcad", new Dictionary { { "SignSecurityInstructions", ("SignSecurityInstructions", "texture") }, { "SignWarning", ("SignWarning", "texture") }, { "SignCoolingChamber", ("SignCoolingChamber", "texture") }, { "SignSecurityLockdown", ("SignSecurityLockdown", "texture") }, { "SignSecurityCheckpoint", ("SignSecurityCheckpoint", "texture") } } }, { "7927c42db92e4164cae682a55e6b7725", new Dictionary { { "SignSecurityInstructions", ("SignSecurityInstructions", "texture") }, { "SignWarning", ("SignWarning", "texture") }, { "SignCoolingChamber", ("SignCoolingChamber", "texture") }, { "SignSecurityLockdown", ("SignSecurityLockdown", "texture") }, { "SignSecurityCheckpoint", ("SignSecurityCheckpoint", "texture") } } }, { "5bcb2e0461e7fce408badfcb6778c271", new Dictionary { { "SignSecurityInstructions", ("SignSecurityInstructions", "texture") }, { "SignWarning", ("SignWarning", "texture") }, { "SignCoolingChamber", ("SignCoolingChamber", "texture") }, { "SignSecurityLockdown", ("SignSecurityLockdown", "texture") }, { "SignSecurityCheckpoint", ("SignSecurityCheckpoint", "texture") } } }, { "3e978dea8d12a0146b46cb0c302d66e2", new Dictionary { { "SignSecurityInstructions", ("SignSecurityInstructions", "texture") }, { "SignWarning", ("SignWarning", "texture") }, { "SignCoolingChamber", ("SignCoolingChamber", "texture") }, { "SignSecurityLockdown", ("SignSecurityLockdown", "texture") }, { "SignSecurityCheckpoint", ("SignSecurityCheckpoint", "texture") } } }, { "5541f073d290f4348884fa3f76072afd", new Dictionary { { "abandonhope2", ("abandonhope2", "texture") }, { "SignSecurityInstructions", ("SignSecurityInstructions", "texture") }, { "SignWarning", ("SignWarning", "texture") }, { "SignCoolingChamber", ("SignCoolingChamber", "texture") }, { "SignSecurityLockdown", ("SignSecurityLockdown", "texture") }, { "SignSecurityCheckpoint", ("SignSecurityCheckpoint", "texture") } } }, { "8038b251ea4683b4db4ef432205184f6", new Dictionary { { "electricitybox", ("electricitybox", "texture") } } }, { "36abcaae9708abc4d9e89e6ec73a2846", new Dictionary { { "forgiveme", ("forgiveme", "texture") } } }, { "6440445a799e22842babe18edf7da792", new Dictionary { { "electricitybox", ("electricitybox", "texture") }, { "", ("Batch 2-2", "texture") } } }, { "4e039f071c1fba04a82a7b6b44feadc2", new Dictionary { { "", ("Batch 2-3", "texture") }, { "watercontrol1", ("watercontrol1", "texture") }, { "watercontrol2", ("watercontrol2", "texture") } } }, { "38748a67bc9e67a43956a92f87d1e742", new Dictionary { { "traitor", ("traitor", "texture") }, { "", ("Batch 4-3", "texture") } } }, { "fba3bcfce7b99ae4d90356c81c5586b3", new Dictionary { { "WaterProcessingAttention", ("WaterProcessingAttention", "texture") }, { "", ("Batch 5-1", "texture") } } }, { "1567f75bc4488644684d7a25471dbe95", new Dictionary { { "", ("Batch 5-S", "texture") }, { "Bait Label", ("Bait Label", "texture") } } }, { "aa55551f768b5224997a4b5e0ef315ea", new Dictionary { { "", ("Batch 7-2", "texture") }, { "exit", ("exit", "texture") } } }, { "7a11d5684479d2446a735fa154d6bc7c", new Dictionary { { "marble_inverted 3", ("marble_inverted 3", "texture") } } }, { "6e981b1865c649749a610aafc471e198", new Dictionary { { "T_Cent_PlantRoom", ("T_Cent_PlantRoom", "texture") }, { "electricitybox", ("electricitybox", "texture") }, { "T_DawgControls_Emissive", ("T_DawgControls_Emissive", "texture") }, { "T_DawgControls_EmissiveOff", ("T_DawgControls_EmissiveOff", "texture") } } }, { "aa8b84f8b1443ef4783afbc6b1db1e30", new Dictionary { { "T_Placard", ("T_Placard", "texture") }, { "T_TrailSign", ("T_TrailSign", "texture") } } }, { "36c5b4853d1d63d4686ea9a23ca61f8c", new Dictionary { { "exit", ("exit", "texture") }, { "abandonhope2", ("abandonhope2", "texture") }, { "SignSecurityInstructions", ("SignSecurityInstructions", "texture") }, { "SignWarning", ("SignWarning", "texture") }, { "SignCoolingChamber", ("SignCoolingChamber", "texture") }, { "SignSecurityLockdown", ("SignSecurityLockdown", "texture") }, { "SignSecurityCheckpoint", ("SignSecurityCheckpoint", "texture") } } }, { "e92f893de47503a4f959f7d5bca84261", new Dictionary { { "sign_map_Texture_2", ("sign_map_Texture_2", "texture") }, { "poster", ("poster", "texture") }, { "Staff only sign_texture", ("Staff only sign_texture", "texture") } } }, { "ab5460c767500b748a7f5497682ffc63", new Dictionary { { "VendingMachine", ("VendingMachine", "texture") }, { "wecamein", ("wecamein", "texture") }, { "wecamein2", ("wecamein2", "texture") }, { "T_LionPlaque", ("T_LionPlaque", "texture") }, { "ArchangelNamePlateGabriel", ("ArchangelNamePlateGabriel", "texture") }, { "ArchangelNamePlateMichael", ("ArchangelNamePlateMichael", "texture") }, { "ArchangelNamePlatePhanuel", ("ArchangelNamePlatePhanuel", "texture") }, { "ArchangelNamePlateRaphael", ("ArchangelNamePlateRaphael", "texture") }, { "", ("Batch 8-1", "texture") } } }, { "45addc6c3730dae418321e00af1116c5", new Dictionary { { "StatsBoard", ("StatsBoard", "texture") }, { "inthemirror", ("inthemirror", "texture") }, { "VendingMachine", ("VendingMachine", "texture") }, { "big_hakita", ("big_hakita", "texture") }, { "presentation2", ("presentation2", "texture") }, { "", ("Batch 8-2", "texture") }, { "ad_clothes_1", ("ad_clothes_1", "texture") }, { "ad_fox_1", ("ad_fox_1", "texture") }, { "ad_wing_1", ("ad_wing_1", "texture") }, { "ad_clothes", ("ad_clothes", "texture") }, { "ad_fox", ("ad_fox", "texture") }, { "ad_wing", ("ad_wing", "texture") }, { "OfficeArchive", ("OfficeArchive", "texture") }, { "OfficeMaintenance", ("OfficeMaintenance", "texture") } } }, { "4d0787cb97dbde141b6957720788c4dd", new Dictionary { { "T_LionPlaque", ("T_LionPlaque", "texture") }, { "VendingMachine", ("VendingMachine", "texture") }, { "SignWarning", ("SignWarning", "texture") }, { "", ("Batch 8-3", "texture") } } }, { "7f3f5eabda008e04cb2364d6f0327aa5", new Dictionary { { "VendingMachine", ("VendingMachine", "texture") }, { "", ("Batch 8-4", "texture") }, { "SignWarning", ("SignWarning", "texture") }, { "CityoftheDeadSunPoster", ("CityoftheDeadSunPoster", "texture") } } } }; initialized = true; Plugin.LoggerInstance.LogInfo((object)$"[TexturePatcher] Loaded {globalTextureReplacements.Count} global and {levelTextureMappings.Count} level-specific mappings"); } } [HarmonyPatch(typeof(SceneHelper), "OnSceneLoaded")] [HarmonyPostfix] private static void OnSceneLoaded() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown cancellationTokenSource?.Cancel(); cancellationTokenSource?.Dispose(); cancellationTokenSource = new CancellationTokenSource(); if ((Object)(object)coroutineStarter == (Object)null) { GameObject val = new GameObject("TexturePatcher_CoroutineStarter"); coroutineStarter = (MonoBehaviour)(object)val.AddComponent(); } coroutineStarter.StartCoroutine(ProcessSceneChange()); } [IteratorStateMachine(typeof(d__23))] private static IEnumerator ProcessSceneChange() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__23(0); } [IteratorStateMachine(typeof(d__24))] private static IEnumerator ProcessBatchTextures(string sceneName) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__24(0) { sceneName = sceneName }; } private static void ResetInternalState() { ClearTextureCache(); processedObjectIds.Clear(); processedRawImages.Clear(); batchTextureCache.Clear(); batchRegionCache.Clear(); currentReplacements = null; currentLevel = null; isProcessing = false; } private static void ClearTextureCache() { foreach (Texture2D value in textureCache.Values) { Object.Destroy((Object)(object)value); } textureCache.Clear(); } private static Dictionary GetLevelSpecificTextures(string sceneName) { foreach (KeyValuePair> levelTextureMapping in levelTextureMappings) { if (sceneName.Contains(levelTextureMapping.Key)) { return levelTextureMapping.Value; } } return null; } private static Texture2D FindBatchTexture(string sceneName) { if (batchTextureCache.TryGetValue(sceneName, out var value)) { return value; } Material[] array = Resources.FindObjectsOfTypeAll(); foreach (Material val in array) { if ((Object)(object)val == (Object)null || ((Object)val).name.IndexOf("Batch Material Environment", StringComparison.OrdinalIgnoreCase) < 0) { continue; } string[] textureProps = TextureProps; foreach (string text in textureProps) { int num = Shader.PropertyToID(text); if (val.HasProperty(num)) { Texture texture = val.GetTexture(num); Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (!((Object)(object)val2 == (Object)null)) { batchTextureCache[sceneName] = val2; Plugin.LoggerInstance.LogInfo((object)$"[TexturePatcher] Batch texture found: {((Object)val2).name} ({((Texture)val2).width}x{((Texture)val2).height})"); return val2; } } } } Plugin.LoggerInstance.LogWarning((object)"[TexturePatcher] Batch texture not found"); return null; } [IteratorStateMachine(typeof(d__29))] private static IEnumerator LoadTextures(Dictionary textureMap) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0) { textureMap = textureMap }; } [IteratorStateMachine(typeof(d__30))] private static IEnumerator BackgroundTextureCheck() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__30(0); } private static float GetSceneCheckDelay(string sceneName) { if (sceneName.IndexOf("4-S", StringComparison.OrdinalIgnoreCase) >= 0) { return 3f; } return 0.5f; } [IteratorStateMachine(typeof(d__34))] private static IEnumerator ReplaceTexturesInScene(bool isInitialPass) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__34(0) { isInitialPass = isInitialPass }; } private static bool TryGetReplacement(string textureName, out Texture2D replacement) { return currentReplacements.TryGetValue(textureName, out replacement) || currentReplacements.TryGetValue(textureName.ToLower(), out replacement); } private static void ReplaceTextureRegion(Texture2D atlas, Rect region, Texture2D replacement) { if (!((Object)(object)atlas == (Object)null) && !((Object)(object)replacement == (Object)null)) { int num = Mathf.Min((int)((Rect)(ref region)).width, ((Texture)replacement).width); int num2 = Mathf.Min((int)((Rect)(ref region)).height, ((Texture)replacement).height); Color32[] pixels = replacement.GetPixels32(); atlas.SetPixels32((int)((Rect)(ref region)).x, (int)((Rect)(ref region)).y, num, num2, pixels); atlas.Apply(false, false); Plugin.LoggerInstance.LogInfo((object)$"[TexturePatcher] Patched atlas region at {((Rect)(ref region)).x},{((Rect)(ref region)).y}"); } } private static bool IsValidRenderer(Renderer rend, Camera mainCam) { if ((Object)(object)rend == (Object)null || (Object)(object)((Component)rend).gameObject == (Object)null || !((Component)rend).gameObject.activeInHierarchy) { return false; } if (Object.op_Implicit((Object)(object)mainCam) && ((Object)(object)((Component)rend).gameObject == (Object)(object)((Component)mainCam).gameObject || (Object)(object)((Component)rend).GetComponentInParent(true) != (Object)null)) { return false; } return true; } private static bool IsValidRawImage(RawImage raw) { return (Object)(object)raw != (Object)null && ((Component)raw).gameObject.activeInHierarchy; } [IteratorStateMachine(typeof(d__39))] private static IEnumerator LoadTexture(string filename, Action callback) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__39(0) { filename = filename, callback = callback }; } private static string FindTextureFile(string filename) { string[] array = new string[4] { ".png", ".jpg", ".jpeg", ".tga" }; string[] array2 = array; foreach (string text in array2) { string text2 = Path.Combine(texturesFolder, filename + text); if (File.Exists(text2)) { return text2; } } string text3 = Path.Combine(texturesFolder, filename); return File.Exists(text3) ? text3 : null; } private static string GetHierarchyPath(Transform transform) { List list = new List(); while ((Object)(object)transform != (Object)null) { list.Insert(0, ((Object)transform).name); transform = transform.parent; } return string.Join("/", list); } private static bool IsInIgnoredPath(GameObject obj) { string hierarchyPath = GetHierarchyPath(obj.transform); foreach (string ignoredPathPattern in IgnoredPathPatterns) { if (hierarchyPath.Contains(ignoredPathPattern)) { return true; } } return false; } private static bool ShouldIgnoreScene(string sceneName) { return ignoredScenes.Any((string i) => sceneName.Equals(i, StringComparison.OrdinalIgnoreCase)); } } } namespace TexturePatcher.TexturePatcher.HarmonyPatches { [HarmonyPatch(typeof(FinalRank), "SetInfo")] public static class FinalRank_SetInfo_Patch { [HarmonyPrefix] private static void Prefix(FinalRank __instance) { if ((Object)(object)__instance.extraInfo != (Object)null) { __instance.extraInfo.text = StyleBonusStrings.TranslateBonus(__instance.extraInfo.text); } } } }