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.6
plugins/Stitchwork.dll
Decompiled a week 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 TMProOld; using TeamCherry.Cinematics; using TeamCherry.Localization; 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.TextCore; using UnityEngine.TextCore.LowLevel; using UnityEngine.UI; using UnityEngine.Video; using UnityStandardAssets.ImageEffects; [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.6.0")] [assembly: AssemblyInformationalVersion("0.8.6+c28c073e0f977ca49375077628d1be4bda3c86ac")] [assembly: AssemblyProduct("Stitchwork")] [assembly: AssemblyTitle("Stitchwork")] [assembly: AssemblyMetadata("GameLibsPin", "1.2.0-silksong1.0.30000")] [assembly: AssemblyMetadata("DevTools", "false")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.8.6.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 SharedFromPack; public int PerClip; public readonly List<string> MissingShared = new List<string>(); } 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 float _wsCountAt = -999f; private static int _wsListSize = -1; private static List<tk2dSpriteAnimationClip> _wsClips; private const float SuffixColW = 132f; private static GUIStyle _suffixStyle; private static readonly Dictionary<(int libId, string clip, string coll), ClipCoverage> _coverage = new Dictionary<(int, string, string), ClipCoverage>(); private static int _coverageIndexVersion = -1; private static readonly FieldInfo _windyLibField = AccessTools.Field(typeof(HeroAnimationController), "windyAnimLib"); private static readonly Type _heroConfigType = AccessTools.TypeByName("HeroControllerConfig"); private static readonly FieldInfo _heroConfigOverrideLib = ((_heroConfigType != null) ? AccessTools.Field(_heroConfigType, "heroAnimOverrideLib") : null); private static readonly List<tk2dSpriteAnimation> _configOverrideLibs = new List<tk2dSpriteAnimation>(); private static float _configLibsNextScan; private static readonly Dictionary<int, string> _libDominantColl = new Dictionary<int, string>(); private static int _dominantCollVersion = -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 SuffixStyle { get { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown object obj = _suffixStyle; if (obj == null) { GUIStyle val = new GUIStyle(GUIHelper.LabelStyle) { wordWrap = false, clipping = (TextClipping)1 }; _suffixStyle = val; obj = (object)val; } return (GUIStyle)obj; } } 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) { 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; _clipSearch = ""; } 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) 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 = (((Object)(object)val.materialInst != (Object)null) ? 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_0515: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05d0: 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; } List<tk2dSpriteAnimationClip> list = library.clips.Where((tk2dSpriteAnimationClip c) => c != null && !string.IsNullOrEmpty(c.name)).ToList(); IEnumerable<tk2dSpriteAnimationClip> enumerable = SecondaryLibClips(e, library); if (enumerable != null) { list.AddRange(enumerable); } HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); HashSet<string> hashSet2 = new HashSet<string>(StringComparer.Ordinal); foreach (tk2dSpriteAnimationClip item in list) { if (!hashSet2.Add(item.name)) { hashSet.Add(item.name); } } IEnumerable<tk2dSpriteAnimationClip> source = list; if (!string.IsNullOrEmpty(_clipSearch)) { string q = _clipSearch; source = source.Where((tk2dSpriteAnimationClip c) => c.name.IndexOf(q, StringComparison.OrdinalIgnoreCase) >= 0); } if (_lensSpriteId >= 0) { source = source.Where((tk2dSpriteAnimationClip c) => ClipUsesSprite(c, _lensColl, _lensSpriteId)); } List<tk2dSpriteAnimationClip> list2 = source.OrderBy<tk2dSpriteAnimationClip, string>((tk2dSpriteAnimationClip c) => c.name, StringComparer.OrdinalIgnoreCase).ToList(); HashSet<tk2dSpriteAnimationClip> mainSet = new HashSet<tk2dSpriteAnimationClip>(library.clips ?? Array.Empty<tk2dSpriteAnimationClip>()); int num = list2.Count((tk2dSpriteAnimationClip c) => !mainSet.Contains(c)); int num2 = list2.Count - num; GUI.contentColor = GUIHelper.ColFaint; GUILayout.Label((num > 0) ? string.Format(Loc.T("{0} + {1} variants"), num2, num) : $"{num2} / {library.clips.Length}", GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; bool reserveSuffixCol = false; string dominantCollection = GetDominantCollection(library); foreach (tk2dSpriteAnimationClip item2 in list2) { string text = PrimaryCollectionName(item2); if (text != null && (hashSet.Contains(item2.name) || !string.Equals(text, dominantCollection, StringComparison.Ordinal))) { reserveSuffixCol = true; break; } } string dominantCollection2 = GetDominantCollection(library); if (dominantCollection2 != null) { GUI.contentColor = GUIHelper.ColMuted; GUILayout.Label(Loc.T("Collection") + ": " + dominantCollection2, GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } DrawBatchRow(list2); tk2dSpriteAnimationClip val = ((!flag) ? e.Clip : ((e.ViewClip != null) ? e.ViewClip : e.Clip)); 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 val2 = ((val != null && val.name == recentClip) ? val : FindClip(library, recentClip)); if (val2 != null) { DrawClipRow(e, library, val2, val, currentClip, live, hashSet, reserveSuffixCol); } } GUI.contentColor = GUIHelper.ColMuted; GUILayout.Label(Loc.T("All clips"), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; } foreach (tk2dSpriteAnimationClip item3 in list2) { DrawClipRow(e, library, item3, val, currentClip, live, hashSet, reserveSuffixCol); } GUILayout.EndScrollView(); } private static void DrawBatchRow(List<tk2dSpriteAnimationClip> list) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) if (AnimCanvasBatch.IsRunning) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.contentColor = GUIHelper.ColMuted; GUILayout.Label(string.Format(Loc.T("Batch: {0}/{1}"), AnimCanvasBatch.Processed, AnimCanvasBatch.Total) + " · " + AnimCanvasBatch.CurrentClip, GUIHelper.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUI.contentColor = Color.white; if (GUILayout.Button(Loc.T("Cancel"), GUIHelper.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(80f) })) { AnimCanvasBatch.Cancel(); } GUILayout.EndHorizontal(); return; } if (Time.unscaledTime - _wsCountAt > 2f || _wsClips == null || list.Count != _wsListSize) { _wsClips = AnimCanvasBatch.WithWorkspace(list); _wsListSize = list.Count; _wsCountAt = Time.unscaledTime; } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.contentColor = GUIHelper.ColMuted; GUILayout.Label(Loc.T("Canvas:"), GUIHelper.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(58f) }); GUI.contentColor = Color.white; if (GUILayout.Button(string.Format(Loc.T("Extract {0} listed"), list.Count), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { AnimCanvasBatch.ExtractAll(list, fromCurrentRender: false); } if (GUILayout.Button(Loc.T("Extract As Rendered"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { AnimCanvasBatch.ExtractAll(list, fromCurrentRender: true); } GUI.enabled = _wsClips.Count > 0; if (GUILayout.Button(string.Format(Loc.T("Compile {0} workspaces"), _wsClips.Count), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { AnimCanvasBatch.CompileAll(_wsClips); } GUI.enabled = true; GUILayout.EndHorizontal(); } private static void DrawClipRow(AnimEntry e, tk2dSpriteAnimation lib, tk2dSpriteAnimationClip clip, tk2dSpriteAnimationClip currentObj, string currentClip, bool live, HashSet<string> dupNames, bool reserveSuffixCol) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) ClipCoverage coverage = GetCoverage(lib, clip); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Color color = ((coverage.Shared == 0) ? GUIHelper.ColBorderHi : ((coverage.SharedFromPack > 0) ? GUIHelper.ColPackBlue : GUIHelper.ColConfirm)); string text = string.Format("{0}: {1}/{2}", Loc.T("shared replacements"), coverage.Shared, coverage.Frames); if (coverage.SharedFromPack > 0) { text = text + " · " + string.Format(Loc.T("{0} from pack"), coverage.SharedFromPack); } if (coverage.Shared > 0 && coverage.Shared < coverage.Frames && coverage.MissingShared.Count > 0) { text = text + "\n" + Loc.T("not found") + ": " + string.Join(", ", coverage.MissingShared) + ((coverage.Frames - coverage.Shared > coverage.MissingShared.Count) ? ", …" : ""); } GUIHelper.StatusDotSlot(DotStateFor(coverage.Shared, coverage.Frames), color, text); GUIHelper.StatusDotSlot(DotStateFor(coverage.PerClip, coverage.Frames), (coverage.PerClip > 0) ? GUIHelper.ColAccent : GUIHelper.ColBorderHi, string.Format("{0}: {1}/{2}", Loc.T("per-clip (Appliqué)"), coverage.PerClip, coverage.Frames)); bool flag = ((currentObj != null) ? (clip == currentObj) : (clip.name == currentClip)); GUI.contentColor = (flag ? 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; if (reserveSuffixCol) { string text2 = PrimaryCollectionName(clip); bool flag2 = dupNames?.Contains(clip.name) ?? false; bool num = text2 != null && (flag2 || !string.Equals(text2, GetDominantCollection(lib), StringComparison.Ordinal)); GUI.contentColor = (flag ? GUIHelper.ColConfirm : GUIHelper.ColFaint); GUILayout.Label((GUIContent)((!num) ? ((object)GUIContent.none) : ((object)new GUIContent("· " + text2, text2))), SuffixStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(132f) }); 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 void RefreshConfigOverrideLibs() { if (_heroConfigOverrideLib == null || Time.realtimeSinceStartup < _configLibsNextScan) { return; } _configLibsNextScan = Time.realtimeSinceStartup + 5f; _configOverrideLibs.Clear(); Object[] array = Resources.FindObjectsOfTypeAll(_heroConfigType); foreach (Object val in array) { if (!(val == (Object)null)) { object? value = _heroConfigOverrideLib.GetValue(val); tk2dSpriteAnimation val2 = (tk2dSpriteAnimation)((value is tk2dSpriteAnimation) ? value : null); if (val2 != null && (Object)(object)val2 != (Object)null && val2.clips != null && !_configOverrideLibs.Contains(val2)) { _configOverrideLibs.Add(val2); } } } } private static IEnumerable<tk2dSpriteAnimationClip> SecondaryLibClips(AnimEntry e, tk2dSpriteAnimation mainLib) { if (e == null) { return null; } tk2dSpriteAnimator live = e.Live; if ((Object)(object)live == (Object)null) { return null; } HeroAnimationController component = ((Component)live).GetComponent<HeroAnimationController>(); if ((Object)(object)component == (Object)null) { return null; } List<tk2dSpriteAnimation> list = new List<tk2dSpriteAnimation>(); if (_windyLibField != null) { object? value = _windyLibField.GetValue(component); tk2dSpriteAnimation val = (tk2dSpriteAnimation)((value is tk2dSpriteAnimation) ? value : null); if (val != null && (Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)mainLib && val.clips != null) { list.Add(val); } } RefreshConfigOverrideLibs(); foreach (tk2dSpriteAnimation configOverrideLib in _configOverrideLibs) { if ((Object)(object)configOverrideLib != (Object)null && (Object)(object)configOverrideLib != (Object)(object)mainLib && !list.Contains(configOverrideLib)) { list.Add(configOverrideLib); } } if (list.Count == 0) { return null; } HashSet<tk2dSpriteAnimationClip> mainSet = new HashSet<tk2dSpriteAnimationClip>(mainLib.clips ?? Array.Empty<tk2dSpriteAnimationClip>()); HashSet<tk2dSpriteAnimationClip> seen = new HashSet<tk2dSpriteAnimationClip>(); return from c in list.SelectMany((tk2dSpriteAnimation l) => l.clips) where c != null && !string.IsNullOrEmpty(c.name) && !mainSet.Contains(c) && seen.Add(c) select c; } private static string GetDominantCollection(tk2dSpriteAnimation lib) { if (_dominantCollVersion != SpriteLoader.FileIndexVersion) { _libDominantColl.Clear(); _dominantCollVersion = SpriteLoader.FileIndexVersion; } int instanceID = ((Object)lib).GetInstanceID(); if (_libDominantColl.TryGetValue(instanceID, out var value)) { return value; } Dictionary<string, int> dictionary = new Dictionary<string, int>(); if (lib.clips != null) { tk2dSpriteAnimationClip[] clips = lib.clips; foreach (tk2dSpriteAnimationClip val in clips) { if (val == null || val.frames == null) { continue; } tk2dSpriteAnimationFrame[] frames = val.frames; for (int j = 0; j < frames.Length; j++) { tk2dSpriteCollectionData spriteCollection = frames[j].spriteCollection; if (!((Object)(object)spriteCollection == (Object)null)) { dictionary[((Object)spriteCollection).name] = ((!dictionary.TryGetValue(((Object)spriteCollection).name, out var value2)) ? 1 : (value2 + 1)); } } } } string text = null; int num = 0; foreach (KeyValuePair<string, int> item in dictionary) { if (item.Value > num) { num = item.Value; text = item.Key; } } _libDominantColl[instanceID] = text; return text; } private static string PrimaryCollectionName(tk2dSpriteAnimationClip clip) { if (clip.frames == null) { return null; } tk2dSpriteAnimationFrame[] frames = clip.frames; for (int i = 0; i < frames.Length; i++) { tk2dSpriteCollectionData spriteCollection = frames[i].spriteCollection; if ((Object)(object)spriteCollection != (Object)null) { return ((Object)spriteCollection).name; } } return null; } private static GUIHelper.DotState DotStateFor(int n, int total) { if (n > 0) { if (n < total) { return GUIHelper.DotState.Partial; } return GUIHelper.DotState.Full; } return GUIHelper.DotState.None; } private static ClipCoverage GetCoverage(tk2dSpriteAnimation lib, tk2dSpriteAnimationClip clip) { if (_coverageIndexVersion != SpriteLoader.FileIndexVersion) { _coverage.Clear(); _coverageIndexVersion = SpriteLoader.FileIndexVersion; } (int, string, string) key = (((Object)lib).GetInstanceID(), clip.name, PrimaryCollectionName(clip)); 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++; SpriteLoader.ReplacementSource spriteProvenance = SpriteLoader.GetSpriteProvenance(spriteCollection, val2); if (spriteProvenance != SpriteLoader.ReplacementSource.None) { value.Shared++; } else if (value.MissingShared.Count < 4) { string text = (((Object)(object)val2.material != (Object)null) ? ((Object)val2.material).name.Split(' ')[0] : "?"); value.MissingShared.Add(val2.name + " (" + ((Object)spriteCollection).name + "/" + text + ")"); } if (spriteProvenance == SpriteLoader.ReplacementSource.Pack) { value.SharedFromPack++; } 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Invalid comparison between Unknown and I4 //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05db: 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_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0373: 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_037a: Unknown result type (might be due to invalid IL or missing references) //IL_067a: Unknown result type (might be due to invalid IL or missing references) //IL_06af: Unknown result type (might be due to invalid IL or missing references) //IL_06e9: Unknown result type (might be due to invalid IL or missing references) //IL_06e2: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0724: Unknown result type (might be due to invalid IL or missing references) //IL_074f: Unknown result type (might be due to invalid IL or missing references) //IL_076e: Unknown result type (might be due to invalid IL or missing references) //IL_07a8: Unknown result type (might be due to invalid IL or missing references) //IL_07a1: Unknown result type (might be due to invalid IL or missing references) //IL_07c7: Unknown result type (might be due to invalid IL or missing references) //IL_07f2: Unknown result type (might be due to invalid IL or missing references) //IL_0818: Unknown result type (might be due to invalid IL or missing references) //IL_086c: 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 = (((Object)(object)val.materialInst != (Object)null) ? 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, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(GUIHelper.Scaled(30f)) }); 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 = (((Object)(object)def.materialInst != (Object)null) ? def.materialInst : def.material); if ((Object)(object)val == (Object)null) { return; } string text = ((Object)val).name.Split(' ')[0]; string text2 = SpriteLoader.FindWorkspaceSpriteFile(coll, def) ?? 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); } IOUtil.OpenPath(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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Invalid comparison between Unknown and I4 //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Expected O, but got Unknown //IL_031f: Unknown result type (might be due to invalid IL or missing references) if (!TexUtil.RotateDrawAvailable) { return null; } 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, TexUtil.ReadWriteForSource(atlas)); Texture2D val; try { RenderTexture.active = temporary; GL.Clear(true, true, Color.clear); GL.PushMatrix(); GL.LoadPixelMatrix(0f, (float)num8, 0f, (float)num9); TexUtil.SetPassTextured(atlas); 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Invalid comparison between Unknown and I4 //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_0504: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Invalid comparison between Unknown and I4 //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0774: Unknown result type (might be due to invalid IL or missing references) //IL_0779: Unknown result type (might be due to invalid IL or missing references) //IL_077b: Unknown result type (might be due to invalid IL or missing references) //IL_079f: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_097c: Unknown result type (might be due to invalid IL or missing references) //IL_09af: Unknown result type (might be due to invalid IL or missing references) //IL_0a8a: Unknown result type (might be due to invalid IL or missing references) //IL_0aae: 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_0a04: Unknown result type (might be due to invalid IL or missing references) //IL_0a5a: Unknown result type (might be due to invalid IL or missing references) //IL_0a7e: Unknown result type (might be due to invalid IL or missing references) //IL_0aff: Unknown result type (might be due to invalid IL or missing references) //IL_0b23: Unknown result type (might be due to invalid IL or missing references) //IL_0e4d: Unknown result type (might be due to invalid IL or missing references) //IL_0e9e: Unknown result type (might be due to invalid IL or missing references) //IL_0fa7: Unknown result type (might be due to invalid IL or missing references) //IL_0fac: 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 = (((Object)(object)val.materialInst != (Object)null) ? 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((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinHeight(GUIHelper.Scaled(28f)) }); 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} · id {spriteId}{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>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(Loc.T(File.Exists(Path.Combine(SpriteLoader.LoadPath, ((Object)coll).name, text, val.name + ".png")) ? "Edit (opens your file)" : "Edit (new from vanilla)"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { OpenSpriteForEdit(coll, val); } if (GUILayout.Button(Loc.T("Folder"), GUIHelper.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(64f) })) { IOUtil.OpenDeepestExisting(Path.Combine(SpriteLoader.LoadPath, ((Object)coll).name, text)); } GUILayout.EndHorizontal(); GUI.enabled = clip != null; Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = GUIHelper.ColAccent; bool num2 = GUILayout.Button(Loc.T("Detach for This Clip"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>()); GUI.backgroundColor = backgroundColor; if (num2) { 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)) { IOUtil.OpenPath(text8); } } } GUI.enabled = true; GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(GUIHelper.Scaled(48f)), GUILayout.ExpandWidth(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.FlexibleSpace(); GUILayout.EndVertical(); 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 && !AnimCanvasBatch.IsRunning; if (GUILayout.Button(Loc.T("Ready All for Edit"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { int num3 = 0; for (int num4 = 0; num4 < clip.frames.Length; num4++) { tk2dSpriteAnimationFrame val3 = clip.frames[num4]; 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)(((Object)(object)val4.materialInst != (Object)null) ? val4.materialInst : val4.material)).name.Split(' ')[0]; string text13 = Path.Combine(SpriteLoader.LoadPath, ((Object)spriteCollection).name, text12, val4.name + ".png"); if (File.Exists(text13)) { num3++; 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); num3++; } } Plugin.Logger.LogInfo((object)$"[AnimCtrl] Copied {num3} sprites from '{clip.name}' ({clip.frames.Length} frames) to {SpriteLoader.LoadPath}"); for (int num5 = 0; num5 < clip.frames.Length; num5++) { tk2dSpriteAnimationFrame val5 = clip.frames[num5]; 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)(((Object)(object)val6.materialInst != (Object)null) ? val6.materialInst : val6.material)).name.Split(' ')[0]; string path3 = Path.Combine(SpriteLoader.LoadPath, ((Object)spriteCollection2).name, path2, val6.name + ".png"); if (File.Exists(path3)) { IOUtil.OpenPath(path3); } } } _anchorCacheKey = null; } string text15 = AnimCanvasAuthoring.WipDirFor(clip); if (text15 != null) { string fileName2 = Path.GetFileName(Path.GetDirectoryName(text15)); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.contentColor = GUIHelper.ColMuted; GUILayout.Label(Loc.T("Workspace") + ": " + fileName2 + "/" + Path.GetFileName(text15), GUIHelper.LabelStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = Color.white; if (GUILayout.Button(Loc.T("Open"), GUIHelper.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUIHelper.Width(52f) })) { IOUtil.OpenDeepestExisting(text15); } GUILayout.EndHorizontal(); } 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)) { IOUtil.OpenPath(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)) { IOUtil.OpenPath(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 backgroundColor2 = 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 = backgroundColor2; GUILayout.EndHorizontal(); if (GUILayout.Button(Loc.T("Export GIF"), GUIHelper.ButtonStyle, Array.Empty<GUILayoutOption>())) { int width; int height; List<Color32[]> list = AnimCanvasAuthoring.RenderClipSequence(clip, fromCurrentRender: true, 0.1f, out width, out height); if (list == null) { Plugin.Logger.LogWarning((object)("[Showcase] '" + clip.name + "': no renderable frames — GIF not written.")); } else { string text18 = Path.Combine(Plugin.BasePath, "Showcase"); IOUtil.EnsureDirectoryExists(text18); string text19 = Path.Combine(text18, T2DUtil.SanitizeForFilesystem(clip.name) + ".gif"); int num6 = Mathf.Max(2, Mathf.RoundToInt(100f / Mathf.Max(1f, _previewFps))); try { GifEncoder.Write(text19, width, height, list, num6); Plugin.Logger.LogInfo((object)$"[Showcase] GIF: {list.Count} frame(s) {width}×{height} @ {num6} cs/frame → {text19}"); IOUtil.OpenPath(text19); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { Plugin.Logger.LogError((object)("[Showcase] GIF write failed: " + ex.Message)); } } } 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 sealed class StoredCopyBridge { public Type Type; public MethodInfo Refresh; public FieldInfo KeyField; } private static string _cachedLangString; private static bool _gameLanguageAlive; 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; private static FieldInfo _entrySheetsField; private static bool _entrySheetsResolved; private static object _lastDictInstance; private static readonly Dictionary<(string sheet, string key), (bool existed, string value)> _dictOriginals = new Dictionary<(string, string), (bool, string)>(); private static List<StoredCopyBridge> _storedCopyBridges; 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (_cachedLangString != null) { return _cachedLangString; } if (!_gameLanguageAlive) { return "EN"; } try { return _cachedLangString = ((object)Language.CurrentLanguage()/*cast due to .constrained prefix*/).ToString(); } catch (TypeInitializationException) { return "EN"; } } 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.TryGetValue(lang, out var value) && value.Remove(sheet)) { Plugin.Logger.LogDebug((object)("Invalidating text cache for sheet: " + sheet + ", lang: " + lang)); } } 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() { ConflictTracker.ClearTypes("text"); 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() { _gameLanguageAlive = true; _cachedLangString = null; Loc.OnGameLanguageChanged(); SyncGameLanguageDict(); } private static void GetTextPostfix(string key, string sheetTitle, ref string __result) { if (!_gameLanguageAlive) { _gameLanguageAlive = true; Loc.OnGameLanguageChanged(); } if (_dumpInProgress) { return; } long heapBefore = DevProfiler.SnapshotHeapBytes(); try { string text = CurrentLangStringCached(); if (GetOrLoad