Decompiled source of UltrakULL Apodidae Remix v1.4.0
plugins/UltrakULL_Apodidae_Remix/UltrakULL.angry.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AngryLevelLoader.Containers; using AngryLevelLoader.Fields; using AngryLevelLoader.Managers; using AngryLevelLoader.Notifications; using AngryLevelLoader.Patches; using AngryLevelLoader.UserInterface; using AngryUiComponents; using HarmonyLib; using Microsoft.CodeAnalysis; using PluginConfig.API; using PluginConfig.API.Decorators; using PluginConfig.API.Functionals; using TMPro; using UltrakULL.API; using UltrakULL.json; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("AngryLevelLoader")] [assembly: IgnoresAccessChecksTo("AngryUiComponents")] [assembly: IgnoresAccessChecksTo("RudeLevelScripts.Essentials")] [assembly: AssemblyCompany("UltrakULL.angry")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+814c6b1131c4d3112e36c74cbd216bc8c5c2e452")] [assembly: AssemblyProduct("UltrakULL.angry")] [assembly: AssemblyTitle("UltrakULL.angry")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace UltrakULL { public static class AngryUtil { public static void ApplyHeaders(ConfigPanel panel, (string original, string translation)[] headers) { if (panel == null) { return; } ConfigField[] allFields = panel.GetAllFields(); foreach (ConfigField obj in allFields) { ConfigHeader val = (ConfigHeader)(object)((obj is ConfigHeader) ? obj : null); if (val == null) { continue; } for (int j = 0; j < headers.Length; j++) { var (text, text2) = headers[j]; if (val.text == text && !StringHelper.IsEmpty(text2)) { val.text = text2; break; } } } } public static void LocalizeNotifierHeader(ConfigHeader header, string color, string englishPrefix, string template) { header.text = string.Join("\n", from line in header.text.Split('\n') select RewriteTemplateLine(line, color, englishPrefix, "</color>", template)); static string RewriteTemplateLine(string line, string text2, string text3, string close, string format) { string text = text2 + text3; if (!line.StartsWith(text) || !line.EndsWith(close)) { return line; } string text4 = line.Substring(text.Length, line.Length - text.Length - close.Length); if (string.IsNullOrEmpty(text4)) { return line; } return text2 + string.Format(format, text4) + close; } } } [HarmonyPatch(typeof(StatsManager_SendInfo_Patch))] public static class AngryChallengePatch { [HarmonyPatch("Postfix")] [HarmonyPostfix] public static void PostfixPatch() { if (!LanguageManager.IsEnglish && AngrySceneTracker.InAngryLevel) { LocalizationExtensions.Localize<TextMeshProUGUI>(((Component)MonoSingleton<FinalRank>.Instance).gameObject, AngryLevelText.Challenge(), new string[2] { "Challenge", "ChallengeText" }, false, true); } } } [HarmonyPatch(typeof(LevelNamePopup))] public static class AngryLevelCreditPatch { [HarmonyPatch("NameAppear")] [HarmonyPostfix] public static void NameAppear_CreditText() { if (!LanguageManager.IsEnglish && AngrySceneTracker.InAngryLevel) { string text = BuildCredit(); if (text != null) { CreditText.Show(text, 6f, 0.6f); } } } [HarmonyPatch("NameReset")] [HarmonyPostfix] public static void NameReset_CreditText() { CreditText.Hide(); } private static string BuildCredit() { AngryLevel val = AngryLevelText.Current(); if (val == null) { return null; } string creditFormat = LanguageManager.Current.angry.angryBundles.creditFormat; object[] args = new string[4] { AngryLevelText.BundleAuthor, AngryLevelText.LevelName, AngryLevelText.BundleName, val.translator }; return string.Format(creditFormat, args); } } [HarmonyPatch(typeof(BundleContainer))] public static class BundleContainerPatch { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] public static void LocalizeBundleContainer(BundleContainer __instance) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { LevelPanel levelPanel = LanguageManager.Current.angry.angryUi.levelPanel; ConfigField obj = ((ConfigPanel)__instance.rootPanel)[((ConfigField)__instance.rootPanel).guid + "_reloadButtons"]; ConfigField obj2 = ((obj is ButtonArrayField) ? obj : null); if (obj2 != null) { ((ButtonArrayField)obj2).SetButtonText(0, levelPanel.reloadFile); } ConfigField obj3 = ((ConfigPanel)__instance.rootPanel)[((ConfigField)__instance.rootPanel).guid + "_reloadButtons"]; ConfigField obj4 = ((obj3 is ButtonArrayField) ? obj3 : null); if (obj4 != null) { ((ButtonArrayField)obj4).SetButtonText(1, levelPanel.forceReloadFile); } AngryUtil.ApplyHeaders((ConfigPanel)(object)__instance.rootPanel, new(string, string)[1] { ("Levels", levelPanel.levels) }); } } } [HarmonyPatch(typeof(LevelField))] public static class LevelFieldPatch { [HarmonyPatch("OnCreateUI")] [HarmonyPostfix] public static void LocalizeButtons(LevelField __instance) { if (LanguageManager.IsEnglish || !LanguageManager.IsAngryTranslationLoaded || !__instance.inited) { return; } AngryLevelFieldComponent currentUi = __instance.currentUi; AngryTranslation angry = LanguageManager.Current.angry; Text[] headers = currentUi.headers; foreach (Text val in headers) { if (!((Object)(object)val == (Object)null)) { val.text = LocalizationExtensions.Or(((Object)val).name switch { "TimeHeader" => angry.angryUi.levelPanel.time, "KillHeader" => angry.angryUi.levelPanel.kills, "StyleHeader" => angry.angryUi.levelPanel.style, "SecretsHeader" => angry.angryUi.levelPanel.secrets, _ => null, }, val.text); } } LocalizationExtensions.Localize<Text>(((Component)__instance.currentUi.challengeContainer).gameObject, angry.angryUi.levelPanel.challenge, new string[1] { "Header" }, false, true); } } [HarmonyPatch(typeof(LevelUpdateNotification))] public static class LevelUpdateNotificationPatch { [HarmonyPatch("OnUI")] [HarmonyPostfix] public static void Localize(ref RectTransform panel) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { AngryLevelUpdateNotificationComponent componentInChildren = ((Component)panel).GetComponentInChildren<AngryLevelUpdateNotificationComponent>(true); if (!((Object)(object)componentInChildren == (Object)null)) { LevelUpdateNotification levelUpdateNotification = LanguageManager.Current.angry.angryUi.notifications.levelUpdateNotification; LocalizationExtensions.Localize<Text>(((Component)componentInChildren).gameObject, levelUpdateNotification.header, new string[2] { "ConcretePanel", "Text (1)" }, false, true); LocalizationExtensions.Localize<Text>(((Component)componentInChildren.cancel).gameObject, levelUpdateNotification.b_cancel, new string[1] { "Text" }, false, true); LocalizationExtensions.Localize<Text>(((Component)componentInChildren.update).gameObject, levelUpdateNotification.b_update, new string[1] { "Text" }, false, true); } } } } [HarmonyPatch(typeof(ScriptUpdateNotification))] public static class ScriptUpdateNotificationPatch { [HarmonyPatch("OnUI")] [HarmonyPostfix] public static void Localize(ScriptUpdateNotification __instance) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { AngryScriptUpdateNotificationComponent ui = __instance.ui; ScriptUpdateNotification scriptUpdateNotification = LanguageManager.Current.angry.angryUi.notifications.scriptUpdateNotification; LocalizationExtensions.Localize<Text>(((Component)ui).gameObject, scriptUpdateNotification.header, new string[2] { "ConcretePanel", "Text (1)" }, false, true); LocalizationExtensions.Localize<Text>(((Component)ui.cancel).gameObject, scriptUpdateNotification.b_cancel, new string[1] { "Text" }, false, true); LocalizationExtensions.Localize<Text>(((Component)ui.update).gameObject, scriptUpdateNotification.b_update, new string[1] { "Text" }, false, true); LocalizationExtensions.Localize<Text>(((Component)ui.continueButton).gameObject, scriptUpdateNotification.b_continue, new string[1] { "Text" }, false, true); } } } [PatchTrigger("AngryLevelLoader.Managers.ConfigManager", "InitializeConfig", null)] [HarmonyPatch(typeof(OnlineLevelField))] public static class OnlineLevelFieldPatch { [HarmonyPatch("OnCreateUI")] [HarmonyPostfix] public static void LocalizeOnlineLevelListPanel(OnlineLevelField __instance) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded && __instance.inited) { OnlineLevel onlineLevel = LanguageManager.Current.angry.angryUi.onlineLevel; LocalizationExtensions.Localize<Text>(((Component)__instance.currentUi.changelog).GetComponentInChildren<Text>(true), onlineLevel.changelog, false); LocalizationExtensions.Localize<Text>(((Component)__instance.currentUi.update).GetComponentInChildren<Text>(true), onlineLevel.update, false); LocalizationExtensions.Localize<Text>(((Component)__instance.currentUi.install).GetComponentInChildren<Text>(true), onlineLevel.install, false); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] public static void LocalizeOnlineLevelFieldTitle(OnlineLevelField __instance) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded && !((Object)(object)__instance.currentUi == (Object)null)) { OnlineLevel onlineLevel = LanguageManager.Current.angry.angryUi.onlineLevel; _ = LanguageManager.Current.angry.angryUi.bundleStatus; string text = __instance.currentUi.infoText.text; text = text.Replace("<color=red>(OUTDATED/LOCKED)</color>", "<color=red>" + onlineLevel.outdateAndLocked + "</color>"); text = text.Replace("Author: ", onlineLevel.author ?? ""); text = text.Replace("Size: ", onlineLevel.size ?? ""); __instance.currentUi.infoText.text = text; } } [HarmonyPatch("GetStatusString")] [HarmonyPostfix] public static void LocalizeStatusString(ref string __result) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { BundleStatus bundleStatus = LanguageManager.Current.angry.angryUi.bundleStatus; __result = __result switch { "<color=red><b>Network error</b></color>" => "<color=red><b>" + bundleStatus.networkError + "</b></color>", "<color=red><b>Validation error</b></color>" => "<color=red><b>" + bundleStatus.validationError + "</b></color>", "<color=red><b>File was modified</b></color>" => "$<color=red><b>" + bundleStatus.fileWasModified + "</b></color>", "<color=red><b>Locked</b></color>" => "<color=red><b>" + bundleStatus.locked + "</b></color>", "<color=red>Not installed</color>" => "<color=red>" + bundleStatus.notInstalled + "</color>", "<color=#00FFFF>Update available</color>" => "<color=#00FFFF>" + bundleStatus.updateAvailable + "</color>", "<color=#00FF00>Installed</color>" => "<color=#00FF00>" + bundleStatus.installed + "</color>", _ => __result, }; } } } [HarmonyPatch(typeof(OnlineLevelsList))] public static class OnlineLevelsListPatch { [HarmonyPatch("Init")] [HarmonyPostfix] public static void LocalizeOnlineLevelListPanel() { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { OnlineLevelsListLocalizer.LocalizeOnlineLevelsList(); } } } public static class OnlineLevelsListLocalizer { public static void LocalizeOnlineLevelsList() { SearchBarField searchBar = OnlineLevelsList.searchBar; searchBar.onValueChange = (Action<string>)Delegate.Combine(searchBar.onValueChange, (Action<string>)delegate { if (OnlineLevelsList.searchKeywords.Length != 0) { AngryTranslation angry = LanguageManager.Current.angry; string[] array = new string[2] { OnlineLevelsList.onlineLevels.Values.Count((OnlineLevelField val) => !((ConfigField)val).hidden).ToString(), OnlineCatalogManager.Catalog.Levels.Count.ToString() }; ConfigHeader searchInfo = OnlineLevelsList.searchInfo; string format = LocalizationExtensions.Or(angry.angryUi.onlineSearchInfo, "Showing {0} of {1} bundles"); object[] args = array; searchInfo.text = string.Format(format, args); } }); } } [HarmonyPatch(typeof(OnlineSortField))] public static class OnlineSortFieldPatch { [HarmonyPatch("OnCreateUI")] [HarmonyPostfix] public static void LocalizeButtons(OnlineSortField __instance) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { SortingOption val = LanguageManager.Current?.angry?.angryUi.sortingOption; ((TMP_Text)__instance.currentUi.nameText).text = val.name; ((TMP_Text)__instance.currentUi.authorText).text = val.author; ((TMP_Text)__instance.currentUi.lastUpdateText).text = val.lastUpdate; ((TMP_Text)__instance.currentUi.votesText).text = val.votes; } } } [HarmonyPatch(typeof(OnlineStatusFilterField))] public static class OnlineStatusFilterFieldPatch { [HarmonyPatch("OnCreateUI")] [HarmonyPostfix] public static void LocalizeOnlineStatusFilter(OnlineStatusFilterField __instance) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { BundleStatus val = LanguageManager.Current?.angry?.angryUi.bundleStatus; LocalizationExtensions.Localize<TMP_Text>(((Component)__instance.currentUi.installed).GetComponentInChildren<TMP_Text>(true), val.installed, false); LocalizationExtensions.Localize<TMP_Text>(((Component)__instance.currentUi.notInstalled).GetComponentInChildren<TMP_Text>(true), val.notInstalled, false); LocalizationExtensions.Localize<TMP_Text>(((Component)__instance.currentUi.updateAvailable).GetComponentInChildren<TMP_Text>(true), val.updateAvailable, false); } } } [PatchTrigger("AngryLevelLoader.Plugin", "ScanForLevels", null)] [HarmonyPatch(typeof(AngryBundleList))] public static class AngryBundleListPatch { public static MethodInfo fp_LocalizeLevelBundleHeaderAndSearchInfo = AccessTools.Method(typeof(AngryBundleListPatch), "LocalizeLevelBundleHeaderAndSearchInfo", (Type[])null, (Type[])null); [HarmonyPatch("UpdateBundleSearch")] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> LocalizeSearchInfoAndLevelBundles(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).End().MatchEndBackwards((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ret), (string)null) }).Insert((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldloc_1, (object)null), new CodeInstruction(OpCodes.Ldloc_2, (object)null), new CodeInstruction(OpCodes.Call, (object)fp_LocalizeLevelBundleHeaderAndSearchInfo) }) .InstructionEnumeration(); } public static void LocalizeLevelBundleHeaderAndSearchInfo(int filterCount, int totalCount) { AngryTranslation angry = LanguageManager.Current.angry; ConfigManager.levelBundlesHeader.text = LocalizationExtensions.Or(angry.angryUi.rootPanel.levelBundles, ConfigManager.levelBundlesHeader.text); ConfigManager.searchInfo.text = string.Format(LocalizationExtensions.Or(angry.angryUi.onlineSearchInfo, "Showing {0} of {1} bundles"), filterCount, totalCount); } [HarmonyPatch("DisplayFolder")] [HarmonyPostfix] public static void LocalizeDisplayedFolder() { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { FolderButtonField displayedFolder = AngryBundleList.displayedFolder; string levelBundles = LanguageManager.Current.angry.angryUi.rootPanel.levelBundles; if (displayedFolder == AngryBundleList.rootFolder) { ConfigManager.levelBundlesHeader.text = levelBundles; } else { ConfigManager.levelBundlesHeader.text = levelBundles + " <color=grey>" + displayedFolder.GetRelativeFolderPath() + "</color>"; } } } } [HarmonyPatch(typeof(ConfigManager))] public static class ConfigManagerPatch { [HarmonyPatch("InitializeConfig")] [HarmonyPostfix] public static void LocalizeMainAndSettingPanel() { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { AngryUILocalizer.Localize(); } } } public static class AngryUILocalizer { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static OpenPanelEventDelegate <>9__1_0; internal void <LocalizeRootPanel>b__1_0(bool _) { LocalizeNewLevel.LocalizeNewLevelLine(); } } public static void Localize() { AngryUi angry = LanguageManager.Current?.angry.angryUi; LocalizeRootPanel(angry); LocalizeSettingPanel(angry); } public static void LocalizeRootPanel(AngryUi angry) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown RootPanel rootPanel = angry.rootPanel; ConfigPanel rootPanel2 = ConfigManager.config.rootPanel; object obj = <>c.<>9__1_0; if (obj == null) { OpenPanelEventDelegate val = delegate { LocalizeNewLevel.LocalizeNewLevelLine(); }; <>c.<>9__1_0 = val; obj = (object)val; } rootPanel2.onPannelOpenEvent += (OpenPanelEventDelegate)obj; ((ConfigField)OnlineLevelsList.onlineLevelsPanel).displayName = rootPanel.onlineLevels; OnlineLevelsList.onlineLevelsPanel.headerText = rootPanel.onlineLevelsHeader; OnlineLevelsList.onlineLevelsPanel.buttonText = rootPanel.open; ((ConfigField)ConfigManager.bannedModsPanel).displayName = rootPanel.leaderboardBannedMods; ((ConfigField)ConfigManager.pendingRecords).displayName = rootPanel.pendingRecords; ((ConfigField)ConfigManager.sendPendingRecords).displayName = rootPanel.sendPendingRecords; ConfigField obj2 = ConfigManager.config.rootPanel["settingsAndReload"]; ConfigField obj3 = ((obj2 is ButtonArrayField) ? obj2 : null); if (obj3 != null) { ((ButtonArrayField)obj3).SetButtonText(0, rootPanel.settings); } ConfigField obj4 = ConfigManager.config.rootPanel["settingsAndReload"]; ConfigField obj5 = ((obj4 is ButtonArrayField) ? obj4 : null); if (obj5 != null) { ((ButtonArrayField)obj5).SetButtonText(1, rootPanel.scanForLevels); } ((ConfigField)ConfigManager.reportsButton).displayName = rootPanel.viewReports; ((ConfigField)ConfigManager.levelBundlesHeader).displayName = rootPanel.levelBundles; (string, string)[] headers = new(string, string)[1] { ("Difficulty is overridden by gamemode\nWarning: Some levels may not be compatible with gamemodes", rootPanel.difficultyOverrideWarning) }; AngryUtil.ApplyHeaders(ConfigManager.config.rootPanel, headers); } public static void LocalizeSettingPanel(AngryUi angry) { SettingPanel settingPanel = angry.settingPanel; ((ConfigField)ConfigManager.changelogButton).displayName = settingPanel.changelog; ConfigManager.openButtons.SetButtonText(0, settingPanel.openLevelsFolder); ConfigManager.openButtons.SetButtonText(1, settingPanel.openScriptsFolder); ((ConfigField)ConfigManager.reloadFileKeybind).displayName = settingPanel.reloadFile; ((ConfigField)ConfigManager.reloadScriptKeybind).displayName = settingPanel.reloadScript; ((ConfigField)ConfigManager.filterMode).displayName = settingPanel.unityLogLevel; ((ConfigField)ConfigManager.customLevelButtonPosition).displayName = settingPanel.customLevelButtonPosition; ((ConfigField)ConfigManager.customLevelButtonFrameColor).displayName = settingPanel.customLevelButtonFrameColor; ((ConfigField)ConfigManager.customLevelButtonTextColor).displayName = settingPanel.customLevelButtonTextColor; ((ConfigField)ConfigManager.showLeaderboardOnLevelEnd).displayName = settingPanel.showLeaderboardOnLevelEnd; ((ConfigField)ConfigManager.showLeaderboardOnSecretLevelEnd).displayName = settingPanel.showLeaderboardOnSecretLevelEnd; ((ConfigField)ConfigManager.defaultLeaderboardCategory).displayName = settingPanel.defaultLeaderboardCategory; ((ConfigField)ConfigManager.defaultLeaderboardDifficulty).displayName = settingPanel.defaultLeaderboardDifficulty; ((ConfigField)ConfigManager.defaultLeaderboardFilter).displayName = settingPanel.defaultLeaderboardFilter; ((ConfigField)ConfigManager.refreshCatalogOnBoot).displayName = settingPanel.refreshCatalogOnBoot; ((ConfigField)ConfigManager.useDevelopmentBranch).displayName = settingPanel.useDevelopmentBranch; ((ConfigField)ConfigManager.useLocalServer).displayName = settingPanel.useLocalServer; ((ConfigField)ConfigManager.levelUpdateNotifierToggle).displayName = settingPanel.levelUpdateNotifier; ((ConfigField)ConfigManager.levelUpdateIgnoreCustomBuilds).displayName = settingPanel.levelUpdateIgnoreCustomBuilds; ((ConfigField)ConfigManager.newLevelNotifierToggle).displayName = settingPanel.newLevelNotifierToggle; ((ConfigField)ConfigManager.scriptUpdateIgnoreCustom).displayName = settingPanel.updateIgnoreCustomBuilds; ((ConfigField)ConfigManager.scriptCertificateIgnoreField).displayName = settingPanel.certificateIgnore; ((ConfigField)ConfigManager.reloadAlwaysGoToMainMenu).displayName = settingPanel.reloadAlwaysGoToMainMenu; ((ConfigField)InternalConfigManager.leaderboardToggle).displayName = settingPanel.postRecordsToLeaderboards; PluginConfigurator internalConfig = InternalConfigManager.internalConfig; object obj; if (internalConfig == null) { obj = null; } else { ConfigPanel rootPanel = internalConfig.rootPanel; obj = ((rootPanel != null) ? rootPanel["p_settings"] : null); } ConfigPanel val = (ConfigPanel)((obj is ConfigPanel) ? obj : null); val.headerText = settingPanel.settingsHeader; val["customLevelButtonPanel"].displayName = settingPanel.customLevelButtonColors; val["s_dataPathInput"].displayName = settingPanel.dataPath; val["s_changeDataPath"].displayName = settingPanel.moveData; val["s_deleteOldBundles"].displayName = settingPanel.deleteOldBundles; (string, string)[] headers = new(string, string)[6] { ("User Interface", settingPanel.userInterface), ("Leaderboards", settingPanel.leaderboards), ("Online", settingPanel.online), ("Scripts", settingPanel.scripts), ("Compatibility", settingPanel.compatibility), ("Danger Zone", settingPanel.dangerZone) }; AngryUtil.ApplyHeaders(val, headers); } } [HarmonyPatch(typeof(BundleSortField))] public static class BundleSortFieldPatch { [HarmonyPatch("OnCreateUI")] [HarmonyPostfix] public static void LocalizeButtons(BundleSortField __instance) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { SortingOption val = LanguageManager.Current?.angry?.angryUi.sortingOption; ((TMP_Text)__instance.currentUi.nameText).text = val.name; ((TMP_Text)__instance.currentUi.authorText).text = val.author; ((TMP_Text)__instance.currentUi.lastUpdateText).text = val.lastUpdate; ((TMP_Text)__instance.currentUi.lastPlayedText).text = val.lastPlayed; } } } [HarmonyPatch(typeof(OnlineLevelsList))] public static class CheckNewLevelUpdatePatch { [HarmonyPatch("CheckLevelUpdateText")] [HarmonyPostfix] public static void LocalizeNewLevelUpdatePanel() { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { LocalizeUpdateAvailable.LocalizeLevelUpdateLine(); } } } public static class LocalizeUpdateAvailable { public static void LocalizeLevelUpdateLine() { AngryUtil.LocalizeNotifierHeader(ConfigManager.levelUpdateNotifier, "<color=#00FFFF>", "Update available for ", LanguageManager.Current.angry.angryUi.rootPanel.newUpdateNotifier); } } [HarmonyPatch(typeof(OnlineLevelsList))] public static class CheckNewLevelTextPatch { [HarmonyPatch("CheckNewLevelText")] [HarmonyPostfix] public static void LocalizeNewLevelTextPanel() { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { LocalizeNewLevel.LocalizeNewLevelLine(); } } } public static class LocalizeNewLevel { public static void LocalizeNewLevelLine() { AngryUtil.LocalizeNotifierHeader(ConfigManager.newLevelNotifier, "<color=#00FF00>", "New level: ", LanguageManager.Current.angry.angryUi.rootPanel.newLevelNotifier); } } [HarmonyPatch(typeof(ConfigPanelForBundles))] public static class ConfigPanelForBundlesPatch { [HarmonyPatch("CreateUI")] [HarmonyPostfix] public static void LocalizeOpenButton(ConfigPanelForBundles __instance) { if (!LanguageManager.IsEnglish && LanguageManager.IsAngryTranslationLoaded) { string buttonText = LanguageManager.Current?.angry?.angryUi.rootPanel?.open; ((ConfigPanel)__instance).buttonText = buttonText; } } } [HarmonyPatch(typeof(DifficultyField))] public static class DifficultyFieldPatch { [HarmonyPatch("OnCreateUI")] [HarmonyPostfix] public static void LocalizeButtons(DifficultyField __instance) { if (LanguageManager.IsEnglish || !LanguageManager.IsAngryTranslationLoaded || !__instance.inited) { return; } AngryTranslation angry = LanguageManager.Current.angry; LocalizationExtensions.Localize<Text>(((Component)__instance.currentUi).gameObject, LanguageManager.CurrentLanguage.frontend.difficulty_title, new string[1] { "DifficultyText" }, false, true); LocalizationExtensions.Localize<Text>(((Component)__instance.currentUi).gameObject, angry.angryUi.rootPanel.gamemode, new string[1] { "GamemodeText" }, false, true); foreach (OptionData option in __instance.currentUi.difficultyList.options) { option.text = LocalizationExtensions.Or(option.text switch { "HARMLESS" => LanguageManager.CurrentLanguage.frontend.difficulty_harmless, "LENIENT" => LanguageManager.CurrentLanguage.frontend.difficulty_lenient, "STANDARD" => LanguageManager.CurrentLanguage.frontend.difficulty_standard, "VIOLENT" => LanguageManager.CurrentLanguage.frontend.difficulty_violent, "BRUTAL" => LanguageManager.CurrentLanguage.frontend.difficulty_brutal, _ => option.text, }, option.text); } foreach (OptionData option2 in __instance.currentUi.gamemodeList.options) { option2.text = LocalizationExtensions.Or(option2.text switch { "None" => angry.angryUi.category.none, "No Monsters" => angry.angryUi.category.noMonsters, "No Monsters/Weapons" => angry.angryUi.category.noMonstersAndWeapons, _ => option2.text, }, option2.text); } } } } namespace UltrakULL.Angry { public class AngryPatchModule : IPatchModule { private Harmony harmony; public string Name => "UltrakULL.angry"; public void PatchAll() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0074: 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) if (harmony != null) { return; } harmony = new Harmony("greycsont.ultrakull.angry"); AngrySceneTracker.ReadCurrentLevel = delegate { if (ConfigManager.config == null) { return ((string BundleGuid, string BundleAuthor, string BundleName, string LevelId, string LevelName)?)null; } if (!AngrySceneManager.isInCustomLevel) { return ((string BundleGuid, string BundleAuthor, string BundleName, string LevelId, string LevelName)?)null; } BundleContainer currentBundleContainer = AngrySceneManager.currentBundleContainer; LevelContainer currentLevelContainer = AngrySceneManager.currentLevelContainer; return (currentBundleContainer.bundleGuid, currentBundleContainer.BundleAuthor, currentBundleContainer.BundleName, currentLevelContainer.levelId, currentLevelContainer.LevelName); }; Type[] types = typeof(AngryPatchModule).Assembly.GetTypes(); foreach (Type type in types) { PatchTrigger customAttribute = ((MemberInfo)type).GetCustomAttribute<PatchTrigger>(); if (customAttribute != null && !string.IsNullOrEmpty(customAttribute.ClassName)) { TriggerEngine.Bind(type, new MethodTrigger { className = customAttribute.ClassName, methodName = customAttribute.MethodName, argTypes = customAttribute.Args }, (Action)null); } else if (((MemberInfo)type).GetCustomAttribute<HarmonyPatch>() != null) { harmony.PatchAll(type); } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }
plugins/UltrakULL_Apodidae_Remix/UltrakULL.API.dll
Decompiled 3 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("UltrakULL.API")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+814c6b1131c4d3112e36c74cbd216bc8c5c2e452")] [assembly: AssemblyProduct("UltrakULL.API")] [assembly: AssemblyTitle("UltrakULL.API")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace UltrakULL.API { public interface IPatchModule { string Name { get; } void PatchAll(); } }
plugins/UltrakULL_Apodidae_Remix/UltrakULL.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using AngryLevelLoader.Managers; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Discord; using GameConsole; using GameConsole.CommandTree; using GreyAnnouncer.AudioClipLoad; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Sandbox; using ScriptableObjects; using SettingsMenu.Components; using TMPro; using UltrakULL.API; using UltrakULL.Harmony_Patches; using UltrakULL.audio; using UltrakULL.json; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; using plog; using plog.Models; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("AngryLevelLoader")] [assembly: IgnoresAccessChecksTo("AngryUiComponents")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("plog")] [assembly: IgnoresAccessChecksTo("RudeLevelScripts.Essentials")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: AssemblyCompany("UltrakULL")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+814c6b1131c4d3112e36c74cbd216bc8c5c2e452")] [assembly: AssemblyProduct("UltrakULL")] [assembly: AssemblyTitle("UltrakULL")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { public ExtensionMarkerAttribute(string name) { } } } namespace GreyAnnouncer.AudioClipLoad { public static class StringExtension { [SpecialName] public sealed class <G>$34505F560D9EACF86A87F3ED1F85E448 { [SpecialName] public static class <M>$D2C87DABA57FE47E39897F3C24A0705C { } [ExtensionMarker("<M>$D2C87DABA57FE47E39897F3C24A0705C")] public AudioType TryGetAudioType() { throw null; } } public static AudioType TryGetAudioType(this string value) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) string[] array = value.Split('.'); for (int i = 1; i <= array.Length; i++) { AudioType unityAudioType = GetUnityAudioType(array[^i]); if ((int)unityAudioType != 0) { return unityAudioType; } } return (AudioType)0; } [Description("https://docs.unity3d.com/2022.3/Documentation//ScriptReference/AudioType.html")] private static AudioType GetUnityAudioType(string extension) { //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) return (AudioType)(extension switch { "aac" => 1, "aiff" => 2, "aif" => 2, "aifc" => 2, "it" => 10, "mod" => 12, "mp3" => 13, "mpga" => 13, "mpeg" => 13, "ogg" => 14, "s3m" => 17, "wav" => 20, "xm" => 21, "xma" => 22, "vag" => 23, _ => 0, }); } } } namespace UltrakULL { public static class AngryLevelText { public static string BundleGuid { get; private set; } public static string BundleAuthor { get; private set; } public static string BundleName { get; private set; } public static string LevelId { get; private set; } public static string LevelName { get; private set; } public static void SetCurrent(string bundleGuid, string bundleAuthor, string bundleName, string levelId, string levelName) { BundleGuid = bundleGuid; BundleAuthor = bundleAuthor; BundleName = bundleName; LevelId = levelId; LevelName = levelName; } public static string Name() { return Current()?.levelName; } public static string Title() { return Current()?.levelTitle; } public static string Layer() { return Current()?.levelLayer; } public static string Tip() { return Current()?.tipOfTheDay; } public static string Challenge() { return Current()?.challenge; } public static List<Match> HudMessages() { return Current()?.hudMessages ?? new List<Match>(); } public static List<Match> Books() { return Current()?.books ?? new List<Match>(); } public static AngryLevel Current() { if (string.IsNullOrEmpty(BundleGuid) || string.IsNullOrEmpty(LevelId)) { return null; } Dictionary<string, AngryBundle> dictionary = LanguageManager.Current?.angry?.angryBundles?.bundles; if (dictionary == null) { return null; } if (!dictionary.TryGetValue(BundleGuid, out var value) || value?.levels == null) { return null; } if (!value.levels.TryGetValue(LevelId, out var value2)) { return null; } if (!string.IsNullOrEmpty(value2.translator)) { return value2; } return null; } } public static class AngrySceneTracker { public static Func<(string BundleGuid, string BundleAuthor, string BundleName, string LevelId, string LevelName)?> ReadCurrentLevel; public static bool InAngryLevel { get; private set; } public static void ReadCurrentScene() { (string, string, string, string, string)? tuple = ReadCurrentLevel?.Invoke(); InAngryLevel = tuple.HasValue; AngryLevelText.SetCurrent(tuple?.Item1, tuple?.Item2, tuple?.Item3, tuple?.Item4, tuple?.Item5); } } public static class CreditText { private class FadeEffect : MonoBehaviour { private TMP_Text target; private float alpha; private float targetAlpha; private float speed; private float hideAt = -1f; public void Init(TMP_Text owner) { target = owner; ((Behaviour)this).enabled = false; } public void Play(float seconds, float fadeSeconds) { speed = 1f / fadeSeconds; targetAlpha = 1f; hideAt = ((seconds > 0f) ? (Time.unscaledTime + seconds) : (-1f)); ((Behaviour)this).enabled = true; } public void HideNow() { targetAlpha = 0f; hideAt = -1f; ((Behaviour)this).enabled = true; } private void Update() { if (!MonoSingleton<OptionsManager>.Instance.paused) { if (hideAt > 0f && Time.unscaledTime >= hideAt) { targetAlpha = 0f; hideAt = -1f; } alpha = Mathf.MoveTowards(alpha, targetAlpha, speed * Time.unscaledDeltaTime); if ((Object)(object)target != (Object)null) { target.alpha = alpha; } if (hideAt < 0f && Mathf.Approximately(alpha, 0f)) { ((Behaviour)this).enabled = false; } } } } private const float MARGIN = 24f; private const float HEIGHT = 40f; private static TextMeshProUGUI label; private static FadeEffect fadeEffect; private static TextMeshProUGUI Label { get { if ((Object)(object)label == (Object)null) { Build(); } return label; } } public static void Show(string text, float seconds = 4f, float fadeSeconds = 0.6f) { if (!string.IsNullOrEmpty(text)) { TextMeshProUGUI val = Label; if (!((Object)(object)val == (Object)null)) { ((TMP_Text)val).text = text; ((TMP_Text)val).font = LanguageManager.Current.MainFontAsset; fadeEffect.Play(seconds, fadeSeconds); } } } public static void Hide() { if ((Object)(object)fadeEffect != (Object)null) { fadeEffect.HideNow(); } } private static void Build() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) Canvas val = SceneObjects.FindCanvas(); if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("UltrakULL_CreditText"); label = val2.AddComponent<TextMeshProUGUI>(); fadeEffect = val2.AddComponent<FadeEffect>(); RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent(((Component)val).transform, false); val3.anchorMin = new Vector2(0f, 0f); val3.anchorMax = new Vector2(1f, 0f); val3.pivot = new Vector2(1f, 0f); val3.offsetMin = new Vector2(24f, 24f); val3.offsetMax = new Vector2(-24f, 64f); ((TMP_Text)label).alignment = (TextAlignmentOptions)1028; ((TMP_Text)label).fontSize = 20f; ((Graphic)label).raycastTarget = false; ((TMP_Text)label).alpha = 0f; fadeEffect.Init((TMP_Text)(object)label); } } } public class NeedDebugMode : Attribute { } public class NeedRework : Attribute { } public class NonSenseNeedChange : Attribute { } [AttributeUsage(AttributeTargets.Class)] public class PatchTrigger : Attribute { public string ClassName; public string MethodName; public string[] Args; public PatchTrigger(string className = null, string methodName = null, string[] args = null) { ClassName = className; MethodName = methodName; Args = args; } } public static class SubtitledAudioSourcesReplacer { public static SubtitledSourcesConfig Config; public static void ReplaceSubsAndAudio() { if (!TryLoadMetadata(out var references)) { return; } List<(AudioSource source, string path)> audioReplacements = new List<(AudioSource, string)>(); foreach (SubtitledObjectReference item in references) { foreach (string @object in item.Objects) { GameObject val = SceneObjects.GetObject(@object); SubtitledAudioSource component = val.GetComponent<SubtitledAudioSource>(); if (ActiveDubbingEnabled()) { audioReplacements.Add((val.GetComponentInChildren<AudioSource>(), Path.Combine(AudioSwapper.SpeechFolder, item.AudioPath))); } if ((Object)(object)component != (Object)null) { SubtitleData val2 = item.ToSubtitleData(); if (val2.lines.Any((SubtitleDataLine line) => !StringHelper.IsEmpty(line.subtitle))) { component.subtitles = val2; } } } } AudioSwapper.WhenReady(delegate { foreach (var item2 in audioReplacements) { item2.source.clip = AudioSwapper.SwapClipWithFile(item2.source.clip, item2.path); } }); } private static bool ActiveDubbingEnabled() { return Settings.activeDubbing.Value; } private static bool TryLoadMetadata(out List<SubtitledObjectReference> references) { if (Config != null && Config.Scenes.TryGetValue(SceneObjects.GetCurrentSceneName(), out references)) { return true; } references = null; return false; } } public class SubtitledSourcesConfig { [JsonProperty("scenes")] public Dictionary<string, List<SubtitledObjectReference>> Scenes; } public class SubtitledObjectReference { [JsonProperty("objects")] public List<string> Objects; [JsonProperty("audio")] public string AudioPath; [JsonProperty("lines")] public List<Line> Lines; public SubtitleData ToSubtitleData() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown return new SubtitleData { lines = ((IEnumerable<Line>)Lines).Select((Func<Line, SubtitleDataLine>)((Line line) => new SubtitleDataLine { subtitle = ColorIfNecessary(LanguageManager.CurrentLanguage.subtitles.GetField(line.Reference), line.Color), time = line.Delay })).ToArray() }; } private static string ColorIfNecessary(string line, string color) { if (color == null || StringHelper.IsEmpty(line)) { return line; } return "<color=#" + color + ">" + line + "</color>"; } } public class Line { [JsonProperty("line")] public string Reference; [JsonProperty("delay")] public float Delay; [JsonProperty("color")] public string Color; } public static class SubtitleLocalizer { private static readonly MethodInfo DisplaySubtitle = AccessTools.Method(typeof(SubtitleController), "DisplaySubtitle", new Type[3] { typeof(string), typeof(AudioSource), typeof(bool) }, (Type[])null); private static readonly MethodInfo DisplaySubtitleOverride = AccessTools.Method(typeof(SubtitleController), "DisplaySubtitle", new Type[3] { typeof(string), typeof(float), typeof(GameObject) }, (Type[])null); public static IEnumerable<CodeInstruction> InjectLocalize2(IEnumerable<CodeInstruction> instructions, MethodInfo localize, OpCode? anchorOpcode = null) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.Calls(i, DisplaySubtitle) || CodeInstructionExtensions.Calls(i, DisplaySubtitleOverride)), (string)null) }).Repeat((Action<CodeMatcher>)delegate(CodeMatcher m) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown int pos = m.Pos; m.SearchBack((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == (anchorOpcode ?? OpCodes.Ldstr))); if (m.IsInvalid || pos - m.Pos > 8) { Logging.Warn($"InjectLocalize: no nearby {anchorOpcode ?? OpCodes.Ldstr} before DisplaySubtitle, skipped.", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\AudioClip\\SubtitleLocalizer.cs"); m.Start().Advance(pos + 1); } else { m.Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)localize) }).Advance(pos + 2 - m.Pos); } }, (Action<string>)null).InstructionEnumeration(); } public static IEnumerable<CodeInstruction> InjectLocalize3(IEnumerable<CodeInstruction> instructions, MethodInfo localize, int position = -2) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.Calls(i, DisplaySubtitle) || CodeInstructionExtensions.Calls(i, DisplaySubtitleOverride)), (string)null) }).Repeat((Action<CodeMatcher>)delegate(CodeMatcher m) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown int pos = m.Pos; m.Advance(position).Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)localize) }).Advance(pos + 2 - m.Pos); }, (Action<string>)null).InstructionEnumeration(); } } public sealed class CommandToRegister : CommandRoot, IConsoleLogger { public override string Name => "ultrakull"; public override string Description => "tons of setting"; public Logger Log { get; } = new Logger("ultrakull"); public CommandToRegister(Console con) : base(con) { }//IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown public override Branch BuildTree(Console con) { return CommandRoot.Branch(((CommandRoot)this).Name, (Node[])(object)new Node[4] { (Node)CommandRoot.Leaf("migrate", (Action)delegate { LegacyLanguageMigrator.LegacyMigrationResult legacyMigrationResult = LegacyLanguageMigrator.Migrate(); Log.Info($"Migrated {legacyMigrationResult.MigratedLanguages} legacy language package(s).", (IEnumerable<Tag>)null, (string)null, (object)null); foreach (string warning in legacyMigrationResult.Warnings) { Log.Warning(warning, (IEnumerable<Tag>)null, (string)null, (object)null); } if (legacyMigrationResult.SkippedLanguages > 0) { Log.Warning($"Skipped {legacyMigrationResult.SkippedLanguages} language package(s). See messages above.", (IEnumerable<Tag>)null, (string)null, (object)null); } if (legacyMigrationResult.MigratedLanguages > 0) { Log.Info("A copy of every migrated file was kept in \"" + legacyMigrationResult.BackupDirectory + "\".", (IEnumerable<Tag>)null, (string)null, (object)null); } Log.Info("Restart the game before editing or removing the backup.", (IEnumerable<Tag>)null, (string)null, (object)null); }, false), (Node)CommandRoot.Leaf("dhm", (Action)delegate { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Logging.Info("=========================", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Commands\\CommandsToRegister.cs"); Scene activeScene = SceneManager.GetActiveScene(); GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { HudMessage[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren<HudMessage>(true); foreach (HudMessage val in componentsInChildren) { string arg = (((Object)(object)val.actionReference == (Object)null) ? "-" : val.actionReference.action.id.ToString()); Logging.Info($"\n[HudMsgScan] obj='{((Object)((Component)val).gameObject).name}' (active={((Component)val).gameObject.activeInHierarchy})" + "\n msg ='" + val.message + "'\n m2 ='" + val.message2 + "'\n fm = '" + GetFullMessage(val) + "'" + $"\n advanced={val.advancedMessage} action={arg}" + "\n ------------------------------", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Commands\\CommandsToRegister.cs"); } } }, false), (Node)CommandRoot.Branch("gene", (Node[])(object)new Node[1] { (Node)CommandRoot.Leaf("angry", (Action)delegate { try { string path; JObject val = LoadAngryFile(out path); JToken obj = val["angryUi"]; JObject val2 = (JObject)(object)((obj is JObject) ? obj : null); if (val2 != null) { FillGaps(val2, BlankOf(new AngryUi())); } else { val["angryUi"] = (JToken)(object)BlankOf(new AngryUi()); } File.WriteAllText(path, ((JToken)val).ToString((Formatting)1, Array.Empty<JsonConverter>())); Log.Info("Written " + path + " (angry ui).", (IEnumerable<Tag>)null, (string)null, (object)null); } catch (Exception arg) { Log.Error($"Failed to write the angry ui: {arg}", (IEnumerable<Tag>)null, (string)null, (object)null); } }, false) }), (Node)CommandRoot.Branch("scan", (Node[])(object)new Node[1] { (Node)CommandRoot.Leaf("angrylevel", (Action)delegate { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0069: Expected O, but got Unknown //IL_006e: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_00ec: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0147: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_016c: Expected O, but got Unknown try { if (!AngrySceneTracker.InAngryLevel) { Log.Warning("Not in an Angry level. Load a custom level first, then scan it.", (IEnumerable<Tag>)null, (string)null, (object)null); } else { string path; JObject val = LoadAngryFile(out path); JToken obj = val["angryBundles"]; JToken obj2 = ((obj != null) ? obj[(object)"bundles"] : null); JObject val2 = (JObject)(object)((obj2 is JObject) ? obj2 : null); if (val2 == null) { JObject val3 = new JObject(); JObject val4 = new JObject(); val2 = val4; val3["bundles"] = (JToken)val4; val["angryBundles"] = (JToken)val3; } string bundleGuid = AngryLevelText.BundleGuid; string levelId = AngryLevelText.LevelId; if (string.IsNullOrEmpty(bundleGuid) || string.IsNullOrEmpty(levelId)) { Log.Error("In an Angry level but its ids are empty... (bundle='" + bundleGuid + "', level='" + levelId + "').", (IEnumerable<Tag>)null, (string)null, (object)null); } else { JToken obj3 = val2[bundleGuid]; JObject val5 = (JObject)(object)((obj3 is JObject) ? obj3 : null); if (val5 == null) { JObject obj4 = val2; JObject val6 = new JObject(); val5 = val6; obj4[bundleGuid] = (JToken)val6; } JObject val7 = val5; if (val7["bundleName"] == null) { JToken val8 = (val7["bundleName"] = JToken.op_Implicit(AngrySceneManager.currentBundleContainer.BundleName)); } JToken obj5 = val5["levels"]; JObject val10 = (JObject)(object)((obj5 is JObject) ? obj5 : null); if (val10 == null) { JObject obj6 = val5; JObject val11 = new JObject(); val10 = val11; obj6["levels"] = (JToken)val11; } JToken obj7 = val10[levelId]; JObject val12 = (JObject)(object)((obj7 is JObject) ? obj7 : null); if (val12 == null) { JObject obj8 = val10; JObject val13 = new JObject(); val12 = val13; obj8[levelId] = (JToken)val13; } FillGaps(val12, BlankOf(new AngryLevel())); JArray array = ArrayIn(val12, "books"); JArray array2 = ArrayIn(val12, "hudMessages"); Scene activeScene = SceneManager.GetActiveScene(); GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects(); foreach (GameObject val14 in rootGameObjects) { HudMessage[] componentsInChildren = val14.GetComponentsInChildren<HudMessage>(true); foreach (HudMessage hm in componentsInChildren) { AddMatch(array2, GetFullMessage(hm), ""); } Readable[] componentsInChildren2 = val14.GetComponentsInChildren<Readable>(true); foreach (Readable val15 in componentsInChildren2) { AddMatch(array, val15.content, ""); } } File.WriteAllText(path, ((JToken)val).ToString((Formatting)1, Array.Empty<JsonConverter>())); Log.Info("Written " + path + ": " + AngrySceneManager.currentBundleContainer.BundleName + " / " + levelId + ".", (IEnumerable<Tag>)null, (string)null, (object)null); } } } catch (Exception arg) { Log.Error($"Failed to scan the angry level: {arg}", (IEnumerable<Tag>)null, (string)null, (object)null); } }, false) }) }); } private static string GetFullMessage(HudMessage hm) { if (hm.advancedMessage) { return hm.message; } if ((Object)(object)hm.actionReference == (Object)null) { return hm.message; } return hm.message + "{0}" + hm.message2; } private static JObject LoadAngryFile(out string path) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) string angryLevelFolder = LanguageManager.Current.AngryLevelFolder; path = Path.Combine(angryLevelFolder, "angry.json"); Directory.CreateDirectory(angryLevelFolder); if (!File.Exists(path)) { return new JObject(); } return (JObject)(((object)JObject.Parse(File.ReadAllText(path))) ?? ((object)new JObject())); } private static JObject BlankOf(object target) { JObject val = JObject.FromObject(target); foreach (JToken item in (from t in ((JContainer)val).Descendants() where (int)t.Type == 10 select t).ToList()) { item.Replace(JToken.op_Implicit("")); } return val; } private static void FillGaps(JObject node, JObject template) { foreach (JProperty item in template.Properties()) { JToken value = item.Value; JObject val = (JObject)(object)((value is JObject) ? value : null); if (val != null) { JToken obj = node[item.Name]; JObject val2 = (JObject)(object)((obj is JObject) ? obj : null); if (val2 != null) { FillGaps(val2, val); } else { node[item.Name] = ((JToken)val).DeepClone(); } } else if (node[item.Name] == null) { node[item.Name] = item.Value.DeepClone(); } } } private static JArray ArrayIn(JObject parent, string name) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown JToken obj = parent[name]; JArray val = (JArray)(object)((obj is JArray) ? obj : null); if (val != null) { return val; } return (JArray)(object)(parent[name] = (JToken)new JArray()); } private static void AddMatch(JArray array, string match, string text) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown if (string.IsNullOrEmpty(match)) { return; } foreach (JToken item in array) { JObject val = (JObject)(object)((item is JObject) ? item : null); if (val != null && (string)val["match"] == match) { return; } } array.Add((JToken)new JObject { ["match"] = JToken.op_Implicit(match), ["text"] = JToken.op_Implicit(text) }); } } [HarmonyPatch(typeof(Console))] public class ConsolePatcher { [HarmonyPatch("Awake")] [HarmonyPrefix] public static void AddConsoleCommands(Console __instance) { CommandToRegister commandToRegister = new CommandToRegister(__instance); __instance.RegisterCommand((ICommand)(object)commandToRegister); } } public static class ConfigPaths { public static string RootDirectory => Path.Combine(Paths.ConfigPath, "ultrakull"); public static string LanguagesDirectory => Path.Combine(RootDirectory, "languages"); public static string TemplatesDirectory => Path.Combine(RootDirectory, "templates"); public static string LegacyBackupDirectory => Path.Combine(RootDirectory, "legacy-backup"); public static string SettingsFile => Path.Combine(RootDirectory, "lastLang.cfg"); public static string GetLegacyAudioDirectory(string languageId) { return Path.Combine(RootDirectory, "audio", languageId); } public static string GetLegacyTextureDirectory(string languageId) { return Path.Combine(RootDirectory, "textures", languageId); } public static string GetLegacyAngryDirectory(string languageId) { return Path.Combine(RootDirectory, "angry", languageId); } public static string GetLegacyVideoDirectory(string languageID) { return Path.Combine(RootDirectory, "video", languageID); } public static string GetFontBundlePath(string languageId) { return Path.Combine(MainPatch.ModFolder, "fonts", languageId); } public static string GetUIOverridePath(string languageId) { return Path.Combine(MainPatch.ModFolder, "fonts", languageId, "layout.json"); } } public static class Core { public static bool wasLanguageReset; public static void LocalizeScene(GameObject canvasObj, bool sceneEntry) { string currentSceneName = SceneObjects.GetCurrentSceneName(); if (currentSceneName == "Intro" || currentSceneName == "Bootstrap") { return; } if (!Object.op_Implicit((Object)(object)canvasObj)) { Logging.Fatal("UNABLE TO FIND CANVAS IN CURRENT SCENE", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } else if (currentSceneName == "Main Menu") { if (wasLanguageReset) { wasLanguageReset = false; HudMessageReceiver instance = MonoSingleton<HudMessageReceiver>.Instance; if (instance != null) { instance.SendHudMessage("<color=orange>The currently set language file could not be loaded.\nLanguage has been reset to English to avoid problems.</color>", "", "", 0, false, false, true); } } MainMenu.Patch(canvasObj); Options.Patch(canvasObj); } else { if (sceneEntry) { UILayoutOverride.AdjustOptionTextPosition(); } if (LanguageManager.IsEnglish) { Logging.Warn("Current language is English, not patching.", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); return; } Logging.Message("Regular scene", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); PatchingBaseElements(canvasObj); LevelPatcher.Patch(currentSceneName, canvasObj); } } private static void PatchingBaseElements(GameObject canvasObj) { Logging.Message("Attempting to patch base elements", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); try { _PauseMenu.PatchPauseMenu(canvasObj); } catch (Exception ex) { Logging.Error(ex.ToString(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } try { Cheats.PatchCheatConsentPanel(canvasObj); } catch (Exception ex2) { Logging.Error(ex2.ToString(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } try { Sandbox.PatchAlterMenu(); } catch (Exception ex3) { Logging.Error(ex3.ToString(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } try { HUDMessages.PatchDeathScreen(canvasObj); } catch (Exception ex4) { Logging.Error(ex4.ToString(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } try { LevelStatWindow.PatchStats(canvasObj); } catch (Exception ex5) { Logging.Error(ex5.ToString(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } try { HUDMessages.PatchMisc(canvasObj); } catch (Exception ex6) { Logging.Error(ex6.ToString(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } try { Options.Patch(canvasObj); } catch (Exception ex7) { Logging.Error(ex7.ToString(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } Logging.Message("Base elements patched", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Core.cs"); } } internal static class DependencyGuid { public const string ANGRY_LEVEL_LOADER = "com.eternalUnion.angryLevelLoader"; } public static class LocalizationExtensions { internal static bool DebugMode; public static T Localize<T>(this T target, string translation, bool uppercase = false) where T : Component { if ((Object)(object)target == (Object)null) { return target; } object obj = target; TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); if (val == null) { object obj2 = target; Text val2 = (Text)((obj2 is Text) ? obj2 : null); if (val2 != null) { val2.text = translation.Or(val2.text).ToUpperIf(uppercase); } } else { val.text = translation.Or(val.text).ToUpperIf(uppercase); } return target; } public static OptionData Localize(this OptionData option, string translation, bool uppercase = false) { if (option == null) { return option; } option.text = translation.Or(option.text).ToUpperIf(uppercase); return option; } public static T Localize<T>(this GameObject parent, string translation, string[] path, bool uppercase = false, bool saveToCache = true) where T : Component { return SceneObjects.FindComponent<T>(parent, path).Localize(translation, uppercase); } public static string Or(this string translation, string original) { if (!StringHelper.IsEmpty(translation)) { return Penis(original, translation); } return original; } public static string ToUpperIf(this string text, bool uppercase) { if (!uppercase) { return text; } return text.ToUpper(); } private static string Penis(string original, string replacement) { original = ((!DebugMode) ? replacement : (original + "/" + replacement)); return original; } public static VideoPlayer ReplaceUrl(this VideoPlayer videoPlayer) { if ((Object)(object)videoPlayer == (Object)null || (Object)(object)videoPlayer.clip == (Object)null) { return videoPlayer; } string videoFolder = LanguageManager.Current.VideoFolder; if (!Directory.Exists(videoFolder)) { return videoPlayer; } string text = Directory.GetFiles(videoFolder).FirstOrDefault((string file) => string.Equals(Path.GetFileNameWithoutExtension(file), ((Object)videoPlayer.clip).name)); if (text == null) { return videoPlayer; } videoPlayer.url = text; videoPlayer.Prepare(); return videoPlayer; } public static string Format(string format, params object[] parts) { if (string.IsNullOrEmpty(format) || parts == null || parts.Length == 0) { return null; } foreach (object obj in parts) { if (obj == null || (obj is string text && StringHelper.IsEmpty(text))) { return null; } } try { return string.Format(format, parts); } catch (FormatException) { Logging.Warn("Format failed for template: '" + format + "'", addCallerFilePath: true, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Extensions\\LocalizationExtensions.cs"); return null; } } public static string FormatWith(this string format, params object[] parts) { return Format(format, parts); } } public class FontConfig { public string FontPackName; public string MainFont; public string TerminalFont; public string MuseumFont; public string SecretFont; public bool UseFallback; } public static class FontManager { public static bool TMPFontReady; public static TMP_FontAsset MeseumFontAsset; public static TMP_FontAsset TwinFont; private static TMP_FontAsset defaultMainFont; private static TMP_FontAsset defaultMuseumFont; private static TMP_FontAsset defaultTerminalFont; private static TMP_FontAsset defaultSecretFont; public static void Initialize() { LanguageManager.OnLanguageChanged += ApplyLanguageFonts; } public static void LoadFonts() { Logging.Message("Loading font resource bundle...", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\FontManager.cs"); AssetBundle obj = AssetBundle.LoadFromFile(Path.Combine(MainPatch.ModFolder, "basegameasset.bundle")); MeseumFontAsset = obj.LoadAsset<TMP_FontAsset>("GFSGaraldus SDF"); TwinFont = obj.LoadAsset<TMP_FontAsset>("VCR_OSD_MONO_TWINFONT"); TMPFontReady = true; } public static void LoadLangFonts(Lang lang) { if ((Object)(object)lang.FontBundle != (Object)null) { return; } string fontBundlePath = ConfigPaths.GetFontBundlePath(lang.Name); FontConfig fontConfig = JsonConvert.DeserializeObject<FontConfig>(File.ReadAllText(Path.Combine(fontBundlePath, "fontconfig.json"))); AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(fontBundlePath, fontConfig.FontPackName)); if ((Object)(object)val == (Object)null) { Logging.Warn("Failed to load language font bundle: " + fontBundlePath, addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\FontManager.cs"); return; } StringBuilder stringBuilder = new StringBuilder(); TMP_FontAsset[] array = val.LoadAllAssets<TMP_FontAsset>(); foreach (TMP_FontAsset val2 in array) { stringBuilder.AppendLine(((Object)val2).name); } Logging.Info(stringBuilder.ToString() ?? "", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\FontManager.cs"); lang.FontBundle = val; lang.UseFontFallback = fontConfig.UseFallback; lang.MainFontAsset = val.LoadAsset<TMP_FontAsset>(fontConfig.MainFont); lang.TerminalAsset = val.LoadAsset<TMP_FontAsset>(fontConfig.TerminalFont); lang.MuseumAsset = val.LoadAsset<TMP_FontAsset>(fontConfig.MuseumFont); lang.SecretTerminalAsset = val.LoadAsset<TMP_FontAsset>(fontConfig.SecretFont); } private static void ResolveFonts(Lang lang) { Lang lang2 = lang; if (lang2.MainFontAsset == null) { TMP_FontAsset val = (lang2.MainFontAsset = defaultMainFont); } lang2 = lang; if (lang2.MuseumAsset == null) { TMP_FontAsset val = (lang2.MuseumAsset = defaultMuseumFont); } lang2 = lang; if (lang2.TerminalAsset == null) { TMP_FontAsset val = (lang2.TerminalAsset = defaultTerminalFont); } lang2 = lang; if (lang2.SecretTerminalAsset == null) { TMP_FontAsset val = (lang2.SecretTerminalAsset = defaultSecretFont); } } private static void ApplyLanguageFonts(ValueChangedEvent<Lang> change) { if (!TMPFontReady) { return; } RemoveFallbacksOf(change.OldValue); Lang newValue = change.NewValue; if (newValue != null && !newValue.IsEnglish) { LoadLangFonts(newValue); ResolveFonts(newValue); if (newValue.UseFontFallback) { RegisterFallbacksForLoadedFonts(newValue); } } } public static void RefreshFallback() { Lang current = LanguageManager.Current; if (TMPFontReady && current != null && !current.IsEnglish && current.UseFontFallback) { RegisterFallbacksForLoadedFonts(current); } } private static void RegisterFallbacksForLoadedFonts(Lang lang) { TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); foreach (TMP_FontAsset val in array) { if ((Object)(object)val == (Object)null) { continue; } string text = ((Object)val).name?.ToLowerInvariant(); if (!string.IsNullOrEmpty(text) && !text.Contains("_alignedto_") && !((Object)(object)val == (Object)(object)lang.MainFontAsset) && !((Object)(object)val == (Object)(object)lang.MuseumAsset) && !((Object)(object)val == (Object)(object)lang.TerminalAsset) && !((Object)(object)val == (Object)(object)lang.SecretTerminalAsset)) { TMP_FontAsset fallback = null; if (text.Contains("tahoma")) { fallback = lang.TerminalAsset; } else if (text.Contains("bittypix")) { fallback = lang.SecretTerminalAsset; } else if (text.Contains("garaldus") || text.Contains("garamond") || text.Contains("museum")) { fallback = lang.MuseumAsset; } else if (text.Contains("vcr-osd-replayed")) { fallback = lang.MainFontAsset; } else if ((Object)(object)val == (Object)(object)TwinFont) { fallback = lang.MainFontAsset; } AddFallback(lang, val, fallback); } } } public static TMP_FontAsset GetTwinFont(string sourceFontName) { string text = sourceFontName?.ToLowerInvariant(); bool flag = !string.IsNullOrEmpty(text) && (text.Contains("garaldus") || text.Contains("garamond") || text.Contains("museum")); TMP_FontAsset val = (flag ? (MeseumFontAsset ?? TwinFont) : TwinFont); Lang current = LanguageManager.Current; if (current == null || current.IsEnglish || current.UseFontFallback) { return val; } object obj; if (!flag) { obj = current.MainFontAsset; if (obj == null) { return val; } } else { obj = current.MuseumAsset ?? current.MainFontAsset ?? val; } return (TMP_FontAsset)obj; } private static void AddFallback(Lang lang, TMP_FontAsset primary, TMP_FontAsset fallback) { if (!((Object)(object)primary == (Object)null) && !((Object)(object)fallback == (Object)null) && !((Object)(object)primary == (Object)(object)fallback)) { if (primary.fallbackFontAssetTable == null) { List<TMP_FontAsset> list = (primary.fallbackFontAssetTable = new List<TMP_FontAsset>()); } if (!primary.fallbackFontAssetTable.Contains(fallback)) { primary.fallbackFontAssetTable.Add(fallback); lang.AppliedFallbacks.Add((primary, fallback)); } } } private static void RemoveFallbacksOf(Lang lang) { if (lang == null) { return; } foreach (var (val, item) in lang.AppliedFallbacks) { if (val != null) { val.fallbackFontAssetTable?.Remove(item); } } lang.AppliedFallbacks.Clear(); } } public static class LegacyLanguageMigrator { public struct LegacyMigrationResult { public int MigratedLanguages; public int SkippedLanguages; public IReadOnlyList<string> Warnings; public string BackupDirectory; public LegacyMigrationResult(int migrated, int skipped, IReadOnlyList<string> warnings, string backupDirectory) { MigratedLanguages = migrated; SkippedLanguages = skipped; Warnings = warnings; BackupDirectory = backupDirectory; } } public static LegacyMigrationResult Migrate() { int num = 0; int num2 = 0; List<string> list = new List<string>(); if (!Directory.Exists(ConfigPaths.RootDirectory)) { return new LegacyMigrationResult(0, 0, Array.Empty<string>(), null); } string legacyBackupDirectory = ConfigPaths.LegacyBackupDirectory; MirrorLegacyLayout(legacyBackupDirectory); foreach (string item in Directory.EnumerateFiles(ConfigPaths.RootDirectory, "*.json", SearchOption.TopDirectoryOnly)) { try { if (MoveToPackage(item)) { num++; } } catch (Exception ex) { num2++; list.Add("Skipped '" + item + "': " + ex.Message); } } return new LegacyMigrationResult(num, num2, list, legacyBackupDirectory); } private static void MirrorLegacyLayout(string backupRoot) { Directory.CreateDirectory(backupRoot); foreach (string item in Directory.EnumerateFiles(ConfigPaths.RootDirectory, "*.json", SearchOption.TopDirectoryOnly)) { File.Copy(item, Path.Combine(backupRoot, Path.GetFileName(item)), overwrite: true); } CopyDirectoryIfExists(Path.Combine(ConfigPaths.RootDirectory, "audio"), Path.Combine(backupRoot, "audio")); CopyDirectoryIfExists(Path.Combine(ConfigPaths.RootDirectory, "textures"), Path.Combine(backupRoot, "textures")); } private static bool MoveToPackage(string sourceFile) { string text = JsonConvert.DeserializeObject<JsonFormat>(File.ReadAllText(sourceFile))?.metadata?.langName; if (text == "te-mp") { MoveTemplate(sourceFile); return false; } if (!IsSafeLanguageId(text)) { throw new InvalidDataException("Invalid or missing language id"); } string text2 = Path.Combine(ConfigPaths.LanguagesDirectory, text); string text3 = Path.Combine(text2, "language.json"); string legacyAudioDirectory = ConfigPaths.GetLegacyAudioDirectory(text); string legacyTextureDirectory = ConfigPaths.GetLegacyTextureDirectory(text); string text4 = Path.Combine(text2, "audio"); string text5 = Path.Combine(text2, "textures"); if (File.Exists(text3) || (Directory.Exists(legacyAudioDirectory) && Directory.Exists(text4)) || (Directory.Exists(legacyTextureDirectory) && Directory.Exists(text5))) { throw new IOException("The destination package already contains data"); } Directory.CreateDirectory(text2); MoveDirectoryIfExists(legacyAudioDirectory, text4); MoveDirectoryIfExists(legacyTextureDirectory, text5); File.Move(sourceFile, text3); return true; } private static void MoveTemplate(string sourceFile) { string text = Path.Combine(ConfigPaths.TemplatesDirectory, "language.json"); if (!File.Exists(text)) { Directory.CreateDirectory(ConfigPaths.TemplatesDirectory); File.Move(sourceFile, text); } } private static void CopyDirectoryIfExists(string source, string destination) { if (Directory.Exists(source)) { CopyDirectory(source, destination); } } private static void MoveDirectoryIfExists(string source, string destination) { if (Directory.Exists(source)) { Directory.Move(source, destination); } } private static void CopyDirectory(string source, string destination) { Directory.CreateDirectory(destination); foreach (string item in Directory.EnumerateFiles(source)) { File.Copy(item, Path.Combine(destination, Path.GetFileName(item)), overwrite: true); } foreach (string item2 in Directory.EnumerateDirectories(source)) { CopyDirectory(item2, Path.Combine(destination, Path.GetFileName(item2))); } } private static bool IsSafeLanguageId(string languageId) { if (!string.IsNullOrWhiteSpace(languageId) && languageId != "." && languageId != ".." && languageId.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 && languageId.IndexOf(Path.DirectorySeparatorChar) < 0) { return languageId.IndexOf(Path.AltDirectorySeparatorChar) < 0; } return false; } } public static class Logging { public static ManualLogSource UllLogger = Logger.CreateLogSource("ULL LOGGING"); public static void Debug(string text, bool addCallerFilePath = false, [CallerFilePath] string callerFilePath = "") { UllLogger.LogDebug((object)TryAddCallerName(text, addCallerFilePath, callerFilePath)); } public static void Message(string text, bool addCallerFilePath = false, [CallerFilePath] string callerFilePath = "") { UllLogger.LogMessage((object)TryAddCallerName(text, addCallerFilePath, callerFilePath)); } public static void Warn(string text, bool addCallerFilePath = false, [CallerFilePath] string callerFilePath = "") { UllLogger.LogWarning((object)TryAddCallerName(text, addCallerFilePath, callerFilePath)); } public static void Error(string text, bool addCallerFilePath = false, [CallerFilePath] string callerFilePath = "") { UllLogger.LogError((object)TryAddCallerName(text, addCallerFilePath, callerFilePath)); } public static void Fatal(string text, bool addCallerFilePath = false, [CallerFilePath] string callerFilePath = "") { UllLogger.LogFatal((object)TryAddCallerName(text, addCallerFilePath, callerFilePath)); } public static void Info(string text, bool addCallerFilePath = false, [CallerFilePath] string callerFilePath = "") { UllLogger.LogInfo((object)TryAddCallerName(text, addCallerFilePath, callerFilePath)); } private static string TryAddCallerName(string text, bool addCallerFilePath, string callerFilePath) { if (!addCallerFilePath) { return text; } return "[" + GetFileName(callerFilePath) + "] " + text; } private static string GetFileName(string callerFilePath) { return Path.GetFileNameWithoutExtension(callerFilePath); } } [BepInPlugin("clearwater.ultrakill.ultrakull", "clearwater.ultrakull.ultrakULL", "1.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class MainPatch : BaseUnityPlugin { private const string Guid = "clearwater.ultrakill.ultrakull"; private const string InternalName = "clearwater.ultrakull.ultrakULL"; internal const string InternalVersion = "1.3.0"; public static Dictionary<string, string> OptionModuleNames = new Dictionary<string, string> { ["com.eternalUnion.angryLevelLoader"] = "UltrakULL.angry" }; public static MainPatch Instance; public bool ready; private static readonly List<IPatchModule> modules = new List<IPatchModule>(); public static string ModFolder => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); public static string GetVersion() { return "1.3.0"; } public void DisableMod() { ready = false; } private void Awake() { Instance = this; Debug.unityLogger.filterLogType = (LogType)4; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)4; Logging.Warn("UltrakULL Loading... | Version v.1.3.0", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); try { InitializeLocalization(); Logging.Warn(" --- All done. Enjoy! ---", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); ready = true; SceneManager.sceneLoaded += OnSceneLoaded; } catch (Exception ex) { Logging.Fatal("An error occured while initialising!", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); Logging.Fatal(ex.ToString(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); Logging.Fatal("Scene name: " + SceneObjects.GetCurrentSceneName(), addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); ready = false; } } private static void InitializeLocalization() { Logging.Warn("--- Initializing config ---", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); Settings.InitializeConfig(); Logging.Warn("--- Loading shared font assets ---", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); FontManager.LoadFonts(); Logging.Warn("--- Registering language-change handlers ---", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); FontManager.Initialize(); TextMeshProFontSwap.Initialize(); TextureSwapper.Initialize(); UILayoutOverride.Initialize(); Logging.Warn("--- Loading languages and selecting the active language ---", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); LanguageManager.InitializeManager("1.3.0"); Logging.Warn("--- Installing game hooks ---", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); LoadPatches(); Logging.Warn("--- Loading optional modules ---", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); LoadPatchModules(); } private static void LoadPatches() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Harmony val = new Harmony("clearwater.ultrakill.ultrakull"); TriggerEngine.Init(val); Type[] types = typeof(MainPatch).Assembly.GetTypes(); foreach (Type type in types) { try { if (((MemberInfo)type).GetCustomAttribute<HarmonyPatch>() != null) { val.PatchAll(type); } } catch (Exception arg) { Logging.Error($"Failed to inspect {type}: {arg}", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); } } } private static void LoadPatchModules() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown foreach (KeyValuePair<string, string> kvp in OptionModuleNames) { if (!Chainloader.PluginInfos.ContainsKey(kvp.Key)) { continue; } try { Type[] types = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => assembly.GetName().Name == kvp.Value).GetTypes(); foreach (Type type in types) { if (typeof(IPatchModule).IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface) { IPatchModule val = (IPatchModule)Activator.CreateInstance(type); val.PatchAll(); modules.Add(val); Logging.Message(val.Name + " Loaded", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); } } } catch (Exception arg) { Logging.Error($"Failed to load optional module: {arg}", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); } } } private void ApplySceneLocalization(Scene scene, LoadSceneMode mode, bool clearObjectCaches, bool sceneEntry) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!ready || LanguageManager.CurrentLanguage == null) { Logging.Error("UltrakULL has been deactivated to prevent crashing. Check the console for any errors!", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Main.cs"); return; } if (clearObjectCaches) { SceneObjects.ClearObjectCaches(scene, mode); } FontManager.RefreshFallback(); GameObject inactiveRootObject = SceneObjects.GetInactiveRootObject("Canvas"); AngrySceneTracker.ReadCurrentScene(); Core.LocalizeScene(inactiveRootObject, sceneEntry); AudioSwapper.OnSceneLoaded(SceneObjects.GetCurrentSceneName()); RunDeferred(((Scene)(ref scene)).handle); } private async void RunDeferred(int sceneHandle) { await Task.Delay(250); Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).handle == sceneHandle) { SubtitledAudioSourcesReplacer.ReplaceSubsAndAudio(); TextureSwapper.Apply(); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) ApplySceneLocalization(scene, mode, clearObjectCaches: true, sceneEntry: true); } public void RefreshCurrentScene() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ApplySceneLocalization(SceneManager.GetActiveScene(), (LoadSceneMode)0, clearObjectCaches: false, sceneEntry: false); } } public static class LanguageOptions { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__6_0; internal void <BuildLanguagePage>b__6_0() { Application.OpenURL(ConfigPaths.LanguagesDirectory); } } private const string PageName = "Language Page"; private static TextMeshProUGUI navigationLabel; private static TextMeshProUGUI pageTitle; private static TextMeshProUGUI openFolderLabel; public static void Initialize(SettingsMenu settingsMenu) { Transform pageContainer = settingsMenu.pageContainer; if (!((Object)(object)pageContainer.Find("Language Page") != (Object)null)) { Logging.Message("Adding language option to options menu...", addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Menus\\LanguageOptions.cs"); Transform navigationRail = settingsMenu.navigationRail; GameObject gameObject = ((Component)navigationRail.Find("General")).gameObject; GameObject languagePage = BuildLanguagePage(((Component)settingsMenu).transform, pageContainer, gameObject); GameObject val = BuildButton(gameObject, navigationRail, "Language", LanguageManager.CurrentLanguage.options.language_title, null, resizeText: false); val.transform.SetSiblingIndex(7); navigationLabel = val.GetComponentInChildren<TextMeshProUGUI>(); ConfigureNavigationButton(settingsMenu, languagePage, val); RefreshText(); } } public static void RefreshText() { Option options = LanguageManager.CurrentLanguage.options; if ((Object)(object)navigationLabel != (Object)null) { ((TMP_Text)navigationLabel).text = options.language_title; } if ((Object)(object)pageTitle != (Object)null) { ((TMP_Text)pageTitle).text = "--" + options.language_languages + "--"; } if ((Object)(object)openFolderLabel != (Object)null) { ((TMP_Text)openFolderLabel).text = "<color=#03fc07>" + options.language_openLanguageFolder + "</color>"; } } private static GameObject BuildLanguagePage(Transform optionsMenu, Transform pages, GameObject buttonTemplate) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Expected O, but got Unknown //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Expected O, but got Unknown Transform val = pages.Find("General"); Transform val2 = val.Find("Scroll Rect"); Transform val3 = val2.Find("Contents"); GameObject val4 = new GameObject("Language Page", new Type[2] { typeof(RectTransform), typeof(CanvasRenderer) }); val4.transform.SetParent(pages, false); val4.GetComponent<RectTransform>().sizeDelta = new Vector2(600f, 800f); val4.SetActive(false); GameObject val5 = new GameObject("Scroll Rect", new Type[4] { typeof(RectTransform), typeof(ScrollRect), typeof(Image), typeof(Mask) }); val5.transform.SetParent(val4.transform, false); CopyRect(((Component)val2).GetComponent<RectTransform>(), val5.GetComponent<RectTransform>()); ((Graphic)val5.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.5f); val5.GetComponent<Mask>().showMaskGraphic = false; ScrollRect component = val5.GetComponent<ScrollRect>(); component.horizontal = false; component.vertical = true; component.verticalScrollbarVisibility = (ScrollbarVisibility)2; component.scrollSensitivity = 20f; GameObject val6 = new GameObject("Contents", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); val6.transform.SetParent(val5.transform, false); RectTransform component2 = val6.GetComponent<RectTransform>(); CopyRect(((Component)val3).GetComponent<RectTransform>(), component2); VerticalLayoutGroup component3 = val6.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component3).spacing = 10f; ((LayoutGroup)component3).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true; val6.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2; component.content = component2; Transform transform = val6.transform; Scrollbar val7 = Object.Instantiate<Scrollbar>(((Component)val).GetComponentsInChildren<Scrollbar>().First(), val4.transform); val7.direction = (Direction)2; component.verticalScrollbar = val7; GameObject obj = Object.Instantiate<GameObject>(((Component)optionsMenu.Find("Text")).gameObject, transform); ((Object)obj).name = "Title"; pageTitle = obj.GetComponent<TextMeshProUGUI>(); ((TMP_Text)pageTitle).alignment = (TextAlignmentOptions)514; ((TMP_Text)pageTitle).fontSize = 24f; ((TMP_Text)pageTitle).rectTransform.sizeDelta = new Vector2(400f, 50f); foreach (KeyValuePair<string, Lang> allLanguage in LanguageManager.allLanguages) { string languageId = allLanguage.Key; BuildButton(buttonTemplate, transform, languageId, allLanguage.Value.DisplayName, (UnityAction)delegate { SelectLanguage(languageId); }, resizeText: true, (Vector2?)new Vector2(160f, 40f)); } string empty = string.Empty; object obj2 = <>c.<>9__6_0; if (obj2 == null) { UnityAction val8 = delegate { Application.OpenURL(ConfigPaths.LanguagesDirectory); }; <>c.<>9__6_0 = val8; obj2 = (object)val8; } openFolderLabel = BuildButton(buttonTemplate, transform, "openLangFolder", empty, (UnityAction)obj2).GetComponentInChildren<TextMeshProUGUI>(); return val4; } private static GameObject BuildButton(GameObject template, Transform parent, string name, string label, UnityAction onClick = null, bool resizeText = true, Vector2? size = null) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0042: 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_0087: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(template, parent); ((Object)obj).name = name; RectTransform component = obj.GetComponent<RectTransform>(); ((Transform)component).localPosition = Vector3.zero; ((Transform)component).localRotation = Quaternion.identity; ((Transform)component).localScale = Vector3.one; if (size.HasValue) { component.sizeDelta = size.Value; } Button component2 = obj.GetComponent<Button>(); component2.onClick = new ButtonClickedEvent(); if (onClick != null) { ((UnityEvent)component2.onClick).AddListener(onClick); } ((Selectable)component2).interactable = true; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component2).navigation = navigation; TextMeshProUGUI componentInChildren = obj.GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).text = label; ((TMP_Text)componentInChildren).richText = true; ((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)514; ((TMP_Text)componentInChildren).enableAutoSizing = resizeText; if (resizeText) { ((TMP_Text)componentInChildren).fontSizeMin = 10f; ((TMP_Text)componentInChildren).fontSizeMax = 36f; } } obj.SetActive(true); return obj; } private static void SelectLanguage(string languageId) { Logging.Message("Selected language: " + languageId, addCallerFilePath: false, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Menus\\LanguageOptions.cs"); LanguageManager.TrySwitchLanguage(languageId); } private static void ConfigureNavigationButton(SettingsMenu settingsMenu, GameObject languagePage, GameObject navigationButton) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown ButtonHighlightParent highlight = ((Component)settingsMenu.navigationRail).GetComponent<ButtonHighlightParent>(); Button component = navigationButton.GetComponent<Button>(); Image image = navigationButton.GetComponent<Image>(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { ButtonHighlightParent obj = highlight; if (obj != null) { obj.ChangeButton(image); } settingsMenu.SetActivePage(languagePage); }); RegisterNavigationButton(highlight, image); } private static void RegisterNavigationButton(ButtonHighlightParent highlight, Image image) { if (highlight?.buttons != null && !highlight.buttons.Contains(image)) { TMP_Text componentInChildren = ((Component)image).GetComponentInChildren<TMP_Text>(); int num = highlight.buttons.Length; Array.Resize(ref highlight.buttons, num + 1); Array.Resize(ref highlight.buttonTexts, num + 1); Array.Resize(ref highlight.buttonSprites, num + 1); highlight.buttons[num] = image; highlight.buttonTexts[num] = componentInChildren; highlight.buttonSprites[num] = image.sprite; } } private static void CopyRect(RectTransform source, RectTransform target) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) target.anchorMin = source.anchorMin; target.anchorMax = source.anchorMax; target.pivot = source.pivot; target.anchoredPosition = source.anchoredPosition; target.sizeDelta = source.sizeDelta; } } public static class Settings { public static ConfigEntry<string> lastLanguage; public static ConfigEntry<bool> activeDubbing; public static ConfigFile configFile; public static void InitializeConfig() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown configFile = new ConfigFile(ConfigPaths.SettingsFile, true); lastLanguage = configFile.Bind<string>("General", "LastLanguage", "en-GB", (ConfigDescription)null); activeDubbing = configFile.Bind<bool>("General", "activeDubbing", false, (ConfigDescription)null); } } internal static class StaticBatchAtlasSwapper { private readonly struct Template { public readonly string Name; public readonly int Width; public readonly int Height; public readonly Color32[] Pixels; public Template(string name, int width, int height, Color32[] pixels) { Name = name; Width = width; Height = height; Pixels = pixels; } } private sealed class AtlasState(Texture2D texture, Color32[] originalPixels) { public readonly Texture2D Texture = texture; public readonly Color32[] OriginalPixels = originalPixels; public readonly List<(string Name, RectInt Rect)> Regions = new List<(string, RectInt)>(); } private readonly struct FeaturePoint { public readonly int X; public readonly int Y; public readonly Color32 Color; public readonly int Contrast; public FeaturePoint(int x, int y, Color32 color, int contrast) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) X = x; Y = y; Color = color; Contrast = contrast; } } private static readonly List<Template> pendingTemplates = new List<Template>(); private static readonly Dictionary<Texture2D, AtlasState> atlases = new Dictionary<Texture2D, AtlasState>(); private static readonly HashSet<string> diagnostics = new HashSet<string>(); private static int optimizerId; private static bool resolving; internal static void Capture(StaticSceneOptimizer optimizer) { ReleaseAtlases(); pendingTemplates.Clear(); TextureSwapper.RestoreMutatedTextures(); optimizerId = (((Object)(object)optimizer != (Object)null) ? ((Object)optimizer).GetInstanceID() : 0); if ((Object)(object)optimizer == (Object)null || LanguageManager.IsEnglish) { return; } HashSet<Texture2D> seenBefore = new HashSet<Texture2D>(); List<MeshRenderer> staticMRends = optimizer.staticMRends; if (staticMRends == null) { WarnOnce("no-renderers", "StaticSceneOptimizer.staticMRends is null; cannot capture pre-batch texture names."); return; } foreach (MeshRenderer item2 in staticMRends) { CaptureRenderer(item2); } Logging.Message($"Captured {pendingTemplates.Count} named " + $"pre-batch template(s) from {staticMRends.Count} renderer(s).", addCallerFilePath: true, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Textures\\AtlasBatchSwapper.cs"); void CaptureMaterial(Material material) { foreach (var mainTexture in GetMainTextures(material)) { Texture2D item = mainTexture.Texture; Texture2D originalTexture = TextureSwapper.GetOriginalTexture(item); Texture2D val = (((Object)(object)originalTexture != (Object)null) ? originalTexture : item); string text = (((Object)(object)originalTexture != (Object)null) ? ((Object)originalTexture).name : ((Object)item).name); if (seenBefore.Add(item) && TextureSwapper.TryGetFile(text, out var _)) { Color32[] array = ReadPixels((Texture)(object)val); if (array == null) { WarnOnce($"template-read:{((Object)item).GetInstanceID()}", "Cannot read source template " + $"'{text}' ({((Texture)val).width}x{((Texture)val).height})."); } else { pendingTemplates.Add(new Template(text, ((Texture)val).width, ((Texture)val).height, array)); } } } } void CaptureRenderer(MeshRenderer renderer) { if (!((Object)(object)renderer == (Object)null)) { Material[] sharedMaterials = ((Renderer)renderer).sharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { CaptureMaterial(sharedMaterials[i]); } } } } private static void ReleaseAtlases() { foreach (AtlasState value in atlases.Values) { if ((Object)(object)value.texture != (Object)null && value.originalPixels.Length == ((Texture)value.texture).width * ((Texture)value.texture).height) { value.texture.SetPixels32(value.originalPixels); value.texture.Apply(false, false); } } atlases.Clear(); } internal static IEnumerator Resolve(StaticSceneOptimizer optimizer) { if (resolving || (Object)(object)optimizer == (Object)null || ((Object)optimizer).GetInstanceID() != optimizerId || pendingTemplates.Count == 0 || LanguageManager.IsEnglish) { yield break; } resolving = true; List<AtlasState> sceneAtlases = GetOrCreateAtlases(optimizer); if (sceneAtlases.Count == 0) { WarnOnce($"missing-atlas:{optimizerId}", "Optimizer finished, but no runtime Texture2D was found on its batch materials."); resolving = false; yield break; } Template[] pending = pendingTemplates.ToArray(); HashSet<string> found = new HashSet<string>(); foreach (AtlasState sceneAtlas in sceneAtlases) { Color32[] source = sceneAtlas.originalPixels; int sourceWidth = ((Texture)sceneAtlas.texture).width; int sourceHeight = ((Texture)sceneAtlas.texture).height; Task<List<(Template Template, RectInt Rect)>> task = Task.Run(() => FindRegions(source, sourceWidth, sourceHeight, pending)); while (!task.IsCompleted) { yield return null; } if (task.IsFaulted) { Logging.Error("Region search failed for " + $"{sourceWidth}x{sourceHeight} atlas: {task.Exception}", addCallerFilePath: true, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Textures\\AtlasBatchSwapper.cs"); continue; } foreach (var item2 in task.Result) { RectInt item = item2.Rect; if (((RectInt)(ref item)).width > 0) { sceneAtlas.Regions.Add((item2.Template.Name, item2.Rect)); found.Add(item2.Template.Name); string[] obj = new string[5] { "Located '", item2.Template.Name, "' at ", null, null }; item = item2.Rect; object arg = ((RectInt)(ref item)).x; item = item2.Rect; object arg2 = ((RectInt)(ref item)).y; item = item2.Rect; obj[3] = $"({arg},{arg2}) {((RectInt)(ref item)).width}x"; item = item2.Rect; obj[4] = $"{((RectInt)(ref item)).height}."; Logging.Message(string.Concat(obj), addCallerFilePath: true, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Textures\\AtlasBatchSwapper.cs"); } } } Template[] array = pending; for (int num = 0; num < array.Length; num++) { Template template = array[num]; if (!found.Contains(template.Name)) { WarnOnce($"not-found:{optimizerId}:{template.Name}", "'" + template.Name + "' was not found in " + $"{sceneAtlases.Count} runtime atlas(es)."); } } pendingTemplates.Clear(); resolving = false; Apply(); } internal static void Apply() { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (AtlasState value in atlases.Values) { if ((Object)(object)value.texture == (Object)null || value.originalPixels.Length != ((Texture)value.texture).width * ((Texture)value.texture).height) { continue; } value.texture.SetPixels32(value.originalPixels); if (LanguageManager.IsEnglish) { value.texture.Apply(false, false); continue; } foreach (var region in value.Regions) { if (!TextureSwapper.TryGetFile(region.Name, out var file)) { continue; } int width = file.Width; RectInt item = region.Rect; if (width == ((RectInt)(ref item)).width) { int height = file.Height; item = region.Rect; if (height == ((RectInt)(ref item)).height) { try { Color32[] array = DecodePixels(file.Bytes); if (array != null) { Texture2D texture = value.texture; item = region.Rect; int x = ((RectInt)(ref item)).x; item = region.Rect; int y = ((RectInt)(ref item)).y; item = region.Rect; int width2 = ((RectInt)(ref item)).width; item = region.Rect; texture.SetPixels32(x, y, width2, ((RectInt)(ref item)).height, array); num++; } } catch (Exception ex) { WarnOnce("apply:" + region.Name + ":" + file.Path, "Failed to apply '" + file.Path + "': " + ex.Message); } continue; } } string key = "size:" + region.Name + ":" + file.Path; string[] obj = new string[6] { "Cannot put '", file.Path, "' into cached ", $"region '{region.Name}': PNG is {file.Width}x{file.Height}, region is ", null, null }; item = region.Rect; object arg = ((RectInt)(ref item)).width; item = region.Rect; obj[4] = $"{arg}x{((RectInt)(ref item)).height}. Atlas layout "; obj[5] = "must not be resized."; WarnOnce(key, string.Concat(obj)); } value.texture.Apply(false, false); } if (num > 0) { Logging.Message($"Applied {num} cached region(s) to " + $"{atlases.Count} atlas(es) without rescanning.", addCallerFilePath: true, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Textures\\AtlasBatchSwapper.cs"); } } private static List<AtlasState> GetOrCreateAtlases(StaticSceneOptimizer optimizer) { List<AtlasState> list = new List<AtlasState>(); HashSet<Texture2D> hashSet = new HashSet<Texture2D>(); Material[] array = (Material[])(object)new Material[2] { optimizer.batchMaterialOutdoors, optimizer.batchMaterialEnvironment }; foreach (Material val in array) { foreach (var mainTexture in GetMainTextures(val)) { if (!hashSet.Add(mainTexture.Texture)) { continue; } if (atlases.TryGetValue(mainTexture.Texture, out var value)) { list.Add(value); continue; } Color32[] array2 = ReadPixels((Texture)(object)mainTexture.Texture); if (array2 != null) { AtlasState atlasState = new AtlasState(mainTexture.Texture, array2); atlases[mainTexture.Texture] = atlasState; list.Add(atlasState); Logging.Message("Runtime atlas candidate: material '" + ((Object)val).name + "', " + mainTexture.Property + ", texture '" + ((Object)mainTexture.Texture).name + "' " + $"{((Texture)mainTexture.Texture).width}x{((Texture)mainTexture.Texture).height}.", addCallerFilePath: true, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Textures\\AtlasBatchSwapper.cs"); } } } return list; } private static IEnumerable<(string Property, Texture2D Texture)> GetMainTextures(Material material) { if ((Object)(object)material == (Object)null || (Object)(object)material.shader == (Object)null) { yield break; } int count = material.shader.GetPropertyCount(); for (int i = 0; i < count; i++) { if ((int)material.shader.GetPropertyType(i) != 4) { continue; } string propertyName = material.shader.GetPropertyName(i); if (!(propertyName != "_MainTex") || !(propertyName != "_BaseMap") || !(propertyName != "_MainTexture")) { Texture texture = material.GetTexture(propertyName); Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (val != null) { yield return (Property: propertyName, Texture: val); } } } } private static List<(Template Template, RectInt Rect)> FindRegions(Color32[] source, int sourceWidth, int sourceHeight, Template[] templates) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) List<(Template, RectInt)> list = new List<(Template, RectInt)>(templates.Length); foreach (Template template in templates) { list.Add((template, FindRegion(source, sourceWidth, sourceHeight, template))); } return list; } private static RectInt FindRegion(Color32[] source, int sourceWidth, int sourceHeight, Template template) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (template.Width > sourceWidth || template.Height > sourceHeight) { return default(RectInt); } FeaturePoint[] featurePoints = GetFeaturePoints(template); int num = sourceWidth - template.Width; int num2 = sourceHeight - template.Height; for (int i = 0; i <= num2; i++) { for (int j = 0; j <= num; j++) { if (MatchesFeatures(source, sourceWidth, j, i, featurePoints) && MatchesImage(source, sourceWidth, j, i, template)) { return new RectInt(j, i, template.Width, template.Height); } } } return default(RectInt); } private static FeaturePoint[] GetFeaturePoints(Template template) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) long num = 0L; long num2 = 0L; long num3 = 0L; long num4 = 0L; Color32[] pixels = template.Pixels; foreach (Color32 val in pixels) { num += val.r; num2 += val.g; num3 += val.b; num4 += val.a; } int num5 = template.Pixels.Length; int num6 = (int)(num / num5); int num7 = (int)(num2 / num5); int num8 = (int)(num3 / num5); int num9 = (int)(num4 / num5); List<FeaturePoint> list = new List<FeaturePoint>(25); for (int j = 0; j < 5; j++) { for (int k = 0; k < 5; k++) { int num10 = k * (template.Width - 1) / 4; int num11 = j * (template.Height - 1) / 4; Color32 val2 = template.Pixels[num11 * template.Width + num10]; int contrast = Math.Abs(val2.r - num6) + Math.Abs(val2.g - num7) + Math.Abs(val2.b - num8) + Math.Abs(val2.a - num9); list.Add(new FeaturePoint(num10, num11, val2, contrast)); } } list.Sort((FeaturePoint a, FeaturePoint b) => b.Contrast.CompareTo(a.Contrast)); return list.GetRange(0, Math.Min(8, list.Count)).ToArray(); } private static bool MatchesFeatures(Color32[] source, int sourceWidth, int x, int y, FeaturePoint[] features) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < features.Length; i++) { FeaturePoint featurePoint = features[i]; Color32 val = source[(y + featurePoint.Y) * sourceWidth + x + featurePoint.X]; if (!((object)featurePoint.Color/*cast due to .constrained prefix*/).Equals((object?)val)) { return false; } } return true; } private unsafe static bool MatchesImage(Color32[] source, int sourceWidth, int x, int y, Template template) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < template.Height; i++) { for (int j = 0; j < template.Width; j++) { Color32 val = template.Pixels[i * template.Width + j]; Color32 val2 = source[(y + i) * sourceWidth + x + j]; if (!((object)(*(Color32*)(&val))/*cast due to .constrained prefix*/).Equals((object?)val2)) { return false; } } } return true; } private static Color32[] DecodePixels(byte[] png) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); try { return ImageConversion.LoadImage(val, png, false) ? val.GetPixels32() : null; } catch (Exception) { return null; } finally { Object.Destroy((Object)(object)val); } } private static Color32[] ReadPixels(Texture source) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) RenderTexture val = null; RenderTexture active = RenderTexture.active; Texture2D val2 = null; try { val = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)0); Graphics.Blit(source, val); RenderTexture.active = val; val2 = new Texture2D(source.width, source.height, (TextureFormat)4, false); val2.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0); val2.Apply(); return val2.GetPixels32(); } catch (Exception ex) { WarnOnce($"read:{((Object)source).GetInstanceID()}", "Failed to read '" + ((Object)source).name + "': " + ex.Message); return null; } finally { RenderTexture.active = active; if ((Object)(object)val != (Object)null) { RenderTexture.ReleaseTemporary(val); } if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } } private static void WarnOnce(string key, string message) { if (diagnostics.Add(key)) { Logging.Warn(message, addCallerFilePath: true, "H:\\C#Project\\UltrakULL-1\\src\\Core\\Textures\\AtlasBatchSwapper.cs"); } } } [HarmonyPatch(typeof(StaticSceneOptimizer))] internal static class StaticSceneOptimizerPatch { [HarmonyPatch("Start")] [HarmonyPrefix] private static void Prefix(StaticSceneOptimizer __instance) { StaticBatchAtlasSwapper.Capture(__instance); } [HarmonyPatch("Start")] [HarmonyPostfix] private static void Postfix(StaticSceneOptimizer __instance) { if ((Object)(object)MainPatch.Instance != (Object)null) { ((MonoBehaviour)MainPatch.Instance).StartCoroutine(ApplyAfterOptimizer(__instance)); } } private static IEnumerator ApplyAfterOptimizer(StaticSceneOptimizer optimizer) { yield return null; yield return null; yield return StaticBatchAtlasSwapper.Resolve(optimizer); } } internal sealed class ReplacementCache<T> where T : Object { private readonly struct Replacement { public readonly T Original; public readonly T Current; public Replacement(T original, T current) { Original = original; Current = current; } } private readonly Dictionary<T, Replacement> replacements = new Dictionary<T, Replacement>(); private readonly HashSet<T> active = new HashSet<T>(); private readonly List<T> stale = new List<T>(); public T GetOriginal(T value) { if (!((Object)(object)value != (Object)null) || !replacements.TryGetValue(value, out var value2)) { return value; } return value2.Original; } public bool TryGetCurrent(T original, out T current) { Replacement value; bool flag = replacements.TryGetValue(original, out value); current = (flag ? value.Current : default(T)); return (Object)(object)current != (Object)null; } public bool IsReplacement(T value) { if ((Object)(object)value != (Object)null && replacements.TryGetValue(value, out var value2)) { return (Object)(object)value2.Current == (Object)(object)value; } return false; } public void Add(T original, T replacement, bool cache = true) { Replacement value = new Replacement(original, replacement); if (cache) { replacements[original] = value; } replacements[replacement] = value; active.Add(replacement); } public void QueueCleanup() { foreach (T item in active) { Replacement replacement = replacements[item]; if (replacements.TryGetValue(replacement.Original, out var value) && (Object)(object)value.Current == (Object)(object)item) { replacements.Remove(replacement.Original); } } stale.AddRange(active); active.Clear(); } public void Cleanup(Action<T> destroy) { foreach (T item in stale) { replacements.Remove(item); if (!((Object)(object)item == (Object)null)) { destroy(item); } } stale.Clear(); } } public static class TextureSwapper { internal readonly struct ReplacementFile { public readonly string Path; public readonly byte[] Bytes; public readonly int Width; public readonly int Height; public ReplacementFile(string path, byte[] bytes, int width, int height) { Path = path; Bytes = bytes; Width = width; Height = height; } } private readonly struct MutatedTexture { public readonly byte[] OriginalPng; public readonly FilterMode FilterMode; public readonly TextureWrapMode WrapMode; public readonly int AnisoLevel; public MutatedTexture(byte[] originalPng, FilterMode filterMode, TextureWrapMode wrapMode, int anisoLevel) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) OriginalPng = originalPng; FilterMode = filterMode; WrapMode = wrapMode; AnisoLevel = anisoLevel; } } private static readonly ReplacementCache<Sprite> spriteReplacementCache = new ReplacementCache<Sprite>(); private static readonly ReplacementCache<Texture> textureReplacementCache = new ReplacementCache<Texture>(); private static readonly Dictionary<(Material, string), Texture2D> materialTextureCache = new Dictionary<(Material, string), Texture2D>(); private static readonly HashSet<string> diagnostics = new HashSet<string>(); private static readonly Dictionary<string, int> replacementCount = new Dictionary<string, int> { ["Image slot(s)"] = 0, ["StyleHUD rank sprite(s)"] = 0, ["RawImage(s)"] = 0, ["SpriteRenderer(s)"] = 0, ["SpriteMask(s)"] = 0, ["Renderer property block slot(s)"] = 0, ["material property(s)"] = 0, ["loaded Texture2D object(s)"] = 0 }; private static bool scanInProgress; private static readonly Dictionary<string, ReplacementFile> files = new Dictionary<string, ReplacementFile>(); private static readonly Dictionary<Texture2D, MutatedTexture> mutatedTextures = new Dictionary<Texture2D, MutatedTexture>(); private static Sprite GetDesiredSprite(Sprite value) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)value == (Object)null) { return null; } Sprite original = spriteReplacementCache.GetOriginal(value); if (LanguageManager.IsEnglish || !TryGetFile(((Object)original).name, out var file)) { return original; } if (spriteReplacementCache.TryGetCurrent(original, out var current)) { return current; } Rect rect = original.rect; int num = Mathf.RoundToInt(((Rect)(ref rect)).width); int num2 = Mathf.RoundToInt(((Rect)(ref rect)).height); if (num <= 0 || num2 <= 0) { WarnOnce($"sprite-empty:{((Object)original).GetInstanceID()}", $"Invalid sprite rect '{((Object)original).name}': {num}x{num2}."); return original; } float num3 = (float)file.Width / ((Rect)(ref rect)).width; float num4 = (float)file.Height / ((Rect)(ref rect)).height; float num5 = ((Rect)(ref rect)).width / ((Rect)(ref rect)).height; float num6 = (float)file.Width / (float)file.Height; if (!Mathf.Approximately(num5, num6)) { WarnOnce($"sprite-aspect:{((Object)original).GetInstanceID()}:{file.Path}", $"Aspect change '{((Object)original).name}': {num5:0.###} -> " + $"{num6:0.###} ({num}x{num2} -> {file.Width}x{file.Height})."); } Texture2D val = CreateTexture(file, (Texture)(object)original.texture); if ((Object)(object)val == (Object)null) { return original; } Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(original.pivot.x / ((Rect)(ref rect)).width, original.pivot.y / ((Rect)(ref rect)).height); Vector4 border = original.border; ((Vector4)(ref border))..ctor(border.x * num3, border.y * num4, border.z * num3, border.w * num4); Sprite val3; try { val3 = Sprite.Create(val, new Rect(0f, 0f, (float)file.Width, (float)file.Height), val2, original.pixelsPerUnit, 0u, (SpriteMeshType)0, border); } catch (Exception ex) { Object.Destroy((Object)(object)val); WarnOnce($"sprite-create:{((Object)original).GetInstanceID()}:{file.Path}", "Cannot create sprite '" + ((Object)original).name + "': " + ex.Message); return original; } ((Object)val3).name = ((Object)original).name; spriteReplacementCache.Add(original, val3); return val3; } private static Texture GetDesiredTexture(Texture value) { if ((Object)(object)value == (Object)null) { return null; } Texture original = textureReplacementCache.GetOriginal(value); if (!LanguageManager.IsEnglish) { Texture2D val = (Texture2D)(object)((original is Texture2D) ? original : null); if (val != null && TryGetFile(((Object)original).name, out var file)) { if (textureReplacementCache.TryGetCurrent((Texture)(object)val, out var current)) { return current; } Texture2D val2 = CreateTexture(file, (Texture)(object)val); if ((Object)(object)val2 == (Object)null) { return original; } textureReplacementCache.Add(original, (Texture)(object)val2); return (Texture)(object)val2; } } return original; } private static Texture GetCanonicalTexture(Texture value) { return textureReplacementCache.GetOriginal(value); } internal static Texture2D GetOriginalTexture(Texture2D current) { Texture original = textureReplacementCache.GetOriginal((Texture)(object)current); Texture2D val = (Texture2D)(object)((original is Texture2D) ? original : null); if (!((Object)(object)val != (Object)null) || !((Object)(object)val != (Object)(object)current)) { return null; } return val; } private static Texture GetDesiredMaterialTexture(Material material, string property, Texture original, ReplacementFile file) { if (LanguageManager.IsEnglish) { return original; } (Material, string) key = (material, property); if (materialTextureCache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return (Texture)(object)value; } Texture2D val = CreateTexture(file, original); if ((Object)(object)val == (Object)null) { return original; } materialTextureCache[key] = val; textureReplacementCache.Add(original, (Texture)(object)val, cache: false); return (Texture)(object)val; } private static bool IsUnusableAssetName(string name) { if (!string.IsNullOrWhiteSpace(name)) { return string.Equals(name.Trim(), "untitled"); } return true; } private static bool IsMainTextureProperty(string property) { if (!string.Equals(property, "_MainTex") && !string.Equals(property, "_BaseMap")) { return string.Equals(property, "_MainTexture"); } return true; } private static Texture2