using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LunarCatsStudio.Compass;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("UIScaleAndDeclutter")]
[assembly: AssemblyDescription("Resize any movable Erenshor UI panel and remove leftover edit-mode decorations")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UIScaleAndDeclutter")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5d71b4a8-2e93-4c60-bb1f-70a4e9c82d36")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace UIScaleAndDeclutter;
[BepInPlugin("com.erenshor.uiscaleanddeclutter", "UI Scale and Declutter", "1.0.0")]
public class UIScaleAndDeclutterPlugin : BaseUnityPlugin
{
public enum DumpKeyBinding
{
None,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12
}
internal class Panel
{
public DragUI Drag;
public RectTransform Root;
public string Key;
public string RawName;
public ConfigEntry<float> Scale;
public Image[] Decorations;
public readonly List<Image> HiddenByUs = new List<Image>();
public bool DeclutterSafe;
public bool IsExtra;
public bool Excluded;
public int ExclusionVersion = -1;
public float AppliedScale = float.NaN;
public int DeclutterState = -1;
}
internal class KnownPanel
{
public readonly string Raw;
public readonly string Friendly;
public readonly string Section;
public KnownPanel(string raw, string friendly, string section)
{
Raw = raw;
Friendly = friendly;
Section = section;
}
}
public const string PluginGuid = "com.erenshor.uiscaleanddeclutter";
public const string PluginName = "UI Scale and Declutter";
public const string PluginVersion = "1.0.0";
internal const string SecScale = "Scale";
internal const string SecHud = "Scale HUD";
internal const string SecWindows = "Scale Windows";
internal static ManualLogSource _log;
internal static ConfigFile _instanceConfig;
internal static ConfigEntry<float> _cfgAllScale;
internal static ConfigEntry<bool> _cfgDeclutter;
internal static ConfigEntry<string> _cfgExclude;
internal static ConfigEntry<string> _cfgExtraPanels;
internal static ConfigEntry<string> _cfgExtraHide;
internal static ConfigEntry<bool> _cfgFixKnownStrays;
internal static ConfigEntry<string> _cfgStraySprites;
internal static ConfigEntry<string> _cfgDeepDump;
internal static ConfigEntry<DumpKeyBinding> _cfgDumpKey;
internal static ConfigEntry<bool> _cfgDiagnostics;
private static int _lastFrame = -1;
private static bool _needsWork = true;
private static int _knownElementCount = -1;
private static bool _lastEditMode;
internal static readonly KnownPanel[] KnownPanels = new KnownPanel[16]
{
new KnownPanel("PlayerLifePar", "PlayerFrame", "Scale HUD"),
new KnownPanel("NewGroupPar", "PartyFrame", "Scale HUD"),
new KnownPanel("NewTargetWindow", "TargetFrame", "Scale HUD"),
new KnownPanel("EngagedTarParent", "EngagedTarget", "Scale HUD"),
new KnownPanel("CharmedPar", "PetFrame", "Scale HUD"),
new KnownPanel("HotbarPar", "ActionBar", "Scale HUD"),
new KnownPanel("StatusPar", "BuffBar", "Scale HUD"),
new KnownPanel("CastBarPar", "CastBar", "Scale HUD"),
new KnownPanel("RadioButtonPar", "MenuBar", "Scale HUD"),
new KnownPanel("DPSPAR", "DPSMeter", "Scale HUD"),
new KnownPanel("ChatBox", "ChatLog", "Scale HUD"),
new KnownPanel("CombatBox", "CombatLog", "Scale HUD"),
new KnownPanel("InvPar", "Inventory", "Scale Windows"),
new KnownPanel("QuestLogPar", "QuestLog", "Scale Windows"),
new KnownPanel("GuildPar", "GuildWindow", "Scale Windows"),
new KnownPanel("GroupBuilderPar", "GroupBuilder", "Scale Windows")
};
private static readonly Dictionary<string, KnownPanel> _known = BuildKnownLookup();
internal static readonly Dictionary<string, string[]> KnownStrays = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) {
{
"PlayerLifePar",
new string[1] { "Image (3)" }
} };
internal static readonly Dictionary<int, Panel> _panels = new Dictionary<int, Panel>();
internal static readonly List<Panel> _extraPanels = new List<Panel>();
private static readonly HashSet<string> _usedKeys = new HashSet<string>();
private static readonly Dictionary<string, string> _keyByPath = new Dictionary<string, string>(StringComparer.Ordinal);
private static readonly Dictionary<string, ConfigEntry<float>> _scaleEntries = new Dictionary<string, ConfigEntry<float>>(StringComparer.Ordinal);
private static readonly HashSet<string> _excluded = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private static string _excludeCache = "<unset>";
internal static int _exclusionVersion;
private static readonly List<string> _pendingExtras = new List<string>();
private static string _extraCache = "<unset>";
private static float _extraRetryTimer;
private static int _extraSweepsLeft = 15;
private static bool _raidBound;
private static bool _compassBound;
private static float _compassSearchTimer = 15f;
private static KeyCode ToKeyCode(DumpKeyBinding binding)
{
if (binding == DumpKeyBinding.None)
{
return (KeyCode)0;
}
return (KeyCode)(282 + (binding - 1));
}
private void Awake()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
_log = ((BaseUnityPlugin)this).Logger;
_instanceConfig = ((BaseUnityPlugin)this).Config;
_cfgAllScale = ((BaseUnityPlugin)this).Config.Bind<float>("Scale", "All", 1f, new ConfigDescription("The size of your whole interface.\nEvery panel below has its own setting, and the two multiply -- so set\nan overall size here and correct individual panels there.\n1.0 is the size the game draws them.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.4f, 2.5f), Array.Empty<object>()));
KnownPanel[] knownPanels = KnownPanels;
foreach (KnownPanel knownPanel in knownPanels)
{
ScaleEntry(knownPanel.Friendly, knownPanel.Raw, knownPanel.Section);
}
ScaleEntry("Compass", "Compass", "Scale HUD");
ScaleEntry("RaidFrame", "RaidUI", "Scale Windows");
_cfgDeclutter = ((BaseUnityPlugin)this).Config.Bind<bool>("Declutter", "Enabled", true, "Remove the leftover outlines and corner boxes drawn around panels. They are edit-mode decorations the game does not always switch off. Handles still appear normally while UI editing is on.");
_cfgFixKnownStrays = ((BaseUnityPlugin)this).Config.Bind<bool>("Declutter", "FixKnownStrays", true, "Hide decorations the game never switches off in any mode. Currently that is the outline box around the player frame, which is missing from its panel's border list, so vanilla holds no reference to it and cannot hide it.");
_cfgExclude = ((BaseUnityPlugin)this).Config.Bind<string>("Declutter", "ExcludePanels", "", "Comma-separated panel names to leave alone. Either the friendly name or the game's own name works.");
_cfgStraySprites = ((BaseUnityPlugin)this).Config.Bind<string>("Declutter", "StraySprites", "", "Comma-separated sprite names to treat as stray outlines wherever they appear. The player frame's box uses \"Facebook_Frame\". Empty by default because it is a blunt instrument.");
_cfgExtraHide = ((BaseUnityPlugin)this).Config.Bind<string>("Declutter", "ExtraHide", "", "Comma-separated child objects to hide that are not DragUI decorations, written as Panel/Child. Turn on Diagnostics and use DeepDumpPanels to find the right name.");
_cfgExtraPanels = ((BaseUnityPlugin)this).Config.Bind<string>("Extra", "Panels", "", "Comma-separated GameObject names to treat as scalable panels even though they have no DragUI. Each gets its own Scale entry. Turn on Diagnostics and press the dump key with a window open to see what it is called.");
_cfgDiagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("Troubleshooting", "Diagnostics", false, "Turns on the dump key and all discovery logging. Off by default: while it is off none of that code runs at all, not even the key check.");
_cfgDumpKey = ((BaseUnityPlugin)this).Config.Bind<DumpKeyBinding>("Troubleshooting", "DumpKey", DumpKeyBinding.F10, "Press in-game to list every panel found, every open window with no drag\nhandle, and the contents of anything named in DeepDumpPanels.\nDoes nothing unless Diagnostics is on, so this key is left alone for\nwhatever else you use it for.");
_cfgDeepDump = ((BaseUnityPlugin)this).Config.Bind<string>("Troubleshooting", "DeepDumpPanels", "", "Comma-separated panel names. On the dump key these get every image inside them listed with name, enabled state, colour, size and sprite, which is how you identify a stray border. Requires Diagnostics to be on.");
try
{
Harmony.CreateAndPatchAll(typeof(UIScaleAndDeclutterPlugin), (string)null);
_log.LogInfo((object)("Active. Scale.All=" + _cfgAllScale.Value + ", Declutter=" + _cfgDeclutter.Value + ". Settings apply on restart."));
}
catch (Exception ex)
{
_log.LogError((object)("Harmony patch failed; the mod will do nothing. " + ex));
}
}
[HarmonyPatch(typeof(DragUI), "Update")]
[HarmonyPostfix]
public static void DragUI_Update_Postfix(DragUI __instance)
{
try
{
int frameCount = Time.frameCount;
if (_lastFrame != frameCount)
{
_lastFrame = frameCount;
FrameTick(frameCount);
}
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.Parent == (Object)null))
{
Panel orRegister = GetOrRegister(__instance);
if (orRegister != null && _needsWork)
{
ApplyScale(orRegister);
ApplyDeclutter(orRegister);
}
}
}
catch (Exception ex)
{
_log.LogError((object)("UI Scale and Declutter error: " + ex));
}
}
private static void FrameTick(int frame)
{
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
_needsWork = false;
int num = ((GameData.AllUIElements != null) ? GameData.AllUIElements.Count : 0);
if (num != _knownElementCount)
{
_knownElementCount = num;
_needsWork = true;
PruneDestroyed();
}
bool editUIMode = GameData.EditUIMode;
if (editUIMode != _lastEditMode)
{
_lastEditMode = editUIMode;
_needsWork = true;
}
if (frame % 60 == 0)
{
_needsWork = true;
}
RefreshExclusions();
RefreshExtras();
BindCompass();
BindRaidPanels();
if (_needsWork)
{
ScaleExtras();
}
if (_cfgDiagnostics.Value && _cfgDumpKey.Value != DumpKeyBinding.None && Input.GetKeyDown(ToKeyCode(_cfgDumpKey.Value)))
{
Dump();
}
}
private static Dictionary<string, KnownPanel> BuildKnownLookup()
{
Dictionary<string, KnownPanel> dictionary = new Dictionary<string, KnownPanel>(StringComparer.OrdinalIgnoreCase);
KnownPanel[] knownPanels = KnownPanels;
foreach (KnownPanel knownPanel in knownPanels)
{
dictionary[knownPanel.Raw] = knownPanel;
}
return dictionary;
}
internal static Panel GetOrRegister(DragUI drag)
{
int instanceID = ((Object)drag).GetInstanceID();
if (_panels.TryGetValue(instanceID, out var value))
{
if ((Object)(object)value.Root != (Object)null)
{
return value;
}
_panels.Remove(instanceID);
}
for (int num = _extraPanels.Count - 1; num >= 0; num--)
{
if ((Object)(object)_extraPanels[num].Root == (Object)(object)drag.Parent)
{
LogInfo("\"" + _extraPanels[num].Key + "\" turns out to have a drag handle, so it is handled as a normal panel from here.");
_extraPanels.RemoveAt(num);
}
}
value = new Panel();
value.Drag = drag;
value.Root = drag.Parent;
value.RawName = ((Object)drag.Parent).name;
KnownPanel value2;
bool num2 = _known.TryGetValue(value.RawName, out value2);
string desiredName = (num2 ? value2.Friendly : value.RawName);
string section = (num2 ? value2.Section : "Scale Windows");
value.Key = KeyForPath(PathOf((Transform)(object)value.Root), desiredName);
value.Scale = ScaleEntry(value.Key, value.RawName, section);
value.DeclutterSafe = (Object)(object)((Component)drag).transform != (Object)(object)value.Root;
List<Image> list = new List<Image>();
Image[] componentsInChildren = ((Component)drag).GetComponentsInChildren<Image>(true);
foreach (Image val in componentsInChildren)
{
if ((Object)(object)val != (Object)null)
{
list.Add(val);
}
}
if (drag.Borders != null)
{
foreach (Image border in drag.Borders)
{
if ((Object)(object)border != (Object)null && !list.Contains(border))
{
list.Add(border);
}
}
}
AppendExtraHides(value, list);
value.Decorations = list.ToArray();
UIScaleToOne component = ((Component)value.Root).GetComponent<UIScaleToOne>();
if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled)
{
((Behaviour)component).enabled = false;
LogInfo("Disabled a UIScaleToOne on \"" + value.Key + "\" -- it would have reverted any scaling every frame.");
}
_panels[instanceID] = value;
_needsWork = true;
LogInfo(string.Format("Panel \"{0}\" (game name \"{1}\", {2}) -- handle \"{3}\", {4} decoration(s){5}.", value.Key, value.RawName, PathOf((Transform)(object)value.Root), ((Object)drag).name, value.Decorations.Length, value.DeclutterSafe ? "" : ", declutter skipped: the handle is the panel root"));
return value;
}
internal static void PruneDestroyed()
{
List<int> list = null;
foreach (KeyValuePair<int, Panel> panel in _panels)
{
if ((Object)(object)panel.Value.Root == (Object)null)
{
if (list == null)
{
list = new List<int>();
}
list.Add(panel.Key);
}
}
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
_panels.Remove(list[i]);
}
}
bool flag = false;
for (int num = _extraPanels.Count - 1; num >= 0; num--)
{
if ((Object)(object)_extraPanels[num].Root == (Object)null)
{
_extraPanels.RemoveAt(num);
flag = true;
}
}
if (flag)
{
_compassBound = false;
_raidBound = false;
}
}
private static string KeyForPath(string path, string desiredName)
{
if (_keyByPath.TryGetValue(path, out var value))
{
return value;
}
string text = MakeKey(desiredName);
_keyByPath[path] = text;
return text;
}
private static string MakeKey(string rawName)
{
StringBuilder stringBuilder = new StringBuilder(rawName.Length);
foreach (char c in rawName)
{
if (c != '=' && c != '\\' && c != '"' && c != '\'' && c != '[' && c != ']' && !char.IsControl(c))
{
stringBuilder.Append(c);
}
}
string text = stringBuilder.ToString().Trim();
if (text.Length == 0)
{
text = "Panel";
}
string text2 = text;
int num = 2;
while (_usedKeys.Contains(text2))
{
text2 = text + "_" + num;
num++;
}
_usedKeys.Add(text2);
return text2;
}
internal static ConfigEntry<float> ScaleEntry(string key, string rawName, string section)
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
if (_scaleEntries.TryGetValue(key, out var value))
{
return value;
}
string text = (string.Equals(key, rawName, StringComparison.OrdinalIgnoreCase) ? "" : (" (the game calls this one \"" + rawName + "\")"));
value = _instanceConfig.Bind<float>(section, key, 1f, new ConfigDescription("The size of the " + key + " panel" + text + ".\nMultiplies with Scale.All.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.4f, 2.5f), Array.Empty<object>()));
_scaleEntries[key] = value;
return value;
}
internal static bool NameMatches(Panel p, string wanted)
{
if (!string.Equals(p.Key, wanted, StringComparison.OrdinalIgnoreCase) && (p.RawName == null || !string.Equals(p.RawName, wanted, StringComparison.OrdinalIgnoreCase)))
{
if ((Object)(object)p.Root != (Object)null)
{
return string.Equals(((Object)p.Root).name, wanted, StringComparison.OrdinalIgnoreCase);
}
return false;
}
return true;
}
internal static string PathOf(Transform t)
{
StringBuilder stringBuilder = new StringBuilder(((Object)t).name);
Transform parent = t.parent;
while ((Object)(object)parent != (Object)null)
{
stringBuilder.Insert(0, ((Object)parent).name + "/");
parent = parent.parent;
}
return stringBuilder.ToString();
}
internal static void LogInfo(string message)
{
if (_cfgDiagnostics.Value)
{
_log.LogInfo((object)message);
}
}
internal static void ApplyScale(Panel p)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
float num = _cfgAllScale.Value * p.Scale.Value;
if (num != p.AppliedScale || ((Transform)p.Root).localScale.x != num)
{
((Transform)p.Root).localScale = new Vector3(num, num, 1f);
if (p.AppliedScale != num)
{
LogInfo("Panel \"" + p.Key + "\" scale set to " + num + ".");
}
p.AppliedScale = num;
}
}
internal static void ApplyDeclutter(Panel p)
{
if (p.IsExtra)
{
return;
}
if (p.ExclusionVersion != _exclusionVersion)
{
p.ExclusionVersion = _exclusionVersion;
p.Excluded = _excluded.Contains(p.Key) || (p.RawName != null && _excluded.Contains(p.RawName));
}
bool flag = _cfgDeclutter.Value && p.DeclutterSafe && !GameData.EditUIMode && !p.Excluded;
int num = (flag ? 1 : 0);
if (p.DeclutterState == num)
{
return;
}
p.DeclutterState = num;
if (!flag)
{
Restore(p);
return;
}
for (int i = 0; i < p.Decorations.Length; i++)
{
Image val = p.Decorations[i];
if (!((Object)(object)val == (Object)null) && ((Behaviour)val).enabled)
{
((Behaviour)val).enabled = false;
p.HiddenByUs.Add(val);
}
}
}
private static void Restore(Panel p)
{
for (int i = 0; i < p.HiddenByUs.Count; i++)
{
Image val = p.HiddenByUs[i];
if ((Object)(object)val != (Object)null)
{
((Behaviour)val).enabled = true;
}
}
p.HiddenByUs.Clear();
}
private static void AppendExtraHides(Panel p, List<Image> decorations)
{
string[] array;
if (_cfgFixKnownStrays.Value && p.RawName != null && KnownStrays.TryGetValue(p.RawName, out var value))
{
array = value;
foreach (string text in array)
{
if (AddByName(p, decorations, text) > 0)
{
LogInfo("Hiding known stray decoration \"" + text + "\" on " + p.Key + " -- vanilla never switches this one off.");
}
}
}
string value2 = _cfgStraySprites.Value;
if (!string.IsNullOrEmpty(value2))
{
array = value2.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
string text2 = array[i].Trim();
if (text2.Length == 0)
{
continue;
}
Image[] componentsInChildren = ((Component)p.Root).GetComponentsInChildren<Image>(true);
foreach (Image val in componentsInChildren)
{
if ((Object)(object)val != (Object)null && (Object)(object)val.sprite != (Object)null && string.Equals(((Object)val.sprite).name, text2, StringComparison.OrdinalIgnoreCase) && !decorations.Contains(val))
{
decorations.Add(val);
LogInfo("Hiding \"" + ((Object)val).name + "\" on " + p.Key + " (sprite " + text2 + ").");
}
}
}
}
string value3 = _cfgExtraHide.Value;
if (string.IsNullOrEmpty(value3))
{
return;
}
array = value3.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
string text3 = array[i].Trim();
int num = text3.IndexOf('/');
if (num > 0 && num < text3.Length - 1)
{
string wanted = text3.Substring(0, num).Trim();
string childName = text3.Substring(num + 1).Trim();
if (NameMatches(p, wanted))
{
LogInfo("ExtraHide \"" + text3 + "\" matched " + AddByName(p, decorations, childName) + " image(s).");
}
}
}
}
private static int AddByName(Panel p, List<Image> decorations, string childName)
{
int num = 0;
Image[] componentsInChildren = ((Component)p.Root).GetComponentsInChildren<Image>(true);
foreach (Image val in componentsInChildren)
{
if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, childName, StringComparison.OrdinalIgnoreCase) && !decorations.Contains(val))
{
decorations.Add(val);
num++;
}
}
return num;
}
internal static void RefreshExclusions()
{
string text = _cfgExclude.Value ?? "";
if (text == _excludeCache)
{
return;
}
_excludeCache = text;
_excluded.Clear();
string[] array = text.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
string text2 = array[i].Trim();
if (text2.Length > 0)
{
_excluded.Add(text2);
}
}
_exclusionVersion++;
_needsWork = true;
}
internal static void RefreshExtras()
{
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
string text = _cfgExtraPanels.Value ?? "";
if (text != _extraCache)
{
_extraCache = text;
_pendingExtras.Clear();
string[] array = text.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
string text2 = array[i].Trim();
if (text2.Length > 0 && !HasExtra(text2))
{
_pendingExtras.Add(text2);
}
}
_extraRetryTimer = 0f;
_extraSweepsLeft = 15;
}
if (_pendingExtras.Count == 0 || _extraSweepsLeft <= 0)
{
return;
}
_extraRetryTimer -= Time.unscaledDeltaTime;
if (_extraRetryTimer > 0f)
{
return;
}
_extraRetryTimer = 2f;
_extraSweepsLeft--;
if (_extraSweepsLeft == 0)
{
_log.LogWarning((object)("Gave up looking for these Extra.Panels entries after 30s: " + string.Join(", ", _pendingExtras.ToArray()) + ". Check the spelling, or open the window they belong to and correct the name from the dump."));
}
RectTransform[] array2 = Resources.FindObjectsOfTypeAll<RectTransform>();
foreach (RectTransform val in array2)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
Scene scene = ((Component)val).gameObject.scene;
if (!((Scene)(ref scene)).IsValid())
{
continue;
}
for (int num = _pendingExtras.Count - 1; num >= 0; num--)
{
if (string.Equals(((Object)val).name, _pendingExtras[num], StringComparison.OrdinalIgnoreCase))
{
RegisterExtra(val, _pendingExtras[num], "Scale Windows");
_pendingExtras.RemoveAt(num);
break;
}
}
if (_pendingExtras.Count == 0)
{
break;
}
}
}
private static bool HasExtra(string name)
{
for (int i = 0; i < _extraPanels.Count; i++)
{
if (string.Equals(_extraPanels[i].Key, name, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private static void RegisterExtra(RectTransform rt, string requestedName, string section)
{
for (int i = 0; i < _extraPanels.Count; i++)
{
if ((Object)(object)_extraPanels[i].Root == (Object)(object)rt)
{
return;
}
}
foreach (KeyValuePair<int, Panel> panel2 in _panels)
{
if ((Object)(object)panel2.Value.Root == (Object)(object)rt)
{
LogInfo("Extra panel \"" + requestedName + "\" is already handled as the \"" + panel2.Value.Key + "\" panel; leaving it to that.");
return;
}
}
foreach (KeyValuePair<int, Panel> panel3 in _panels)
{
Panel value = panel3.Value;
if ((Object)(object)value.Root != (Object)null && (Object)(object)value.Root != (Object)(object)rt && ((Transform)value.Root).IsChildOf((Transform)(object)rt))
{
_log.LogWarning((object)("Refusing to register extra panel \"" + requestedName + "\" at " + PathOf((Transform)(object)rt) + ": it contains the \"" + value.Key + "\" panel, so scaling it would compound with that panel's own scale. Use Scale.All if you want everything smaller."));
return;
}
}
Panel panel = new Panel();
panel.Root = rt;
panel.Key = KeyForPath(PathOf((Transform)(object)rt), requestedName);
panel.RawName = ((Object)rt).name;
panel.IsExtra = true;
panel.DeclutterSafe = false;
panel.Decorations = (Image[])(object)new Image[0];
panel.Scale = ScaleEntry(panel.Key, ((Object)rt).name, section);
UIScaleToOne component = ((Component)rt).GetComponent<UIScaleToOne>();
if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled)
{
((Behaviour)component).enabled = false;
LogInfo("Disabled a UIScaleToOne on extra panel \"" + panel.Key + "\".");
}
_extraPanels.Add(panel);
_needsWork = true;
string text = null;
foreach (KeyValuePair<int, Panel> panel4 in _panels)
{
if ((Object)(object)panel4.Value.Root != (Object)null && (Object)(object)rt != (Object)(object)panel4.Value.Root && ((Transform)rt).IsChildOf((Transform)(object)panel4.Value.Root))
{
text = panel4.Value.Key;
break;
}
}
LogInfo("Extra panel \"" + panel.Key + "\" found at " + PathOf((Transform)(object)rt) + ((text != null) ? (". It sits inside panel \"" + text + "\", so the two scales multiply.") : "."));
}
internal static void ScaleExtras()
{
for (int i = 0; i < _extraPanels.Count; i++)
{
Panel panel = _extraPanels[i];
if ((Object)(object)panel.Root != (Object)null)
{
ApplyScale(panel);
}
}
}
internal static void BindRaidPanels()
{
if (_raidBound)
{
return;
}
RaidManager raidManager = GameData.RaidManager;
if ((Object)(object)raidManager == (Object)null)
{
return;
}
_raidBound = true;
if ((Object)(object)raidManager.RaidUI == (Object)null)
{
LogInfo("RaidManager has no RaidUI; nothing to bind for raids.");
return;
}
RectTransform component = raidManager.RaidUI.GetComponent<RectTransform>();
if ((Object)(object)component != (Object)null)
{
RegisterExtra(component, "RaidFrame", "Scale Windows");
}
}
internal static void BindCompass()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if (_compassBound)
{
return;
}
CompassBarPro val = null;
CompassBarPro[] array = Resources.FindObjectsOfTypeAll<CompassBarPro>();
foreach (CompassBarPro val2 in array)
{
if ((Object)(object)val2 != (Object)null)
{
Scene scene = ((Component)val2).gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
val = val2;
break;
}
}
}
if ((Object)(object)val == (Object)null)
{
_compassSearchTimer -= Time.unscaledDeltaTime;
if (_compassSearchTimer <= 0f)
{
_compassBound = true;
_log.LogWarning((object)"No CompassBarPro found after 15s, so the compass cannot be scaled. Its Scale entry will have no effect.");
}
}
else
{
_compassBound = true;
RectTransform component = ((Component)val).GetComponent<RectTransform>();
if ((Object)(object)component == (Object)null)
{
_log.LogWarning((object)"Found the compass but it has no RectTransform; not scaling it.");
}
else
{
RegisterExtra(component, "Compass", "Scale HUD");
}
}
}
internal static void Dump()
{
DumpPanels();
DumpUnregistered();
DeepDump();
}
private static void DumpPanels()
{
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_021e: Unknown result type (might be due to invalid IL or missing references)
StringBuilder stringBuilder = new StringBuilder("=== Movable UI panels (").Append(_panels.Count).Append(" seen so far) ===");
foreach (KeyValuePair<int, Panel> panel in _panels)
{
Panel value = panel.Value;
if (!((Object)(object)value.Root == (Object)null))
{
stringBuilder.Append("\n ").Append(value.Key).Append(" (game name: ")
.Append(value.RawName)
.Append(")")
.Append("\n path=")
.Append(PathOf((Transform)(object)value.Root))
.Append("\n scale=")
.Append(((Transform)value.Root).localScale.x)
.Append(" (All ")
.Append(_cfgAllScale.Value)
.Append(" x panel ")
.Append(value.Scale.Value)
.Append(")")
.Append("\n handle=")
.Append(((Object)(object)value.Drag != (Object)null) ? ((Object)value.Drag).name : "<gone>")
.Append(" decorations=")
.Append(value.Decorations.Length)
.Append(" currentlyHidden=")
.Append(value.HiddenByUs.Count);
if (!value.DeclutterSafe)
{
stringBuilder.Append("\n declutter skipped: handle is the panel root");
}
if (value.Excluded)
{
stringBuilder.Append("\n excluded by config");
}
}
}
foreach (Panel extraPanel in _extraPanels)
{
if (!((Object)(object)extraPanel.Root == (Object)null))
{
stringBuilder.Append("\n ").Append(extraPanel.Key).Append(" [extra, scale only]")
.Append("\n path=")
.Append(PathOf((Transform)(object)extraPanel.Root))
.Append("\n scale=")
.Append(((Transform)extraPanel.Root).localScale.x)
.Append(" (All ")
.Append(_cfgAllScale.Value)
.Append(" x panel ")
.Append(extraPanel.Scale.Value)
.Append(")");
}
}
_log.LogInfo((object)stringBuilder.ToString());
}
private static void DumpUnregistered()
{
HashSet<Transform> hashSet = new HashSet<Transform>();
HashSet<Transform> hashSet2 = new HashSet<Transform>();
foreach (KeyValuePair<int, Panel> panel in _panels)
{
Panel value = panel.Value;
if (!((Object)(object)value.Root == (Object)null))
{
hashSet2.Add((Transform)(object)value.Root);
if ((Object)(object)((Transform)value.Root).parent != (Object)null)
{
hashSet.Add(((Transform)value.Root).parent);
}
}
}
foreach (Panel extraPanel in _extraPanels)
{
if ((Object)(object)extraPanel.Root != (Object)null)
{
hashSet2.Add((Transform)(object)extraPanel.Root);
}
}
StringBuilder stringBuilder = new StringBuilder("=== Open windows with no DragUI (add a name to Extra.Panels to scale it) ===");
int num = 0;
foreach (Transform item in hashSet)
{
if ((Object)(object)item == (Object)null)
{
continue;
}
for (int i = 0; i < item.childCount; i++)
{
if (num >= 40)
{
break;
}
Transform child = item.GetChild(i);
if (!hashSet2.Contains(child) && ((Component)child).gameObject.activeInHierarchy && !((Object)(object)((Component)child).GetComponent<RectTransform>() == (Object)null))
{
stringBuilder.Append("\n ").Append(((Object)child).name).Append(" (")
.Append(PathOf(child))
.Append(")");
num++;
}
}
if (num >= 40)
{
stringBuilder.Append("\n ... stopping at 40");
break;
}
}
if (num == 0)
{
stringBuilder.Append("\n none open right now -- open the window you want, then dump again.");
}
_log.LogInfo((object)stringBuilder.ToString());
}
private static void DeepDump()
{
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
string value = _cfgDeepDump.Value;
if (string.IsNullOrEmpty(value))
{
return;
}
string[] array = value.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (text.Length == 0)
{
continue;
}
RectTransform val = null;
foreach (KeyValuePair<int, Panel> panel in _panels)
{
Panel value2 = panel.Value;
if ((Object)(object)value2.Root != (Object)null && NameMatches(value2, text))
{
val = value2.Root;
break;
}
}
if ((Object)(object)val == (Object)null)
{
_log.LogInfo((object)("DeepDump: no panel named \"" + text + "\"."));
continue;
}
StringBuilder stringBuilder = new StringBuilder("=== Deep dump of \"").Append(text).Append("\" -- every image inside it ===");
Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(true);
foreach (Image val2 in componentsInChildren)
{
Vector2 val3 = (((Object)(object)((Graphic)val2).rectTransform != (Object)null) ? ((Graphic)val2).rectTransform.sizeDelta : Vector2.zero);
stringBuilder.Append("\n ").Append(PathOf(((Component)val2).transform)).Append("\n name=\"")
.Append(((Object)val2).name)
.Append("\"")
.Append(" enabled=")
.Append(((Behaviour)val2).enabled)
.Append(" color=")
.Append(((Graphic)val2).color)
.Append(" size=")
.Append(val3)
.Append(" sprite=")
.Append(((Object)(object)val2.sprite != (Object)null) ? ((Object)val2.sprite).name : "<none>");
}
_log.LogInfo((object)stringBuilder.ToString());
}
}
}