Decompiled source of UiKit v1.0.0
BepInEx/plugins/DiceModders.UiKit.dll
Decompiled 21 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using DiceKingdoms.Game; using DiceKingdoms.Interface; using DiceKingdoms.Meta; using DiceModders.UiKit.Custom; using DiceModders.UiKit.Native; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.Localization; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("DiceModders.UiKit")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c00eb7618c647446973ed0a890ba16337924bff9")] [assembly: AssemblyProduct("UiKit")] [assembly: AssemblyTitle("DiceModders.UiKit")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DiceModders.UiKit { public sealed class CustomApi { private readonly UiScope _scope; public UiTheme Theme => _scope.Runtime.Theme; internal CustomApi(UiScope scope) { _scope = scope; } public UiWindow? Window(Action<UiWindow>? build = null) { if (!_scope.IsAlive) { UiLog.OnceError("custom:disposed-scope", "cannot create a window in a disposed scope"); return null; } UiWindow uiWindow = UiGuard.Func("window.create", () => new UiWindow(_scope), _scope.Id); if (uiWindow == null) { return null; } _scope.Owned.Add(uiWindow); try { build?.Invoke(uiWindow); uiWindow.FinalizeBuild(); if (uiWindow.IsAlive) { return uiWindow; } UiGuard.Run("window.cleanup", uiWindow.Dispose, _scope.Id); return null; } catch (Exception exception) { UiGuard.Report("window.build", exception, _scope.Id); UiGuard.Run("window.cleanup", uiWindow.Dispose, _scope.Id); return null; } } } public enum Layer { BehindGame, Game, AboveGame } public sealed class NativeApi { public TopBarApi TopBar { get; } public SettingsApi Settings { get; } public ScoreboardApi Scoreboard { get; } public RulesApi Rules { get; } internal NativeApi(UiScope scope) { TopBar = new TopBarApi(scope); Settings = new SettingsApi(scope); Scoreboard = new ScoreboardApi(scope); Rules = new RulesApi(scope); } } public enum OrnamentStyle { None, Border, BorderWithTwoCorners, BorderWithFourCorners, Classic } public enum TemplatePolicy { PreferNative, ManagedOnly, NativeOnly } public static class UiKit { private static UiKitRuntime? _runtime; public static bool IsInitialized => _runtime != null; public static bool IsDemoVisible { get { UiKitRuntime runtime = _runtime; if (runtime != null) { return UiGuard.Value("demo.visible", () => runtime.IsDemoVisible, fallback: false, "runtime"); } return false; } } internal static UiKitRuntime? Initialize(BasePlugin? plugin, UiOptions? options = null) { return Initialize((plugin != null) ? plugin.Log : null, options); } internal static UiKitRuntime? Initialize(ManualLogSource? log, UiOptions? options = null) { if (_runtime != null) { UiLog.Warn("UiKit.Initialize called twice; keeping the existing runtime"); return _runtime; } UiLog.SetLogger(log); UiLog.ResetOnce(); try { _runtime = new UiKitRuntime(log, options); return _runtime; } catch (Exception ex) { _runtime = null; UiLog.Error("UiKit initialization failed: " + ex); return null; } } public static UiScope? CreateScope(string? id = null) { UiKitRuntime runtime = _runtime; if (runtime == null) { UiLog.OnceError("uikit:not-initialized", "UiKit.CreateScope called before the UiKit plugin initialized the runtime; returning null"); return null; } return UiGuard.Func("scope.create", () => runtime.CreateScope(id), "runtime"); } public static void ShowDemo() { RunDemo("demo.show", delegate(UiKitRuntime runtime) { runtime.ShowDemo(); }); } public static void HideDemo() { RunDemo("demo.hide", delegate(UiKitRuntime runtime) { runtime.HideDemo(); }); } public static void ToggleDemo() { RunDemo("demo.toggle", delegate(UiKitRuntime runtime) { runtime.ToggleDemo(); }); } public static void RebuildDemo() { RunDemo("demo.rebuild", delegate(UiKitRuntime runtime) { runtime.RebuildDemo(); }); } internal static void Shutdown() { UiKitRuntime runtime = _runtime; _runtime = null; if (runtime != null) { UiGuard.Run("runtime.shutdown", runtime.Dispose, "runtime"); } } private static void RunDemo(string operation, Action<UiKitRuntime> action) { UiKitRuntime runtime = _runtime; if (runtime == null) { UiLog.OnceError("uikit:not-initialized", "the UiKit runtime is not available; demo command ignored"); return; } UiGuard.Run(operation, delegate { action(runtime); }, "runtime"); } } internal sealed class UiKitRuntime { private sealed class ReadyRegistration { internal UiScope Scope { get; } internal Action<UiScope> Build { get; } internal ReadyRegistration(UiScope scope, Action<UiScope> build) { Scope = scope; Build = build; } } private readonly List<UiScope> _scopes = new List<UiScope>(); private readonly List<ReadyRegistration> _readyCallbacks = new List<ReadyRegistration>(); private UnityAction<Scene, LoadSceneMode>? _sceneLoaded; private UnityAction<Scene>? _sceneUnloaded; private DemoController? _demo; private int _windowIndex; private int _scopeIndex; private bool _disposed; private bool _uiReady; private bool _uiReadyCandidate; internal AssetCatalog Assets { get; } internal TemplateCatalog Templates { get; } internal UiTheme Theme { get; } internal LayerCanvases Layers { get; } internal NativeUiHost NativeUi { get; } internal UiOptions Options { get; } internal bool IsDisposed => _disposed; internal bool IsUiReady => _uiReady; internal IReadOnlyList<UiScope> Scopes => _scopes; internal bool IsDemoVisible { get { if (_demo != null) { return _demo.IsVisible; } return false; } } internal UiKitRuntime(ManualLogSource? log, UiOptions? options) { Options = options ?? new UiOptions(); UiLog.SetLogger(log); Assets = new AssetCatalog(); Templates = new TemplateCatalog(); Theme = new UiTheme(Assets); Layers = new LayerCanvases(this); NativeUi = new NativeUiHost(); RegisterComponents(); LayoutOnce.Begin(); LayoutEvents.Activate(); LayoutEvents.CanvasChanged += OnCanvasChanged; NativeHooks.Install(this); try { Action<Scene, LoadSceneMode> action = OnSceneLoaded; Action<Scene> action2 = OnSceneUnloaded; _sceneLoaded = DelegateSupport.ConvertDelegate<UnityAction<Scene, LoadSceneMode>>((Delegate)action); _sceneUnloaded = DelegateSupport.ConvertDelegate<UnityAction<Scene>>((Delegate)action2); SceneManager.sceneLoaded += _sceneLoaded; SceneManager.sceneUnloaded += _sceneUnloaded; } catch (Exception ex) { UiLog.Warn("could not subscribe to scene changes: " + ex.Message); } if (Options.EnableDemo) { UiGuard.Run("demo.create", delegate { _demo = new DemoController(this); _demo.Request(); _demo.OnSceneLoaded(); }, "runtime"); if (_demo == null) { UiLog.Error("the built-in demo could not be created"); } } UiGuard.Run("startup.ready", TryMarkUiReady, "runtime"); RequestReadyProbe(); UiLog.Info("UI kit runtime created"); } internal void ShowDemo() { if (_disposed) { return; } UiGuard.Run("demo.show", delegate { if (_demo == null) { _demo = new DemoController(this); } _demo.Show(); }, "runtime"); } internal void HideDemo() { if (!_disposed) { UiGuard.Run("demo.hide", delegate { _demo?.Hide(); }, "runtime"); } } internal void ToggleDemo() { if (_disposed) { return; } UiGuard.Run("demo.toggle", delegate { if (_demo == null) { _demo = new DemoController(this); } _demo.Toggle(); }, "runtime"); } internal void RebuildDemo() { if (_disposed) { return; } UiGuard.Run("demo.rebuild", delegate { if (_demo == null) { _demo = new DemoController(this); } _demo.Rebuild(); }, "runtime"); } internal UiScope? CreateScope(string? id) { if (_disposed) { UiLog.OnceError("runtime:disposed", "cannot create a UiKit scope after the runtime has been disposed"); return null; } string text = NormalizeScopeId(id); try { UiScope uiScope = new UiScope(this, text); _scopes.Add(uiScope); return uiScope; } catch (Exception value) { UiLog.Error($"could not create UiKit scope '{text}': {value}"); return null; } } private string NormalizeScopeId(string? id) { if (!string.IsNullOrWhiteSpace(id)) { return id.Trim(); } return "scope-" + ++_scopeIndex; } internal void RemoveScope(UiScope scope) { if (scope != null) { _scopes.Remove(scope); } } internal void RegisterWhenReady(UiScope scope, Action<UiScope> build) { if (_disposed || scope == null || build == null) { return; } if (_uiReady) { UiGuard.Run("scope.ready", delegate { build(scope); }, scope.Id); } else { _readyCallbacks.Add(new ReadyRegistration(scope, build)); } } internal void RemoveReady(UiScope scope) { if (scope == null) { return; } for (int num = _readyCallbacks.Count - 1; num >= 0; num--) { if (_readyCallbacks[num].Scope == scope) { _readyCallbacks.RemoveAt(num); } } } internal void TryMarkUiReady() { if (!_disposed && !_uiReady) { if (!HasUsableGameUi()) { _uiReadyCandidate = false; } else if (!_uiReadyCandidate) { _uiReadyCandidate = true; } else { MarkUiReady(); } } } internal void RequestReadyProbe() { if (!_disposed && !_uiReady) { LayoutOnce.Request(TryMarkUiReady); } } private bool HasUsableGameUi() { if ((Object)(object)UiGuard.Func("ready.bar", GameUi.FindActiveBar, "runtime") == (Object)null) { return false; } if ((Object)(object)UiGuard.Func("ready.layers", () => Layers.Get(Options.DefaultLayer), "runtime") == (Object)null) { return false; } return UiGuard.Value("ready.layer-refresh", delegate { Layers.Refresh(); return true; }, fallback: false, "runtime"); } private void MarkUiReady() { _uiReady = true; _uiReadyCandidate = false; UiLog.Info("game UI is ready; opening the content registration point"); UiGuard.Run("ready.native", NativeUi.Refresh, "runtime"); ReadyRegistration[] array = _readyCallbacks.ToArray(); _readyCallbacks.Clear(); int num = 0; foreach (ReadyRegistration registration in array) { UiScope scope = registration.Scope; if (scope != null && scope.IsAlive) { UiGuard.Run("scope.ready", delegate { registration.Build(scope); }, scope.Id); num++; } } if (num > 0) { UiLog.Info($"content registration point fired for {num} callback(s)"); } } internal int NextWindowIndex() { return _windowIndex++; } private static void RegisterComponents() { Register<ClickRelay>(); Register<SliderRelay>(); Register<WindowDragHandler>(); Register<PointerReceiver>(); Register<AutoHeightText>(); Register<WidthWatcher>(); Register<ScrollPin>(); Register<CanvasLayoutWatcher>(); Register<DelegateLifetime>(); Register<ScoreboardRowLifetime>(); Register<SettingsScreenLifetime>(); } private static void Register<T>() where T : class { try { ClassInjector.RegisterTypeInIl2Cpp<T>(); } catch (Exception ex) { UiLog.Warn("could not register " + typeof(T).Name + ": " + ex.Message); } } private void OnCanvasChanged() { if (!_disposed) { UiGuard.Run("layout.windows", UiWindow.FitAllToScreen, "runtime"); UiGuard.Run("layout.native", NativeUi.OnCanvasLayoutChanged, "runtime"); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (!_disposed) { if (!_uiReady) { _uiReadyCandidate = false; } UiGuard.Run("scene.assets", delegate { Assets.Invalidate(); Templates.Invalidate(); }, "runtime"); UiGuard.Run("scene.delegates", Il2CppDelegates.Sweep, "runtime"); UiGuard.Run("scene.layers", Layers.Refresh, "runtime"); UiGuard.Run("scene.native", NativeUi.Refresh, "runtime"); UiGuard.Run("scene.demo", delegate { _demo?.OnSceneLoaded(); }, "runtime"); UiGuard.Run("scene.ready", TryMarkUiReady, "runtime"); RequestReadyProbe(); } } private void OnSceneUnloaded(Scene scene) { if (!_disposed) { if (!_uiReady) { _uiReadyCandidate = false; } UiGuard.Run("scene.assets", delegate { Assets.Invalidate(); Templates.Invalidate(); }, "runtime"); UiGuard.Run("scene.delegates", Il2CppDelegates.Sweep, "runtime"); UiGuard.Run("scene.native", NativeUi.Detach, "runtime"); UiGuard.Run("scene.native.refresh", NativeUi.RequestRefresh, "runtime"); } } internal void Dispose() { if (_disposed) { return; } _disposed = true; _uiReady = false; _uiReadyCandidate = false; UiGuard.Run("runtime.unsubscribe", delegate { if ((Delegate)(object)_sceneLoaded != (Delegate)null) { SceneManager.sceneLoaded -= _sceneLoaded; } if ((Delegate)(object)_sceneUnloaded != (Delegate)null) { SceneManager.sceneUnloaded -= _sceneUnloaded; } LayoutEvents.CanvasChanged -= OnCanvasChanged; _sceneLoaded = null; _sceneUnloaded = null; }, "runtime"); UiGuard.Run("runtime.layout", delegate { LayoutOnce.Clear(); LayoutEvents.Clear(); }, "runtime"); DemoController demo = _demo; _demo = null; if (demo != null) { UiGuard.Run("demo.dispose", demo.Dispose, "runtime"); } UiGuard.Run("native.hooks", NativeHooks.Uninstall, "runtime"); UiGuard.Run("native.dispose", NativeUi.Dispose, "runtime"); _readyCallbacks.Clear(); UiScope[] array = _scopes.ToArray(); _scopes.Clear(); for (int num = array.Length - 1; num >= 0; num--) { UiGuard.Run("scope.dispose", array[num].Dispose, array[num].Id); } UiGuard.Run("runtime.pointer", PointerTracker.Clear, "runtime"); UiGuard.Run("runtime.templates", Templates.Invalidate, "runtime"); UiGuard.Run("runtime.assets", Assets.Invalidate, "runtime"); UiGuard.Run("runtime.delegates", Il2CppDelegates.Clear, "runtime"); UiGuard.Run("runtime.staging", Staging.Reset, "runtime"); UiGuard.Run("runtime.layers", Layers.Dispose, "runtime"); UiLog.Info("UI kit runtime disposed"); } } internal sealed class UiOptions { public TemplatePolicy Templates { get; init; } public Layer DefaultLayer { get; init; } = Layer.AboveGame; public bool EnableDemo { get; init; } } public sealed class UiScope : IDisposable { private readonly List<IDisposable> _owned = new List<IDisposable>(); internal UiKitRuntime Runtime { get; } public string Id { get; } public CustomApi Custom { get; } public NativeApi Native { get; } public bool IsDisposed { get; private set; } internal bool IsAlive { get { if (!IsDisposed) { return !Runtime.IsDisposed; } return false; } } internal List<IDisposable> Owned => _owned; internal UiScope(UiKitRuntime runtime, string id) { Runtime = runtime; Id = id; Custom = new CustomApi(this); Native = new NativeApi(this); } internal void RemoveOwned(IDisposable item) { if (item != null) { _owned.Remove(item); } } public UiScope WhenReady(Action<UiScope>? build) { if (build == null) { return this; } if (IsDisposed) { UiLog.OnceError("scope:ready-disposed:" + Id, "cannot register UI on disposed scope '" + Id + "'"); return this; } if (Runtime.IsDisposed) { UiLog.OnceError("scope:ready-runtime:" + Id, "cannot register UI on scope '" + Id + "': the UiKit runtime is shutting down"); return this; } try { Runtime.RegisterWhenReady(this, build); } catch (Exception value) { UiLog.Error($"scope '{Id}' ready registration failed: {value}"); } return this; } public void Dispose() { if (IsDisposed) { return; } IsDisposed = true; try { Runtime.RemoveReady(this); } catch (Exception value) { UiLog.Error($"scope '{Id}' ready unregister failed: {value}"); } IDisposable[] array = _owned.ToArray(); _owned.Clear(); for (int num = array.Length - 1; num >= 0; num--) { try { array[num].Dispose(); } catch (Exception value2) { UiLog.Error($"scope '{Id}' dispose failed: {value2}"); } } try { Runtime.RemoveScope(this); } catch (Exception value3) { UiLog.Error($"scope '{Id}' unregister failed: {value3}"); } } } public sealed class UiTheme { private readonly AssetCatalog _assets; public TMP_FontAsset? Font => UiGuard.Func("theme.font", () => _assets.Font); public Material? FontMaterial => UiGuard.Func("theme.material", () => _assets.FontShadowMaterial); public Color TextColor => AssetCatalog.DefaultTextColor; internal Sprite? Panel => UiGuard.Func("theme.panel", () => _assets.PanelSprite); internal UiTheme(AssetCatalog assets) { _assets = assets; } public Sprite? Sprite(string? name) { return UiGuard.Func("theme.sprite", () => _assets.Sprite(name ?? string.Empty)); } public Sprite? Icon(string? name) { return UiGuard.Func("theme.icon", () => _assets.Sprite(name ?? string.Empty)); } public Sprite? Ornament(OrnamentStyle style) { return UiGuard.Func("theme.ornament", () => _assets.Ornament(style)); } public IEnumerable<string> SpriteNames(string? contains = null) { try { return new List<string>(_assets.SpriteNames(contains)); } catch (Exception exception) { UiGuard.Report("theme.sprite-names", exception); return Array.Empty<string>(); } } internal Sprite? Button(AssetCatalog.ButtonVariant variant, AssetCatalog.ButtonState state) { return UiGuard.Func("theme.button", () => _assets.ButtonSprite(variant, state)); } } internal sealed class DemoController { private const string DemoScopeId = "dicemodders.uikit.demo"; private readonly UiKitRuntime _runtime; private readonly List<UiWindow> _windows = new List<UiWindow>(); private UiScope? _scope; private UiWindow? _main; private ScoreboardColumnHandle? _scoreboard; private bool _requested; private bool _visible; private bool _built; public bool IsVisible { get { if (_visible && _built && _main != null) { return _main.IsAlive; } return false; } } public DemoController(UiKitRuntime runtime) { _runtime = runtime; } public void Request() { _requested = true; } public void Show() { _requested = true; if (!_built || _scope == null || _main == null || !_main.IsAlive) { DestroyScope(); Build(); } else { SetVisible(visible: true); } } public void Hide() { _requested = false; SetVisible(visible: false); } public void Toggle() { if (IsVisible) { Hide(); } else { Show(); } } public void Rebuild() { _requested = true; DestroyScope(); Build(); } public void OnSceneLoaded() { if (!_requested) { return; } try { if ((Object)(object)GameUi.FindActiveBar() == (Object)null) { UiLog.Info("demo is enabled and will be created after a scene with the game UI loads"); return; } _runtime.Layers.Refresh(); if (_built && _main != null && _main.IsAlive) { RefreshDemoScoreboard(); return; } DestroyScope(); Build(); } catch (Exception ex) { UiLog.Error("demo scene hook failed: " + ex); } } public void Dispose() { _requested = false; DestroyScope(); } private void Build() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (_built) { return; } try { _runtime.Layers.Refresh(); UiScope uiScope = _runtime.CreateScope("dicemodders.uikit.demo"); if (uiScope == null) { UiLog.Error("demo could not create its UiKit scope"); return; } _scope = uiScope; _built = true; _visible = true; _windows.Clear(); BuildMain(); uiScope.WhenReady(delegate(UiScope ui) { UiLog.Info("demo: the startup registration point fired"); ui.Native.TopBar.AddIconButton("hammer", "UiKit demo", Toggle); bool interactable = true; TopBarButtonHandle toggleInteractable = null; toggleInteractable = ui.Native.TopBar.Add(new TopBarButtonSpec { Id = "uikit.demo.interactable", IconName = "hammer", Tooltip = "UiKit order 5; click toggles interactable", Order = 5, OnClick = delegate { interactable = !interactable; toggleInteractable?.SetInteractable(interactable); } }); ui.Native.TopBar.Add(new TopBarButtonSpec { Id = "uikit.demo.order", IconName = "hammer", Tooltip = "UiKit order 15", Order = 15, OnClick = Toggle }); if (ui.Native.TopBar.Get("uikit.demo.interactable") == null) { UiLog.Warn("demo: TopBar.Get did not return the ordered button"); } }); BuildDemoSettings(); BuildNativeDemo(uiScope); BuildProbe(Layer.Game, "This window is on Layer.Game. It should sit in the HUD band, below the game's popups.", new Vector2(700f, 80f), OrnamentStyle.BorderWithTwoCorners); BuildProbe(Layer.BehindGame, "This window is on Layer.BehindGame. The game's own UI should draw over it.", new Vector2(760f, 300f), OrnamentStyle.None); UiLog.Info("demo windows created; use Rebuild inside the demo after the game's UI has loaded to re-scan native skins"); } catch (Exception ex) { UiLog.Error("demo build failed: " + ex); DestroyScope(); } } private void BuildMain() { UiScope scope = _scope; if (scope == null) { return; } UiText status = null; _main = scope.Custom.Window(delegate(UiWindow w) { w.Title("UiKit demo").Size(620f, 640f).Position(80f, 80f) .Draggable() .Fullscreenable() .FullscreenButton() .Closable() .Ornament(OrnamentStyle.Border); w.OnClose(Close); w.Body.Scroll(delegate(UiContainer body) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0310: 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) body.Paragraph("This is the library's built-in smoke test. It uses the same public API as a mod. The widgets below are native clones when their game templates are available, otherwise managed fallbacks. Use Rebuild after entering a match to re-scan the native templates."); body.Text($"Template policy: {_runtime.Options.Templates}"); status = body.Text("Ready."); status?.Color(new Color(0.95f, 0.83f, 0.55f, 1f)); body.Separator(3f); body.Text("Buttons"); body.Row(delegate(UiContainer row) { row.Button("Click me", delegate { if (status != null) { status.Value = "Text button clicked."; } }); row.Button("Disabled")?.Interactable(on: false); row.IconButton("hammer", delegate { if (status != null) { status.Value = "Icon button clicked."; } }, "UiKit demo icon button"); Sprite val = _runtime.Theme.Icon("hammer"); if ((Object)(object)val != (Object)null) { row.IconButton(val, delegate { if (status != null) { status.Value = "Sprite icon button clicked."; } }, "UiKit demo sprite icon"); row.Button("Sprite icon", delegate { if (status != null) { status.Value = "Button sprite icon clicked."; } })?.Icon(val); } })?.Spacing(10f, 0f); body.Text("Toggle, slider and dropdown"); body.Toggle("Toggle me", value: true, delegate(bool value) { if (status != null) { status.Value = "Toggle: " + value; } }); body.Slider(0f, 100f, 50f, delegate(float value) { if (status != null) { status.Value = "Slider: " + value.ToString("0"); } })?.Format("0"); body.Dropdown(new string[3] { "First option", "Second option", "Third option" }, 0, delegate(int index) { if (status != null) { status.Value = "Dropdown index: " + index; } }); body.Text("Grid"); body.Grid(3, 90f, 32f, delegate(UiContainer grid) { for (int i = 0; i < 6; i++) { int number = i; grid.Button(number.ToString(), delegate { if (status != null) { status.Value = "Grid button " + number; } }); } }).Height(72f); body.Text("Flexible grid"); UiContainer? uiContainer = body.Grid(delegate(UiContainer grid) { for (int i = 0; i < 4; i++) { int number = i; grid.Button("Auto " + number, delegate { if (status != null) { status.Value = "Flexible grid button " + number; } }); } }); uiContainer?.Height(48f); uiContainer?.Spacing(10f, 4f); body.Text("Image pointer Move and wheel"); UiImage picture = body.Image((Texture?)(object)Texture2D.whiteTexture); picture?.Height(90f).FillWidth(); picture?.Tint(new Color(0.35f, 0.55f, 0.9f, 1f)).UvRect(new Rect(0f, 0f, 1f, 1f)); picture?.OnPointer(delegate(UiPointerEvent e) { //IL_004c: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if (status != null && e.Kind == UiPointerKind.Move) { status.Value = $"Image Move uv=({e.Uv.x:0.00}, {e.Uv.y:0.00}) size={picture?.Size.x:0}x{picture?.Size.y:0}"; } }); picture?.OnScroll(delegate(float notches) { if (status != null) { status.Value = "Image wheel: " + notches.ToString("0.##"); } }); body.Text("Fixed and weighted layout"); body.Row(delegate(UiContainer row) { row.Column(delegate(UiContainer fixedWidth) { fixedWidth.Text("Fixed 120"); })?.FixedW(120f); row.Column(delegate(UiContainer one) { one.Text("Weight 1"); })?.WeightW(1f); row.Column(delegate(UiContainer two) { two.Text("Weight 2"); })?.WeightW(2f); })?.FixedH(48f); body.Text("Window ornament"); body.Row(delegate(UiContainer row) { row.Button("Border", delegate { w.Ornament(OrnamentStyle.Border); }); row.Button("Corners", delegate { w.Ornament(OrnamentStyle.BorderWithFourCorners); }); row.Button("Classic", delegate { w.Ornament(OrnamentStyle.Classic); }); row.Button("None", delegate { w.Ornament(OrnamentStyle.None); }); }); body.Separator(); body.Button("Rebuild (re-scan native skins)", Rebuild); body.Button("Hide demo", Hide); body.Separator(); body.Text("Scroll content"); for (int num = 1; num <= 30; num++) { body.Text("Scroll row " + num); } }).FillHeight(); }); if (_main != null) { _windows.Add(_main); } } private void BuildDemoSettings() { UiScope scope = _scope; if (scope == null) { return; } scope.Native.Settings.AddTab("uikit.demo", "UiKit", delegate(SettingsTabHandle tab) { tab.AddHeader("UiKit native settings"); tab.AddToggle("Demo toggle", value: true, delegate(bool value) { UiLog.Info("demo settings toggle: " + value); }); tab.AddSlider("Demo slider", 0f, 100f, 50f, delegate(float value) { UiLog.Info("demo settings slider: " + value.ToString("0")); }, "0"); tab.AddDropdown("Demo dropdown", new string[3] { "First", "Second", "Third" }, 0, delegate(int index) { UiLog.Info("demo settings dropdown: " + index); }); tab.AddButton("Demo button", "Click", delegate { UiLog.Info("demo settings button clicked"); }); tab.AddInfo("Info rows wrap and can be updated through SetText."); tab.AddStepper("Stepper", () => "3", delegate(int delta) { UiLog.Info("demo settings step: " + delta); }); tab.AddButtons("Buttons", ("One", delegate { UiLog.Info("demo settings buttons: one"); }), ("Two", delegate { UiLog.Info("demo settings buttons: two"); })); }); int gameCount = 3; SettingsRowHandle gameInfo = null; scope.Native.Settings.AddBlock(new SettingsBlockSpec { Id = "uikit.demo.builtin.game", Page = SettingsPage.Game, Title = "UiKit demo block (Game)", Order = 10, Build = delegate(SettingsBlockHandle block) { gameInfo = block.AddInfo("Stable Info row on the game's own Game page."); block.AddToggle("Demo toggle", value: true, delegate(bool value) { gameInfo?.SetText("Game-page toggle: " + value); }); block.AddSlider("Demo slider", 0f, 10f, 4f, delegate(float value) { gameInfo?.SetText("Game-page slider: " + value.ToString("0")); }, "0", wholeNumbers: true); block.AddDropdown("Demo dropdown", new string[3] { "First", "Second", "Third" }, 0, delegate(int index) { gameInfo?.SetText("Game-page dropdown: " + index); }); block.AddStepper("Demo counter", () => gameCount.ToString(), delegate(int delta) { gameCount += delta; gameInfo?.SetText("Game-page counter: " + gameCount); }); block.AddButtons("Demo buttons", ("Reset", delegate { gameCount = 3; gameInfo?.SetText("Game-page counter reset."); }), ("Notify", delegate { gameInfo?.SetText("Game-page button clicked."); })); } }); int lobbyCount = 1; SettingsRowHandle lobbyInfo = null; scope.Native.Settings.AddBlock(new SettingsBlockSpec { Id = "uikit.demo.builtin.lobby", Page = SettingsPage.Lobby, Title = "UiKit demo block (Lobby)", Order = 10, Build = delegate(SettingsBlockHandle block) { lobbyInfo = block.AddInfo("This block is appended to the match-start settings box."); block.AddToggle("Lobby toggle", value: true, delegate(bool value) { lobbyInfo?.SetText("Lobby toggle: " + value); }); block.AddStepper("Lobby counter", () => lobbyCount.ToString(), delegate(int delta) { lobbyCount += delta; lobbyInfo?.SetText("Lobby counter: " + lobbyCount); }); block.AddButtons("Lobby buttons", ("Reset", delegate { lobbyCount = 1; lobbyInfo?.SetText("Lobby counter reset."); })); } }); } private void BuildNativeDemo(UiScope scope) { _scoreboard = scope.Native.Scoreboard.AddColumn("uikit.demo.score", "UiKit demo column"); RefreshDemoScoreboard(); TechTree tree = FindDemoTree(); if ((Object)(object)tree == (Object)null) { UiLog.Info("demo: no game tech tree is available, the Rules civilization demo is skipped"); return; } scope.Native.Rules.AddCivilization("uikit.demo.civ", "UiKit civilization", () => tree); } private void RefreshDemoScoreboard() { ScoreboardColumnHandle scoreboard = _scoreboard; if (scoreboard == null || scoreboard.IsDisposed) { return; } Dictionary<Island, string> dictionary = new Dictionary<Island, string>(); try { foreach (Island item in Object.FindObjectsOfType<Island>()) { if (!((Object)(object)item == (Object)null) && !Staging.IsOurs(((Component)item).transform)) { dictionary[item] = (Math.Abs(((Object)item).GetInstanceID()) % 100).ToString(); } } } catch (Exception ex) { UiLog.OnceError("demo:scoreboard", "demo scoreboard values failed: " + ex); } scoreboard.SetValues(dictionary); } private static TechTree? FindDemoTree() { try { foreach (Object item in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.Of<Technologies>())) { Technologies val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<Technologies>() : null); if (!((Object)(object)val == (Object)null)) { return val.TechTree((Civilization)0); } } } catch (Exception ex) { UiLog.OnceError("demo:tech-tree", "could not read a game tech tree: " + ex); } return null; } private void BuildProbe(Layer layer, string text, Vector2 position, OrnamentStyle ornament) { //IL_000e: 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) UiScope scope = _scope; if (scope != null) { UiWindow uiWindow = scope.Custom.Window(delegate(UiWindow w) { w.Title("Layer." + layer).Size(340f, 240f).Position(position.x, position.y) .Layer(layer) .Draggable() .Closable() .Ornament(ornament); w.Body.Paragraph(text); w.Body.Button("Bring to front", w.BringToFront); }); if (uiWindow != null) { _windows.Add(uiWindow); } } } private void Close() { _requested = false; DestroyScope(); } private void SetVisible(bool visible) { _visible = visible; foreach (UiWindow window in _windows) { if (window != null && window.IsAlive) { if (visible) { window.Show(); } else { window.Hide(); } } } } private void DestroyScope() { _built = false; _visible = false; _main = null; _scoreboard = null; _windows.Clear(); UiScope scope = _scope; _scope = null; if (scope == null) { return; } try { scope.Dispose(); } catch (Exception ex) { UiLog.Error("demo scope dispose failed: " + ex); } } } [BepInPlugin("DiceModders.UiKit", "UiKit", "1.0.0")] public sealed class Plugin : BasePlugin { public override void Load() { try { LoadCore(); } catch (Exception ex) { ((BasePlugin)this).Log.LogError((object)("UiKit plugin failed to load; the library will stay unavailable: " + ex)); } } private void LoadCore() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown ConfigEntry<bool> demo = ((BasePlugin)this).Config.Bind<bool>("Demo", "Enabled", false, "Show the library's built-in test windows after a scene with the game UI loads. Use the Rebuild button inside the demo after entering a match to re-scan native templates. Can also be enabled with the command-line flag --uikit-demo."); ConfigEntry<string> val = ((BasePlugin)this).Config.Bind<string>("Widgets", "Templates", "PreferNative", "Widget skin policy: PreferNative, ManagedOnly or NativeOnly."); TemplatePolicy result = TemplatePolicy.PreferNative; if (!Enum.TryParse<TemplatePolicy>(val.Value, ignoreCase: true, out result) || !Enum.IsDefined(typeof(TemplatePolicy), result)) { ManualLogSource log = ((BasePlugin)this).Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(42, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("unknown Widgets/Templates value '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(val.Value); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'; using "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<TemplatePolicy>(TemplatePolicy.PreferNative); } log.LogWarning(val2); result = TemplatePolicy.PreferNative; } if (UiKit.Initialize((BasePlugin?)(object)this, new UiOptions { Templates = result, EnableDemo = (demo.Value || HasCommandLineFlag("--uikit-demo")) }) == null) { ((BasePlugin)this).Log.LogError((object)"UiKit runtime initialization failed; mods calling UiKit.CreateScope will receive null"); return; } demo.SettingChanged += delegate { try { if (demo.Value) { UiKit.ShowDemo(); } else { UiKit.HideDemo(); } } catch (Exception ex) { ((BasePlugin)this).Log.LogError((object)("UiKit demo toggle failed: " + ex)); } }; } public override bool Unload() { try { UiKit.Shutdown(); } catch (Exception ex) { ((BasePlugin)this).Log.LogError((object)("UiKit shutdown failed: " + ex)); } return true; } private static bool HasCommandLineFlag(string flag) { string[] commandLineArgs = Environment.GetCommandLineArgs(); for (int i = 0; i < commandLineArgs.Length; i++) { if (string.Equals(commandLineArgs[i], flag, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } } internal sealed class AssetCatalog { internal enum ButtonVariant { Regular = 1, Selected } internal enum ButtonState { Ready, Hovered, Pressed, Disabled } public static readonly Color DefaultTextColor = new Color(0.969f, 0.94f, 0.893f, 1f); private readonly Dictionary<string, Sprite> _sprites = new Dictionary<string, Sprite>(); private readonly Dictionary<string, Material> _materials = new Dictionary<string, Material>(); private readonly Dictionary<string, TMP_FontAsset> _fonts = new Dictionary<string, TMP_FontAsset>(); private bool _scanned; private float _nextRescan; private TMP_FontAsset? _font; public TMP_FontAsset? Font { get { if ((Object)(object)_font != (Object)null) { return _font; } TMP_FontAsset val = FontAsset("Main-Font-Normal"); if ((Object)(object)val != (Object)null) { return _font = val; } TMP_FontAsset val2 = FontFromLive(); if ((Object)(object)val2 != (Object)null) { return _font = val2; } try { return _font = TMP_Settings.defaultFontAsset; } catch { return null; } } } public Material? FontShadowMaterial => Material("Main-Font-Normal-Shadow"); public Sprite? PanelSprite => Sprite("Background-3") ?? Sprite("Background-4"); public void Invalidate() { _sprites.Clear(); _materials.Clear(); _fonts.Clear(); _scanned = false; _nextRescan = 0f; _font = null; } private void Scan() { _sprites.Clear(); _materials.Clear(); _fonts.Clear(); foreach (Object item in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.From(typeof(Sprite)))) { Sprite val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<Sprite>() : null); if (val != null && !string.IsNullOrEmpty(((Object)val).name)) { _sprites.TryAdd(((Object)val).name, val); } } foreach (Object item2 in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.From(typeof(Material)))) { Material val2 = ((item2 != null) ? ((Il2CppObjectBase)item2).TryCast<Material>() : null); if (val2 != null && !string.IsNullOrEmpty(((Object)val2).name)) { _materials.TryAdd(((Object)val2).name, val2); } } foreach (Object item3 in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.From(typeof(TMP_FontAsset)))) { TMP_FontAsset val3 = ((item3 != null) ? ((Il2CppObjectBase)item3).TryCast<TMP_FontAsset>() : null); if (val3 != null && !string.IsNullOrEmpty(((Object)val3).name)) { _fonts.TryAdd(((Object)val3).name, val3); } } _scanned = true; _nextRescan = Time.realtimeSinceStartup + 3f; } private void EnsureScanned() { if (!_scanned) { Scan(); } } private T? Lookup<T>(Dictionary<string, T> map, string? name) where T : Object { if (string.IsNullOrEmpty(name)) { return default(T); } EnsureScanned(); if (map.TryGetValue(name, out T value) && (Object)(object)value != (Object)null) { return value; } if (Time.realtimeSinceStartup < _nextRescan) { return default(T); } Scan(); if (!map.TryGetValue(name, out value) || !((Object)(object)value != (Object)null)) { return default(T); } return value; } public Sprite? Sprite(string? name) { return Lookup<Sprite>(_sprites, name); } public Material? Material(string? name) { return Lookup<Material>(_materials, name); } public TMP_FontAsset? FontAsset(string? name) { return Lookup<TMP_FontAsset>(_fonts, name); } public IEnumerable<string> SpriteNames(string? contains = null) { EnsureScanned(); foreach (KeyValuePair<string, Sprite> sprite in _sprites) { if (!((Object)(object)sprite.Value == (Object)null) && (contains == null || sprite.Key.IndexOf(contains, StringComparison.OrdinalIgnoreCase) >= 0)) { yield return sprite.Key; } } } public Sprite? ButtonSprite(ButtonVariant variant, ButtonState state) { return Sprite($"Button-{variant}-{state}"); } public Sprite? Ornament(OrnamentStyle style) { return (Sprite?)(style switch { OrnamentStyle.Border => Sprite("Ornament-1"), OrnamentStyle.BorderWithTwoCorners => Sprite("Ornament-2"), OrnamentStyle.BorderWithFourCorners => Sprite("Ornament-5"), OrnamentStyle.Classic => Sprite("Ornament-3"), _ => null, }); } private TMP_FontAsset? FontFromLive() { try { foreach (TMP_Text item in Object.FindObjectsOfType<TMP_Text>()) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item.font == (Object)null) && ((Component)item).gameObject.activeInHierarchy) { return item.font; } } } catch { } return null; } } internal static class EventRelay { public static UnityAction? ToUnity(Action? action) { if (action == null) { return null; } return DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate { try { action(); } catch (Exception ex) { UiLog.Error("UI callback failed: " + ex); } }); } public static UnityAction<float>? ToUnity(Action<float>? action) { if (action == null) { return null; } return DelegateSupport.ConvertDelegate<UnityAction<float>>((Delegate)(Action<float>)delegate(float value) { try { action(value); } catch (Exception ex) { UiLog.Error("UI callback failed: " + ex); } }); } public static UnityAction<BaseEventData>? ToEvent(Action<BaseEventData>? action) { if (action == null) { return null; } return DelegateSupport.ConvertDelegate<UnityAction<BaseEventData>>((Delegate)(Action<BaseEventData>)delegate(BaseEventData data) { try { action(data); } catch (Exception ex) { UiLog.Error("UI event callback failed: " + ex); } }); } } internal sealed class LayerCanvases : IDisposable { private readonly UiKitRuntime _runtime; private Canvas? _behind; private Canvas? _game; private Canvas? _above; private int _gameOrder; private int _behindOrder; private int _aboveOrder; private bool _initialized; internal event Action? OrdersChanged; public LayerCanvases(UiKitRuntime runtime) { _runtime = runtime; } public Canvas? Get(Layer layer) { Ensure(); return (Canvas?)(layer switch { Layer.BehindGame => _behind, Layer.Game => _game, _ => _above, }); } public int OrderFor(Layer layer) { Ensure(); return layer switch { Layer.BehindGame => _behindOrder, Layer.Game => _gameOrder, _ => _aboveOrder, }; } public void Refresh() { if (_initialized) { Canvas val = FindHudCanvas(); ComputeOrders(val); ApplyOrder(_behind, _behindOrder); ApplyOrder(_game, _gameOrder); ApplyOrder(_above, _aboveOrder); ApplyRenderMode(_behind, Layer.BehindGame, val); ApplyRenderMode(_game, Layer.Game, val); ApplyRenderMode(_above, Layer.AboveGame, val); if ((Object)(object)val != (Object)null) { ApplySortingLayer(_behind, val); ApplySortingLayer(_game, val); ApplySortingLayer(_above, val); CopyScaler(val, ((Object)(object)_behind != (Object)null) ? ((Component)_behind).GetComponent<CanvasScaler>() : null); CopyScaler(val, ((Object)(object)_game != (Object)null) ? ((Component)_game).GetComponent<CanvasScaler>() : null); CopyScaler(val, ((Object)(object)_above != (Object)null) ? ((Component)_above).GetComponent<CanvasScaler>() : null); } NotifyOrdersChanged(); } } private void NotifyOrdersChanged() { Action action = this.OrdersChanged; if (action == null) { return; } Delegate[] invocationList = action.GetInvocationList(); foreach (Delegate obj in invocationList) { try { ((Action)obj)(); } catch (Exception ex) { UiLog.Error("layer order listener failed: " + ex.Message); } } } public void Invalidate() { Refresh(); } private void Ensure() { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (!_initialized) { Canvas val = FindHudCanvas(); ComputeOrders(val); Canvas val2 = null; Canvas val3 = null; Canvas val4 = null; try { val2 = Create("DiceModders UiKit [Behind]", Layer.BehindGame, _behindOrder, val); val3 = Create("DiceModders UiKit [Game]", Layer.Game, _gameOrder, val); val4 = Create("DiceModders UiKit [Above]", Layer.AboveGame, _aboveOrder, val); } catch (Exception ex) { Destroy(val4); Destroy(val3); Destroy(val2); UiLog.Error("could not create the shared UI layers: " + ex); return; } _behind = val2; _game = val3; _above = val4; _initialized = true; string value = (((Object)(object)val != (Object)null) ? ((object)val.renderMode/*cast due to .constrained prefix*/).ToString() : "no HUD"); string value2 = (((Object)(object)val != (Object)null) ? ("'" + ((Object)val).name + "'") : "none"); UiLog.Info($"UI layers ready (HUD {value2}, {value}, order {_gameOrder - 1}; game {_gameOrder}, behind {_behindOrder}, above {_aboveOrder})"); } } private static Canvas Create(string name, Layer layer, int order, Canvas? hud) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) RectTransform val = null; try { val = UiFactory.NewRect(name, null); GameObject gameObject = ((Component)val).gameObject; Object.DontDestroyOnLoad((Object)(object)gameObject); gameObject.layer = (((Object)(object)hud != (Object)null) ? ((Component)hud).gameObject.layer : 5); val.sizeDelta = new Vector2(1920f, 1080f); Canvas val2 = gameObject.AddComponent<Canvas>(); ApplyRenderMode(val2, layer, hud); val2.sortingOrder = order; if ((Object)(object)hud != (Object)null) { val2.sortingLayerID = hud.sortingLayerID; } CanvasScaler target = gameObject.AddComponent<CanvasScaler>(); CopyScaler(hud, target); gameObject.AddComponent<GraphicRaycaster>(); LayoutEvents.Watch((Transform?)(object)val); return val2; } catch { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } throw; } } private static void ApplyRenderMode(Canvas? canvas, Layer layer, Canvas? hud) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)canvas == (Object)null)) { if ((Object)(object)hud == (Object)null || (int)hud.renderMode == 0 || (Object)(object)hud.worldCamera == (Object)null) { canvas.renderMode = (RenderMode)0; return; } canvas.renderMode = (RenderMode)1; canvas.worldCamera = hud.worldCamera; float num = ((hud.planeDistance > 0.01f) ? hud.planeDistance : 100f); float num2 = (((Object)(object)hud.worldCamera != (Object)null) ? (hud.worldCamera.nearClipPlane + 0.01f) : 0.01f); canvas.planeDistance = layer switch { Layer.BehindGame => num + 10f, Layer.Game => num, _ => Mathf.Max(num2, num - 10f), }; } } private static void ApplyOrder(Canvas? canvas, int order) { if ((Object)(object)canvas != (Object)null) { canvas.sortingOrder = order; } } private static void ApplySortingLayer(Canvas? canvas, Canvas? hud) { if ((Object)(object)canvas != (Object)null && (Object)(object)hud != (Object)null) { canvas.sortingLayerID = hud.sortingLayerID; } } private static void CopyScaler(Canvas? source, CanvasScaler? target) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) if (!((Object)(object)target == (Object)null)) { CanvasScaler val = (((Object)(object)source != (Object)null) ? ((Component)source).GetComponent<CanvasScaler>() : null); if ((Object)(object)val == (Object)null) { target.uiScaleMode = (ScaleMode)1; target.referenceResolution = new Vector2(1920f, 1080f); target.screenMatchMode = (ScreenMatchMode)0; target.matchWidthOrHeight = 0.5f; target.referencePixelsPerUnit = 100f; } else { target.uiScaleMode = val.uiScaleMode; target.referenceResolution = val.referenceResolution; target.screenMatchMode = val.screenMatchMode; target.matchWidthOrHeight = val.matchWidthOrHeight; target.referencePixelsPerUnit = val.referencePixelsPerUnit; target.scaleFactor = val.scaleFactor; target.physicalUnit = val.physicalUnit; target.fallbackScreenDPI = val.fallbackScreenDPI; target.defaultSpriteDPI = val.defaultSpriteDPI; } } } private void ComputeOrders(Canvas? hud) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 int num = (((Object)(object)hud != (Object)null) ? hud.sortingOrder : 0); _gameOrder = num + 1; int num2 = num; int num3 = num; foreach (Canvas item in Object.FindObjectsOfType<Canvas>()) { if (!((Object)(object)item == (Object)null) && item.isRootCanvas && ((Component)item).gameObject.activeInHierarchy && (int)item.renderMode != 2 && !((Object)((Component)item).gameObject).name.StartsWith("DiceModders UiKit") && item.sortingOrder <= 1000) { num2 = Mathf.Min(num2, item.sortingOrder); num3 = Mathf.Max(num3, item.sortingOrder); } } _behindOrder = num2 - 100; _aboveOrder = num3 + 100; } private static Canvas? FindHudCanvas() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 try { Canvas result = null; int num = int.MinValue; foreach (Canvas item in Object.FindObjectsOfType<Canvas>()) { if (!((Object)(object)item == (Object)null) && item.isRootCanvas && ((Component)item).gameObject.activeInHierarchy && (int)item.renderMode != 2 && !((Object)((Component)item).gameObject).name.StartsWith("DiceModders UiKit")) { int num2 = 0; if (item.sortingOrder <= 100) { num2 += 10; } if (item.sortingOrder == 0) { num2 += 2; } if ((Object)(object)GameUi.FindBar(((Component)item).transform) != (Object)null) { num2 += 1000; } if (num2 > num) { num = num2; result = item; } } } return result; } catch { return null; } } public void Dispose() { this.OrdersChanged = null; UiGuard.Run("layers.behind", delegate { Destroy(_behind); }); UiGuard.Run("layers.game", delegate { Destroy(_game); }); UiGuard.Run("layers.above", delegate { Destroy(_above); }); _behind = null; _game = null; _above = null; _initialized = false; } private static void Destroy(Canvas? canvas) { if (!((Object)(object)canvas == (Object)null)) { Object.Destroy((Object)(object)((Component)canvas).gameObject); } } } internal static class LayoutEvents { private static bool _active; internal static event Action? CanvasChanged; public static void Activate() { _active = true; LayoutEvents.CanvasChanged = null; } public static void RequestCanvasChanged() { if (_active) { LayoutOnce.Request(NotifyCanvasChanged); } } public static void Watch(Transform? transform) { if (!_active || (Object)(object)transform == (Object)null) { return; } try { GameObject gameObject = ((Component)transform).gameObject; if (!((Object)(object)gameObject == (Object)null) && !((Object)(object)gameObject.GetComponent<CanvasLayoutWatcher>() != (Object)null)) { gameObject.AddComponent<CanvasLayoutWatcher>(); } } catch (Exception ex) { UiLog.Once("layout:watch", "could not watch a canvas for size changes: " + ex.Message); } } public static void Clear() { _active = false; LayoutEvents.CanvasChanged = null; } private static void NotifyCanvasChanged() { Action canvasChanged = LayoutEvents.CanvasChanged; if (canvasChanged == null) { return; } Delegate[] invocationList = canvasChanged.GetInvocationList(); foreach (Delegate obj in invocationList) { try { ((Action)obj)(); } catch (Exception ex) { UiLog.Error("canvas layout listener failed: " + ex.Message); } } } } internal static class LayoutOnce { private static readonly List<Action> Pending = new List<Action>(); private static WillRenderCanvases? _handler; private static bool _scheduled; private static bool _enabled = true; public static void Begin() { _enabled = true; } public static void Request(Action? action) { if (!_enabled || action == null) { return; } Pending.Add(action); if (_scheduled) { return; } try { WillRenderCanvases val = DelegateSupport.ConvertDelegate<WillRenderCanvases>((Delegate)new Action(Flush)); if ((Delegate)(object)val == (Delegate)null) { Flush(); return; } _handler = val; _scheduled = true; Canvas.willRenderCanvases += val; } catch (Exception ex) { _handler = null; _scheduled = false; UiLog.Once("layout:once", "could not schedule a layout callback: " + ex.Message); Flush(); } } public static void Clear() { _enabled = false; Unsubscribe(); Pending.Clear(); } private static void Flush() { Unsubscribe(); Action[] array = Pending.ToArray(); Pending.Clear(); for (int i = 0; i < array.Length; i++) { UiGuard.Callback("layout.once", array[i]); } } private static void Unsubscribe() { WillRenderCanvases handler = _handler; _handler = null; _scheduled = false; if ((Delegate)(object)handler == (Delegate)null) { return; } try { Canvas.willRenderCanvases -= handler; } catch (Exception ex) { UiLog.Once("layout:unsubscribe", "could not remove a layout callback: " + ex.Message); } } } internal static class SkinPolicy { public static bool AllowNative(UiKitRuntime runtime) { if (runtime != null) { return runtime.Options.Templates != TemplatePolicy.ManagedOnly; } return false; } public static bool AllowManaged(UiKitRuntime runtime) { if (runtime != null) { return runtime.Options.Templates != TemplatePolicy.NativeOnly; } return true; } public static T? TryNative<T>(string widget, Func<T?> create) where T : class { try { return create(); } catch (Exception value) { UiLog.OnceError("skin:error:" + widget, $"native {widget} could not be created: {value}"); return null; } } public static bool MissingNative(UiKitRuntime runtime, string widget) { if (AllowManaged(runtime)) { UiLog.Once("skin:fallback:" + widget, "native " + widget + " template not found; using the managed fallback"); return true; } UiLog.OnceError("skin:missing:" + widget, "native " + widget + " template not found and TemplatePolicy is NativeOnly; the widget was skipped"); return false; } public static bool MissingManaged(UiKitRuntime runtime, string widget) { UiLog.OnceError("skin:managed-disabled:" + widget, widget + " needs a managed fallback, but TemplatePolicy is NativeOnly; the widget was skipped"); return false; } } internal static class TmpTextSafety { public static bool EnsureMeasurable(TMP_Text? text) { if ((Object)(object)text == (Object)null) { return false; } try { if ((Object)(object)text.font == (Object)null) { return false; } if ((Object)(object)text.fontSharedMaterial == (Object)null) { Material material = ((TMP_Asset)text.font).material; if ((Object)(object)material == (Object)null) { return false; } text.fontSharedMaterial = material; } return true; } catch { return false; } } public static bool TryPreferredValues(TMP_Text? text, string? value, float width, float height, out Vector2 result) { //IL_0002: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) result = default(Vector2); if (!EnsureMeasurable(text)) { return false; } try { result = text.GetPreferredValues(value ?? string.Empty, width, height); if (float.IsNaN(result.x) || float.IsInfinity(result.x) || float.IsNaN(result.y) || float.IsInfinity(result.y)) { result = default(Vector2); return false; } return true; } catch { return false; } } } internal static class UiFactory { private static readonly Il2CppReferenceArray<Type> RectTypes = BuildRectTypes(); private static Il2CppReferenceArray<Type> BuildRectTypes() { return new Il2CppReferenceArray<Type>(1L) { [0] = Il2CppType.Of<RectTransform>() }; } public static RectTransform NewRect(string name, Transform? parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject(name, RectTypes); RectTransform component = val.GetComponent<RectTransform>(); if ((Object)(object)parent != (Object)null) { ((Transform)component).SetParent(parent, false); val.layer = ((Component)parent).gameObject.layer; } else { val.layer = 5; } return component; } public static void Stretch(RectTransform rect) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null)) { rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; } } public static Image AddImage(RectTransform? parent, string name, Sprite? sprite, Color? color = null, bool raycast = false) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)NewRect(name, (Transform?)(object)parent)).gameObject.AddComponent<Image>(); obj.sprite = sprite; obj.type = (Type)(((Object)(object)sprite != (Object)null) ? 1 : 0); ((Graphic)obj).color = (Color)(((??)color) ?? Color.white); ((Graphic)obj).raycastTarget = raycast; return obj; } public static TextMeshProUGUI AddText(RectTransform? parent, string name, string? value, float size, TextAlignmentOptions align, UiTheme? theme, bool raycast = false) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI obj = ((Component)NewRect(name, (Transform?)(object)parent)).gameObject.AddComponent<TextMeshProUGUI>(); ApplyFont((TMP_Text?)(object)obj, theme); ((TMP_Text)obj).text = value ?? string.Empty; ((TMP_Text)obj).fontSize = size; ((TMP_Text)obj).alignment = align; ((Graphic)obj).color = theme?.TextColor ?? AssetCatalog.DefaultTextColor; ((Graphic)obj).raycastTarget = raycast; return obj; } public static void ApplyFont(TMP_Text? text, UiTheme? theme) { if (!((Object)(object)text == (Object)null) && theme != null) { TMP_FontAsset font = theme.Font; if ((Object)(object)font != (Object)null) { text.font = font; } Material fontMaterial = theme.FontMaterial; if ((Object)(object)fontMaterial != (Object)null) { text.fontSharedMaterial = fontMaterial; } else if ((Object)(object)font != (Object)null) { text.fontSharedMaterial = ((TMP_Asset)font).material; } } } public static LayoutElement? Layout(RectTransform? rect) { if ((Object)(object)rect == (Object)null) { return null; } return ((Component)rect).gameObject.GetComponent<LayoutElement>() ?? ((Component)rect).gameObject.AddComponent<LayoutElement>(); } public static void Destroy(Object obj) { if (obj != (Object)null) { Object.Destroy(obj); } } public static void Destroy(GameObject go) { if ((Object)(object)go != (Object)null) { Object.Destroy((Object)(object)go); } } } internal static class UiGuard { public static void Run(string operation, Action? action, string? scope = null) { if (action == null) { return; } try { action(); } catch (Exception exception) { Report(operation, exception, scope); } } public static T? Func<T>(string operation, Func<T>? action, string? scope = null) where T : class? { if (action == null) { return null; } try { return action(); } catch (Exception exception) { Report(operation, exception, scope); return null; } } public static T Value<T>(string operation, Func<T>? action, T fallback, string? scope = null) { if (action == null) { return fallback; } try { return action(); } catch (Exception exception) { Report(operation, exception, scope); return fallback; } } public static void Callback(string operation, Action? callback) { if (callback == null) { return; } try { callback(); } catch (Exception exception) { Report("callback." + operation, exception); } } public static void Report(string operation, Exception exception, string? scope = null) { string text = (string.IsNullOrWhiteSpace(scope) ? "uikit" : ("uikit[" + scope + "]")); try { UiLog.OnceError("guard:" + text + ":" + operation, $"{text}: {operation} failed: {exception}"); } catch { } } public static string Text(string? value) { return value ?? string.Empty; } public static float Finite(float value, float fallback) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return value; } return fallback; } } internal static class UiLog { private static ManualLogSource? _log; private static readonly HashSet<string> OnceKeys = new HashSet<string>(); public static void SetLogger(ManualLogSource? log) { _log = log; } public static void ResetOnce() { lock (OnceKeys) { OnceKeys.Clear(); } } public static void Info(string? message) { Write(delegate(ManualLogSource log) { log.LogInfo((object)message); }); } public static void Warn(string? message) { Write(delegate(ManualLogSource log) { log.LogWarning((object)message); }); } public static void Error(string? message) { Write(delegate(ManualLogSource log) { log.LogError((object)message); }); } public static void Once(string key, string? message) { lock (OnceKeys) { if (!OnceKeys.Add(key)) { return; } } Warn(message); } public static void InfoOnce(string key, string? message) { lock (OnceKeys) { if (!OnceKeys.Add(key)) { return; } } Info(message); } public static void OnceError(string key, string? message) { lock (OnceKeys) { if (!OnceKeys.Add(key)) { return; } } Error(message); } private static void Write(Action<ManualLogSource> write) { ManualLogSource log = _log; if (log == null) { return; } try { write(log); } catch { } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "DiceModders.UiKit"; public const string PLUGIN_NAME = "UiKit"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace DiceModders.UiKit.Custom { internal static class AutoHeightRegistry { private sealed class Binding { public Action? Callback; } private static readonly ConditionalWeakTable<AutoHeightText, Binding> Table = new ConditionalWeakTable<AutoHeightText, Binding>(); public static void SetAfterMeasure(AutoHeightText? owner, Action? callback) { if (!((Object)(object)owner == (Object)null)) { if (callback == null) { Table.Remove(owner); return; } if (Table.TryGetValue(owner, out Binding value)) { value.Callback = callback; return; } Table.Add(owner, new Binding { Callback = callback }); } } public static void Invoke(AutoHeightText? owner) { if (!((Object)(object)owner == (Object)null) && Table.TryGetValue(owner, out Binding value)) { UiGuard.Callback("auto-height", value.Callback); } } public static void Clear(AutoHeightText? owner) { if ((Object)(object)owner != (Object)null) { Table.Remove(owner); } } } internal sealed class AutoHeightText : MonoBehaviour { private TMP_Text? _text; private LayoutElement? _layout; private float _lastHeight = -1f; private bool _scheduled; private WillRenderCanvases? _canvasHandler; public bool Enabled { get; private set; } public AutoHeightText(IntPtr ptr) : base(ptr) { } public void Bind(TMP_Text? text, LayoutElement? layout) { _text = text; _layout = layout; } public void SetEnabled(bool enabled) { Enabled = enabled; _lastHeight = -1f; if (enabled) { MeasureSoon(); } } private void OnEnable() { if (Enabled) { MeasureSoon(); } } private void Start() { if (Enabled) { MeasureSoon(); } } private void OnRectTransformDimensionsChange() { if (Enabled) { Measure(); } } public void MeasureNow() { if (Enabled) { Measure(); } } public void Refresh() { MeasureSoon(); } private void MeasureSoon() { if (Enabled && !_scheduled && !((Object)(object)_text == (Object)null)) { WillRenderCanvases val = DelegateSupport.ConvertDelegate<WillRenderCanvases>((Delegate)new Action(OnWillRenderCanvases)); if (!((Delegate)(object)val == (Delegate)null)) { _scheduled = true; _canvasHandler = val; Canvas.willRenderCanvases += val; } } } private void OnWillRenderCanvases() { if ((Delegate)(object)_canvasHandler != (Delegate)null) { Canvas.willRenderCanvases -= _canvasHandler; _canvasHandler = null; } _scheduled = false; Measure(); } private void Measure() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (!Enabled) { return; } TMP_Text text = _text; LayoutElement layout = _layout; if ((Object)(object)text == (Object)null || (Object)(object)layout == (Object)null) { return; } float width; try { RectTransform rectTransform = text.rectTransform; if ((Object)(object)rectTransform == (Object)null) { return; } Rect rect = rectTransform.rect; width = ((Rect)(ref rect)).width; } catch (Exception) { return; } if (width < 1f || !TmpTextSafety.TryPreferredValues(text, text.text, width, 0f, out var result)) { return; } float num = Mathf.Ceil(result.y); float num2 = Mathf.Ceil(text.fontSize * 1.2f); if (num < num2) { num = num2; } if (Mathf.Abs(num - _lastHeight) < 0.5f) { return; } _lastHeight = num; layout.minHeight = num; layout.preferredHeight = num; layout.flexibleHeight = 0f; Transform parent = ((Transform)text.rectTransform).parent; if ((Object)(object)parent != (Object)null) { RectTransform val = ((Il2CppObjectBase)parent).TryCast<RectTransform>(); if ((Object)(object)val != (Object)null) { LayoutRebuilder.MarkLayoutForRebuild(val); } } AutoHeightRegistry.Invoke(this); } private void OnDisable() { if ((Delegate)(object)_canvasHandler != (Delegate)null) { Canvas.willRenderCanvases -= _canvasHandler; _canvasHandler = null; } _scheduled = false; } private void OnDestroy() { OnDisable(); AutoHeightRegistry.Clear(this); _text = null; _layout = null; } } internal sealed class CanvasLayoutWatcher : MonoBehaviour { public CanvasLayoutWatcher(IntPtr ptr) : base(ptr) { } private void OnEnable() { LayoutEvents.RequestCanvasChanged(); } private void OnRectTransformDimensionsChange() { LayoutEvents.RequestCanvasChanged(); } } internal sealed class ClickRelay : MonoBehaviour { public ClickRelay(IntPtr ptr) : base(ptr) { } private void OnDestroy() { ClickRelayRegistry.Clear(this); } } internal static class ClickRelayRegistry { private sealed class Binding { public Button? Button; public UnityAction? Callback; } private static readonly ConditionalWeakTable<ClickRelay, Binding> Table = new ConditionalWeakTable<ClickRelay, Binding>(); public static void Bind(ClickRelay relay, Button? button, Action? action) { if ((Object)(object)relay == (Object)null) { return; } Clear(relay); if (!((Object)(object)button == (Object)null) && action != null) { UnityAction val = EventRelay.ToUnity(action); if (!((Delegate)(object)val == (Delegate)null)) { ((UnityEvent)button.onClick).AddListener(val); Table.Add(relay, new Binding { Button = button, Callback = val }); } } } public static void Clear(ClickRelay relay) { if (!((Object)(object)relay == (Object)null) && Table.TryGetValue(relay, out Binding value)) { Table.Remove(relay); if ((Object)(object)value.Button != (Object)null && (Delegate)(object)value.Callback != (Delegate)null) { ((UnityEvent)value.Button.onClick).RemoveListener(value.Callback); } } } } internal static class EventTriggerBinder { public static void Add(EventTrigger trigger, List<UnityAction<BaseEventData>>? keep, EventTriggerType type, UnityAction<BaseEventData>? action) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (!((Object)(object)trigger == (Object)null) && !((Delegate)(object)action == (Delegate)null)) { Entry val = new Entry { eventID = type }; ((UnityEvent<BaseEventData>)(object)val.callback).AddListener(action); trigger.triggers.Add(val); keep?.Add(action); } } } internal sealed class PointerReceiver : MonoBehaviour { public RectTransform? Area; private EventTrigger? _trigger; private readonly List<UnityAction<BaseEventData>> _keep = new List<UnityAction<BaseEventData>>(); private PointerTracker.Entry? _entry; private bool _hover; private Vector2 _lastLocal; private bool _hasLastLocal; public PointerReceiver(IntPtr ptr) : base(ptr) { } public void Bind(RectTransform? area) { Area = area; if ((Object)(object)_trigger == (Object)null) { EventTrigger val = (_trigger = ((Component)this).gameObject.GetComponent<EventTrigger>() ?? ((Component)this).gameObject.AddComponent<EventTrigger>()); val.triggers.Clear(); EventTriggerBinder.Add(val, _keep, (EventTriggerType)0, EventRelay.ToEvent(OnEnter)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)1, EventRelay.ToEvent(OnExit)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)2, EventRelay.ToEvent(OnDown)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)3, EventRelay.ToEvent(OnUp)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)4, EventRelay.ToEvent(OnClick)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)13, EventRelay.ToEvent(OnBeginDrag)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)5, EventRelay.ToEvent(OnDrag)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)14, EventRelay.ToEvent(OnEndDrag)); } if (_entry == null) { _entry = PointerTracker.Add((Object?)(object)this, (Vector2 position) => _hover && (Object)(object)Area != (Object)null && ((Component)Area).gameObject.activeInHierarchy && RectTransformUtility.RectangleContainsScreenPoint(Area, position, PointerTracker.CameraFor(Area)), OnWheel, OnMove); } } private static Camera? CameraFor(RectTransform? rect) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rect == (Object)null) { return null; } Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>(); componentInParent = (((Object)(object)componentInParent != (Object)null) ? componentInParent.rootCanvas : null); if (!((Object)(object)componentInParent != (Object)null) || (int)componentInParent.renderMode == 0) { return null; } return componentInParent.worldCamera; } private static float ScaleFor(RectTransform? rect) { if ((Object)(object)rect == (Object)null) { return 1f; } Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>(); componentInParent = (((Object)(object)componentInParent != (Object)null) ? componentInParent.rootCanvas : null); if (!((Object)(object)componentInParent != (Object)null) || !(componentInParent.scaleFactor > 0.0001f)) { return 1f; } return componentInParent.scaleFactor; } private void Raise(int kind, PointerEventData? data, int button) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) Action<UiPointerEvent> action = PointerRegistry.Pointer(this); Vector2 val = default(Vector2); if (action == null || (Object)(object)Area == (Object)null || data == null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(Area, data.position, CameraFor(Area), ref val)) { return; } Rect rect = Area.rect; Vector2 val2 = val - ((Rect)(ref rect)).min; Vector2 uv = default(Vector2); ((Vector2)(ref uv))..ctor((((Rect)(ref rect)).width > 0.001f) ? (val2.x / ((Rect)(ref rect)).width) : 0f, (((Rect)(ref rect)).height > 0.001f) ? (val2.y / ((Rect)(ref rect)).height) : 0f); Vector2 delta = data.delta / ScaleFor(Area); try { action(new UiPointerEvent((UiPointerKind)kind, button, uv, val2, delta)); } catch (Exception ex) { UiLog.Error("image pointer handler: " + ex); } } private void OnEnter(BaseEventData? data) { _hover = true; _hasLastLocal = false; Raise(5, (data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null, -1); } private void OnExit(BaseEventData? data) { _hover = false; _hasLastLocal = false; Raise(6, (data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null, -1); } private void OnDown(BaseEventData? data) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); Raise(0, val, (val == null) ? (-1) : ((int)val.button)); } private void OnUp(BaseEventData? data) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); Raise(1, val, (val == null) ? (-1) : ((int)val.button)); } private void OnClick(BaseEventData? data) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); Raise(2, val, (val == null) ? (-1) : ((int)val.button)); } private void OnBeginDrag(BaseEventData? data) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); Raise(4, val, (val == null) ? (-1) : ((int)val.button)); } private void OnDrag(BaseEventData? data) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); Raise(4, val, (val == null) ? (-1) : ((int)val.button)); } private void OnEndDrag(BaseEventData? data) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); Raise(1, val, (val == null) ? (-1) : ((int)val.button)); } private bool OnWheel(float notches) { Action<float> action = PointerRegistry.Scroll(this); if (action == null) { return false; } try { action(notches); } catch (Exception ex) { UiLog.Error("image scroll handler: " + ex); } return true; } private void OnMove(Vector2 screen) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Action<UiPointerEvent> action = PointerRegistry.Pointer(this); RectTransform area = Area; Vector2 val = default(Vector2); if (action == null || (Object)(object)area == (Object)null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(area, screen, PointerTracker.CameraFor(area), ref val)) { return; } Rect rect = area.rect; Vector2 val2 = val - ((Rect)(ref rect)).min; if (_hasLastLocal && val2 == _lastLocal) { return; } Vector2 uv = default(Vector2); ((Vector2)(ref uv))..ctor((((Rect)(ref rect)).width > 0.001f) ? (val2.x / ((Rect)(ref rect)).width) : 0f, (((Rect)(ref rect)).height > 0.001f) ? (val2.y / ((Rect)(ref rect)).height) : 0f); Vector2 delta = (_hasLastLocal ? (val2 - _lastLocal) : Vector2.zero); _lastLocal = val2; _hasLastLocal = true; try { action(new UiPointerEvent(UiPointerKind.Move, -1, uv, val2, delta)); } catch (Exception ex) { UiLog.Error("image pointer handler: " + ex); } } private void OnDestroy() { PointerRegistry.Clear(this); PointerTracker.Remove(_entry); _entry = null; _keep.Clear(); } } internal static class PointerRegistry { private sealed class Handlers { public Action<UiPointerEvent>? Pointer; public Action<float>? Scroll; } private static readonly ConditionalWeakTable<PointerReceiver, Handlers> Table = new ConditionalWeakTable<PointerReceiver, Handlers>(); public static void SetPointer(PointerReceiver? owner, Action<UiPointerEvent>? handler) { if (!((Object)(object)owner == (Object)null)) { if (!Table.TryGetValue(owner, out Handlers value)) { value = new Handlers(); Table.Add(owner, value); } value.Pointer = handler; if (value.Pointer == null && value.Scroll == null) { Table.Remove(owner); } } } public static void SetScroll(PointerReceiver? owner, Action<float>? handler) { if (!((Object)(object)owner == (Object)null)) { if (!Table.TryGetValue(owner, out Handlers value)) { value = new Handlers(); Table.Add(owner, value); } value.Scroll = handler; if (value.Pointer == null && value.Scroll == null) { Table.Remove(owner); } } } public static Action<UiPointerEvent>? Pointer(PointerReceiver? owner) { if (!((Object)(object)owner != (Object)null) || !Table.TryGetValue(owner, out Handlers value)) { return null; } return value.Pointer; } public static Action<float>? Scroll(PointerReceiver? owner) { if (!((Object)(object)owner != (Object)null) || !Table.TryGetValue(owner, out Handlers value)) { return null; } return value.Scroll; } public static void Clear(PointerReceiver? owner) { if ((Object)(object)owner != (Object)null) { Table.Remove(owner); } } } internal sealed class ScrollPin : MonoBehaviour { private ScrollRect? _scroll; private UnityAction<Vector2>? _handler; private bool _pinned = true; private bool _applying; public ScrollPin(IntPtr ptr) : base(ptr) { } public void Bind(ScrollRect? scroll) { if (!((Object)(object)scroll == (Object)null)) { _scroll = scroll; UnityAction<Vector2> val = DelegateSupport.ConvertDelegate<UnityAction<Vector2>>((Delegate)new Action<Vector2>(OnScroll)); if (!((Delegate)(object)val == (Delegate)null)) { _handler = val; ((UnityEvent<Vector2>)(object)scroll.onValueChanged).AddListener(val); } } } private void OnScroll(Vector2 position) { if (!_applying && !((Object)(object)_scroll == (Object)null)) { _pinned = _scroll.verticalNormalizedPosition > 0.999f; } } private void OnRectTransformDimensionsChange() { if (!((Object)(object)_scroll == (Object)null) && _pinned) { _applying = true; _scroll.verticalNormalizedPosition = 1f; _applying = false; } } private void OnDestroy() { if ((Object)(object)_scroll != (Object)null && (Delegate)(object)_handler != (Delegate)null) { ((UnityEvent<Vector2>)(object)_scroll.onValueChanged).RemoveListener(_handler); } _scroll = null; _handler = null; } } internal sealed class SliderRelay : MonoBehaviour { public SliderRelay(IntPtr ptr) : base(ptr) { } private void OnDestroy() { SliderRelayRegistry.Clear(this); } } internal static class SliderRelayRegistry { private sealed class Binding { public Slider? Slider; public UnityAction<float>? Callback; } private static readonly ConditionalWeakTable<SliderRelay, Binding> Table = new ConditionalWeakTable<SliderRelay, Binding>(); public static void Bind(SliderRelay relay, Slider? slider, Action<float>? action) { if ((Object)(object)relay == (Object)null) { return; } Clear(relay); if (!((Object)(object)slider == (Object)null) && action != null) { UnityAction<float> val = EventRelay.ToUnity(action); if (!((Delegate)(object)val == (Delegate)null)) { ((UnityEvent<float>)(object)slider.onValueChanged).AddListener(val); Table.Add(relay, new Binding { Slider = slider, Callback = val }); } } } public static void Clear(SliderRelay relay) { if (!((Object)(object)relay == (Object)null) && Table.TryGetValue(relay, out Binding value)) { Table.Remove(relay); if ((Object)(object)value.Slider != (Object)null && (Delegate)(object)value.Callback != (Delegate)null) { ((UnityEvent<float>)(object)value.Slider.onValueChanged).RemoveListener(value.Callback); } } } } internal sealed class WidthWatcher : MonoBehaviour { private TMP_Text? _text; private float _lastWidth = -1f; public WidthWatcher(IntPtr ptr) : base(ptr) { } public void Bind(TMP_Text? text) { _text = text; } private void OnEnable() { _lastWidth = -1f; } private void OnRectTransformDimensionsChange() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) TMP_Text text = _text; if ((Object)(object)text == (Object)null) { return; } try { RectTransform rectTransform = text.rectTransform; if ((Object)(object)rectTransform == (Object)null) { return; } Rect rect = rectTransform.rect; float width = ((Rect)(ref rect)).width; if (!(Mathf.Abs(width - _lastWidth) < 0.5f)) { _lastWidth = width; if (TmpTextSafety.EnsureMeasurable(text)) { ((Graphic)text).SetAllDirty(); text.ForceMeshUpdate(false, false); } } } catch { } } private void OnDestroy() { _text = null; } } internal sealed class WindowDragHandler : MonoBehaviour { private RectTransform? _root; private float _minVisible = 8f; private bool _canDragNow = true; private bool _dragging; private bool _canDrag; private Canvas? _canvas; private EventTrigger? _trigger; private readonly List<UnityAction<BaseEventData>> _keep = new List<UnityAction<BaseEventData>>(); public WindowDragHandler(IntPtr ptr) : base(ptr) { } public void Bind(RectTransform? root, float minVisible) { _root = root; _minVisible = minVisible; _canDragNow = true; _canvas = ((Component)this).GetComponentInParent<Canvas>(); if ((Object)(object)_canvas != (Object)null) { _canvas = _canvas.rootCanvas; } if (!((Object)(object)_trigger != (Object)null)) { EventTrigger val = (_trigger = ((Component)this).gameObject.GetComponent<EventTrigger>() ?? ((Component)this).gameObject.AddComponent<EventTrigger>()); val.triggers.Clear(); EventTriggerBinder.Add(val, _keep, (EventTriggerType)2, EventRelay.ToEvent(OnPointerDown)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)13, EventRelay.ToEvent(OnBeginDrag)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)5, EventRelay.ToEvent(OnDrag)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)14, EventRelay.ToEvent(OnEndDrag)); EventTriggerBinder.Add(val, _keep, (EventTriggerType)4, EventRelay.ToEvent(OnPointerClick)); } } public void SetCanDrag(bool canDrag) { _canDragNow = canDrag; if (!canDrag) { _dragging = false; _canDrag = false; } } private static bool IsInteractive(GameObject hit) { if ((Object)(object)hit == (Object)null) { return false; } if ((Object)(object)hit.GetComponentInParent<Selectable>() != (Object)null) { return true; } if ((Object)(object)hit.GetComponentInParent<ScrollRect>() != (Object)null) { return true; } return (Object)(object)hit.GetComponentInParent<TMP_InputField>() != (Object)null; } private void OnPointerDown(BaseEventData? data) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); if (val != null && (int)val.button == 0) { WindowDragRegistry.BringToFront(this); _canDrag = !IsInteractive(val.pointerCurrentRaycast.gameObject); } } private void OnBeginDrag(BaseEventData? data) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); _dragging = _canDrag && val != null && (int)val.button == 0; } private void OnDrag(BaseEventData? data) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); if (_dragging && !((Object)(object)_root == (Object)null) && val != null && _canDragNow) { float num = (((Object)(object)_canvas != (Object)null && _canvas.scaleFactor > 0.0001f) ? _canvas.scaleFactor : 1f); Vector2 position = _root.anchoredPosition + val.delta / num; ClampToParent(_root, ref position); _root.anchoredPosition = position; } } private void OnEndDrag(BaseEventData? data) { _dragging = false; } private void OnPointerClick(BaseEventData? data) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null); if (val != null && (int)val.button == 0 && val.clickCount >= 2 && !IsInteractive(val.pointerCurrentRaycast.gameObject)) { WindowDragRegistry.DoubleClick(this); } } private void OnDisable() { _dragging = false; _canDrag = false; } private void ClampToParent(RectTransform root, ref Vector2 position) { //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) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (((Object)(object)((Transform)root).parent != (Object)null) ? ((Il2CppObjectBase)((Transform)root).parent).TryCast<RectTransform>() : null); if (!((Object)(object)val == (Object)null)) { Rect rect = val.rect; Rect rect2 = root.rect; float num = 0f; float num2 = Mathf.Max(0f, ((Rect)(ref rect)).width - ((Rect)(ref rect2)).width); float num3 = 0f - Mathf.Max(0f, ((Rect)(ref rect)).height - _minVisible); float num4 = 0f; position.x = Mathf.Clamp(position.x, num, num2); position.y = Mathf.Clamp(position.y, num3, num4); } } private void OnDestroy() { WindowDragRegistry.Clear(this); _keep.Clear(); _root = null; } } internal static class WindowDragRegistry { private sealed class Binding { public UnityAction? BringToFront; public UnityAction? DoubleClick; } private static readonly ConditionalWeakTable<WindowDragHandler, Binding> Table = new ConditionalWeakTable<WindowDragHandler, Binding>(); public static void Bind(WindowDragHandler handler, Action? bringToFront, Action? doubleClick) { if (!((Object)(object)handler == (Object)null)) { Table.Remove(handler); Table.Add(handler, new Binding { BringToFront = EventRelay.ToUnity(bringToFront), DoubleClick = EventRelay.ToUnity(doubleClick) }); } } public static void BringToFront(WindowDragHandler handler) { if ((Object)(object)handler != (Object)null && Table.TryGetValue(handler, out Binding value)) { UnityAction? bringToFront = value.BringToFront; if (bringToFront != null) { bringToFront.Invoke(); } } } public static void DoubleClick(WindowDragHandler handler) { if ((Object)(object)handler != (Object)null && Table.TryGetValue(handler, out Binding value)) { UnityAction? doubleClick = value.DoubleClick; if (doubleClick != null) { doubleClick.Invoke(); } } } public static void Clear(WindowDragHandler handler) { if ((Object)(object)handler != (Object)null) { Table.Remove(handler); } } } internal static class PointerTracker { internal sealed class Entry { public Object? Owner; public Func<Vector2, bool>? Hover; public Func<float, bool>? Wheel; public Action<Vector2>? Move; public int WheelPriority; } private static readonly List<Entry> Entries = new List<Entry>(); private static Action? _updateHandler; private static Vector2 _lastPosition; private static bool _hasLastPosition; private static bool _inputErrorLogged; private static int _dispatchDepth; public static Entry Add(Object? owner, Func<Vector2, bool>? hover, Func<float, bool>? wheel, Action<Vector2>? move, int wheelPriority = 0) { Entry entry = new Entry { Owner = owner, Hover = hover, Wheel = wheel, Move = move, WheelPriority = wheelPriority }; Entries.Add(entry); EnsureInput(); return entry; } public static void Remove(Entry? entry) { if (entry != null) { Entries.Remove(entry); DisposeIfIdle(); } } public static void Clear() { Entries.Clear(); DisposeInput(); } private static void DisposeIfIdle() { if (Entries.Count == 0) { if (_dispatchDepth > 0) { LayoutOnce.Request(DisposeIfIdle); } else { DisposeInput(); } } } private static void EndDispatch() { _dispatchDepth--; if (_dispatchDepth == 0 && Entries.Count == 0) { LayoutOnce.Request(DisposeIfIdle); } } private static void EnsureInput() { if ((Delegate)(object)_updateHandler != (Delegate)null || Entries.Count == 0) { return; } try { Action obj = DelegateSupport.ConvertDelegate<Action>((Delegate)new Action(OnInputAfterUpdate)); if ((Delegate)(object)obj == (Delegate)null) { throw new InvalidOperationException("could not create the pointer update callback"); } InputSystem.onAfterUpdate += obj; _updateHandler = obj; } catch (Exception ex) { DisposeInput(); if (!_inputErrorLogged) { _inputErrorLogged = true; UiLog.Warn("pointer input could not be initialized; image Move and wheel callbacks are disabled: " + ex.Message); } } } private static void DisposeInput() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) Action updateHandler = _updateHandler; _updateHandler = null; _hasLastPosition = false; _lastPosition = default(Vector2); if ((Delegate)(object)updateHandler == (Delegate)null) { return; } try { InputSystem.onAfterUpdate -= updateHandler; } catch (Exception ex) { UiLog.Once("pointer:input-dispose", "could not remove the pointer update callback: " + ex.Message); } } private static void OnInputAfterUpdate() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0033: Unknown result type (might be due to invalid IL or mis