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 Stitchwork v0.8.0
plugins/StitchworkRoot/Stitchwork.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GlobalEnums; using HarmonyLib; using Microsoft.CodeAnalysis; using Stitchwork; using Stitchwork.GUI; using Stitchwork.GUI.Pillars; using Stitchwork.Handlers; using Stitchwork.Packs; using Stitchwork.Util; using Stitchwork.Watchers; using TeamCherry.Cinematics; using TeamCherry.Localization; using Unity.Mathematics; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.Scripting; using UnityEngine.UI; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Stitchwork")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.8.0.0")] [assembly: AssemblyInformationalVersion("0.8.0+0475ee1ae4a7529149d6d3ad4b00f66006b5e890")] [assembly: AssemblyProduct("Stitchwork")] [assembly: AssemblyTitle("Stitchwork")] [assembly: AssemblyMetadata("GameLibsPin", "1.2.0-silksong1.0.30000")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.8.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [HarmonyPatch] public static class AnimationController { private sealed class AnimEntry { public string Name; public int Seq; public tk2dSpriteAnimator Live; public bool Stale; public float LastSeenRealtime; public tk2dSpriteAnimationClip Clip; public tk2dSpriteCollectionData FrameColl; public int Frame; public int SpriteId; public string ClipName; public string CollName; public string SpriteName; public int FrameCount; public tk2dSpriteAnimation Library; public tk2dSpriteAnimationClip ViewClip; public int ViewFrame; public readonly List<string> RecentClips = new List<string>(); } private sealed class ClipCoverage { public int Frames; public int Shared; public int PerClip; } private static bool Paused = false; private static bool FrameChangeRequested = false; private static bool Frozen = false; private static Vector3 FrozenPosition; private const string HeroName = "Hero_Hornet(Clone)"; private const int MaxRecentClips = 5; private static readonly Dictionary<string, AnimEntry> _entries = new Dictionary<string, AnimEntry>(); private static int _seqCounter = 0; private const int MaxEntries = 64; private static readonly Color ColStale = new Color(0.5f, 0.5f, 0.5f); private static bool _browseClips; private static Vector2 _objectScroll; private static Vector2 _clipScroll; private static string _clipSearch = ""; private static tk2dSpriteCollectionData _lensColl; private static int _lensSpriteId = -1; private static string _lensSpriteName; private static Action _pendingUiAction; private static bool _previewPlaying; private static tk2dSpriteAnimationClip _previewClip; private static int _previewFrame; private static float _previewClock; private static float _previewFps = 12f; private const float PreviewFallbackFps = 12f; private static readonly Dictionary<(int libId, string clip), ClipCoverage> _coverage = new Dictionary<(int, string), ClipCoverage>(); private static int _coverageIndexVersion = -1; private const string KeybindHex = "#B78CFF"; private static GUIStyle _transportStyle; private static GUIStyle _hintStyle; private static Texture2D _spritePreviewTex; private static int _spvCollId = 0; private static int _spvSpriteId = -1; private static int _spvFileVer = -1; private static readonly Dictionary<(int coll, int sprite), Texture2D> _thumbCache = new Dictionary<(int, int), Texture2D>(); private static int _thumbFileVer = -1; private const int ThumbCacheCap = 96; private const int ThumbRenderSize = 96; private static Texture2D _previewWhite; private static string _reuseCacheKey = null; private static int _reuseFrameCount = 0; private static int _reuseClipCount = 0; private static readonly List<(tk2dSpriteAnimationClip Clip, List<int> Frames)> _reuseSources = new List<(tk2dSpriteAnimationClip, List<int>)>(); private static string _anchorCacheKey = null; private static bool _anchorReplExists = false; private static string _anchorCurrent = null; private static string _anchorFilePath = null; private static string _anchorPackSource = null; public static string SelectedAnimator { get; private set; } = null; private static GUIStyle TransportStyle { get { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown int num = GUIHelper.FontSize(12); if (_transportStyle == null || _transportStyle.fontSize != num) { _transportStyle = new GUIStyle(GUI.skin.button) { fontSize = num, richText = true, alignment = (TextAnchor)4 }; } return _transportStyle; } } private static GUIStyle HintStyle { get { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown int num = GUIHelper.FontSize(12); if (_hintStyle == null || _hintStyle.fontSize != num) { _hintStyle = new GUIStyle(GUI.skin.label) { fontSize = num, wordWrap = true }; } return _hintStyle; } } internal static void SelectFromWorldPick(string name) { SelectedAnimator = name; _browseClips = true; } public static void RegisterAnimator(tk2dSpriteAnimator animator) { if (!((Object)(object)animator == (Object)null) && !((Object)(object)((Component)animator).gameObject == (Object)null)) { string name = ((Object)((Component)animator).gameObject).name; if (!_entries.TryGetValue(name, out var value)) { value = new AnimEntry { Name = name, Seq = _seqCounter++ }; _entries[name] = value; } value.Live = animator; value.Stale = false; } } public static void ClearAnimators() { _entries.Clear(); SelectedAnimator = null; Paused = false; Frozen = false; _seqCounter = 0; _browseClips = false; _clipSearch = ""; ClearLens(); StopPreview(); _coverage.Clear(); ClearThumbCache(); } public static void ApplyPatches(Harmony harmony) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_030b: 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) { long heapBefore = DevProfiler.SnapshotHeapBytes(); try { if ((Object)(object)__instance != (Object)null) { RegisterAnimator(__instance); if (SelectedAnimator == ((Object)((Component)__instance).gameObject).name && Paused && !FrameChangeRequested) { return false; } } return true; } finally { DevProfiler.AddOpPositiveNetHeapDelta("Prefix.tk2dAnim.Play", heapBefore); } } 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); } private static bool TryGetLiveSelected(out tk2dSpriteAnimator animator) { animator = null; if (SelectedAnimator != null && _entries.TryGetValue(SelectedAnimator, out var value) && (Object)(object)value.Live != (Object)null && (Object)(object)((Component)value.Live).gameObject != (Object)null) { animator = value.Live; } return (Object)(object)animator != (Object)null; } public static void Update() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!GUIHelper.IsTextFieldFocused) { if (Input.GetKeyDown(Plugin.Config.AnimationControllerPauseKey)) { TogglePause(); } if (Input.GetKeyDown(Plugin.Config.AnimationControllerFreezeKey)) { ToggleFreeze(); } if (Input.GetKeyDown(Plugin.Config.AnimationControllerNextFrameKey)) { StepFrame(1); } if (Input.GetKeyDown(Plugin.Config.AnimationControllerPrevFrameKey)) { StepFrame(-1); } } if (Frozen && TryGetLiveSelected(out var animator)) { ((Component)animator).gameObject.transform.position = FrozenPosition; } if (_previewPlaying) { tk2dSpriteAnimationClip previewClip = _previewClip; if (previewClip == null || previewClip.frames == null || previewClip.frames.Length == 0) { StopPreview(); } else { int num = previewClip.frames.Length; float num2 = 1f / _previewFps; _previewClock += Time.unscaledDeltaTime; while (_previewClock >= num2) { _previewClock -= num2; _previewFrame = (_previewFrame + 1) % num; } } } foreach (AnimEntry value in _entries.Values) { tk2dSpriteAnimator live = value.Live; if ((Object)(object)live == (Object)null || (Object)(object)((Component)live).gameObject == (Object)null) { value.Live = null; MarkStale(value); continue; } if (!((Component)live).gameObject.activeSelf || live.CurrentClip == null || live.CurrentFrame < 0 || live.CurrentFrame >= live.CurrentClip.frames.Length) { MarkStale(value); continue; } RefreshSnapshot(value, live); value.Stale = false; value.ViewClip = null; value.LastSeenRealtime = Time.realtimeSinceStartup; } if (_entries.Count > 64) { EvictOldestStale(); } } private static void RefreshSnapshot(AnimEntry e, tk2dSpriteAnimator a) { tk2dSpriteAnimationClip currentClip = a.CurrentClip; int currentFrame = a.CurrentFrame; tk2dSpriteAnimationFrame val = currentClip.frames[currentFrame]; if (e.ClipName != currentClip.name) { e.RecentClips.Remove(currentClip.name); e.RecentClips.Insert(0, currentClip.name); if (e.RecentClips.Count > 5) { e.RecentClips.RemoveAt(5); } } e.Clip = currentClip; e.Frame = currentFrame; e.FrameColl = val.spriteCollection; e.SpriteId = val.spriteId; e.ClipName = currentClip.name; e.FrameCount = currentClip.frames.Length; e.Library = a.Library; if ((Object)(object)e.FrameColl != (Object)null && val.spriteId >= 0 && val.spriteId < e.FrameColl.spriteDefinitions.Length) { e.CollName = ((Object)e.FrameColl).name; e.SpriteName = e.FrameColl.spriteDefinitions[val.spriteId].name; } } private static void MarkStale(AnimEntry e) { e.Stale = true; if (e.ViewClip == null && e.Clip != null) { e.ViewClip = e.Clip; e.ViewFrame = e.Frame; } } private static void EvictOldestStale() { List<AnimEntry> list = (from e in _entries.Values where e.Stale && e.Name != SelectedAnimator && e.Name != "Hero_Hornet(Clone)" orderby e.LastSeenRealtime select e).ToList(); int num = _entries.Count - 64; int num2 = 0; while (num2 < list.Count && num > 0) { _entries.Remove(list[num2].Name); num2++; num--; } } private static void SelectAnimator(AnimEntry e) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Frozen = false; if (Paused && TryGetLiveSelected(out var animator)) { animator.Resume(); } Paused = false; SelectedAnimator = e.Name; _browseClips = true; _clipSearch = ""; _clipScroll = Vector2.zero; ClearLens(); StopPreview(); } private static void TogglePause() { StopPreview(); if (TryGetLiveSelected(out var animator)) { Paused = !Paused; if (Paused) { animator.Pause(); } else { animator.Resume(); } } } private static void ToggleFreeze() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (TryGetLiveSelected(out var animator)) { Frozen = !Frozen; FrozenPosition = ((Component)animator).gameObject.transform.position; } } private static void StepFrame(int delta) { StopPreview(); tk2dSpriteAnimator animator; if (SelectedAnimator != null && _entries.TryGetValue(SelectedAnimator, out var value) && (value.Stale || (Object)(object)value.Live == (Object)null)) { if (value.ViewClip != null && value.ViewClip.frames != null && value.ViewClip.frames.Length != 0) { int num = value.ViewClip.frames.Length; value.ViewFrame = ((value.ViewFrame + delta) % num + num) % num; } } else if (TryGetLiveSelected(out animator) && Paused && animator.CurrentClip != null) { int num2 = animator.CurrentClip.frames.Length; if (num2 > 0) { int num3 = ((animator.CurrentFrame + delta) % num2 + num2) % num2; FrameChangeRequested = true; animator.PlayFromFrame(num3); animator.UpdateAnimation(Time.deltaTime); FrameChangeRequested = false; } } } private static float ResolvePreviewFps(AnimEntry e, tk2dSpriteAnimationClip clip) { tk2dSpriteAnimator val = e?.Live; if ((Object)(object)val != (Object)null && val.CurrentClip == clip && val.ClipFps > 0f) { return val.ClipFps; } return 12f; } private static void StopPreview() { _previewPlaying = false; _previewClip = null; } private static void ClearLens() { _lensColl = null; _lensSpriteId = -1; _lensSpriteName = null; } private static void SetLens(tk2dSpriteCollectionData coll, int spriteId, string spriteName) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) _lensColl = coll; _lensSpriteId = spriteId; _lensSpriteName = spriteName; _browseClips = true; _clipScroll = Vector2.zero; } private static AnimEntry SelectedEntry() { if (SelectedAnimator == null || !_entries.TryGetValue(SelectedAnimator, out var value)) { return null; } return value; } public static void DrawPillarContent() { AnimEntry animEntry = SelectedEntry(); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (_browseClips && animEntry != null && animEntry.ClipName != null) { DrawClipStage(animEntry); } else { DrawObjectStage(); } GUILayout.EndVertical(); float num = GUIHelper.Scaled(190f); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num) }); DrawPreviewColumn(animEntry, num); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUIHelper.Space(4f); DrawConsole(animEntry); if (_pendingUiAction != null) { Action pendingUiAction = _pendingUiAction; _pendingUiAction = null; pendingUiAction(); } } private static void DrawObjectStage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = GUIHelper.ColConfirm; if (GUILayout.Button(Loc.T("Pick object in world"), GUIHelper.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Height(40f) })) { _pendingUiAction = delegate { WorldPickMode.Enter(WorldPickMode.Preset.Tk2d); }; } GUI.backgroundColor = backgroundColor; if (_entries.Count == 0) { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("No animators registered."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; return; } _objectScroll = GUILayout.BeginScrollView(_objectScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); foreach (AnimEntry item in from x in _entries.Values orderby (!(x.Name == "Hero_Hornet(Clone)")) ? 1 : 0, x.Seq select x) { if (item.ClipName != null) { DrawObjectRow(item); } } GUILayout.EndScrollView(); } private static void DrawObjectRow(AnimEntry e) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) bool flag = SelectedAnimator == e.Name; bool flag2 = e.Stale || (Object)(object)e.Live == (Object)null; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); float num = GUIHelper.Scaled(40f); DrawSpriteThumb(GUILayoutUtility.GetRect(num, num, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(num), GUILayout.Height(num) }), e.FrameColl, e.SpriteId, flag2); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUI.contentColor = (flag ? GUIHelper.ColConfirm : (flag2 ? ColStale : Color.white)); if (GUILayout.Button(e.Name, GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { _pendingUiAction = delegate { SelectAnimator(e); }; } GUI.contentColor = Color.white; GUI.contentColor = (flag2 ? ColStale : GUIHelper.ColMuted); GUILayout.Label($"{e.ClipName} · {e.Frame + 1}/{e.FrameCount}" + (flag2 ? (" " + Loc.T("(stopped)")) : ""), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUIHelper.Space(2f); } private static void DrawSpriteThumb(Rect r, tk2dSpriteCollectionData coll, int spriteId, bool dim) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: 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_020f: Unknown result type (might be due to invalid IL or missing references) EnsurePreviewWhite(); GUI.color = GUIHelper.ColSurface2; GUI.DrawTexture(r, (Texture)(object)_previewWhite); GUI.color = Color.white; if ((Object)(object)coll == (Object)null || coll.spriteDefinitions == null || spriteId < 0 || spriteId >= coll.spriteDefinitions.Length) { return; } tk2dSpriteDefinition val = coll.spriteDefinitions[spriteId]; Material val2 = val.materialInst ?? val.material; Texture val3 = (((Object)(object)val2 != (Object)null) ? val2.mainTexture : null); Vector2[] uvs = val.uvs; if ((Object)(object)val3 == (Object)null || uvs == null || uvs.Length < 4) { return; } Rect container = default(Rect); ((Rect)(ref container))..ctor(((Rect)(ref r)).x + 2f, ((Rect)(ref r)).y + 2f, ((Rect)(ref r)).width - 4f, ((Rect)(ref r)).height - 4f); GUI.color = (Color)(dim ? new Color(1f, 1f, 1f, 0.45f) : Color.white); Texture2D uprightThumb = GetUprightThumb(coll, spriteId, val, val3); if ((Object)(object)uprightThumb != (Object)null) { GUI.DrawTexture(ScaleToFitRect(container, ((Texture)uprightThumb).width, ((Texture)uprightThumb).height), (Texture)(object)uprightThumb); } else { float num = uvs.Min((Vector2 v) => v.x); float num2 = uvs.Max((Vector2 v) => v.x); float num3 = uvs.Min((Vector2 v) => v.y); float num4 = uvs.Max((Vector2 v) => v.y); int texW = Mathf.Max(1, Mathf.RoundToInt((num2 - num) * (float)val3.width)); int texH = Mathf.Max(1, Mathf.RoundToInt((num4 - num3) * (float)val3.height)); GUI.DrawTextureWithTexCoords(ScaleToFitRect(container, texW, texH), val3, new Rect(num, num3, num2 - num, num4 - num3), true); } GUI.color = Color.white; } private static void DrawClipStage(AnimEntry e) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: 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_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_031f: 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_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) bool flag = e.Stale || (Object)(object)e.Live == (Object)null; bool live = !flag && (Object)(object)e.Live != (Object)null && (Object)(object)((Component)e.Live).gameObject != (Object)null; if (GUILayout.Button("◂ " + e.Name + " · " + Loc.T("click to change object"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { _pendingUiAction = delegate { _browseClips = false; }; } if (flag) { GUI.contentColor = ColStale; GUILayout.Label(Loc.T("(stopped — inspecting the snapshot)"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } tk2dSpriteAnimation library = e.Library; if ((Object)(object)library == (Object)null || library.clips == null || library.clips.Length == 0) { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("No clip library on this object."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; return; } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(Loc.T("Search:"), GUIHelper.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(60f) }); _clipSearch = GUIHelper.TextField(_clipSearch, GUILayout.ExpandWidth(true), GUIHelper.Height(32f)); GUILayout.EndHorizontal(); if (_lensSpriteName != null) { Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = GUIHelper.ColWarn; if (GUILayout.Button(Loc.T("Reusing this sprite") + ": " + _lensSpriteName + " ✕", GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { _pendingUiAction = ClearLens; } GUI.backgroundColor = backgroundColor; } IEnumerable<tk2dSpriteAnimationClip> source = library.clips.Where((tk2dSpriteAnimationClip c) => c != null && !string.IsNullOrEmpty(c.name)); if (!string.IsNullOrEmpty(_clipSearch)) { source = source.Where((tk2dSpriteAnimationClip c) => c.name.ToLower().Contains(_clipSearch.ToLower())); } if (_lensSpriteId >= 0) { source = source.Where((tk2dSpriteAnimationClip c) => ClipUsesSprite(c, _lensColl, _lensSpriteId)); } List<tk2dSpriteAnimationClip> list = source.OrderBy<tk2dSpriteAnimationClip, string>((tk2dSpriteAnimationClip c) => c.name, StringComparer.OrdinalIgnoreCase).ToList(); GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label($"{list.Count} / {library.clips.Length}", GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; string currentClip = ((!flag) ? e.ClipName : ((e.ViewClip != null) ? e.ViewClip.name : e.ClipName)); _clipScroll = GUILayout.BeginScrollView(_clipScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); if (string.IsNullOrEmpty(_clipSearch) && _lensSpriteId < 0 && e.RecentClips.Count > 0) { GUI.contentColor = GUIHelper.ColMuted; GUILayout.Label(Loc.T("Recently played"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; foreach (string recentClip in e.RecentClips) { tk2dSpriteAnimationClip val = FindClip(library, recentClip); if (val != null) { DrawClipRow(e, library, val, currentClip, live); } } GUI.contentColor = GUIHelper.ColMuted; GUILayout.Label(Loc.T("All clips"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } foreach (tk2dSpriteAnimationClip item in list) { DrawClipRow(e, library, item, currentClip, live); } GUILayout.EndScrollView(); } private static void DrawClipRow(AnimEntry e, tk2dSpriteAnimation lib, tk2dSpriteAnimationClip clip, string currentClip, bool live) { //IL_0022: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) ClipCoverage coverage = GetCoverage(lib, clip); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.contentColor = ((coverage.Shared > 0) ? GUIHelper.ColConfirm : GUIHelper.ColBorderHi); GUILayout.Label(new GUIContent(DotFor(coverage.Shared, coverage.Frames), string.Format("{0}: {1}/{2}", Loc.T("shared replacements"), coverage.Shared, coverage.Frames)), GUIHelper.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(16f) }); GUI.contentColor = ((coverage.PerClip > 0) ? GUIHelper.ColAccent : GUIHelper.ColBorderHi); GUILayout.Label(new GUIContent(DotFor(coverage.PerClip, coverage.Frames), string.Format("{0}: {1}/{2}", Loc.T("per-clip (Appliqué)"), coverage.PerClip, coverage.Frames)), GUIHelper.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(16f) }); GUI.contentColor = Color.white; GUI.contentColor = ((clip.name == currentClip) ? GUIHelper.ColConfirm : Color.white); if (GUILayout.Button(clip.name, GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { PlayClip(e, clip, live); } GUI.contentColor = Color.white; GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label($"×{((clip.frames != null) ? clip.frames.Length : 0)}", GUIHelper.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(40f) }); GUI.contentColor = Color.white; GUILayout.EndHorizontal(); } private static void PlayClip(AnimEntry e, tk2dSpriteAnimationClip clip, bool live) { StopPreview(); if (live && (Object)(object)e.Live != (Object)null) { tk2dSpriteAnimator live2 = e.Live; Paused = true; live2.Pause(); FrameChangeRequested = true; live2.Play(clip); live2.UpdateAnimation(Time.deltaTime); FrameChangeRequested = false; } else { e.ViewClip = clip; e.ViewFrame = 0; } } private static tk2dSpriteAnimationClip FindClip(tk2dSpriteAnimation lib, string name) { tk2dSpriteAnimationClip[] clips = lib.clips; foreach (tk2dSpriteAnimationClip val in clips) { if (val != null && val.name == name) { return val; } } return null; } private static bool ClipUsesSprite(tk2dSpriteAnimationClip clip, tk2dSpriteCollectionData coll, int spriteId) { if (clip == null || clip.frames == null || (Object)(object)coll == (Object)null) { return false; } tk2dSpriteAnimationFrame[] frames = clip.frames; foreach (tk2dSpriteAnimationFrame val in frames) { if ((Object)(object)val.spriteCollection == (Object)(object)coll && val.spriteId == spriteId) { return true; } } return false; } private static string DotFor(int n, int total) { if (n > 0) { if (n < total) { return "◐"; } return "●"; } return "○"; } private static ClipCoverage GetCoverage(tk2dSpriteAnimation lib, tk2dSpriteAnimationClip clip) { if (_coverageIndexVersion != SpriteLoader.FileIndexVersion) { _coverage.Clear(); _coverageIndexVersion = SpriteLoader.FileIndexVersion; } (int, string) key = (((Object)lib).GetInstanceID(), clip.name); if (_coverage.TryGetValue(key, out var value)) { return value; } value = new ClipCoverage(); if (clip.frames != null) { tk2dSpriteAnimationFrame[] frames = clip.frames; foreach (tk2dSpriteAnimationFrame val in frames) { tk2dSpriteCollectionData spriteCollection = val.spriteCollection; if ((Object)(object)spriteCollection == (Object)null || spriteCollection.spriteDefinitions == null || val.spriteId < 0 || val.spriteId >= spriteCollection.spriteDefinitions.Length) { continue; } tk2dSpriteDefinition val2 = spriteCollection.spriteDefinitions[val.spriteId]; if (!string.IsNullOrEmpty(val2.name)) { value.Frames++; if (SpriteLoader.HasSpriteReplacement(spriteCollection, val2)) { value.Shared++; } if (AppliqueLoader.HasClipOverride(((Object)spriteCollection).name, clip.name, val2.name)) { value.PerClip++; } } } } _coverage[key] = value; return value; } private static bool TryResolveDisplay(AnimEntry e, out tk2dSpriteAnimationClip clip, out tk2dSpriteCollectionData coll, out int spriteId, out int frame, out int frameCount) { clip = null; coll = null; spriteId = -1; frame = 0; frameCount = 0; if (e == null || e.ClipName == null) { return false; } if (_previewPlaying && _previewClip != null && _previewClip.frames != null && _previewClip.frames.Length != 0) { int num = _previewClip.frames.Length; int num2 = (_previewFrame % num + num) % num; tk2dSpriteAnimationFrame val = _previewClip.frames[num2]; clip = _previewClip; coll = val.spriteCollection; spriteId = val.spriteId; frame = num2; frameCount = num; return true; } if ((e.Stale || (Object)(object)e.Live == (Object)null) && e.ViewClip != null && e.ViewClip.frames != null && e.ViewClip.frames.Length != 0) { int num3 = Mathf.Clamp(e.ViewFrame, 0, e.ViewClip.frames.Length - 1); tk2dSpriteAnimationFrame val2 = e.ViewClip.frames[num3]; clip = e.ViewClip; coll = val2.spriteCollection; spriteId = val2.spriteId; frame = num3; frameCount = e.ViewClip.frames.Length; } else { clip = e.Clip; coll = e.FrameColl; spriteId = e.SpriteId; frame = e.Frame; frameCount = e.FrameCount; } return true; } private static void DrawPreviewColumn(AnimEntry e, float colW) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: 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_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Invalid comparison between Unknown and I4 //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: 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_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_0590: Unknown result type (might be due to invalid IL or missing references) //IL_05d5: Unknown result type (might be due to invalid IL or missing references) //IL_05ce: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0366: 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_036d: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Unknown result type (might be due to invalid IL or missing references) //IL_06a2: Unknown result type (might be due to invalid IL or missing references) //IL_06dc: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_0717: Unknown result type (might be due to invalid IL or missing references) //IL_0742: Unknown result type (might be due to invalid IL or missing references) //IL_0761: Unknown result type (might be due to invalid IL or missing references) //IL_079b: Unknown result type (might be due to invalid IL or missing references) //IL_0794: Unknown result type (might be due to invalid IL or missing references) //IL_07ba: Unknown result type (might be due to invalid IL or missing references) //IL_07e5: Unknown result type (might be due to invalid IL or missing references) //IL_080b: Unknown result type (might be due to invalid IL or missing references) //IL_084c: Unknown result type (might be due to invalid IL or missing references) if (e == null || !TryResolveDisplay(e, out var clip, out var coll, out var spriteId, out var frame, out var _)) { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("Select an object to preview."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; return; } if ((Object)(object)coll == (Object)null || coll.spriteDefinitions == null || spriteId < 0 || spriteId >= coll.spriteDefinitions.Length) { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("Preview unavailable — the animator's atlas was unloaded."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; return; } tk2dSpriteDefinition val = coll.spriteDefinitions[spriteId]; Material val2 = val.materialInst ?? val.material; if ((Object)(object)val2 == (Object)null || (Object)(object)val2.mainTexture == (Object)null) { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("Preview unavailable — material/texture released."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; return; } Texture mainTexture = val2.mainTexture; Vector2[] uvs = val.uvs; bool flag = uvs != null && uvs.Length >= 4; float num = 0f; float num2 = 1f; float num3 = 0f; float num4 = 1f; if (flag) { num = uvs.Min((Vector2 v) => v.x); num2 = uvs.Max((Vector2 v) => v.x); num3 = uvs.Min((Vector2 v) => v.y); num4 = uvs.Max((Vector2 v) => v.y); } float num5 = colW - GUIHelper.Scaled(8f); Rect rect = GUILayoutUtility.GetRect(num5, num5, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(num5), GUILayout.Height(num5) }); GUIHelper.DrawPreviewBackdrop(rect); GUI.DrawTexture(rect, mainTexture, (ScaleMode)2, true); if (flag) { Rect val3 = ScaleToFitRect(rect, mainTexture.width, mainTexture.height); float num6 = ((Rect)(ref val3)).x + num * ((Rect)(ref val3)).width; float num7 = ((Rect)(ref val3)).y + (1f - num4) * ((Rect)(ref val3)).height; float num8 = (num2 - num) * ((Rect)(ref val3)).width; float num9 = (num4 - num3) * ((Rect)(ref val3)).height; EnsurePreviewWhite(); GUI.color = new Color(1f, 1f, 0f, 0.4f); GUI.DrawTexture(new Rect(num6, num7, num8, num9), (Texture)(object)_previewWhite); GUI.color = Color.white; } GUI.contentColor = ColStale; GUILayout.Label(Loc.T("Atlas"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; Rect rect2 = GUILayoutUtility.GetRect(num5, num5, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(num5), GUILayout.Height(num5) }); GUIHelper.DrawPreviewBackdrop(rect2); if ((int)Event.current.type == 7 && flag) { Texture2D uprightSpriteTex = GetUprightSpriteTex(coll, spriteId, val, mainTexture); Rect val4; if ((Object)(object)uprightSpriteTex != (Object)null) { val4 = ScaleToFitRect(rect2, ((Texture)uprightSpriteTex).width, ((Texture)uprightSpriteTex).height); GUI.DrawTexture(val4, (Texture)(object)uprightSpriteTex); } else { int texW = Mathf.Max(1, Mathf.RoundToInt((num2 - num) * (float)mainTexture.width)); int texH = Mathf.Max(1, Mathf.RoundToInt((num4 - num3) * (float)mainTexture.height)); val4 = ScaleToFitRect(rect2, texW, texH); GUI.DrawTextureWithTexCoords(val4, mainTexture, new Rect(num, num3, num2 - num, num4 - num3), true); } Vector3[] positions = val.positions; if (positions != null && positions.Length >= 4) { float num10 = positions.Min((Vector3 p) => p.x); float num11 = positions.Max((Vector3 p) => p.x); float num12 = positions.Min((Vector3 p) => p.y); float num13 = positions.Max((Vector3 p) => p.y); float num14 = num11 - num10; float num15 = num13 - num12; if (num14 > 1E-06f && num15 > 1E-06f) { float num16 = (0f - num10) / num14; float num17 = (0f - num12) / num15; float num18 = ((Rect)(ref val4)).x + num16 * ((Rect)(ref val4)).width; float num19 = ((Rect)(ref val4)).y + (1f - num17) * ((Rect)(ref val4)).height; EnsurePreviewWhite(); GUI.color = new Color(1f, 0.15f, 0.8f, 0.95f); GUI.DrawTexture(new Rect(num18 - 6f, num19 - 0.5f, 13f, 1f), (Texture)(object)_previewWhite); GUI.DrawTexture(new Rect(num18 - 0.5f, num19 - 6f, 1f, 13f), (Texture)(object)_previewWhite); GUI.color = Color.white; } } } GUI.contentColor = ColStale; GUILayout.Label(Loc.T("Sprite ⊹ = pivot"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; GUIHelper.DrawBackdropSliderRow(); GUIHelper.Space(4f); GUILayout.BeginVertical(GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUI.contentColor = (_previewPlaying ? GUIHelper.ColConfirm : Color.white); if (GUILayout.Button(_previewPlaying ? ("▮▮ " + Loc.T("Preview")) : ("▶ " + Loc.T("Preview")), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { if (_previewPlaying) { StopPreview(); } else if (clip != null && clip.frames != null && clip.frames.Length != 0) { _previewClip = clip; _previewFrame = frame; _previewClock = 0f; _previewFps = ResolvePreviewFps(e, clip); _previewPlaying = true; } } GUI.contentColor = Color.white; float num20 = GUIHelper.Scaled(38f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(TransportLabel("|◀", Loc.T("Prev"), Plugin.Config.AnimationControllerPrevFrameKey), TransportStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num20) })) { StepFrame(-1); } GUI.contentColor = (Paused ? GUIHelper.ColWarn : Color.white); if (GUILayout.Button(TransportLabel(Paused ? "▶" : "▮▮", Loc.T(Paused ? "Play" : "Pause"), Plugin.Config.AnimationControllerPauseKey), TransportStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num20) })) { TogglePause(); } GUI.contentColor = Color.white; if (GUILayout.Button(TransportLabel("▶|", Loc.T("Next"), Plugin.Config.AnimationControllerNextFrameKey), TransportStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num20) })) { StepFrame(1); } GUI.contentColor = (Frozen ? Color.cyan : Color.white); if (GUILayout.Button(TransportLabel("❄", Loc.T("Freeze"), Plugin.Config.AnimationControllerFreezeKey), TransportStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num20) })) { ToggleFreeze(); } GUI.contentColor = Color.white; GUILayout.EndHorizontal(); bool num21 = e.Stale || (Object)(object)e.Live == (Object)null; GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(num21 ? Loc.T("Stopped — stepping browses the snapshot.") : ((!Paused) ? Loc.T("Pause to step frames.") : " "), HintStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; GUILayout.EndVertical(); } private static string TransportLabel(string symbol, string word, KeyCode key) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) return symbol + " " + word + "\n<color=#B78CFF>[" + KeyName(key) + "]</color>"; } internal static void OpenSpriteForEdit(tk2dSpriteCollectionData coll, tk2dSpriteDefinition def) { if ((Object)(object)coll == (Object)null || def == null || string.IsNullOrEmpty(def.name)) { return; } Material val = def.materialInst ?? def.material; if ((Object)(object)val == (Object)null) { return; } string text = ((Object)val).name.Split(' ')[0]; string text2 = Path.Combine(SpriteLoader.LoadPath, ((Object)coll).name, text, def.name + ".png"); if (!File.Exists(text2)) { SpriteDumper.DumpSingleSprite(def, coll); string text3 = Path.Combine(SpriteDumper.DumpPath, ((Object)coll).name, text, def.name + ".png"); if (!File.Exists(text3)) { Plugin.Logger.LogError((object)("Failed to dump sprite for editing: " + ((Object)coll).name + "/" + text + "/" + def.name)); return; } IOUtil.EnsureDirectoryExists(Path.Combine(SpriteLoader.LoadPath, ((Object)coll).name, text)); File.Copy(text3, text2, overwrite: true); } Process.Start(text2); _anchorCacheKey = null; } internal static Texture2D GetUprightSpriteTexShared(tk2dSpriteCollectionData coll, int spriteId) { if ((Object)(object)coll == (Object)null || coll.spriteDefinitions == null || spriteId < 0 || spriteId >= coll.spriteDefinitions.Length) { return null; } tk2dSpriteDefinition val = coll.spriteDefinitions[spriteId]; Material val2 = (((Object)(object)val.materialInst != (Object)null) ? val.materialInst : val.material); Texture val3 = (((Object)(object)val2 != (Object)null) ? val2.mainTexture : null); if ((Object)(object)val3 == (Object)null) { return null; } return GetUprightSpriteTex(coll, spriteId, val, val3); } private static Texture2D GetUprightSpriteTex(tk2dSpriteCollectionData coll, int spriteId, tk2dSpriteDefinition def, Texture atlas) { int instanceID = ((Object)coll).GetInstanceID(); int fileIndexVersion = SpriteLoader.FileIndexVersion; if ((Object)(object)_spritePreviewTex != (Object)null && _spvCollId == instanceID && _spvSpriteId == spriteId && _spvFileVer == fileIndexVersion) { return _spritePreviewTex; } Texture2D val = RenderUprightNew(def, atlas, 2048); if ((Object)(object)val == (Object)null) { return null; } if ((Object)(object)_spritePreviewTex != (Object)null) { Object.Destroy((Object)(object)_spritePreviewTex); } _spritePreviewTex = val; _spvCollId = instanceID; _spvSpriteId = spriteId; _spvFileVer = fileIndexVersion; return _spritePreviewTex; } private static Texture2D RenderUprightNew(tk2dSpriteDefinition def, Texture atlas, int maxSize) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Invalid comparison between Unknown and I4 //IL_0236: 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_02a4: 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_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Expected O, but got Unknown //IL_034e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)TexUtil.RotateMaterial == (Object)null || (Object)(object)atlas == (Object)null) { return null; } Vector2[] uvs = def.uvs; Vector3[] positions = def.positions; if (uvs == null || uvs.Length < 4 || positions == null || positions.Length < 4) { return null; } float num = uvs[0].x; float num2 = num; float num3 = uvs[0].y; float num4 = num3; for (int i = 1; i < 4; i++) { num = Mathf.Min(num, uvs[i].x); num2 = Mathf.Max(num2, uvs[i].x); num3 = Mathf.Min(num3, uvs[i].y); num4 = Mathf.Max(num4, uvs[i].y); } int num5 = Mathf.RoundToInt((num2 - num) * (float)atlas.width); int num6 = Mathf.RoundToInt((num4 - num3) * (float)atlas.height); bool num7 = (int)def.flipped > 0; int num8 = Mathf.Clamp(num7 ? num6 : num5, 1, 2048); int num9 = Mathf.Clamp(num7 ? num5 : num6, 1, 2048); if (Mathf.Max(num8, num9) > maxSize) { float num10 = (float)maxSize / (float)Mathf.Max(num8, num9); num8 = Mathf.Max(1, Mathf.RoundToInt((float)num8 * num10)); num9 = Mathf.Max(1, Mathf.RoundToInt((float)num9 * num10)); } float num11 = positions[0].x; float num12 = num11; float num13 = positions[0].y; float num14 = num13; for (int j = 1; j < 4; j++) { num11 = Mathf.Min(num11, positions[j].x); num12 = Mathf.Max(num12, positions[j].x); num13 = Mathf.Min(num13, positions[j].y); num14 = Mathf.Max(num14, positions[j].y); } float num15 = num12 - num11; float num16 = num14 - num13; if (num15 < 1E-06f || num16 < 1E-06f) { return null; } float num17 = (float)num8 / num15; float num18 = (float)num9 / num16; RenderTexture active = RenderTexture.active; RenderTexture temporary = RenderTexture.GetTemporary(num8, num9, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1); Texture2D val; try { RenderTexture.active = temporary; GL.Clear(true, true, Color.clear); GL.PushMatrix(); GL.LoadPixelMatrix(0f, (float)num8, 0f, (float)num9); TexUtil.RotateMaterial.SetVector("_Basis", new Vector4(1f, 0f, 0f, 1f)); TexUtil.RotateMaterial.SetTexture("_MainTex", atlas); TexUtil.RotateMaterial.SetPass(0); GL.Begin(7); GL.Color(Color.white); int[] array = new int[4] { 0, 1, 3, 2 }; foreach (int num19 in array) { GL.TexCoord(Vector2.op_Implicit(uvs[num19])); GL.Vertex3((positions[num19].x - num11) * num17, (positions[num19].y - num13) * num18, 0f); } GL.End(); GL.PopMatrix(); val = new Texture2D(num8, num9, (TextureFormat)4, false) { hideFlags = (HideFlags)32 }; val.ReadPixels(new Rect(0f, 0f, (float)num8, (float)num9), 0, 0); val.Apply(); } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } FlipPreviewHorizontal(val, num8, num9); return val; } internal static void ClearThumbCache() { foreach (Texture2D value in _thumbCache.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } _thumbCache.Clear(); } private static Texture2D GetUprightThumb(tk2dSpriteCollectionData coll, int spriteId, tk2dSpriteDefinition def, Texture atlas) { int fileIndexVersion = SpriteLoader.FileIndexVersion; if (fileIndexVersion != _thumbFileVer) { ClearThumbCache(); _thumbFileVer = fileIndexVersion; } (int, int) key = (((Object)coll).GetInstanceID(), spriteId); if (_thumbCache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } if (_thumbCache.Count >= 96) { ClearThumbCache(); } Texture2D val = RenderUprightNew(def, atlas, 96); if ((Object)(object)val != (Object)null) { _thumbCache[key] = val; } return val; } private static void FlipPreviewHorizontal(Texture2D tex, int w, int h) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Color32[] pixels = tex.GetPixels32(); Color32[] array = (Color32[])(object)new Color32[pixels.Length]; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { array[i * w + j] = pixels[i * w + (w - 1 - j)]; } } tex.SetPixels32(array); tex.Apply(); } private static void DrawConsole(AnimEntry e) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Invalid comparison between Unknown and I4 //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022f: 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_0264: 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_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Invalid comparison between Unknown and I4 //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_08a0: Unknown result type (might be due to invalid IL or missing references) //IL_08d3: Unknown result type (might be due to invalid IL or missing references) //IL_09ae: Unknown result type (might be due to invalid IL or missing references) //IL_09d2: Unknown result type (might be due to invalid IL or missing references) //IL_08f6: Unknown result type (might be due to invalid IL or missing references) //IL_0928: Unknown result type (might be due to invalid IL or missing references) //IL_097e: Unknown result type (might be due to invalid IL or missing references) //IL_09a2: Unknown result type (might be due to invalid IL or missing references) //IL_0a19: Unknown result type (might be due to invalid IL or missing references) //IL_0a3d: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_0de5: Unknown result type (might be due to invalid IL or missing references) //IL_0dea: Unknown result type (might be due to invalid IL or missing references) if (e == null || !TryResolveDisplay(e, out var clip, out var coll, out var spriteId, out var frame, out var frameCount) || (Object)(object)coll == (Object)null || coll.spriteDefinitions == null || spriteId < 0 || spriteId >= coll.spriteDefinitions.Length) { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("Select an object to see its controls."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; return; } tk2dSpriteDefinition val = coll.spriteDefinitions[spriteId]; Material val2 = val.materialInst ?? val.material; if ((Object)(object)val2 == (Object)null) { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("Preview unavailable — material/texture released."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; return; } string text = ((Object)val2).name.Split(' ')[0]; bool flag = e.Stale || (Object)(object)e.Live == (Object)null; bool flag2 = !flag && (Object)(object)e.Live != (Object)null && (Object)(object)((Component)e.Live).gameObject != (Object)null; string text2 = ((Object)coll).GetInstanceID() + "/" + spriteId; if (_reuseCacheKey != text2 && (int)Event.current.type == 8) { _reuseCacheKey = text2; RecomputeReuse(e, coll, spriteId); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); string text3 = ((clip != null) ? clip.name : (e.ClipName ?? "?")); GUILayout.Label(string.Format("{0} · {1} {2}/{3}", text3, Loc.T("Frame"), frame + 1, frameCount) + (flag ? (" " + Loc.T("(stopped)")) : ""), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); if (Paused && flag2) { GUI.contentColor = GUIHelper.ColWarn; GUILayout.Label(Loc.T("[PAUSED]"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } if (Frozen && flag2) { GUI.contentColor = Color.cyan; GUILayout.Label(Loc.T("[FROZEN]"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } if (_previewPlaying) { GUI.contentColor = GUIHelper.ColConfirm; GUILayout.Label(Loc.T("[PREVIEW]"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } GUILayout.FlexibleSpace(); if (_reuseFrameCount > 1) { int num = 0; foreach (var reuseSource in _reuseSources) { if (reuseSource.Clip == clip) { num = reuseSource.Frames.Count; break; } } GUI.contentColor = GUIHelper.ColWarn; if (GUILayout.Button(string.Format("{0} ×{1} · ", Loc.T("Reused frames"), _reuseFrameCount) + string.Format(Loc.T("{0} clips@anim", "{0} clips"), _reuseClipCount) + ((num > 1) ? (" " + string.Format(Loc.T("({0} in this clip)"), num)) : ""), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { tk2dSpriteCollectionData lensColl = coll; int lensId = spriteId; string lensName = val.name; _pendingUiAction = delegate { SetLens(lensColl, lensId, lensName); }; } GUI.contentColor = Color.white; } else { GUI.contentColor = GUIHelper.ColConfirm; GUILayout.Label(Loc.T("Only used here — safe to edit in isolation."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } GUILayout.EndHorizontal(); string text4 = ""; if (clip != null && clip.fps > 0f) { text4 = " · " + string.Format(Loc.T("clip {0:F0} fps"), clip.fps); tk2dSpriteAnimator live = e.Live; if ((Object)(object)live != (Object)null && live.CurrentClip == clip && live.ClipFps > 0f && Mathf.Abs(live.ClipFps - clip.fps) > 0.05f) { text4 += string.Format(Loc.T(" → {0:F0} live"), live.ClipFps); } } GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(((Object)coll).name + " · " + text + " · " + val.name + text4, GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; string text5 = ((Object)coll).name + "/" + text + "/" + val.name; if (_anchorCacheKey != text5 && (int)Event.current.type == 8) { _anchorCacheKey = text5; _anchorReplExists = false; _anchorCurrent = null; _anchorFilePath = null; _anchorPackSource = null; foreach (string pluginPackPath in Plugin.PluginPackPaths) { if (FindTaggedOrPlain(Path.Combine(pluginPackPath, "Sprites", ((Object)coll).name, text), val.name) != null) { string path = pluginPackPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); string fileName = Path.GetFileName(path); if (string.Equals(fileName, "Stitchwork", StringComparison.OrdinalIgnoreCase) || string.Equals(fileName, "Patchwork", StringComparison.OrdinalIgnoreCase)) { fileName = Path.GetFileName(Path.GetDirectoryName(path)); } _anchorPackSource = fileName; break; } } if (_anchorPackSource == null) { string text6 = FindTaggedOrPlain(Path.Combine(SpriteLoader.LoadPath, ((Object)coll).name, text), val.name); if (text6 != null) { _anchorReplExists = true; _anchorFilePath = text6; _anchorCurrent = IOUtil.ParseAnchorTag(Path.GetFileNameWithoutExtension(text6)).anchor; } } } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical(GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Label(Loc.T("This Sprite"), GUIHelper.SectionHeaderStyle, Array.Empty<GUILayoutOption>()); if (GUILayout.Button(Loc.T("Edit Current Sprite"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { OpenSpriteForEdit(coll, val); } GUI.enabled = clip != null; if (GUILayout.Button(Loc.T("Detach for This Clip"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { if (clip.name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) { Plugin.Logger.LogWarning((object)("[AnimCtrl] Detach: clip name '" + clip.name + "' isn't filesystem-safe.")); } else { string text7 = Path.Combine(SpriteLoader.LoadPath, ((Object)coll).name, "Clips", clip.name); string text8 = Path.Combine(text7, val.name + ".png"); if (!File.Exists(text8)) { string text9 = Path.Combine(SpriteLoader.LoadPath, ((Object)coll).name, text, val.name + ".png"); string text10 = (File.Exists(text9) ? text9 : null); if (text10 == null) { SpriteDumper.DumpSingleSprite(val, coll); string text11 = Path.Combine(SpriteDumper.DumpPath, ((Object)coll).name, text, val.name + ".png"); if (File.Exists(text11)) { text10 = text11; } } if (text10 == null) { Plugin.Logger.LogError((object)("[AnimCtrl] Detach: no source for " + ((Object)coll).name + "/" + text + "/" + val.name)); } else { IOUtil.EnsureDirectoryExists(text7); File.Copy(text10, text8, overwrite: true); Plugin.Logger.LogInfo((object)("[AnimCtrl] Detached '" + val.name + "' for clip '" + clip.name + "' → " + text8)); } } if (File.Exists(text8)) { Process.Start(text8); } } } GUI.enabled = true; if (_anchorPackSource != null) { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("Supplied by pack:") + " " + _anchorPackSource, GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } else if (_anchorReplExists) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.contentColor = GUIHelper.ColMuted; GUILayout.Label(Loc.T("Anchor:"), GUIHelper.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(52f) }); GUI.contentColor = Color.white; DrawAnchorButton("↑", "top-center"); DrawAnchorButton("↓", null); DrawAnchorButton("←", "left-center"); DrawAnchorButton("→", "right-center"); DrawAnchorButton("◆", "center"); GUILayout.EndHorizontal(); GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("Anchor affects enlarged replacements only."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } else { GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("No replacement file yet — Edit creates one."), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } GUILayout.EndVertical(); GUILayout.BeginVertical(GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Label(Loc.T("Whole Clip"), GUIHelper.SectionHeaderStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label(Loc.T("Animation canvas — whole-clip workflow:"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; GUI.enabled = clip != null; if (GUILayout.Button(Loc.T("Ready All for Edit"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { int num2 = 0; for (int num3 = 0; num3 < clip.frames.Length; num3++) { tk2dSpriteAnimationFrame val3 = clip.frames[num3]; tk2dSpriteCollectionData spriteCollection = val3.spriteCollection; if ((Object)(object)spriteCollection == (Object)null || val3.spriteId < 0 || val3.spriteId >= spriteCollection.spriteDefinitions.Length) { continue; } tk2dSpriteDefinition val4 = spriteCollection.spriteDefinitions[val3.spriteId]; if (string.IsNullOrEmpty(val4.name)) { continue; } string text12 = ((Object)(val4.materialInst ?? val4.material)).name.Split(' ')[0]; string text13 = Path.Combine(SpriteLoader.LoadPath, ((Object)spriteCollection).name, text12, val4.name + ".png"); if (File.Exists(text13)) { num2++; continue; } SpriteDumper.DumpSingleSprite(val4, spriteCollection); string text14 = Path.Combine(SpriteDumper.DumpPath, ((Object)spriteCollection).name, text12, val4.name + ".png"); if (!File.Exists(text14)) { Plugin.Logger.LogError((object)("Failed to dump: " + ((Object)spriteCollection).name + "/" + text12 + "/" + val4.name)); } else { IOUtil.EnsureDirectoryExists(Path.Combine(SpriteLoader.LoadPath, ((Object)spriteCollection).name, text12)); File.Copy(text14, text13, overwrite: true); num2++; } } Plugin.Logger.LogInfo((object)$"[AnimCtrl] Copied {num2} sprites from '{clip.name}' ({clip.frames.Length} frames) to {SpriteLoader.LoadPath}"); for (int num4 = 0; num4 < clip.frames.Length; num4++) { tk2dSpriteAnimationFrame val5 = clip.frames[num4]; tk2dSpriteCollectionData spriteCollection2 = val5.spriteCollection; if ((Object)(object)spriteCollection2 == (Object)null || val5.spriteId < 0 || val5.spriteId >= spriteCollection2.spriteDefinitions.Length) { continue; } tk2dSpriteDefinition val6 = spriteCollection2.spriteDefinitions[val5.spriteId]; if (!string.IsNullOrEmpty(val6.name)) { string path2 = ((Object)(val6.materialInst ?? val6.material)).name.Split(' ')[0]; string text15 = Path.Combine(SpriteLoader.LoadPath, ((Object)spriteCollection2).name, path2, val6.name + ".png"); if (File.Exists(text15)) { Process.Start(text15); } } } _anchorCacheKey = null; } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(Loc.T("Extract Vanilla"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { AnimCanvasAuthoring.ExtractClip(clip); string text16 = AnimCanvasAuthoring.WipDirFor(clip); if (text16 != null && Directory.Exists(text16)) { Process.Start(text16); } } if (GUILayout.Button(Loc.T("Extract As Rendered"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { AnimCanvasAuthoring.ExtractClip(clip, 0.5f, 0, fromCurrentRender: true); string text17 = AnimCanvasAuthoring.WipDirFor(clip); if (text17 != null && Directory.Exists(text17)) { Process.Start(text17); } } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(Loc.T("Compile Animation from Workspace"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { AnimCanvasCompile.CompileClip(clip); } Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = GUIHelper.ColAccent; if (GUILayout.Button(Loc.T("Compile for This Clip"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { AnimCanvasCompile.CompileClip(clip, forClipOnly: true); } GUI.backgroundColor = backgroundColor; GUILayout.EndHorizontal(); GUI.enabled = true; GUILayout.EndVertical(); GUILayout.EndHorizontal(); } private unsafe static string KeyName(KeyCode k) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: 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_0025: Expected I4, but got Unknown if ((int)k != 127) { return (k - 277) switch { 3 => "PgUp", 4 => "PgDn", 0 => "Ins", _ => ((object)(*(KeyCode*)(&k))/*cast due to .constrained prefix*/).ToString(), }; } return "Del"; } private static void EnsurePreviewWhite() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_previewWhite != (Object)null)) { _previewWhite = new Texture2D(1, 1) { hideFlags = (HideFlags)32 }; _previewWhite.SetPixel(0, 0, Color.white); _previewWhite.Apply(); } } private static Rect ScaleToFitRect(Rect container, int texW, int texH) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (texW <= 0 || texH <= 0) { return container; } float num = Mathf.Min(((Rect)(ref container)).width / (float)texW, ((Rect)(ref container)).height / (float)texH); float num2 = (float)texW * num; float num3 = (float)texH * num; return new Rect(((Rect)(ref container)).x + (((Rect)(ref container)).width - num2) * 0.5f, ((Rect)(ref container)).y + (((Rect)(ref container)).height - num3) * 0.5f, num2, num3); } private static void RecomputeReuse(AnimEntry e, tk2dSpriteCollectionData coll, int spriteId) { _reuseFrameCount = 0; _reuseClipCount = 0; _reuseSources.Clear(); tk2dSpriteAnimation val = e?.Library; if ((Object)(object)val == (Object)null || val.clips == null || (Object)(object)coll == (Object)null) { return; } tk2dSpriteAnimationClip[] clips = val.clips; foreach (tk2dSpriteAnimationClip val2 in clips) { if (val2 == null || val2.frames == null) { continue; } List<int> list = null; for (int j = 0; j < val2.frames.Length; j++) { tk2dSpriteAnimationFrame val3 = val2.frames[j]; if ((Object)(object)val3.spriteCollection == (Object)(object)coll && val3.spriteId == spriteId) { (list ?? (list = new List<int>())).Add(j); } } if (list != null) { _reuseFrameCount += list.Count; _reuseClipCount++; _reuseSources.Add((val2, list)); } } } private static void DrawAnchorButton(string label, string anchor) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) GUI.contentColor = ((_anchorCurrent == anchor) ? GUIHelper.ColConfirm : Color.white); if (GUILayout.Button(label, GUIHelper.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(30f) })) { SetAnchorByRename(anchor); } GUI.contentColor = Color.white; } private static string FindTaggedOrPlain(string dir, string spriteName) { if (!Directory.Exists(dir)) { return null; } string text = Path.Combine(dir, spriteName + ".png"); if (File.Exists(text)) { return text; } string[] array = new string[5] { "@t", "@b", "@l", "@r", "@c" }; foreach (string text2 in array) { string text3 = Path.Combine(dir, spriteName + text2 + ".png"); if (File.Exists(text3)) { return text3; } } return null; } private static void SetAnchorByRename(string anchor) { if (_anchorFilePath == null) { return; } string directoryName = Path.GetDirectoryName(_anchorFilePath); string item = IOUtil.ParseAnchorTag(Path.GetFileNameWithoutExtension(_anchorFilePath)).name; string text = Path.Combine(directoryName, item + anchor switch { "top-center" => "@t", "left-center" => "@l", "right-center" => "@r", "center" => "@c", _ => "", } + ".png"); if (string.Equals(text, _anchorFilePath, StringComparison.OrdinalIgnoreCase)) { return; } if (File.Exists(text)) { Plugin.Logger.LogWarning((object)("[Anchor] Can't set anchor: '" + Path.GetFileName(text) + "' already exists - remove the duplicate first (multiple anchor-tagged files for one sprite).")); return; } try { File.Move(_anchorFilePath, text); _anchorFilePath = text; _anchorCurrent = anchor; _anchorCacheKey = null; Plugin.Logger.LogInfo((object)("[Anchor] " + Path.GetFileName(text) + " anchor set to " + (anchor ?? "bottom (default)"))); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("[Anchor] rename failed: " + ex.Message)); } } } public class DialogueHandler { private static string _cachedLangString; public static Dictionary<string, Dictionary<string, Dictionary<string, string>>> TextCache = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>(); private static readonly HashSet<string> RequestedOverrideKeys = new HashSet<string>(); private static readonly HashSet<string> AllOverrideKeys = new HashSet<string>(); private static bool _staleKeysReported; private static bool _dumpInProgress; public static string TextDumpPath => Path.Combine(Plugin.BasePath, "TextDumps"); public static string TextLoadPath => Path.Combine(Plugin.BasePath, "Text"); public static string CurrentLangCode => CurrentLangStringCached(); public static int StaleKeyCount { get; private set; } public static int CachedSheetCount { get { int num = 0; foreach (Dictionary<string, Dictionary<string, string>> value in TextCache.Values) { num += value.Count; } return num; } } public static int CachedKeyCount { get { int num = 0; foreach (Dictionary<string, Dictionary<string, string>> value in TextCache.Values) { foreach (Dictionary<string, string> value2 in value.Values) { num += value2.Count; } } return num; } } public static event Action<string, string, string> OnTextAccessed; private static string CurrentLangStringCached() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return _cachedLangString ?? (_cachedLangString = ((object)Language.CurrentLanguage()/*cast due to .constrained prefix*/).ToString()); } public static void DumpText() { string text = CurrentLangStringCached(); _dumpInProgress = true; try { foreach (object value in Enum.GetValues(typeof(SupportedLanguages))) { string text2 = value.ToString(); Plugin.Logger.LogDebug((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)); using StreamWriter streamWriter = new StreamWriter(Path.Combine(TextDumpPath, sheet, text2 + ".yml")); 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.LogDebug((object)$"Finished dumping text for language code {text2}. Dumped {num} keys in {num2} sheets."); } Plugin.Logger.LogInfo((object)("[Stitchwork] Text dump complete (vanilla source) → " + TextDumpPath)); } finally { _dumpInProgress = false; Language.SwitchLanguage(text); } } public static void InvalidateCache(string sheet, string lang) { if (TextCache.ContainsKey(lang) && TextCache[lang].ContainsKey(sheet)) { Plugin.Logger.LogDebug((object)("Invalidating text cache for sheet: " + sheet + ", lang: " + lang)); TextCache[lang].Remove(sheet); } } public static IEnumerable<(string Sheet, string Key, string Value)> SearchCache(string filter, HashSet<string> skipKeys = null) { if (string.IsNullOrEmpty(filter) || !TextCache.TryGetValue(CurrentLangCode, out var value)) { yield break; } foreach (KeyValuePair<string, Dictionary<string, string>> item in value) { string sheet = item.Key; bool sheetMatch = sheet.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0; foreach (KeyValuePair<string, string> item2 in item.Value) { if ((skipKeys == null || !skipKeys.Contains(sheet + "|" + item2.Key)) && (sheetMatch || item2.Key.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0 || item2.Value.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)) { yield return (Sheet: sheet, Key: item2.Key, Value: item2.Value); } } } } public static void Reload() { TextCache.Clear(); RequestedOverrideKeys.Clear(); AllOverrideKeys.Clear(); StaleKeyCount = 0; _staleKeysReported = false; Language.SwitchLanguage(CurrentLangStringCached()); Plugin.Logger.LogDebug((object)"[Stitchwork] Text hot-reload: cleared cache and re-switched language to force refresh."); } public static void ApplyPatches(Harmony harmony) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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); try { int num = 0; MethodInfo[] methods = typeof(Language).GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "SwitchLanguage") && !methodInfo.IsGenericMethod) { try { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(DialogueHandler), "SwitchLanguagePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } catch (Exception ex) { Plugin.Logger.LogWarning((object)("[DialogueHandler] Failed to patch Language.SwitchLanguage overload " + $"({methodInfo}): {ex.Message}")); } } } if (num == 0) { Plugin.Logger.LogWarning((object)"[DialogueHandler] No Language.SwitchLanguage overloads were patched. Language-change cache invalidation will be skipped; stale CurrentLangCode is possible until next scene/reload."); } } catch (Exception ex2) { Plugin.Logger.LogError((object)("[DialogueHandler] SwitchLanguage enumeration threw: " + ex2.Message + ". Cache invalidation patches skipped; downstream patches continue.")); } } private static void SwitchLanguagePostfix() { _cachedLangString = null; Loc.OnGameLanguageChanged(); } private static void GetTextPostfix(string key, string sheetTitle, ref string __result) { if (_dumpInProgress) { return; } long heapBefore = DevProfiler.SnapshotHeapBytes(); try { string text = CurrentLangStringCached(); if (!TextCache.TryGetValue(text, out var value)) { value = new Dictionary<string, Dictionary<string, string>>(); TextCache[text] = value; } if (!value.TryGetValue(sheetTitle, out var value2)) { value2 = (value[sheetTitle] = LoadTextSheet(sheetTitle, text)); } if (value2.TryGetValue(key, out var value3)) { __result = value3; RequestedOverrideKeys.Add(text + "|" + sheetTitle + "|" + key); } DialogueHandler.OnTextAccessed?.Invoke(sheetTitle, key, __result); } finally { DevProfiler.AddOpPositiveNetHeapDelta("Postfix.Language.Get", heapBefore); } } private static Dictionary<string, string> LoadTextSheet(string sheetTitle, string lang) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string pluginPackPath in Plugin.PluginPackPaths) { foreach (KeyValuePair<string, string> item in LoadTextSheet(sheetTitle, lang, Path.Combine(pluginPackPath, "Text"))) { if (!dictionary.ContainsKey(item.Key)) { dictionary[item.Key] = item.Value; } } } foreach (KeyValuePair<string, string> item2 in LoadTextSheet(sheetTitle, lang, TextLoadPath)) { dictionary[item2.Key] = item2.Value; } foreach (string key in dictionary.Keys) { AllOverrideKeys.Add(lang + "|" + sheetTitle + "|" + key); } return dictionary; } public static void CheckForStaleKeys() { if (_staleKeysReported) { return; } int num = 0; foreach (string allOverrideKey in AllOverrideKeys) { if (!RequestedOverrideKeys.Contains(allOverrideKey)) { string[] array = allOverrideKey.Split('|', 3); string text = array[0]; string text2 = array[1]; string text3 = array[2]; string text4 = CurrentLangStringCached(); if (!(text != text4)) { num++; Plugin.Logger.LogWarning((object)("[Stitchwork] Text override key \"" + text3 + "\" in sheet \"" + text2 + "\" (" + text + ") was never requested by the game — key may have been renamed by a game update. Consider re-dumping text with DumpText enabled.")); } } } StaleKeyCount = num; _staleKeysReported = true; if (num > 0) { Plugin.Logger.LogWarning((object)$"[Stitchwork] {num} stale text override key(s) detected. These overrides are not being applied."); } } private static Dictionary<string, string> LoadTextSheet(string sheetTitle, string lang, string basePath) { return ParseSheetFile(Path.Combine(basePath, sheetTitle, lang + ".yml")); } internal static Dictionary<string, string> ParseSheetFile(string filePath) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); if (!File.Exists(filePath)) { return dictionary; } string[] array = File.ReadAllLines(filePath); foreach (string text in array) { 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 System.Runtime.CompilerServices { internal static class IsExternalInit { } } namespace Stitchwork { [BepInPlugin("Stitchwork", "Stitchwork", "0.8.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static StitchworkConfig Config; internal static SpriteFileWatcher SpriteFileWatcher; internal static AudioFileWatcher AudioFileWatcher; internal static TextFileWatcher TextFileWatcher; private bool _isInert; private static bool _inertToastDismissed; public static bool ShowPackManager = false; public static bool ShowDevHub = false; private const float MenuSceneDeferDelay = 1f; private static readonly string[] MenuScenePatterns = new string[3] { "menu", "title", "mode_select" }; private const float DeferredReapplyDelay = 0.1f; private static int _conditionPollFrames = 0; private const int ConditionPollInterval = 120; private int _focusRegainReloadFrame = -1; private const int FocusRegainReloadDelayFrames = 3; private static GUIStyle _inertTitleStyle; private static GUIStyle _inertBodyStyle; private static GUIStyle _inertBoxStyle; private static string _noticeTitle; private static string _noticeBody; internal static Harmony HarmonyInstance { get; private set; } public static Plugin Instance { get; private set; } public static string BasePath => Path.GetDirectoryName(typeof(Plugin).Assembly.Location); public static IEnumerable<string> PluginPackPaths => PackManager.ActivePackPaths; public static bool ShowStatusOverlay { get { return Config?.ShowStatusOverlay ?? true; } set { if (Config != null) { Config.ShowStatusOverlay = value; } } } public static int DevHubTab { get { return Config?.DevHubTab ?? 0; } set { if (Config != null) { Config.DevHubTab = value; } } } private void Awake() { //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; if (Chainloader.PluginInfos.ContainsKey("Patchwork")) { Logger.LogWarning((object)"════════════════════════════════════════════════════════"); Logger.LogWarning((object)"[Stitchwork] Upstream Patchwork detected."); Logger.LogWarning((object)""); Logger.LogWarning((object)" Stitchwork is a fork that supersedes Patchwork. Running"); Logger.LogWarning((object)" both at the same time will produce duplicate Harmony"); Logger.LogWarning((object)" patches on sprite/texture setters and unpredictable"); Logger.LogWarning((object)" asset-swap behaviour."); Logger.LogWarning((object)""); Logger.LogWarning((object)" Stitchwork is INERT this session."); Logger.LogWarning((object)" Uninstall Patchwork.dll from BepInEx/plugins/ to enable"); Logger.LogWarning((object)" Stitchwork."); Logger.LogWarning((object)"════════════════════════════════════════════════════════"); _isInert = true; return; } Config = new StitchworkConfig(((BaseUnityPlugin)this).Config); if (Config.DiagnosticMode) { Logger.LogWarning((object)"════════════════════════════════════════════════════════"); Logger.LogWarning((object)"[Stitchwork] DiagnosticMode ACTIVE"); Logger.LogWarning((object)" - No Harmony patches applied"); Logger.LogWarning((object)" - No packs loaded"); Logger.LogWarning((object)" - No replacements will work"); Logger.LogWarning((object)" - DevProfiler [Mem] logging continues"); Logger.LogWarning((object)" - Use this for vanilla allocation-rate measurement only"); Logger.LogWarning((object)" - Toggle DiagnosticMode=false in BepInEx config to restore"); Logger.LogWarning((object)"════════════════════════════════════════════════════════"); DevProfiler.Initialize(); GCUtil.InitBridge(); return; } Logger.LogInfo((object)"Stitchwork is loaded! Version: 0.8.0"); Loc.Init(); int num = ((Config.HeapReserveMB < 0) ? GCUtil.SuggestReserveMB() : Config.HeapReserveMB); if (num > 0) { Logger.LogInfo((object)$"[GC] Pre-warming Mono heap: {num} MB (system RAM: {SystemInfo.systemMemorySize} MB)"); GCUtil.PrewarmHeap((long)num * 1024L * 1024); } switch (BootConfigGC.Sync(Config.AutoEnableIncrementalGC)) { case BootConfigGC.Result.KeyWritten: QueueNoticeToast(Loc.T("#toast.gc-enable.title", "Stitchwork — one restart to smoother performance"), Loc.T("#toast.gc-enable.body", "Incremental garbage collection has been enabled for Silksong (one line in boot.config; the original is backed up). This removes the game's periodic GC stutter.\n\nIt takes effect on the NEXT game launch — restart when convenient.\nOpt out anytime: AutoEnableIncrementalGC = false in Stitchwork's config.")); break; case BootConfigGC.Result.KeyRemoved: QueueNoticeToast(Loc.T("#toast.gc-revert.title", "Stitchwork — restart to finish reverting"), Loc.T("#toast.gc-revert.body", "AutoEnableIncrementalGC is off — the incremental-GC line was removed from boot.config. The game's default GC behaviour returns on the next launch.")); break; } foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { string key = pluginInfo.Key; PluginInfo value = pluginInfo.Value; object obj; if (value == null) { obj = null; } else { BepInPlugin metadata = value.Metadata; obj = ((metadata != null) ? metadata.Name : null); } if (obj == null) { obj = key; } string text = (string)obj; if (key.IndexOf("Customizer", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Customizer", StringComparison.OrdinalIgnoreCase) >= 0) { Logger.LogError((object)("[Stitchwork] Conflicting plugin detected: '" + text + "' (GUID: " + key + "). Both mods patch sprite hooks and will conflict, causing broken sprite loading and enemy AI issues. Remove this plugin — Stitchwork replaces Customizer's functionality.")); } } LogInstallRoot(); PackManager.Initialize(); TexUtil.Initialize(); InitializeFolders(); AudioFileWatcher = new AudioFileWatcher(); SpriteFileWatcher = new SpriteFileWatcher(); TextFileWatcher = new TextFileWatcher(); DevProfiler.Initialize(); T2DLoader.PreloadAllTextures(); FileCache.BeginCycle(); try { VideoHandler.Reload(); } finally { FileCache.EndCycle(); } FileCache.BeginCycle(); try { AudioHandler.Reload(); } finally { FileCache.EndCycle(); } SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneUnloaded += OnSceneUnloaded; Harmony val = (HarmonyInstance = new Harmony("Stitchwork")); val.PatchAll(); AudioHandler.ApplyPatches(val); AnimationController.ApplyPatches(val); SpriteLoader.ApplyPatches(val); VideoHandler.ApplyPatches(val); GUIHelper.InitInputBlocking(); DialogueHandler.OnTextAccessed += delegate(string sheet, string key2, string text2) { TextLog.LogText(sheet, key2, text2); }; DialogueHandler.OnTextAccessed += delegate(string sheet, string key2, string text2) { if (ShowDevHub) { DialogueEditor.TrackText(sheet, key2, text2); } }; AudioHandler.OnAudioPlayed += delegate(AudioClip clip, AudioSource src) { AudioLog.LogAudio(clip, src); }; T2DLoader.OnT2DTrigger += delegate(string raw, string clean, string sprite) { T2DLog.LogTrigger(raw, clean, sprite); }; VideoHandler.OnCinematicTriggered += delegate(string name, bool replaced) { VideoPillar.LogCinematic(name, replaced); }; GCUtil.OnTCGCStutter += delegate { DevProfiler.RecordSpike("TC GCManager stutter — threshold bumped 10%", 0f); }; RawKeyboardLeakBlocker.ApplyPatches(val); ((MonoBehaviour)this).StartCoroutine((IEnumerator)AwakeDelayed(val)); } private IEnumerator<object> AwakeDelayed(Harmony harmony) { yield return null; DialogueHandler.ApplyPatches(harmony); DialogueFlagTracker.ApplyPatches(harmony); GUIHelper.InitCursor(); if (Config.DumpText) { DialogueHandler.DumpText(); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { GCUtil.InitBridge(); GameBridge.InitBridge(); SpriteAtlasBridge.Init(); HealthCheck.LogBootSummaryOnce(); if (SceneTraverser.IsTraversing) { SceneTraverser.NotifySceneLoaded(); } else if (Config.DumpSprites) { Logger.LogInfo((object)("Dumping sprites for scene " + ((Scene)(ref scene)).name)); tk2dSpriteCollectionData[] array = Resources.FindObjectsOfTypeAll<tk2dSpriteCollectionData>(); for (int i = 0; i < array.Length; i++) { SpriteDumper.DumpCollection(array[i]); } T2DDumper.DumpAllT2DSprites(); SceneTraverser.OnDumpCompleted(); Logger.LogInfo((object)("Finished dumping sprites for scene " + ((Scene)(ref scene)).name)); } T2DLoader.ApplyReplacementsInScene(); if (IsMenuScene(((Scene)(ref scene)).name)) { ((MonoBehaviour)this).StartCoroutine(DeferredMenuApply()); } ((MonoBehaviour)this).StartCoroutine(DelayedReapply()); FileCache.BeginCycle(); try { AudioHandler.PrimeForScene(); } finally { FileCache.EndCycle(); } AnimationController.ClearAnimators(); DialogueHandler.CheckForStaleKeys(); PackManager.OnSceneLoaded(((Scene)(ref scene)).name); T2DLoader.OnSceneLoaded(); T2DLoader.CheckForUninitializedSprites(); } private void OnSceneUnloaded(Scene scene) { T2DLoader.PruneStaleOriginals(); T2DLoader.PruneSceneState(); T2DLoader.ResetSceneSeed(); } private static bool IsMenuScene(string sceneName) { if (string.IsNullOrEmpty(sceneName)) { return false; } string[] menuScenePatterns = MenuScenePatterns; foreach (string value in menuScenePatterns) { if (sceneName.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private IEnumerator DeferredMenuApply() { yield return (object)new WaitForSeconds(1f); Logger.LogDebug((object)"[MenuDefer] Running deferred ApplyReplacementsInScene for menu scene."); T2DLoader.ApplyReplacementsInScene(); } private IEnumerator DelayedReapply() { yield return (object)new WaitForSeconds(0.1f); Logger.LogDebug((object)"[SceneLoad] Running deferred ApplyReplacementsInScene (100 ms post-load)."); T2DLoader.ApplyReplacementsInScene(); } public static void ScheduleDeferredApplyPasses() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Instance == (Object)null)) { ((MonoBehaviour)Instance).StartCoroutine(Instance.DelayedReapply()); Scene activeScene = SceneManager.GetActiveScene(); if (IsMenuScene(((Scene)(ref activeScene)).name)) { ((MonoBehaviour)Instance).StartCoroutine(Instance.DeferredMenuApply()); } } } private void LogInstallRoot() { Logger.LogInfo((object)("[Stitchwork] Install root: " + BasePath)); } private void Update() { if (!_isInert) { DevProfiler.RecordFrame(); DevProfiler.BeginUpdateTiming(); long heapBefore = DevProfiler.SnapshotHeapBytes(); T2DLoader.AdvanceSetterTracking(); DevProfiler.StartOp(); T2DLoader.CheckForUninitializedSprites(); DevProfiler.RecordUninitMs(DevProfiler.StopOp("UninitCheck")); T2DLoader.ScanForLogTriggers(); if (PackManager.HasHotReloadPacks && ++_conditionPollFrames >= 120) { _conditionPollFrames = 0; PackManager.PollHotReloadConditions(); } GUIHelper.UpdateInputBlocking(); HotkeyController.Poll(); ReloadCoordinator.Poll(); if (_focusRegainReloadFrame > 0 && Time.frameCount >= _focusRegainReloadFrame) { _focusRegainReloadFrame = -1; Logger.LogDebug((object)"[Plugin] Focus regained; re-running SpriteLoader.Reload + T2D reload to refresh atlas RT contents."); SpriteLoader.Reload(); T2DLoader.ReloadSpritesInScene(); } AnimationController.Update(); DevProfiler.AddOpPositiveNetHeapDelta("Plugin.Update.Total", heapBefore); DevProfiler.EndUpdateTiming(); } } private void LateUpdate() { long heapBefore = DevProfiler.SnapshotHeapBytes(); if (ShowDevHub || ShowPackManager || CanvasPackManager.IsVisible || WorldPickMode.Active) { GUIHelper.ShowCursorForWindow(); } DevProfil