Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Patchwork v2.5.0
Patchwork.dll
Decompiled 5 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GlobalEnums; using HarmonyLib; using Microsoft.CodeAnalysis; using MonoMod.Utils; using Patchwork; using Patchwork.GUI; using Patchwork.Handlers; using Patchwork.Util; using Patchwork.Watchers; using TeamCherry.Cinematics; using TeamCherry.Localization; using Unity.Mathematics; using UnityEngine; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Patchwork")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("2.5.0.0")] [assembly: AssemblyInformationalVersion("2.5.0+a6a806ede1354aafdd5f4c19319739085d2d89bc")] [assembly: AssemblyProduct("Patchwork")] [assembly: AssemblyTitle("Patchwork")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.5.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } [HarmonyPatch] public static class AnimationController { [CompilerGenerated] private static class <>O { public static WindowFunction <0>__AnimationControllerWindow; } private static Vector2 scrollPosition = Vector2.zero; private static Rect windowRect; private static bool Paused = false; private static bool FrameChangeRequested = false; private static bool Frozen = false; private static Vector3 FrozenPosition; private static readonly Dictionary<string, bool> ShowAnimationDropdown = new Dictionary<string, bool>(); private static readonly Dictionary<string, tk2dSpriteAnimator> Animators = new Dictionary<string, tk2dSpriteAnimator>(); public static string SelectedAnimator { get; private set; } = null; public static void RegisterAnimator(tk2dSpriteAnimator animator) { if ((Object)(object)animator != (Object)null && !Animators.ContainsKey(((Object)((Component)animator).gameObject).name)) { Animators.Add(((Object)((Component)animator).gameObject).name, animator); } } public static void ClearAnimators() { Animators.Clear(); } public static void ApplyPatches(Harmony harmony) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Expected O, but got Unknown //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Expected O, but got Unknown //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "Play", (Type[])null, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "Play", new Type[1] { typeof(string) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayWithNamePatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "Play", new Type[1] { typeof(tk2dSpriteAnimationClip) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayWithClipPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "PlayFromFrame", new Type[1] { typeof(int) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayFromFramePatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "PlayFromFrame", new Type[2] { typeof(string), typeof(int) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayFromFrameWithNamePatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "PlayFromFrame", new Type[2] { typeof(tk2dSpriteAnimationClip), typeof(int) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayFromFrameWithClipPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "PlayFrom", new Type[1] { typeof(float) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayFromPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "PlayFrom", new Type[2] { typeof(string), typeof(float) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayFromWithNamePatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "PlayFrom", new Type[2] { typeof(tk2dSpriteAnimationClip), typeof(float) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayFromWithClipPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteAnimator), "Play", new Type[3] { typeof(tk2dSpriteAnimationClip), typeof(float), typeof(float) }, (Type[])null), new HarmonyMethod(typeof(AnimationController), "PlayOverrideFpsPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool PlayPatchInternal(tk2dSpriteAnimator __instance) { if ((Object)(object)__instance != (Object)null) { RegisterAnimator(__instance); if (SelectedAnimator == ((Object)((Component)__instance).gameObject).name && Paused && !FrameChangeRequested) { return false; } } return true; } public static bool PlayPatch(tk2dSpriteAnimator __instance) { return PlayPatchInternal(__instance); } public static bool PlayWithNamePatch(tk2dSpriteAnimator __instance, string name) { return PlayPatchInternal(__instance); } public static bool PlayWithClipPatch(tk2dSpriteAnimator __instance, tk2dSpriteAnimationClip clip) { return PlayPatchInternal(__instance); } public static bool PlayFromFramePatch(tk2dSpriteAnimator __instance, int frame) { return PlayPatchInternal(__instance); } public static bool PlayFromFrameWithNamePatch(tk2dSpriteAnimator __instance, string name, int frame) { return PlayPatchInternal(__instance); } public static bool PlayFromFrameWithClipPatch(tk2dSpriteAnimator __instance, tk2dSpriteAnimationClip clip, int frame) { return PlayPatchInternal(__instance); } public static bool PlayFromPatch(tk2dSpriteAnimator __instance, float clipStartTime) { return PlayPatchInternal(__instance); } public static bool PlayFromWithNamePatch(tk2dSpriteAnimator __instance, string name, float clipStartTime) { return PlayPatchInternal(__instance); } public static bool PlayFromWithClipPatch(tk2dSpriteAnimator __instance, tk2dSpriteAnimationClip clip, float clipStartTime) { return PlayPatchInternal(__instance); } public static bool PlayOverrideFpsPatch(tk2dSpriteAnimator __instance, tk2dSpriteAnimationClip clip, float clipStartTime, float overrideFps) { return PlayPatchInternal(__instance); } public static void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_01df: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(Plugin.Config.AnimationControllerPauseKey) && SelectedAnimator != null) { Paused = !Paused; if (Animators.TryGetValue(SelectedAnimator, out var value)) { if (Paused) { value.Pause(); } else { value.Resume(); } } } if (Input.GetKeyDown(Plugin.Config.AnimationControllerFreezeKey) && SelectedAnimator != null) { Frozen = !Frozen; if (Animators.TryGetValue(SelectedAnimator, out var value2)) { FrozenPosition = ((Component)value2).gameObject.transform.position; } } if (Paused && SelectedAnimator != null && Animators.TryGetValue(SelectedAnimator, out var value3)) { if (Input.GetKeyDown(Plugin.Config.AnimationControllerNextFrameKey)) { int num = value3.CurrentFrame + 1; if (num >= value3.CurrentClip.frames.Length) { num = 0; } FrameChangeRequested = true; value3.PlayFromFrame(num); value3.UpdateAnimation(Time.deltaTime); FrameChangeRequested = false; } if (Input.GetKeyDown(Plugin.Config.AnimationControllerPrevFrameKey)) { int num2 = value3.CurrentFrame - 1; if (num2 < 0) { num2 = value3.CurrentClip.frames.Length - 1; } FrameChangeRequested = true; value3.PlayFromFrame(num2); value3.UpdateAnimation(Time.deltaTime); FrameChangeRequested = false; } } if (Frozen && SelectedAnimator != null && Animators.TryGetValue(SelectedAnimator, out var value4)) { ((Component)value4).gameObject.transform.position = FrozenPosition; } for (int i = 0; i < Animators.Count; i++) { KeyValuePair<string, tk2dSpriteAnimator> keyValuePair = new List<KeyValuePair<string, tk2dSpriteAnimator>>(Animators)[i]; string key = keyValuePair.Key; tk2dSpriteAnimator value5 = keyValuePair.Value; if ((Object)(object)value5 == (Object)null || (Object)(object)((Component)value5).gameObject == (Object)null || !((Component)value5).gameObject.activeSelf || value5.CurrentClip == null) { Animators.Remove(key); if (SelectedAnimator == key) { SelectedAnimator = null; } } else if (value5.CurrentFrame < 0 || value5.CurrentFrame >= value5.CurrentClip.frames.Length) { Animators.Remove(key); if (SelectedAnimator == key) { SelectedAnimator = null; } } } } private static void SelectAnimator(tk2dSpriteAnimator animator) { Frozen = false; if (Paused && SelectedAnimator != null && Animators.TryGetValue(SelectedAnimator, out var value)) { value.Paused = false; Paused = false; } SelectedAnimator = ((Object)((Component)animator).gameObject).name; } public static void DrawAnimationController() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown if (((Rect)(ref windowRect)).width == 0f) { windowRect = new Rect((float)(Screen.width - Screen.width / 3 - 10), 10f, (float)(Screen.width / 3), (float)(Screen.height / 3)); } Rect val = windowRect; object obj = <>O.<0>__AnimationControllerWindow; if (obj == null) { WindowFunction val2 = AnimationControllerWindow; <>O.<0>__AnimationControllerWindow = val2; obj = (object)val2; } windowRect = GUILayout.Window(6971, val, (WindowFunction)obj, "Patchwork Animation Controller", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinWidth(300f), GUILayout.MinHeight(200f) }); } private static void AnimationControllerWindow(int windowID) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) //IL_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); foreach (KeyValuePair<string, tk2dSpriteAnimator> animator in Animators) { string key = animator.Key; tk2dSpriteAnimator value = animator.Value; if ((Object)(object)value == (Object)null || (Object)(object)((Component)value).gameObject == (Object)null || !((Component)value).gameObject.activeSelf || value.CurrentClip == null || value.CurrentFrame < 0 || value.CurrentFrame >= value.CurrentClip.frames.Length) { continue; } int spriteId = value.CurrentClip.frames[value.CurrentFrame].spriteId; tk2dSpriteCollectionData spriteCollection = value.CurrentClip.frames[value.CurrentFrame].spriteCollection; if ((Object)(object)spriteCollection == (Object)null || spriteId < 0 || spriteId >= spriteCollection.spriteDefinitions.Length) { continue; } tk2dSpriteDefinition val = spriteCollection.spriteDefinitions[spriteId]; if (SelectedAnimator == key) { GUI.contentColor = Color.green; } else { GUI.contentColor = Color.white; } if (GUILayout.Button(key, Array.Empty<GUILayoutOption>())) { SelectAnimator(value); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(((Object)spriteCollection).name + "/" + ((Object)val.material).name.Split(' ')[0] + "/" + val.name, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (SelectedAnimator == key) { GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(value.CurrentClip.name + (ShowAnimationDropdown.GetValueOrDefault(key, defaultValue: false) ? " ▲" : " ▼"), Array.Empty<GUILayoutOption>())) { ShowAnimationDropdown[key] = !ShowAnimationDropdown.GetValueOrDefault(key, defaultValue: false); } if (ShowAnimationDropdown.GetValueOrDefault(key, defaultValue: false)) { tk2dSpriteAnimationClip[] clips = value.Library.clips; foreach (tk2dSpriteAnimationClip val2 in clips) { if (!string.IsNullOrEmpty(val2.name) && GUILayout.Button(val2.name, Array.Empty<GUILayoutOption>())) { Paused = true; value.Pause(); ShowAnimationDropdown[key] = false; FrameChangeRequested = true; value.Play(val2); value.UpdateAnimation(Time.deltaTime); FrameChangeRequested = false; } } } GUILayout.EndVertical(); } else { GUILayout.Label(value.CurrentClip.name, Array.Empty<GUILayoutOption>()); } if (Paused && SelectedAnimator == key) { Color contentColor = GUI.contentColor; GUI.contentColor = Color.red; GUILayout.Label("[PAUSED]", Array.Empty<GUILayoutOption>()); GUI.contentColor = contentColor; } if (Frozen && SelectedAnimator == key) { Color contentColor2 = GUI.contentColor; GUI.contentColor = Color.cyan; GUILayout.Label("[FROZEN]", Array.Empty<GUILayoutOption>()); GUI.contentColor = contentColor2; } GUILayout.Label($"[Frame {value.CurrentFrame + 1}/{value.CurrentClip.frames.Length}]", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); if (!(SelectedAnimator == key) || !GUILayout.Button("Edit Current Sprite", Array.Empty<GUILayoutOption>())) { continue; } string text = Path.Combine(SpriteLoader.LoadPath, ((Object)spriteCollection).name, ((Object)val.material).name.Split(' ')[0], val.name + ".png"); if (File.Exists(text)) { Process.Start(text); continue; } SpriteDumper.DumpSingleSprite(val, spriteCollection); if (!File.Exists(Path.Combine(SpriteDumper.DumpPath, ((Object)spriteCollection).name, ((Object)val.material).name.Split(' ')[0], val.name + ".png"))) { Plugin.Logger.LogError((object)("Failed to dump sprite for editing: " + ((Object)spriteCollection).name + "/" + ((Object)val.material).name.Split(' ')[0] + "/" + val.name)); } else { IOUtil.EnsureDirectoryExists(Path.Combine(SpriteLoader.LoadPath, ((Object)spriteCollection).name, ((Object)val.material).name.Split(' ')[0])); File.Copy(Path.Combine(SpriteDumper.DumpPath, ((Object)spriteCollection).name, ((Object)val.material).name.Split(' ')[0], val.name + ".png"), text, overwrite: true); Process.Start(text); } } GUILayout.EndVertical(); GUILayout.EndScrollView(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } } public class DialogueHandler { public static Dictionary<string, Dictionary<string, Dictionary<string, string>>> TextCache = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>(); public static string TextDumpPath => Path.Combine(Plugin.BasePath, "TextDumps"); public static string TextLoadPath => Path.Combine(Plugin.BasePath, "Text"); public static void DumpText() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) LanguageCode val = Language.CurrentLanguage(); string text = ((object)(LanguageCode)(ref val)).ToString(); foreach (object value in Enum.GetValues(typeof(SupportedLanguages))) { string text2 = value.ToString(); Plugin.Logger.LogInfo((object)("Dumping text for language code " + text2 + "...")); Language.SwitchLanguage(text2); int num = 0; int num2 = 0; foreach (string sheet in Language.GetSheets()) { IOUtil.EnsureDirectoryExists(Path.Combine(TextDumpPath, sheet)); string path = Path.Combine(TextDumpPath, sheet, text2 + ".yml"); using StreamWriter streamWriter = new StreamWriter(path); foreach (string key in Language.GetKeys(sheet)) { string text3 = Language.Get(key, sheet); streamWriter.WriteLine(key + ": \"" + text3.Replace("\"", "\\\"") + "\""); num++; } streamWriter.Flush(); streamWriter.Close(); num2++; } Plugin.Logger.LogInfo((object)$"Finished dumping text for language code {text2}. Dumped {num} keys in {num2} sheets."); } Language.SwitchLanguage(text); } public static void InvalidateCache(string sheet, string lang) { if (TextCache.ContainsKey(lang) && TextCache[lang].ContainsKey(sheet)) { Plugin.Logger.LogInfo((object)("Invalidating text cache for sheet: " + sheet + ", lang: " + lang)); TextCache[lang].Remove(sheet); } } public static void ApplyPatches(Harmony harmony) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(Language), "Get", new Type[2] { typeof(string), typeof(string) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(DialogueHandler), "GetTextPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void GetTextPostfix(string key, string sheetTitle, ref string __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) LanguageCode val = Language.CurrentLanguage(); string text = ((object)(LanguageCode)(ref val)).ToString(); if (!TextCache.ContainsKey(text)) { TextCache[text] = new Dictionary<string, Dictionary<string, string>>(); } if (!TextCache[text].ContainsKey(sheetTitle)) { TextCache[text][sheetTitle] = LoadTextSheet(sheetTitle, text); } if (TextCache[text][sheetTitle].ContainsKey(key)) { __result = TextCache[text][sheetTitle][key]; } TextLog.LogText(sheetTitle, key, __result); } private static Dictionary<string, string> LoadTextSheet(string sheetTitle, string lang) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); Extensions.AddRange<string, string>(dictionary, LoadTextSheet(sheetTitle, lang, TextLoadPath)); foreach (string pluginPackPath in Plugin.PluginPackPaths) { Dictionary<string, string> dictionary2 = LoadTextSheet(sheetTitle, lang, Path.Combine(pluginPackPath, "Text")); foreach (KeyValuePair<string, string> item in dictionary2) { dictionary[item.Key] = item.Value; } } return dictionary; } private static Dictionary<string, string> LoadTextSheet(string sheetTitle, string lang, string basePath) { string path = Path.Combine(basePath, sheetTitle, lang + ".yml"); Dictionary<string, string> dictionary = new Dictionary<string, string>(); if (!File.Exists(path)) { return dictionary; } string[] array = File.ReadAllLines(path); string[] array2 = array; foreach (string text in array2) { if (!text.StartsWith("#") && !string.IsNullOrWhiteSpace(text)) { int num = text.IndexOf(':'); if (num != -1) { string key = text.Substring(0, num).Trim(); string value = text.Substring(num + 1).Trim().Trim('"') .Replace("\\\"", "\""); dictionary[key] = value; } } } return dictionary; } } namespace Patchwork { public class PatchworkConfig { private readonly ConfigEntry<bool> _DumpSprites; private readonly ConfigEntry<KeyCode> _FullDumpKey = null; private readonly ConfigEntry<bool> _DumpText; private readonly ConfigEntry<double> _LogAudioDuration; private readonly ConfigEntry<bool> _HideModdedAudioInLog; private readonly ConfigEntry<KeyCode> _ShowAudioLog; private readonly ConfigEntry<KeyCode> _ShowAudioList; private readonly ConfigEntry<KeyCode> _ShowAnimationController; private readonly ConfigEntry<KeyCode> _AnimationControllerPauseKey; private readonly ConfigEntry<KeyCode> _AnimationControllerNextFrameKey; private readonly ConfigEntry<KeyCode> _AnimationControllerPrevFrameKey; private readonly ConfigEntry<KeyCode> _AnimationControllerFreezeKey; private readonly ConfigEntry<KeyCode> _ShowTextLog; private readonly ConfigEntry<double> _TextLogDuration; public bool DumpSprites => _DumpSprites.Value; public KeyCode FullDumpKey => _FullDumpKey.Value; public bool DumpText => _DumpText.Value; public double LogAudioDuration => _LogAudioDuration.Value; public bool HideModdedAudioInLog => _HideModdedAudioInLog.Value; public KeyCode ShowAudioLogKey => _ShowAudioLog.Value; public KeyCode ShowAudioListKey => _ShowAudioList.Value; public KeyCode ShowAnimationControllerKey => _ShowAnimationController.Value; public KeyCode AnimationControllerPauseKey => _AnimationControllerPauseKey.Value; public KeyCode AnimationControllerNextFrameKey => _AnimationControllerNextFrameKey.Value; public KeyCode AnimationControllerPrevFrameKey => _AnimationControllerPrevFrameKey.Value; public KeyCode AnimationControllerFreezeKey => _AnimationControllerFreezeKey.Value; public KeyCode ShowTextLogKey => _ShowTextLog.Value; public double TextLogDuration => _TextLogDuration.Value; public PatchworkConfig(ConfigFile config) { _LogAudioDuration = config.Bind<double>("GUI", "LogAudioDuration", 5.0, "Duration (in seconds) to keep audio log entries visible."); _HideModdedAudioInLog = config.Bind<bool>("GUI", "HideModdedAudioInLog", true, "Hide modded audio clips from the audio log."); _TextLogDuration = config.Bind<double>("GUI", "TextLogDuration", 10.0, "Duration (in seconds) to keep text log entries visible."); _DumpSprites = config.Bind<bool>("Dumping", "DumpSprites", false, "Enable dumping of sprites"); _DumpText = config.Bind<bool>("Dumping", "DumpText", false, "Enable dumping of text when the game starts."); _FullDumpKey = config.Bind<KeyCode>("Keybinds", "FullDumpKey", (KeyCode)287, "Key to load all scenes in the game and dump all their sprites. Only works when DumpSprites is enabled."); _ShowAudioLog = config.Bind<KeyCode>("Keybinds", "ShowAudioLog", (KeyCode)49, "Key to toggle the audio log display."); _ShowAudioList = config.Bind<KeyCode>("Keybinds", "ShowAudioList", (KeyCode)50, "Key to toggle the audio list display."); _ShowAnimationController = config.Bind<KeyCode>("Keybinds", "ShowAnimationController", (KeyCode)51, "Key to toggle the animation controller display."); _ShowTextLog = config.Bind<KeyCode>("Keybinds", "ShowTextLog", (KeyCode)52, "Key to toggle the text log display."); _AnimationControllerPauseKey = config.Bind<KeyCode>("Keybinds", "AnimationControllerPauseKey", (KeyCode)278, "Key to pause/unpause the selected animator in the animation controller."); _AnimationControllerNextFrameKey = config.Bind<KeyCode>("Keybinds", "AnimationControllerNextFrameKey", (KeyCode)280, "Key to advance one frame in the selected animator in the animation controller when paused."); _AnimationControllerPrevFrameKey = config.Bind<KeyCode>("Keybinds", "AnimationControllerPrevFrameKey", (KeyCode)277, "Key to go back one frame in the selected animator in the animation controller when paused."); _AnimationControllerFreezeKey = config.Bind<KeyCode>("Keybinds", "AnimationControllerFreezeKey", (KeyCode)279, "Key to freeze/unfreeze the object of the selected animator in the animation controller."); } } [BepInPlugin("Patchwork", "Patchwork", "2.5.0")] public class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <AwakeDelayed>d__14 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Harmony harmony; public Plugin <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AwakeDelayed>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; DialogueHandler.ApplyPatches(harmony); if (Config.DumpText) { DialogueHandler.DumpText(); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static ManualLogSource Logger; internal static PatchworkConfig Config; internal static SpriteFileWatcher SpriteFileWatcher; internal static AudioFileWatcher AudioFileWatcher; internal static TextFileWatcher TextFileWatcher; private static string PatchworkFolderName = "Patchwork"; public static HashSet<string> PluginPackPaths = new HashSet<string>(); public static bool ShowAudioLog = false; public static bool ShowAudioList = false; public static bool ShowAnimationController = false; public static bool ShowTextLog = false; public static string BasePath => Path.Combine(Paths.PluginPath, PatchworkFolderName); private void Awake() { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; Config = new PatchworkConfig(((BaseUnityPlugin)this).Config); Logger.LogInfo((object)"Patchwork is loaded! Version: 2.5.0"); FindPatchworkFolder(); ScanPluginPacks(); TexUtil.Initialize(); InitializeFolders(); AudioFileWatcher = new AudioFileWatcher(); SpriteFileWatcher = new SpriteFileWatcher(); TextFileWatcher = new TextFileWatcher(); if (Config.DumpSprites) { SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode) { Logger.LogInfo((object)("Dumping sprites for scene " + ((Scene)(ref scene)).name)); tk2dSpriteCollectionData[] array = Resources.FindObjectsOfTypeAll<tk2dSpriteCollectionData>(); tk2dSpriteCollectionData[] array2 = array; foreach (tk2dSpriteCollectionData collection in array2) { SpriteDumper.DumpCollection(collection); } SceneTraverser.OnDumpCompleted(); Logger.LogInfo((object)("Finished dumping sprites for scene " + ((Scene)(ref scene)).name)); }; } SceneManager.sceneLoaded += delegate { AudioHandler.Reload(); }; SceneManager.sceneLoaded += delegate { AnimationController.ClearAnimators(); }; Harmony val = new Harmony("Patchwork"); val.PatchAll(); AudioHandler.ApplyPatches(val); AnimationController.ApplyPatches(val); SpriteLoader.ApplyPatches(val); VideoHandler.ApplyPatches(val); ((MonoBehaviour)this).StartCoroutine((IEnumerator)AwakeDelayed(val)); } [IteratorStateMachine(typeof(<AwakeDelayed>d__14))] private IEnumerator<object> AwakeDelayed(Harmony harmony) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AwakeDelayed>d__14(0) { <>4__this = this, harmony = harmony }; } private void FindPatchworkFolder() { Directory.GetFiles(Paths.PluginPath, "Patchwork.dll", SearchOption.AllDirectories).ToList().ForEach(delegate(string file) { PatchworkFolderName = Path.GetFileName(Path.GetDirectoryName(file)); Logger.LogDebug((object)("Found Patchwork folder name: " + PatchworkFolderName)); }); } private void ScanPluginPacks() { Directory.GetDirectories(Paths.PluginPath, "Patchwork", SearchOption.AllDirectories).ToList().ForEach(delegate(string dir) { if (!BasePath.Equals(dir)) { Logger.LogDebug((object)("Found Patchwork plugin pack at " + dir)); PluginPackPaths.Add(dir); } }); } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(Config.FullDumpKey) && Config.DumpSprites) { SceneTraverser.TraverseAllScenes(); } if (Input.GetKeyDown(Config.ShowAudioLogKey)) { ShowAudioLog = !ShowAudioLog; } if (Input.GetKeyDown(Config.ShowAudioListKey)) { ShowAudioList = !ShowAudioList; } if (Input.GetKeyDown(Config.ShowAnimationControllerKey)) { ShowAnimationController = !ShowAnimationController; } if (Input.GetKeyDown(Config.ShowTextLogKey)) { ShowTextLog = !ShowTextLog; } if (SpriteFileWatcher.ReloadSprites) { SpriteFileWatcher.ReloadSprites = false; SpriteLoader.Reload(); T2DHandler.ReloadSpritesInScene(); } if (AudioFileWatcher.ReloadAudio) { AudioFileWatcher.ReloadAudio = false; AudioHandler.Reload(); } AnimationController.Update(); T2DHandler.CheckForUninitializedSprites(); } private void OnGUI() { if (ShowAudioLog) { AudioLog.DrawAudioLog(); } if (ShowAudioList) { AudioList.DrawAudioList(); } if (ShowAnimationController) { AnimationController.DrawAnimationController(); } if (ShowTextLog) { TextLog.DrawTextLog(); } } private void InitializeFolders() { IOUtil.EnsureDirectoryExists(SpriteDumper.DumpPath); IOUtil.EnsureDirectoryExists(SpriteLoader.LoadPath); IOUtil.EnsureDirectoryExists(SpriteLoader.AtlasLoadPath); IOUtil.EnsureDirectoryExists(T2DHandler.T2DDumpPath); IOUtil.EnsureDirectoryExists(AudioHandler.SoundFolder); IOUtil.EnsureDirectoryExists(VideoHandler.VideoLoadPath); IOUtil.EnsureDirectoryExists(DialogueHandler.TextDumpPath); IOUtil.EnsureDirectoryExists(DialogueHandler.TextLoadPath); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Patchwork"; public const string PLUGIN_NAME = "Patchwork"; public const string PLUGIN_VERSION = "2.5.0"; } } namespace Patchwork.Watchers { public class AudioFileWatcher { public FileSystemWatcher AudioWatcher; public static bool ReloadAudio; public AudioFileWatcher() { AudioWatcher = new FileSystemWatcher(); AudioWatcher.Path = AudioHandler.SoundFolder; AudioWatcher.IncludeSubdirectories = true; AudioWatcher.Filter = "*.*"; AudioWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite; AudioWatcher.Changed += OnAudioChanged; AudioWatcher.Created += OnAudioChanged; AudioWatcher.Deleted += OnAudioChanged; AudioWatcher.Renamed += OnAudioChanged; AudioWatcher.EnableRaisingEvents = true; } private void OnAudioChanged(object sender, FileSystemEventArgs e) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(e.FullPath); AudioHandler.InvalidateCache(fileNameWithoutExtension); ReloadAudio = true; } } public class TextFileWatcher { public FileSystemWatcher TextWatcher; public TextFileWatcher() { TextWatcher = new FileSystemWatcher(); TextWatcher.Path = DialogueHandler.TextLoadPath; TextWatcher.IncludeSubdirectories = true; TextWatcher.Filter = "*.yml"; TextWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite; TextWatcher.Changed += OnTextChanged; TextWatcher.Created += OnTextChanged; TextWatcher.Deleted += OnTextChanged; TextWatcher.Renamed += OnTextChanged; TextWatcher.EnableRaisingEvents = true; } private void OnTextChanged(object sender, FileSystemEventArgs e) { string name = new DirectoryInfo(Path.GetDirectoryName(e.FullPath)).Name; string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(e.FullPath); DialogueHandler.InvalidateCache(name, fileNameWithoutExtension); } } } namespace Patchwork.Util { public static class IOUtil { public static void EnsureDirectoryExists(string path) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } } public static class SpriteUtil { public static Rect GetSpriteRect(tk2dSpriteDefinition def, Texture tex) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) Vector2[] uvs = def.uvs; int num = (int)(uvs.Min((Vector2 uv) => uv.x) * (float)tex.width); int num2 = (int)(uvs.Max((Vector2 uv) => uv.x) * (float)tex.width); int num3 = (int)(uvs.Min((Vector2 uv) => uv.y) * (float)tex.height); int num4 = (int)(uvs.Max((Vector2 uv) => uv.y) * (float)tex.height); int num5 = math.min(num2 - num, tex.width); int num6 = math.min(num4 - num3, tex.height); return new Rect((float)num, (float)num3, (float)num5, (float)num6); } } public static class StringUtil { public static string SanitizeFileName(string name) { char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { name = name.Replace(oldChar, '_'); } return name; } } public static class TexUtil { public static Material RotateMaterial; public static void Initialize() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown string text = Path.Combine(Plugin.BasePath, "patchwork.assetbundle"); AssetBundle val = AssetBundle.LoadFromFile(text); Shader val2 = val.LoadAsset<Shader>("Assets/Patchwork/Rotate.shader"); RotateMaterial = new Material(val2); } public static RenderTexture GetReadable(Texture tex) { RenderTexture temporary = RenderTexture.GetTemporary(tex.width, tex.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1); Graphics.Blit(tex, temporary); return temporary; } public static Texture2D LoadFromPNG(string path) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (!File.Exists(path)) { Plugin.Logger.LogWarning((object)("LoadFromPNG: File " + path + " does not exist")); return null; } byte[] array = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2); if (!ImageConversion.LoadImage(val, array)) { Plugin.Logger.LogWarning((object)("LoadFromPNG: Failed to load image data from " + path)); return null; } return val; } } } namespace Patchwork.Handlers { [HarmonyPatch] public static class AudioHandler { public static readonly string SoundFolder = Path.Combine(Plugin.BasePath, "Sounds"); private static readonly Dictionary<string, AudioClip> LoadedClips = new Dictionary<string, AudioClip>(); public static void ApplyPatches(Harmony harmony) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(AudioSource), "PlayHelper", new Type[2] { typeof(AudioSource), typeof(ulong) }, (Type[])null), new HarmonyMethod(typeof(AudioHandler), "PlayHelperPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(AudioSource), "PlayOneShotHelper", new Type[3] { typeof(AudioSource), typeof(AudioClip), typeof(float) }, (Type[])null), new HarmonyMethod(typeof(AudioHandler), "PlayOneShotHelperPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.PropertySetter(typeof(AudioSource), "clip"), (HarmonyMethod)null, new HarmonyMethod(typeof(AudioHandler), "ClipSetterPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void PlayHelperPatch(AudioSource source, ulong delay) { if ((Object)(object)source.clip != (Object)null) { AudioLog.LogAudio(source.clip); LoadAudio(source); } } public static void PlayOneShotHelperPatch(AudioSource source, ref AudioClip clip, float volumeScale) { if ((Object)(object)clip != (Object)null) { AudioLog.LogAudio(clip); LoadAudio(ref clip); } } public static void ClipSetterPatch(AudioSource __instance, AudioClip value) { if ((Object)(object)value != (Object)null) { AudioLog.LogAudio(value); if (!((Object)value).name.StartsWith("PATCHWORK_") || !LoadedClips.ContainsKey(((Object)value).name.Replace("PATCHWORK_", ""))) { LoadAudio(__instance); } } } public static void Reload() { AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>(); foreach (AudioSource source in array) { LoadAudio(source); AudioList.LogAudio(source); } } public static void LoadAudio(AudioSource source) { if ((Object)(object)source == (Object)null || (Object)(object)source.clip == (Object)null) { return; } AudioClip clip = source.clip; if (string.IsNullOrEmpty((clip != null) ? ((Object)clip).name : null)) { return; } string text = ((Object)source.clip).name.Replace("PATCHWORK_", ""); if (LoadedClips.ContainsKey(text)) { source.clip = LoadedClips[text]; return; } AudioClip val = LoadAudioClip(text); if ((Object)(object)val != (Object)null) { LoadedClips[text] = val; source.clip = val; } } public static void LoadAudio(ref AudioClip clip) { if ((Object)(object)clip == (Object)null) { return; } AudioClip obj = clip; if (string.IsNullOrEmpty((obj != null) ? ((Object)obj).name : null)) { return; } string text = ((Object)clip).name.Replace("PATCHWORK_", ""); if (LoadedClips.ContainsKey(text)) { clip = LoadedClips[text]; return; } AudioClip val = LoadAudioClip(text); if ((Object)(object)val != (Object)null) { LoadedClips[text] = val; clip = val; } } public static void InvalidateCache(string soundName) { LoadedClips.Remove(soundName); } public static AudioClip LoadAudioClip(string soundName) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 string soundPath = GetSoundPath(soundName); if (string.IsNullOrEmpty(soundPath)) { return null; } if (LoadedClips.TryGetValue(soundName, out var value)) { return value; } string text = "file:///" + Uri.EscapeUriString(soundPath.Replace("\\", "/")); UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)0); UnityWebRequestAsyncOperation val = audioClip.SendWebRequest(); while (!((AsyncOperation)val).isDone) { } if ((int)audioClip.result != 1) { Plugin.Logger.LogError((object)("[Patchwork] Failed to load audio clip from " + soundPath + ": " + audioClip.error)); return null; } AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip); ((Object)content).name = "PATCHWORK_" + soundName; LoadedClips[soundName] = content; return content; } private static string GetSoundPath(string soundName) { string[] files = Directory.GetFiles(SoundFolder, soundName + ".*", SearchOption.AllDirectories); if (files.Any()) { return files.First(); } foreach (string pluginPackPath in Plugin.PluginPackPaths) { if (Directory.Exists(Path.Combine(pluginPackPath, "Sounds"))) { string[] files2 = Directory.GetFiles(Path.Combine(pluginPackPath, "Sounds"), soundName + ".*", SearchOption.AllDirectories); if (files2.Any()) { return files2.First(); } } } return null; } } public static class SceneTraverser { private static Queue<string> sceneQueue = new Queue<string>(); public static void TraverseAllScenes() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_0070: Unknown result type (might be due to invalid IL or missing references) Plugin.Logger.LogInfo((object)"Starting scene traversal for full sprite dump..."); sceneQueue.Clear(); Dictionary<string, SceneInfo> teleportMap = SceneTeleportMap.GetTeleportMap(); foreach (string key in teleportMap.Keys) { if (!sceneQueue.Contains(key) && (int)teleportMap[key].MapZone > 0) { Plugin.Logger.LogInfo((object)$"Enqueued scene: {key} : {teleportMap[key].MapZone}"); sceneQueue.Enqueue(key); } } LoadNextScene(); } public static void OnDumpCompleted() { LoadNextScene(); } private static bool LoadNextScene() { if (sceneQueue.Count > 0) { string text = sceneQueue.Dequeue(); GameManager.instance.LoadScene(text); return true; } return false; } } public static class SpriteDumper { public static string DumpPath => Path.Combine(Plugin.BasePath, "Dumps"); public static void DumpCollection(tk2dSpriteCollectionData collection) { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Invalid comparison between Unknown and I4 //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Invalid comparison between Unknown and I4 //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: 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_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Expected O, but got Unknown //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Invalid comparison between Unknown and I4 //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) Material[] materials = collection.materials; foreach (Material mat in materials) { if ((Object)(object)mat == (Object)null || (Object)(object)mat.mainTexture == (Object)null) { continue; } Texture val = mat.mainTexture; if (val.width == 0 || val.height == 0) { continue; } if (!val.isReadable || !(val is RenderTexture)) { val = (Texture)(object)TexUtil.GetReadable(val); } RenderTexture active = RenderTexture.active; RenderTexture.active = (RenderTexture)(object)((val is RenderTexture) ? val : null); GL.PushMatrix(); GL.LoadPixelMatrix(0f, (float)val.width, (float)val.height, 0f); string path = ((Object)mat).name.Split(' ')[0]; tk2dSpriteDefinition[] array = collection.spriteDefinitions.Where((tk2dSpriteDefinition def) => (Object)(object)def.material == (Object)(object)mat).ToArray(); tk2dSpriteDefinition[] array2 = array; foreach (tk2dSpriteDefinition val2 in array2) { if (string.IsNullOrEmpty(val2.name) || File.Exists(Path.Combine(DumpPath, ((Object)collection).name, path, val2.name + ".png"))) { continue; } Rect spriteRect = SpriteUtil.GetSpriteRect(val2, val); if (((Rect)(ref spriteRect)).width == 0f || ((Rect)(ref spriteRect)).height == 0f) { continue; } Texture2D val3 = new Texture2D((int)((Rect)(ref spriteRect)).width, (int)((Rect)(ref spriteRect)).height, (TextureFormat)4, false); val3.ReadPixels(spriteRect, 0, 0); val3.Apply(); if ((int)val2.flipped == 0) { byte[] bytes = ImageConversion.EncodeToPNG(val3); IOUtil.EnsureDirectoryExists(Path.Combine(DumpPath, ((Object)collection).name, path)); File.WriteAllBytes(Path.Combine(DumpPath, ((Object)collection).name, path, val2.name + ".png"), bytes); continue; } RenderTexture temporary = RenderTexture.GetTemporary((int)((Rect)(ref spriteRect)).height, (int)((Rect)(ref spriteRect)).width, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1); RenderTexture active2 = RenderTexture.active; RenderTexture.active = temporary; GL.PushMatrix(); GL.LoadPixelMatrix(0f, (float)((Texture)temporary).height, (float)((Texture)temporary).width, 0f); FlipMode flipped = val2.flipped; FlipMode val4 = flipped; Vector2 val5; Vector2 val6; if ((int)val4 != 1) { if ((int)val4 == 2) { val5 = Vector2.down; val6 = Vector2.right; } else { val5 = Vector2.right; val6 = Vector2.up; } } else { val5 = Vector2.up; val6 = Vector2.left; } TexUtil.RotateMaterial.SetVector("_Basis", new Vector4(val5.x, val5.y, val6.x, val6.y)); Graphics.DrawTextureImpl(new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), (Texture)(object)val3, new Rect(0f, 0f, 1f, 1f), 0, 0, 0, 0, Color.white, TexUtil.RotateMaterial, 0); Texture2D val7 = new Texture2D((int)((Rect)(ref spriteRect)).height, (int)((Rect)(ref spriteRect)).width, (TextureFormat)4, false); val7.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0); val7.Apply(); RenderTexture.active = active2; GL.PopMatrix(); RenderTexture.ReleaseTemporary(temporary); byte[] bytes2 = ImageConversion.EncodeToPNG(val7); IOUtil.EnsureDirectoryExists(Path.Combine(DumpPath, ((Object)collection).name, path)); File.WriteAllBytes(Path.Combine(DumpPath, ((Object)collection).name, path, val2.name + ".png"), bytes2); } GL.PopMatrix(); RenderTexture.active = active; } } public static void DumpSingleSprite(tk2dSpriteDefinition def, tk2dSpriteCollectionData collection) { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Invalid comparison between Unknown and I4 //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Invalid comparison between Unknown and I4 //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Expected O, but got Unknown //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Invalid comparison between Unknown and I4 //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) Material[] materials = collection.materials; foreach (Material val in materials) { if ((Object)(object)def.material != (Object)(object)val || (Object)(object)val == (Object)null || (Object)(object)val.mainTexture == (Object)null) { continue; } Texture val2 = val.mainTexture; if (val2.width == 0 || val2.height == 0) { continue; } if (!val2.isReadable || !(val2 is RenderTexture)) { val2 = (Texture)(object)TexUtil.GetReadable(val2); } RenderTexture active = RenderTexture.active; RenderTexture.active = (RenderTexture)(object)((val2 is RenderTexture) ? val2 : null); GL.PushMatrix(); GL.LoadPixelMatrix(0f, (float)val2.width, (float)val2.height, 0f); string path = ((Object)val).name.Split(' ')[0]; if (string.IsNullOrEmpty(def.name) || File.Exists(Path.Combine(DumpPath, ((Object)collection).name, path, def.name + ".png"))) { break; } Rect spriteRect = SpriteUtil.GetSpriteRect(def, val2); if (((Rect)(ref spriteRect)).width == 0f || ((Rect)(ref spriteRect)).height == 0f) { break; } Texture2D val3 = new Texture2D((int)((Rect)(ref spriteRect)).width, (int)((Rect)(ref spriteRect)).height, (TextureFormat)4, false); val3.ReadPixels(spriteRect, 0, 0); val3.Apply(); if ((int)def.flipped == 0) { byte[] bytes = ImageConversion.EncodeToPNG(val3); IOUtil.EnsureDirectoryExists(Path.Combine(DumpPath, ((Object)collection).name, path)); File.WriteAllBytes(Path.Combine(DumpPath, ((Object)collection).name, path, def.name + ".png"), bytes); GL.PopMatrix(); RenderTexture.active = active; break; } RenderTexture temporary = RenderTexture.GetTemporary((int)((Rect)(ref spriteRect)).height, (int)((Rect)(ref spriteRect)).width, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1); RenderTexture active2 = RenderTexture.active; RenderTexture.active = temporary; GL.PushMatrix(); GL.LoadPixelMatrix(0f, (float)((Texture)temporary).height, (float)((Texture)temporary).width, 0f); FlipMode flipped = def.flipped; FlipMode val4 = flipped; Vector2 val5; Vector2 val6; if ((int)val4 != 1) { if ((int)val4 == 2) { val5 = Vector2.down; val6 = Vector2.right; } else { val5 = Vector2.right; val6 = Vector2.up; } } else { val5 = Vector2.up; val6 = Vector2.left; } TexUtil.RotateMaterial.SetVector("_Basis", new Vector4(val5.x, val5.y, val6.x, val6.y)); Graphics.DrawTextureImpl(new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), (Texture)(object)val3, new Rect(0f, 0f, 1f, 1f), 0, 0, 0, 0, Color.white, TexUtil.RotateMaterial, 0); Texture2D val7 = new Texture2D((int)((Rect)(ref spriteRect)).height, (int)((Rect)(ref spriteRect)).width, (TextureFormat)4, false); val7.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0); val7.Apply(); RenderTexture.active = active2; GL.PopMatrix(); RenderTexture.ReleaseTemporary(temporary); byte[] bytes2 = ImageConversion.EncodeToPNG(val7); IOUtil.EnsureDirectoryExists(Path.Combine(DumpPath, ((Object)collection).name, path)); File.WriteAllBytes(Path.Combine(DumpPath, ((Object)collection).name, path, def.name + ".png"), bytes2); GL.PopMatrix(); RenderTexture.active = active; } } } [HarmonyPatch] public static class SpriteLoader { private static readonly Dictionary<string, HashSet<string>> LoadedAtlases = new Dictionary<string, HashSet<string>>(); private static readonly Dictionary<string, Dictionary<string, RenderTexture>> LoadedAtlasesTextures = new Dictionary<string, Dictionary<string, RenderTexture>>(); private static readonly Dictionary<string, Dictionary<string, HashSet<string>>> LoadedSprites = new Dictionary<string, Dictionary<string, HashSet<string>>>(); public static string LoadPath => Path.Combine(Plugin.BasePath, "Sprites"); public static string AtlasLoadPath => Path.Combine(Plugin.BasePath, "Spritesheets"); public static void ApplyPatches(Harmony harmony) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(tk2dSpriteCollectionData), "Init", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(SpriteLoader), "InitPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void InitPostfix(tk2dSpriteCollectionData __instance) { LoadCollection(__instance); } public static void LoadCollection(tk2dSpriteCollectionData collection) { //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Invalid comparison between Unknown and I4 //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Invalid comparison between Unknown and I4 //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) Material[] materials = collection.materials; foreach (Material mat in materials) { if ((Object)(object)mat == (Object)null) { continue; } string name = ((Object)mat).name; string materialName = ((Object)mat).name.Split(' ')[0]; if (!LoadedAtlases.ContainsKey(((Object)collection).name)) { LoadedAtlases[((Object)collection).name] = new HashSet<string>(); } if (LoadedAtlases[((Object)collection).name].Add(name)) { Texture mainTexture = mat.mainTexture; mat.mainTexture = (Texture)(object)FindSpritesheet(collection, materialName); if (!LoadedAtlasesTextures.ContainsKey(((Object)collection).name)) { LoadedAtlasesTextures[((Object)collection).name] = new Dictionary<string, RenderTexture>(); } Dictionary<string, RenderTexture> dictionary = LoadedAtlasesTextures[((Object)collection).name]; Texture mainTexture2 = mat.mainTexture; dictionary[name] = (RenderTexture)(object)((mainTexture2 is RenderTexture) ? mainTexture2 : null); } else { mat.mainTexture = (Texture)(object)LoadedAtlasesTextures[((Object)collection).name][name]; } RenderTexture active = RenderTexture.active; Texture mainTexture3 = mat.mainTexture; RenderTexture.active = (RenderTexture)(object)((mainTexture3 is RenderTexture) ? mainTexture3 : null); GL.PushMatrix(); GL.LoadPixelMatrix(0f, (float)mat.mainTexture.width, (float)mat.mainTexture.height, 0f); tk2dSpriteDefinition[] array = collection.spriteDefinitions.Where((tk2dSpriteDefinition def) => (Object)(object)def.material == (Object)(object)mat).ToArray(); tk2dSpriteDefinition[] array2 = array; foreach (tk2dSpriteDefinition val in array2) { if (string.IsNullOrEmpty(val.name)) { continue; } if (!LoadedSprites.ContainsKey(((Object)collection).name)) { LoadedSprites[((Object)collection).name] = new Dictionary<string, HashSet<string>>(); } if (!LoadedSprites[((Object)collection).name].ContainsKey(name)) { LoadedSprites[((Object)collection).name][name] = new HashSet<string>(); } if (!LoadedSprites[((Object)collection).name][name].Add(val.name)) { continue; } Texture2D val2 = FindSprite(((Object)collection).name, materialName, val.name); if ((Object)(object)val2 == (Object)null) { continue; } Rect spriteRect = SpriteUtil.GetSpriteRect(val, mat.mainTexture); ((Rect)(ref spriteRect)).y = (float)mat.mainTexture.height - ((Rect)(ref spriteRect)).y - ((Rect)(ref spriteRect)).height; FlipMode flipped = val.flipped; FlipMode val3 = flipped; Vector2 val4; Vector2 val5; if ((int)val3 != 1) { if ((int)val3 == 2) { val4 = Vector2.up; val5 = Vector2.left; } else { val4 = Vector2.right; val5 = Vector2.up; } } else { val4 = Vector2.down; val5 = Vector2.right; } TexUtil.RotateMaterial.SetVector("_Basis", new Vector4(val4.x, val4.y, val5.x, val5.y)); Graphics.DrawTextureImpl(spriteRect, (Texture)(object)val2, new Rect(0f, 0f, 1f, 1f), 0, 0, 0, 0, Color.white, TexUtil.RotateMaterial, 0); } mat.mainTexture.IncrementUpdateCount(); GL.PopMatrix(); RenderTexture.active = active; } } private static Texture2D FindSprite(string collectionName, string materialName, string spriteName) { IEnumerable<string> source = from f in Directory.GetFiles(LoadPath, spriteName + ".png", SearchOption.AllDirectories) where Path.GetDirectoryName(f).EndsWith(Path.Combine(collectionName, materialName)) select f; if (source.Any()) { return TexUtil.LoadFromPNG(source.First()); } foreach (string pluginPackPath in Plugin.PluginPackPaths) { if (Directory.Exists(Path.Combine(pluginPackPath, "Sprites"))) { IEnumerable<string> source2 = from f in Directory.GetFiles(Path.Combine(pluginPackPath, "Sprites"), spriteName + ".png", SearchOption.AllDirectories) where Path.GetDirectoryName(f).EndsWith(Path.Combine(collectionName, materialName)) select f; if (source2.Any()) { return TexUtil.LoadFromPNG(source2.First()); } } } return null; } private static RenderTexture FindSpritesheet(tk2dSpriteCollectionData collection, string materialName) { IEnumerable<string> source = from f in Directory.GetFiles(AtlasLoadPath, materialName + ".png", SearchOption.AllDirectories) where Path.GetDirectoryName(f).EndsWith(((Object)collection).name) select f; if (source.Any()) { Texture2D val = TexUtil.LoadFromPNG(source.First()); RenderTexture temporary = RenderTexture.GetTemporary(((Texture)val).width, ((Texture)val).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1); Graphics.Blit((Texture)(object)val, temporary); Object.Destroy((Object)(object)val); return temporary; } foreach (string pluginPackPath in Plugin.PluginPackPaths) { if (Directory.Exists(Path.Combine(pluginPackPath, "Spritesheets"))) { IEnumerable<string> source2 = from f in Directory.GetFiles(Path.Combine(pluginPackPath, "Spritesheets"), materialName + ".png", SearchOption.AllDirectories) where Path.GetDirectoryName(f).EndsWith(((Object)collection).name) select f; if (source2.Any()) { Texture2D val2 = TexUtil.LoadFromPNG(source2.First()); RenderTexture temporary2 = RenderTexture.GetTemporary(((Texture)val2).width, ((Texture)val2).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1); Graphics.Blit((Texture)(object)val2, temporary2); Object.Destroy((Object)(object)val2); return temporary2; } } } Material val3 = ((IEnumerable<Material>)collection.materials).FirstOrDefault((Func<Material, bool>)((Material m) => ((Object)m).name.StartsWith(materialName + " ") || ((Object)m).name == materialName)); return TexUtil.GetReadable((val3 != null) ? val3.mainTexture : null); } public static void MarkReloadSprite(string collectionName, string atlasName, string spriteName) { lock (LoadedSprites) { if (!LoadedSprites.ContainsKey(collectionName)) { return; } foreach (string item in LoadedSprites[collectionName].Keys.ToList()) { if (item.StartsWith(atlasName)) { LoadedSprites[collectionName][item].Remove(spriteName); } } } } public static void MarkReloadAtlas(string collectionName, string atlasName) { lock (LoadedAtlases) { if (LoadedAtlases.ContainsKey(collectionName)) { foreach (string item in LoadedAtlases[collectionName].Where((string a) => a.StartsWith(atlasName)).ToList()) { LoadedAtlases[collectionName].Remove(item); } } if (!LoadedSprites.ContainsKey(collectionName)) { return; } foreach (string item2 in LoadedSprites[collectionName].Keys.Where((string a) => a.StartsWith(atlasName)).ToList()) { LoadedSprites[collectionName][item2].Clear(); } } } public static void Reload() { //IL_000b: 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) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) ManualLogSource logger = Plugin.Logger; Scene activeScene = SceneManager.GetActiveScene(); logger.LogInfo((object)("Reloading sprites for scene " + ((Scene)(ref activeScene)).name)); tk2dSpriteCollectionData[] array = Resources.FindObjectsOfTypeAll<tk2dSpriteCollectionData>(); tk2dSpriteCollectionData[] array2 = array; foreach (tk2dSpriteCollectionData collection in array2) { LoadCollection(collection); } ManualLogSource logger2 = Plugin.Logger; activeScene = SceneManager.GetActiveScene(); logger2.LogInfo((object)("Finished reloading sprites for scene " + ((Scene)(ref activeScene)).name)); } } [HarmonyPatch] public static class T2DHandler { private static readonly Dictionary<string, Sprite> LoadedT2DSprites = new Dictionary<string, Sprite>(); private static readonly Dictionary<string, HashSet<string>> SpriteAtlasMap = new Dictionary<string, HashSet<string>>(); private static readonly HashSet<int> InitializedSpriteRenderers = new HashSet<int>(); public static string T2DDumpPath => Path.Combine(SpriteDumper.DumpPath, "T2D"); [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static void SetSpritePostfix(SpriteRenderer __instance, Sprite value) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)value == (Object)null) && !(((Object)((Component)__instance).gameObject).name == "TempSpriteRenderer")) { InitializedSpriteRenderers.Add(((Object)__instance).GetInstanceID()); if (Plugin.Config.DumpSprites && !string.IsNullOrEmpty(((Object)value).name) && !string.IsNullOrEmpty(((Object)value.texture).name)) { HandleDump(__instance, value); } StackTrace stackTrace = new StackTrace(); if (!stackTrace.GetFrames().Any((StackFrame f) => f.GetMethod().Name == "HandleLoad")) { HandleLoad(__instance, value); } } } public static void CheckForUninitializedSprites() { SpriteRenderer[] array = Object.FindObjectsByType<SpriteRenderer>((FindObjectsSortMode)0); foreach (SpriteRenderer val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sprite == (Object)null) && !InitializedSpriteRenderers.Contains(((Object)val).GetInstanceID())) { InitializedSpriteRenderers.Add(((Object)val).GetInstanceID()); val.sprite = val.sprite; } } } public static void ReloadSpritesInScene() { LoadedT2DSprites.Clear(); SpriteRenderer[] array = Object.FindObjectsByType<SpriteRenderer>((FindObjectsSortMode)0); foreach (SpriteRenderer val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sprite == (Object)null)) { HandleLoad(val, val.sprite); } } } public static void InvalidateCache(string spriteName) { LoadedT2DSprites.Remove(spriteName); if (!SpriteAtlasMap.ContainsKey(spriteName)) { return; } foreach (string item in SpriteAtlasMap[spriteName]) { LoadedT2DSprites.Remove(item); } SpriteAtlasMap.Remove(spriteName); } private static void HandleLoad(SpriteRenderer spriteRenderer, Sprite sprite) { //IL_00c2: 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_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) if (LoadedT2DSprites.ContainsKey(((Object)sprite).name)) { spriteRenderer.sprite = LoadedT2DSprites[((Object)sprite).name]; } else if (((Object)sprite.texture).name.Contains("-BC7-") || ((Object)sprite.texture).name.Contains("DXT5|BC3-")) { Texture2D val = FindT2DSprite(CleanTextureName(((Object)sprite.texture).name), ((Object)sprite).name); if (!((Object)(object)val == (Object)null)) { ((Object)val).name = ((Object)sprite.texture).name; Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), sprite.pixelsPerUnit); ((Object)val2).name = ((Object)sprite).name; LoadedT2DSprites[((Object)sprite).name] = val2; spriteRenderer.sprite = val2; if (!SpriteAtlasMap.ContainsKey(((Object)sprite.texture).name)) { SpriteAtlasMap[((Object)sprite.texture).name] = new HashSet<string>(); } SpriteAtlasMap[((Object)sprite.texture).name].Add(((Object)sprite).name); } } else if (LoadedT2DSprites.ContainsKey(((Object)sprite.texture).name)) { spriteRenderer.sprite = LoadedT2DSprites[((Object)sprite.texture).name]; } else { Texture2D val3 = FindT2DSprite(((Object)sprite.texture).name); if (!((Object)(object)val3 == (Object)null)) { ((Object)val3).name = ((Object)sprite.texture).name; Sprite val4 = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f), sprite.pixelsPerUnit); ((Object)val4).name = ((Object)sprite).name; LoadedT2DSprites[((Object)sprite.texture).name] = val4; spriteRenderer.sprite = val4; } } } private static void HandleDump(SpriteRenderer spriteRenderer, Sprite sprite) { //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Expected O, but got Unknown //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00dc: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown //IL_0221: Unknown result type (might be due to invalid IL or missing references) if (((Object)sprite.texture).name.Contains("-BC7-") || ((Object)sprite.texture).name.Contains("DXT5|BC3-")) { string path = CleanTextureName(((Object)sprite.texture).name); string text = Path.Combine(T2DDumpPath, path); IOUtil.EnsureDirectoryExists(text); string path2 = Path.Combine(text, ((Object)sprite).name + ".png"); if (!File.Exists(path2)) { Rect rect = sprite.rect; int num = (int)((Rect)(ref rect)).width; rect = sprite.rect; int num2 = (int)((Rect)(ref rect)).height; int num3 = 31; GameObject val = new GameObject("TempSpriteRenderer"); SpriteRenderer val2 = val.AddComponent<SpriteRenderer>(); val2.sprite = sprite; val.layer = num3; Transform transform = val.transform; float x = sprite.pivot.x; rect = sprite.rect; float num4 = (x - ((Rect)(ref rect)).width / 2f) / sprite.pixelsPerUnit; float y = sprite.pivot.y; rect = sprite.rect; transform.position = new Vector3(num4, (y - ((Rect)(ref rect)).height / 2f) / sprite.pixelsPerUnit, 0f); GameObject val3 = new GameObject("TempCamera"); Camera val4 = val3.AddComponent<Camera>(); val4.clearFlags = (CameraClearFlags)2; val4.backgroundColor = new Color(0f, 0f, 0f, 0f); val4.orthographic = true; val4.cullingMask = 1 << num3; val4.orthographicSize = (float)num2 / sprite.pixelsPerUnit / 2f; ((Component)val4).transform.position = new Vector3(0f, 0f, -10f); RenderTexture val5 = new RenderTexture(num, num2, 0, (RenderTextureFormat)0); ((Texture)val5).filterMode = (FilterMode)0; val4.targetTexture = val5; val4.Render(); RenderTexture active = RenderTexture.active; RenderTexture.active = val5; Texture2D val6 = new Texture2D(num, num2, (TextureFormat)5, false); val6.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0); val6.Apply(); RenderTexture.active = active; val4.targetTexture = null; val.SetActive(false); Object.DestroyImmediate((Object)(object)val5); Object.DestroyImmediate((Object)(object)val); Object.DestroyImmediate((Object)(object)val3); byte[] bytes = ImageConversion.EncodeToPNG(val6); File.WriteAllBytes(path2, bytes); } } else { RenderTexture readable = TexUtil.GetReadable((Texture)(object)sprite.texture); Texture2D val7 = new Texture2D(((Texture)readable).width, ((Texture)readable).height, (TextureFormat)5, false); RenderTexture active2 = RenderTexture.active; RenderTexture.active = readable; val7.ReadPixels(new Rect(0f, 0f, (float)((Texture)readable).width, (float)((Texture)readable).height), 0, 0); val7.Apply(); RenderTexture.active = active2; byte[] bytes2 = ImageConversion.EncodeToPNG(val7); string path3 = Path.Combine(T2DDumpPath, ((Object)sprite.texture).name + ".png"); if (!File.Exists(path3)) { File.WriteAllBytes(path3, bytes2); } } } private static Texture2D FindT2DSprite(string spriteName) { IEnumerable<string> source = from f in Directory.GetFiles(SpriteLoader.LoadPath, spriteName + ".png", SearchOption.AllDirectories) where Path.GetDirectoryName(f).EndsWith("T2D") select f; if (source.Any()) { return TexUtil.LoadFromPNG(source.First()); } foreach (string pluginPackPath in Plugin.PluginPackPaths) { if (Directory.Exists(Path.Combine(pluginPackPath, "Sprites"))) { IEnumerable<string> source2 = from f in Directory.GetFiles(Path.Combine(pluginPackPath, "Sprites"), spriteName + ".png", SearchOption.AllDirectories) where Path.GetDirectoryName(f).EndsWith("T2D") select f; if (source2.Any()) { return TexUtil.LoadFromPNG(source2.First()); } } } return null; } private static Texture2D FindT2DSprite(string texName, string spriteName) { IEnumerable<string> source = from f in Directory.GetFiles(SpriteLoader.LoadPath, spriteName + ".png", SearchOption.AllDirectories) where Path.GetDirectoryName(f).EndsWith(Path.Combine("T2D", texName)) select f; if (source.Any()) { return TexUtil.LoadFromPNG(source.First()); } foreach (string pluginPackPath in Plugin.PluginPackPaths) { if (Directory.Exists(Path.Combine(pluginPackPath, "Sprites"))) { IEnumerable<string> source2 = from f in Directory.GetFiles(Path.Combine(pluginPackPath, "Sprites"), spriteName + ".png", SearchOption.AllDirectories) where Path.GetDirectoryName(f).EndsWith(Path.Combine("T2D", texName)) select f; if (source2.Any()) { return TexUtil.LoadFromPNG(source2.First()); } } } return null; } private static string CleanTextureName(string textureName) { if (textureName.Contains("-BC7-")) { string text = textureName.Split(new string[1] { "-BC7-" }, StringSplitOptions.None)[1]; return string.Join("-", text.Split('-').Take(text.Split('-').Length - 1)); } if (textureName.Contains("DXT5|BC3-")) { string text2 = textureName.Split(new string[1] { "DXT5|BC3-" }, StringSplitOptions.None)[1]; return string.Join("-", text2.Split('-').Take(text2.Split('-').Length - 1)); } return textureName; } } public class VideoHandler { public static Dictionary<string, string> VideoFileMap = new Dictionary<string, string>(); public static string VideoLoadPath => Path.Combine(Plugin.BasePath, "Videos"); public static void ApplyPatches(Harmony harmony) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Constructor(typeof(EmbeddedCinematicVideoPlayer), new Type[1] { typeof(CinematicVideoPlayerConfig) }, false), (HarmonyMethod)null, new HarmonyMethod(typeof(VideoHandler), "ConstructorPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(EmbeddedCinematicVideoPlayer), "PlayVideo", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(VideoHandler), "PlayVideoPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(EmbeddedCinematicVideoPlayer), "Update", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(VideoHandler), "UpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(CinematicPlayer), "StartVideo", (Type[])null, (Type[])null), new HarmonyMethod(typeof(VideoHandler), "StartVideoPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static string FindVideoFile(string name) { if (VideoFileMap.ContainsKey(name)) { return VideoFileMap[name]; } string[] files = Directory.GetFiles(VideoLoadPath, name + ".*", SearchOption.AllDirectories); if (files.Any()) { string text = "file:///" + files[0]; VideoFileMap[name] = text; return text; } foreach (string pluginPackPath in Plugin.PluginPackPaths) { if (Directory.Exists(Path.Combine(pluginPackPath, "Videos"))) { string[] files2 = Directory.GetFiles(Path.Combine(pluginPackPath, "Videos"), name + ".*", SearchOption.AllDirectories); if (files2.Any()) { string text2 = "file:///" + files2[0]; VideoFileMap[name] = text2; return text2; } } } VideoFileMap[name] = null; return null; } private static void StartVideoPrefix(CinematicPlayer __instance) { if (__instance.videoClip.VideoFileName != null && FindVideoFile(__instance.videoClip.VideoFileName) != null) { __instance.additionalAudio = null; } } private static void UpdatePostfix(EmbeddedCinematicVideoPlayer __instance) { if (FindVideoFile(((CinematicVideoPlayer)__instance).Config.VideoReference.VideoFileName) != null) { Platform.Current.RestoreFrameRate(); } } private static void ConstructorPostfix(EmbeddedCinematicVideoPlayer __instance, CinematicVideoPlayerConfig config) { string text = FindVideoFile(config.VideoReference.VideoFileName); if (text != null) { __instance.videoPlayer.url = text; __instance.videoPlayer.clip = null; __instance.videoPlayer.playbackSpeed = 1f; if (Object.op_Implicit((Object)(object)config.AudioSource)) { AudioSource val = ((Component)config.AudioSource).gameObject.AddComponent<AudioSource>(); val.playOnAwake = false; __instance.videoPlayer.audioOutputMode = (VideoAudioOutputMode)1; __instance.videoPlayer.SetTargetAudioSource((ushort)0, val); __instance.videoPlayer.controlledAudioTrackCount = 1; val.volume = 1f; } else { Plugin.Logger.LogWarning((object)("Using custom video file '" + config.VideoReference.VideoFileName + "' with direct audio output. This may result in no audio being played.")); __instance.videoPlayer.audioOutputMode = (VideoAudioOutputMode)2; } __instance.videoPlayer.Prepare(); } } private static void PlayVideoPostfix(EmbeddedCinematicVideoPlayer __instance) { if (FindVideoFile(((CinematicVideoPlayer)__instance).Config.VideoReference.VideoFileName) != null && !__instance.isSeeking) { ((CinematicVideoPlayer)__instance).StopAudio(); } } } public class SpriteFileWatcher { public FileSystemWatcher SpriteWatcher; public FileSystemWatcher AtlasWatcher; public static bool ReloadSprites; public SpriteFileWatcher() { SpriteWatcher = new FileSystemWatcher(); SpriteWatcher.Path = SpriteLoader.LoadPath; SpriteWatcher.IncludeSubdirectories = true; SpriteWatcher.Filter = "*.png"; SpriteWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite; SpriteWatcher.Changed += OnSpriteChanged; SpriteWatcher.Created += OnSpriteChanged; SpriteWatcher.Deleted += OnSpriteChanged; SpriteWatcher.Renamed += OnSpriteChanged; SpriteWatcher.EnableRaisingEvents = true; AtlasWatcher = new FileSystemWatcher(); AtlasWatcher.Path = SpriteLoader.AtlasLoadPath; AtlasWatcher.IncludeSubdirectories = true; AtlasWatcher.Filter = "*.png"; AtlasWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite; AtlasWatcher.Changed += OnAtlasChanged; AtlasWatcher.Created += OnAtlasChanged; AtlasWatcher.Deleted += OnAtlasChanged; AtlasWatcher.Renamed += OnAtlasChanged; AtlasWatcher.EnableRaisingEvents = true; } private void OnSpriteChanged(object sender, FileSystemEventArgs e) { string relativePath = Path.GetRelativePath(SpriteLoader.LoadPath, e.FullPath); string[] array = relativePath.Split(Path.DirectorySeparatorChar); if (array[^2] == "T2D" || (array.Length >= 3 && array[^3] == "T2D")) { T2DHandler.InvalidateCache(Path.GetFileNameWithoutExtension(array[^1])); ReloadSprites = true; } else if (array.Length >= 3) { string text = array[^3]; string text2 = array[^2]; string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(array[^1]); SpriteLoader.MarkReloadSprite(text, text2, fileNameWithoutExtension); Plugin.Logger.LogDebug((object)$"Invalidated cache for collection {text}, atlas {text2}, sprite {fileNameWithoutExtension} due to file change: {e.ChangeType} {e.FullPath}"); ReloadSprites = true; } } private void OnAtlasChanged(object sender, FileSystemEventArgs e) { string relativePath = Path.GetRelativePath(SpriteLoader.AtlasLoadPath, e.FullPath); string[] array = relativePath.Split(Path.DirectorySeparatorChar); if (array.Length >= 2) { string text = array[^2]; string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(array[^1]); SpriteLoader.MarkReloadAtlas(text, fileNameWithoutExtension); Plugin.Logger.LogDebug((object)$"Invalidated cache for collection {text} due to atlas change: {e.ChangeType} {e.FullPath}"); ReloadSprites = true; } } } } namespace Patchwork.GUI { public static class AudioList { [CompilerGenerated] private static class <>O { public static WindowFunction <0>__AudioLogWindow; } private static readonly HashSet<string> LoadedAudioClips = new HashSet<string>(); private static Vector2 scrollPosition = Vector2.zero; private static Rect windowRect = new Rect(10f, 10f, 300f, 400f); public static void DrawAudioList() { //IL_0006: 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_0035: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Rect val = windowRect; object obj = <>O.<0>__AudioLogWindow; if (obj == null) { WindowFunction val2 = AudioLogWindow; <>O.<0>__AudioLogWindow = val2; obj = (object)val2; } windowRect = GUILayout.Window(6970, val, (WindowFunction)obj, "Loaded Sounds", Array.Empty<GUILayoutOption>()); } private static void AudioLogWindow(int windowID) { //IL_0015: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_0086: Unknown result type (might be due to invalid IL or missing references) int num = 0; List<string> list = LoadedAudioClips.ToList(); list.Sort(); scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); foreach (string item in list) { GUILayout.Label(item ?? "", Array.Empty<GUILayoutOption>()); num++; } if (num == 0) { GUI.contentColor = Color.yellow; GUILayout.Label("No audio clips loaded.", Array.Empty<GUILayoutOption>()); } GUI.contentColor = Color.white; GUILayout.EndVertical(); GUILayout.EndScrollView(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } public static void LogAudio(AudioSource source) { if (!((Object)(object)source == (Object)null)) { AudioClip clip = source.clip; if (!string.IsNullOrEmpty((clip != null) ? ((Object)clip).name : null)) { string item = ((Object)source.clip).name.Replace("PATCHWORK_", ""); LoadedAudioClips.Add(item); } } } public static void ClearList() { LoadedAudioClips.Clear(); } } public static class AudioLog { internal class AudioPlayEntry { public string ClipName; public DateTime StartTime; public float GetOpacity() { return 1f - (float)((DateTime.Now - StartTime).TotalSeconds / Plugin.Config.LogAudioDuration); } public bool IsExpired() { return DateTime.Now >= StartTime.AddSeconds(Plugin.Config.LogAudioDuration); } } [CompilerGenerated] private static class <>O { public static WindowFunction <0>__AudioLogWindow; } private static readonly Dictionary<string, AudioPlayEntry> AudioPlayLog = new Dictionary<string, AudioPlayEntry>(); private static Rect windowRect = new Rect((float)(Screen.width - 310), 10f, 300f, 400f); public static void DrawAudioLog() { //IL_0006: 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_0035: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Rect val = windowRect; object obj = <>O.<0>__AudioLogWindow; if (obj == null) { WindowFunction val2 = AudioLogWindow; <>O.<0>__AudioLogWindow = val2; obj = (object)val2; } windowRect = GUILayout.Window(6969, val, (WindowFunction)obj, "Patchwork Audio Log", Array.Empty<GUILayoutOption>()); } private static void AudioLogWindow(int windowID) { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) int num = 0; List<AudioPlayEntry> list = new List<AudioPlayEntry>(AudioPlayLog.Values); list.Sort((AudioPlayEntry a, AudioPlayEntry b) => a.ClipName.CompareTo(b.ClipName)); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); Color contentColor = default(Color); foreach (AudioPlayEntry item in list) { if (item.IsExpired()) { AudioPlayLog.Remove(item.ClipName); } else if (!Plugin.Config.HideModdedAudioInLog || !File.Exists(Path.Combine(AudioHandler.SoundFolder, item.ClipName + ".wav"))) { float opacity = item.GetOpacity(); ((Color)(ref contentColor))..ctor(1f, 1f, 1f, opacity); GUI.contentColor = contentColor; GUILayout.Label(item.ClipName ?? "", Array.Empty<GUILayoutOption>()); num++; } } if (num == 0) { GUI.contentColor = Color.yellow; GUILayout.Label("No audio played recently.", Array.Empty<GUILayoutOption>()); } GUI.contentColor = Color.white; GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } public static void LogAudio(AudioClip clip) { AudioPlayLog[((Object)clip).name] = new AudioPlayEntry { ClipName = ((Object)clip).name.Replace("PATCHWORK_", ""), StartTime = DateTime.Now }; } public static void ClearLog() { AudioPlayLog.Clear(); } } public static class TextLog { internal class TextLogEntry { public string SheetName; public string KeyName; public string Text; public DateTime LogTime; public float GetOpacity() { double totalSeconds = (DateTime.Now - LogTime).TotalSeconds; if (totalSeconds >= Plugin.Config.TextLogDuration) { return 0.2f; } float num = 0.8f; return 1f - (float)(totalSeconds / Plugin.Config.TextLogDuration) * num; } public bool IsExpired() { double totalSeconds = (DateTime.Now - LogTime).TotalSeconds; return totalSeconds >= Plugin.Config.TextLogDuration; } } [CompilerGenerated] private static class <>O { public static WindowFunction <0>__TextLogWindow; } private static readonly List<TextLogEntry> TextLogEntries = new List<TextLogEntry>(); private static readonly int MaxPreviewLength = 50; private static Rect windowRect = new Rect((float)(Screen.width - 710), 10f, 700f, 400f); private static Vector2 scrollPosition = Vector2.zero; public static void DrawTextLog() { //IL_0006: 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_0035: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Rect val = windowRect; object obj = <>O.<0>__TextLogWindow; if (obj == null) { WindowFunction val2 = TextLogWindow; <>O.<0>__TextLogWindow = val2; obj = (object)val2; } windowRect = GUILayout.Window(6971, val, (WindowFunction)obj, "Patchwork Text Log", Array.Empty<GUILayoutOption>()); } private static void TextLogWindow(int windowID) { //IL_002b: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) TextLogEntries.RemoveAll((TextLogEntry entry) => entry.IsExpired()); scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); Color contentColor = default(Color); foreach (TextLogEntry textLogEntry in TextLogEntries) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); float opacity = textLogEntry.GetOpacity(); ((Color)(ref contentColor))..ctor(1f, 1f, 1f, opacity); GUI.skin.label.fontSize = 14; GUI.contentColor = contentColor; GUILayout.Label(textLogEntry.SheetName + "." + textLogEntry.KeyName + ":", Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUI.contentColor = new Color(0.8f, 0.8f, 0.8f, opacity); string text = textLogEntry.Text.Replace("\n", "\\n").Replace("\r", "\\r"); if (text.Length > MaxPreviewLength) { text = text.Substring(0, MaxPreviewLength - 3) + "..."; } GUILayout.Label(text, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); } if (TextLogEntries.Count == 0) { GUILayout.Label("No log entries.", Array.Empty<GUILayoutOption>()); } GUILayout.EndVertical(); GUILayout.EndScrollView(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } public static void LogText(string sheet, string key, string text) { TextLogEntry textLogEntry = TextLogEntries.Find((TextLogEntry entry) => entry.SheetName == sheet && entry.KeyName == key); if (textLogEntry != null) { TextLogEntries.Remove(textLogEntry); } TextLogEntries.Add(new TextLogEntry { SheetName = sheet, KeyName = key, Text = text, LogTime = DateTime.Now }); } public static void ClearLog() { TextLogEntries.Clear(); } } }