using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SoDDiskLabels")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.5.0")]
[assembly: AssemblyInformationalVersion("0.2.5")]
[assembly: AssemblyProduct("SoDDiskLabels")]
[assembly: AssemblyTitle("SoDDiskLabels")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.5.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SoDDiskLabels
{
public enum DiskOrder
{
Newest,
Oldest,
Name,
MostUpgraded,
LeastUpgraded
}
internal static class DiskSorter
{
internal static ConfigEntry<DiskOrder> Order = null;
internal static ConfigEntry<bool> Enabled = null;
private static GameObject? button;
private static float lastClick = -10f;
private static bool loggedParts;
private static bool toldWaiting;
private static bool toldApply;
private static TextMeshProUGUI? label;
private const float FrameHeight = 26f;
internal static bool HasButton => (Object)(object)button != (Object)null;
internal static void Bind(ConfigFile cfg)
{
Enabled = cfg.Bind<bool>("Sort", "Enabled", true, "Show a sort button on the sync disk screen.");
Order = cfg.Bind<DiskOrder>("Sort", "Order", DiskOrder.Newest, "How installed sync disks are listed: Newest (just installed at the top), Oldest (the game's own order), Name, MostUpgraded or LeastUpgraded. The sort button changes it and it is remembered.");
}
private static string Pretty(DiskOrder o)
{
return o switch
{
DiskOrder.Newest => "newest",
DiskOrder.Oldest => "oldest",
DiskOrder.Name => "name",
DiskOrder.MostUpgraded => "most upgraded",
_ => "least upgraded",
};
}
internal static List<SyncDiskElementController> Rows(UpgradesController uc)
{
List<SyncDiskElementController> list = new List<SyncDiskElementController>();
if (((uc != null) ? uc.spawnedDisks : null) != null)
{
Enumerator<SyncDiskElementController> enumerator = uc.spawnedDisks.GetEnumerator();
while (enumerator.MoveNext())
{
SyncDiskElementController current = enumerator.Current;
if ((Object)(object)current != (Object)null && (Object)(object)current.rect != (Object)null && ((Component)current).gameObject.activeInHierarchy)
{
list.Add(current);
}
}
}
if (list.Count == 0)
{
foreach (SyncDiskElementController item in Object.FindObjectsOfType<SyncDiskElementController>())
{
if ((Object)(object)item != (Object)null && (Object)(object)item.rect != (Object)null && ((Component)item).gameObject.activeInHierarchy)
{
list.Add(item);
}
}
}
return list;
}
internal static void Apply(UpgradesController uc)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
if (!Enabled.Value)
{
return;
}
try
{
if (!toldApply)
{
toldApply = true;
ManualLogSource l = Plugin.L;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SORT] sorting ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Rows(uc).Count);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" disks (");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(uc.spawnedDisks?.Count ?? (-1));
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" in list) by ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<DiskOrder>(Order.Value);
}
l.LogInfo(val);
}
EnsureButton(uc);
List<SyncDiskElementController> list = Rows(uc);
if (list.Count >= 2)
{
List<Vector2> list2 = (from e in list
select e.rect.anchoredPosition into p
orderby p.y descending
select p).ToList();
List<SyncDiskElementController> list3 = list.OrderByDescending((SyncDiskElementController e) => e.rect.anchoredPosition.y).ToList();
Dictionary<IntPtr, int> index = new Dictionary<IntPtr, int>();
for (int num = 0; num < list.Count; num++)
{
index[((Il2CppObjectBase)list[num]).Pointer] = num;
}
bool installedFirst = Installed(list3[0]);
IOrderedEnumerable<SyncDiskElementController> source = list3.OrderBy((SyncDiskElementController e) => (Installed(e) != installedFirst) ? 1 : 0);
List<SyncDiskElementController> list4 = (Order.Value switch
{
DiskOrder.Newest => source.ThenByDescending((SyncDiskElementController e) => index[((Il2CppObjectBase)e).Pointer]),
DiskOrder.Name => source.ThenBy<SyncDiskElementController, string>(Name, StringComparer.OrdinalIgnoreCase),
DiskOrder.MostUpgraded => source.ThenByDescending(delegate(SyncDiskElementController e)
{
Upgrades upgrade = e.upgrade;
return (upgrade != null) ? upgrade.level : 0;
}).ThenBy<SyncDiskElementController, string>(Name, StringComparer.OrdinalIgnoreCase),
DiskOrder.LeastUpgraded => source.ThenBy(delegate(SyncDiskElementController e)
{
Upgrades upgrade = e.upgrade;
return (upgrade != null) ? upgrade.level : 0;
}).ThenBy<SyncDiskElementController, string>(Name, StringComparer.OrdinalIgnoreCase),
_ => source.ThenBy((SyncDiskElementController e) => index[((Il2CppObjectBase)e).Pointer]),
}).ToList();
for (int num2 = 0; num2 < list4.Count; num2++)
{
list4[num2].rect.anchoredPosition = list2[num2];
((Component)list4[num2]).transform.SetSiblingIndex(num2);
}
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SORT] " + ex.Message));
}
static bool Installed(SyncDiskElementController e)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
if (e.upgrade != null)
{
return (int)e.upgrade.state > 0;
}
return false;
}
static string Name(SyncDiskElementController e)
{
object obj;
if (!((Object)(object)e.titleText != (Object)null))
{
SyncDiskPreset preset = e.preset;
obj = ((preset != null) ? ((Object)preset).name : null);
if (obj == null)
{
return "";
}
}
else
{
obj = Regex.Replace(((TMP_Text)e.titleText).text ?? "", "<[^>]*>", "");
}
return (string)obj;
}
}
private static void EnsureButton(UpgradesController uc)
{
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Expected O, but got Unknown
//IL_0284: Unknown result type (might be due to invalid IL or missing references)
//IL_028e: Unknown result type (might be due to invalid IL or missing references)
//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02be: Unknown result type (might be due to invalid IL or missing references)
//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
//IL_0349: Unknown result type (might be due to invalid IL or missing references)
//IL_034e: Unknown result type (might be due to invalid IL or missing references)
//IL_0368: Unknown result type (might be due to invalid IL or missing references)
//IL_0326: Unknown result type (might be due to invalid IL or missing references)
//IL_0398: Unknown result type (might be due to invalid IL or missing references)
//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0385: Unknown result type (might be due to invalid IL or missing references)
//IL_042e: Unknown result type (might be due to invalid IL or missing references)
//IL_0435: Expected O, but got Unknown
//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
//IL_03f4: Expected O, but got Unknown
//IL_0467: Unknown result type (might be due to invalid IL or missing references)
//IL_0481: Unknown result type (might be due to invalid IL or missing references)
//IL_0486: Unknown result type (might be due to invalid IL or missing references)
string text = "Sort: " + Pretty(Order.Value);
if ((Object)(object)button != (Object)null)
{
if ((Object)(object)label != (Object)null && ((TMP_Text)label).text != text)
{
((TMP_Text)label).text = text;
}
return;
}
ButtonController val = null;
foreach (SyncDiskElementController item in Rows(uc))
{
if ((Object)(object)((item != null) ? item.uninstallButton : null) != (Object)null)
{
val = item.uninstallButton;
break;
}
}
if ((Object)(object)val == (Object)null)
{
foreach (ButtonController componentsInChild in ((Component)uc).GetComponentsInChildren<ButtonController>(true))
{
if ((Object)(object)((componentsInChild != null) ? componentsInChild.text : null) != (Object)null && ((TMP_Text)componentsInChild.text).text.Trim().Equals("Uninstall", StringComparison.OrdinalIgnoreCase))
{
val = componentsInChild;
break;
}
}
}
TextMeshProUGUI installedDisksText = uc.installedDisksText;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val2;
if ((Object)(object)val == (Object)null || (Object)(object)installedDisksText == (Object)null)
{
if (!toldWaiting)
{
toldWaiting = true;
ManualLogSource l = Plugin.L;
val2 = new BepInExInfoLogInterpolatedStringHandler(46, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SORT] no button to copy yet (disks ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(Rows(uc).Count);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", header ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>((Object)(object)installedDisksText != (Object)null);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")");
}
l.LogInfo(val2);
}
return;
}
button = Object.Instantiate<GameObject>(((Component)val).gameObject, ((TMP_Text)installedDisksText).transform.parent);
((Object)button).name = "DiskSortButton";
button.SetActive(true);
(button.GetComponent<LayoutElement>() ?? button.AddComponent<LayoutElement>()).ignoreLayout = true;
ButtonController component = button.GetComponent<ButtonController>();
label = (((Object)(object)component != (Object)null && (Object)(object)component.text != (Object)null) ? component.text : button.GetComponentInChildren<TextMeshProUGUI>(true));
Button val3 = (((Object)(object)component != (Object)null && (Object)(object)component.button != (Object)null) ? component.button : button.GetComponentInChildren<Button>(true));
if ((Object)(object)component != (Object)null)
{
((Behaviour)component).enabled = false;
}
RectTransform component2 = button.GetComponent<RectTransform>();
RectTransform rectTransform = ((TMP_Text)installedDisksText).rectTransform;
component2.anchorMin = new Vector2(0.5f, rectTransform.anchorMin.y);
component2.anchorMax = new Vector2(0.5f, rectTransform.anchorMax.y);
component2.pivot = new Vector2(0.5f, rectTransform.pivot.y);
((Transform)component2).localScale = Vector3.one;
float num = 240f;
if ((Object)(object)label != (Object)null)
{
((TMP_Text)label).enableAutoSizing = false;
((TMP_Text)label).fontSize = ((TMP_Text)installedDisksText).fontSize;
((TMP_Text)label).alignment = (TextAlignmentOptions)514;
num = ((TMP_Text)label).GetPreferredValues("Sort: least upgraded").x + 30f;
((TMP_Text)label).text = text;
}
float num2 = num;
Rect rect = rectTransform.rect;
component2.sizeDelta = new Vector2(num2, Mathf.Min(((Rect)(ref rect)).height, ((TMP_Text)installedDisksText).fontSize * 1.15f));
if ((Object)(object)label != (Object)null)
{
((Graphic)label).color = ((Graphic)installedDisksText).color;
}
component2.anchoredPosition = new Vector2(0f, rectTransform.anchoredPosition.y);
component2.sizeDelta = new Vector2(component2.sizeDelta.x, component2.sizeDelta.y * 0.42f);
if ((Object)(object)val3 != (Object)null)
{
((Selectable)val3).interactable = true;
val3.onClick = new ButtonClickedEvent();
((UnityEvent)val3.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
{
if (!(Time.unscaledTime - lastClick < 0.35f))
{
lastClick = Time.unscaledTime;
Order.Value = (DiskOrder)((int)(Order.Value + 1) % 5);
Plugin.L.LogInfo((object)("[SORT] order " + Order.Value));
Apply(UpgradesController.Instance);
}
}));
}
ManualLogSource l2 = Plugin.L;
val2 = new BepInExInfoLogInterpolatedStringHandler(57, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SORT] sort button made from ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)((Component)val).gameObject).name);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", size ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Vector2>(component2.sizeDelta);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", header text height ");
BepInExInfoLogInterpolatedStringHandler obj = val2;
rect = rectTransform.rect;
((BepInExLogInterpolatedStringHandler)obj).AppendFormatted<float>(((Rect)(ref rect)).height);
}
l2.LogInfo(val2);
}
private static void FitFrame(RectTransform rt)
{
//IL_00bd: 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)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Expected O, but got Unknown
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
try
{
float num = float.MaxValue;
float num2 = float.MinValue;
Vector3[] array = (Vector3[])(object)new Vector3[4];
foreach (Image componentsInChild in ((Component)rt).GetComponentsInChildren<Image>(true))
{
if (!((Object)(object)componentsInChild == (Object)null) && ((Behaviour)componentsInChild).enabled)
{
((Graphic)componentsInChild).rectTransform.GetWorldCorners(Il2CppStructArray<Vector3>.op_Implicit(array));
Vector3[] array2 = array;
foreach (Vector3 val in array2)
{
float y = ((Transform)rt).InverseTransformPoint(val).y;
num = Mathf.Min(num, y);
num2 = Mathf.Max(num2, y);
}
}
}
if (num != float.MaxValue)
{
float num3 = num2 - num;
Rect rect = rt.rect;
float num4 = num3 - ((Rect)(ref rect)).height;
float num5 = Mathf.Max(4f, 26f - num4);
ManualLogSource l = Plugin.L;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(50, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SORT] frame drawn ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(num3, "0.0");
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" high on a box of ");
rect = rt.rect;
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(((Rect)(ref rect)).height, "0.0");
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", box set to ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(num5, "0.0");
}
l.LogInfo(val2);
rt.sizeDelta = new Vector2(rt.sizeDelta.x, num5);
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SORT] fit: " + ex.Message));
}
}
}
[HarmonyPatch(typeof(UpgradesController), "UpdateUpgrades")]
internal static class SortAfterUpdate
{
private static void Postfix(UpgradesController __instance)
{
DiskSorter.Apply(__instance);
}
}
public class SortWatch : MonoBehaviour
{
private float next;
private int lastCount = -1;
private static bool told;
public SortWatch(IntPtr ptr)
: base(ptr)
{
}
private void Update()
{
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Expected O, but got Unknown
if (Time.unscaledTime < next)
{
return;
}
next = Time.unscaledTime + 0.5f;
try
{
UpgradesController instance = UpgradesController.Instance;
if ((Object)(object)instance == (Object)null)
{
lastCount = -1;
return;
}
if (instance.isOpen)
{
InstalledMark.Rows(instance);
}
int count = DiskSorter.Rows(instance).Count;
if (count <= 0)
{
lastCount = -1;
}
else
{
if (count == lastCount && DiskSorter.HasButton)
{
return;
}
if (!told)
{
told = true;
ManualLogSource l = Plugin.L;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(45, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SORT] screen found with ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(count);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" rows (");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(instance.spawnedDisks?.Count ?? (-1));
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" in the list)");
}
l.LogInfo(val);
}
lastCount = count;
DiskSorter.Apply(instance);
}
}
catch
{
}
}
}
[HarmonyPatch(typeof(UpgradesController), "OpenUpgrades")]
internal static class SortOnOpen
{
private static void Postfix(UpgradesController __instance)
{
DiskSorter.Apply(__instance);
}
}
internal static class InstalledMark
{
private const string Tag = "(already installed)";
private static int logged;
internal static void Rows(UpgradesController uc)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.MarkInstalled.Value)
{
return;
}
foreach (SyncDiskElementController item in DiskSorter.Rows(uc))
{
try
{
if ((Object)(object)item == (Object)null || (Object)(object)item.titleText == (Object)null || (SoCustomComparison)(object)item.preset == (SoCustomComparison)null || item.upgrade == null || (int)item.upgrade.state != 0)
{
continue;
}
string text = ((TMP_Text)item.titleText).text ?? "";
if (!text.Contains("(already installed)") && ShopLabel.Installed(item.preset))
{
((TMP_Text)item.titleText).text = "<color=#8C8C8C>" + text + "</color> <color=#E0B040>(already installed)</color>";
if (logged < 6)
{
logged++;
Plugin.L.LogInfo((object)("[LIST] marked already installed: " + ((Object)item.preset).name));
}
}
}
catch
{
}
}
}
}
internal class TrackedWindow
{
internal InfoWindow Window;
internal SyncDiskPreset Disk;
internal string Body;
}
internal static class InspectText
{
internal const string Generic = "SyncDisk";
internal const string GenericBody = "Sync disks contain DNA";
internal const string Currency = "¢r";
internal static readonly Dictionary<long, TrackedWindow> Tracked = new Dictionary<long, TrackedWindow>();
private static readonly Dictionary<string, string> names = new Dictionary<string, string>();
private static readonly HashSet<string> logged = new HashSet<string>();
private static TrackedWindow lastTracked;
private static float lastTime;
private static int scopeDepth;
private static long scopeKey;
private static int scopeFrame = -1;
internal const bool DiagEnabled = false;
internal static float DiagUntil = -1f;
internal static int DiagLines;
private static readonly Regex KeyPrefix = new Regex("^\\d+_\\d+_(?:(?:True|False)_)?", RegexOptions.Compiled);
internal static bool Diag
{
get
{
if (Time.realtimeSinceStartup < DiagUntil)
{
return DiagLines < 40;
}
return false;
}
}
internal static void DiagLog(string msg)
{
DiagLines++;
Plugin.L.LogInfo((object)("[SDL] DIAG " + msg));
}
internal static string Short(string s)
{
if (s != null)
{
return ((s.Length > 70) ? s.Substring(0, 70) : s).Replace("\n", " ");
}
return "null";
}
internal static string BodyState()
{
if (scopeDepth <= 0)
{
if (lastTracked == null)
{
return "no window";
}
return "fallback age " + (Time.realtimeSinceStartup - lastTime).ToString("0.00", CultureInfo.InvariantCulture) + "s";
}
return "scope depth " + scopeDepth + (Tracked.ContainsKey(scopeKey) ? " tracked" : " not tracked");
}
internal static object Prop(object o, string n)
{
if (o == null)
{
return null;
}
try
{
PropertyInfo property = o.GetType().GetProperty(n, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
return (property == null) ? null : property.GetValue(o, null);
}
catch (Exception)
{
return null;
}
}
internal static void SetProp(object o, string n, object v)
{
if (o == null)
{
return;
}
try
{
PropertyInfo property = o.GetType().GetProperty(n, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.CanWrite)
{
property.SetValue(o, v, null);
}
else
{
Plugin.L.LogInfo((object)("[SDL] no writable property " + n + " on " + o.GetType().Name));
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SDL] set " + n + " failed: " + ex.GetType().Name));
}
}
internal static string DiskName(SyncDiskPreset d)
{
string name = ((Object)d).name;
if (names.TryGetValue(name, out var value))
{
return value;
}
value = null;
try
{
string text = Strings.Get("evidence.syncdisks", name, (Casing)0, false, true, false, (Human)null);
if (!string.IsNullOrEmpty(text) && text != name)
{
value = text;
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SDL] name lookup failed: " + ex.GetType().Name));
}
if (value != null)
{
names[name] = value;
}
return value;
}
private static string Num(float v)
{
return v.ToString("0.##", CultureInfo.InvariantCulture);
}
internal static string Fill(SyncDiskPreset d, string desc, float value)
{
if (string.IsNullOrEmpty(desc))
{
return "";
}
desc = Resolve(desc);
string text = desc.Replace("|value%|", Num(Math.Abs(value) * 100f)).Replace("|value|", Num(Math.Abs(value)));
string text2 = text;
string text3 = null;
try
{
text3 = Strings.ComposeText(text, (Object)(object)d, (LinkSetting)0, (List<DataKey>)null, (Object)null, false);
if (!string.IsNullOrEmpty(text3))
{
text2 = text3;
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SDL] ComposeText failed: " + ex.GetType().Name));
}
bool flag = text2.IndexOf("|city.currency|", StringComparison.Ordinal) >= 0;
if (flag)
{
text2 = text2.Replace("|city.currency|", "¢r");
}
if (logged.Add(desc))
{
Plugin.L.LogInfo((object)("[SDL] TOKENS raw=" + desc.Replace("\n", "\\n")));
Plugin.L.LogInfo((object)("[SDL] TOKENS final=" + text2.Replace("\n", "\\n") + " value=" + value + " currencyFallback=" + flag));
}
return text2;
}
private static string Resolve(string desc)
{
if (!KeyPrefix.IsMatch(desc))
{
return desc;
}
try
{
string text = Strings.Get("evidence.syncdisks", desc, (Casing)0, false, true, false, (Human)null);
if (!string.IsNullOrEmpty(text) && text != desc && !KeyPrefix.IsMatch(text))
{
return text;
}
}
catch
{
}
return KeyPrefix.Replace(desc, "");
}
private static string CleanName(string name)
{
if (string.IsNullOrEmpty(name))
{
return name;
}
return KeyPrefix.Replace(name, "");
}
private static void AddEffect(StringBuilder sb, SyncDiskPreset d, string title, string name, string desc, float value)
{
if (!string.IsNullOrEmpty(name) || !string.IsNullOrEmpty(desc))
{
if (sb.Length > 0)
{
sb.Append("\n\n");
}
string text = CleanName(name);
bool flag = !string.IsNullOrEmpty(title) && string.Equals(title, text, StringComparison.OrdinalIgnoreCase);
if (!string.IsNullOrEmpty(text) && !flag)
{
sb.Append(text).Append("\n");
}
sb.Append(Fill(d, desc, value));
}
}
internal static string BuildBody(SyncDiskPreset d)
{
StringBuilder stringBuilder = new StringBuilder();
string title = DiskName(d);
if (Plugin.BadgeInstalled.Value && ShopLabel.Installed(d))
{
stringBuilder.Append("You already have this disk installed.\n\n");
}
AddEffect(stringBuilder, d, title, d.mainEffect1Name, d.mainEffect1Description, d.mainEffect1Value);
AddEffect(stringBuilder, d, title, d.mainEffect2Name, d.mainEffect2Description, d.mainEffect2Value);
AddEffect(stringBuilder, d, title, d.mainEffect3Name, d.mainEffect3Description, d.mainEffect3Value);
string text = Fill(d, d.sideEffectDescription, d.sideEffectValue);
if (text.Length > 0)
{
if (stringBuilder.Length > 0)
{
stringBuilder.Append("\n\n");
}
stringBuilder.Append("Side effect\n").Append(text);
}
return stringBuilder.ToString();
}
internal static void ApplyTitle(InfoWindow w, SyncDiskPreset d)
{
string text = DiskName(d);
if (text != null)
{
object obj = Prop(w, "titleText");
if (obj != null && Prop(obj, "text") as string == "SyncDisk")
{
SetProp(obj, "text", text);
Plugin.L.LogInfo((object)("[SDL] title SyncDisk -> " + text));
}
}
}
internal static void MarkLast(TrackedWindow tw)
{
lastTracked = tw;
lastTime = Time.realtimeSinceStartup;
if (Tracked.Count > 40)
{
Prune();
}
}
private static void Prune()
{
List<long> list = new List<long>();
foreach (KeyValuePair<long, TrackedWindow> item in Tracked)
{
bool flag = false;
try
{
flag = (Object)(object)item.Value.Window != (Object)null && (Object)(object)((Component)item.Value.Window).gameObject != (Object)null;
}
catch (Exception)
{
flag = false;
}
if (!flag)
{
list.Add(item.Key);
}
}
for (int i = 0; i < list.Count; i++)
{
Tracked.Remove(list[i]);
}
}
internal static void EnterScope(WindowContentController wcc)
{
try
{
int frameCount = Time.frameCount;
if (frameCount != scopeFrame)
{
scopeDepth = 0;
scopeKey = 0L;
scopeFrame = frameCount;
}
InfoWindow window = wcc.window;
long num = (((Object)(object)window == (Object)null) ? 0 : ((Il2CppObjectBase)window).Pointer.ToInt64());
if (scopeDepth == 0)
{
scopeKey = num;
}
scopeDepth++;
}
catch (Exception)
{
}
}
internal static void ExitScope()
{
if (scopeDepth > 0)
{
scopeDepth--;
}
if (scopeDepth == 0)
{
scopeKey = 0L;
}
}
internal static string CurrentBody()
{
if (scopeDepth > 0 && scopeKey != 0L)
{
if (Tracked.TryGetValue(scopeKey, out var value))
{
return value.Body;
}
return null;
}
if (lastTracked != null && Time.realtimeSinceStartup - lastTime < 5f)
{
return lastTracked.Body;
}
return null;
}
}
[HarmonyPatch(typeof(InfoWindow), "Setup", new Type[]
{
typeof(WindowStylePreset),
typeof(Evidence),
typeof(List<DataKey>),
typeof(bool),
typeof(Interactable),
typeof(Case),
typeof(CaseElement),
typeof(bool)
})]
public static class InspectSetupPatch
{
private static void Prefix(InfoWindow __instance, Interactable newInteractable)
{
try
{
long key = ((Il2CppObjectBase)__instance).Pointer.ToInt64();
if (newInteractable != null && (SoCustomComparison)(object)newInteractable.syncDisk != (SoCustomComparison)null)
{
SyncDiskPreset syncDisk = newInteractable.syncDisk;
TrackedWindow trackedWindow = new TrackedWindow
{
Window = __instance,
Disk = syncDisk,
Body = InspectText.BuildBody(syncDisk)
};
InspectText.Tracked[key] = trackedWindow;
InspectText.MarkLast(trackedWindow);
}
else
{
InspectText.Tracked.Remove(key);
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SDL] inspect prefix failed: " + ex.GetType().Name + " " + ex.Message));
}
}
private static void Postfix(InfoWindow __instance)
{
try
{
if (InspectText.Tracked.TryGetValue(((Il2CppObjectBase)__instance).Pointer.ToInt64(), out var value))
{
Plugin.L.LogInfo((object)("[SDL] inspect on disk " + ((Object)value.Disk).name));
InspectText.ApplyTitle(__instance, value.Disk);
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SDL] inspect postfix failed: " + ex.GetType().Name + " " + ex.Message));
}
}
}
[HarmonyPatch(typeof(InfoWindow), "SetName")]
public static class InspectSetNamePatch
{
private static void Postfix(InfoWindow __instance)
{
try
{
if (InspectText.Tracked.TryGetValue(((Il2CppObjectBase)__instance).Pointer.ToInt64(), out var value))
{
InspectText.ApplyTitle(__instance, value.Disk);
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SDL] SetName postfix failed: " + ex.GetType().Name));
}
}
}
[HarmonyPatch(typeof(WindowContentController), "ConstructContent")]
public static class InspectConstructPatch
{
private static void Prefix(WindowContentController __instance)
{
InspectText.EnterScope(__instance);
}
private static void Postfix()
{
InspectText.ExitScope();
}
}
[HarmonyPatch(typeof(WindowContentController), "LoadContent")]
public static class InspectLoadContentPatch
{
private static void Prefix(WindowContentController __instance)
{
InspectText.EnterScope(__instance);
}
private static void Postfix()
{
InspectText.ExitScope();
}
}
[HarmonyPatch(typeof(Strings), "ComposeText")]
public static class InspectComposePatch
{
private static int logged;
private static void Postfix(ref string __result)
{
try
{
if (__result == null)
{
return;
}
bool flag = __result.IndexOf("Sync disks contain DNA", StringComparison.Ordinal) >= 0;
if (InspectText.Diag && (flag || __result.IndexOf("DNA", StringComparison.Ordinal) >= 0 || __result.IndexOf("ync disk", StringComparison.OrdinalIgnoreCase) >= 0))
{
InspectText.DiagLog("ComposeText result (generic " + flag + ", " + InspectText.BodyState() + "): " + InspectText.Short(__result));
}
if (!flag)
{
return;
}
string text = InspectText.CurrentBody();
if (text == null)
{
if (InspectText.Diag)
{
InspectText.DiagLog("ComposeText: generic text but no body to put in");
}
return;
}
__result = text;
if (logged < 8)
{
logged++;
Plugin.L.LogInfo((object)("[SDL] REPLACED generic text via ComposeText, chars=" + text.Length));
}
}
catch (Exception)
{
}
}
}
[HarmonyPatch(typeof(Strings), "Get")]
public static class InspectGetPatch
{
private const string BlockKey = "48759cc9-e501-4dbe-b5d8-ac151c684bdc";
private static int logged;
private static void Postfix(string dictionary, string key, ref string __result)
{
try
{
if (InspectText.Diag && dictionary == "dds.blocks")
{
InspectText.DiagLog("Get dds.blocks " + key + ((key == "48759cc9-e501-4dbe-b5d8-ac151c684bdc") ? " (the sync disk block)" : "") + " (" + InspectText.BodyState() + "): " + InspectText.Short(__result));
}
if (key != "48759cc9-e501-4dbe-b5d8-ac151c684bdc" || dictionary != "dds.blocks")
{
return;
}
string text = InspectText.CurrentBody();
if (text == null)
{
if (InspectText.Diag)
{
InspectText.DiagLog("Get: sync disk block but no body to put in");
}
return;
}
__result = text;
if (logged < 8)
{
logged++;
Plugin.L.LogInfo((object)("[SDL] REPLACED generic text via Strings.Get, chars=" + text.Length));
}
}
catch (Exception)
{
}
}
}
internal static class InstalledBadge
{
private const string Name = "SDLInstalledBadge";
private const int Size = 48;
private static Sprite sprite;
private static bool told;
internal static void Apply(InventorySquareController sq)
{
try
{
if (!((Object)(object)sq == (Object)null) && Plugin.BadgeInstalled.Value)
{
Interactable val = ((sq.slot != null) ? sq.slot.GetInteractable() : null);
SyncDiskPreset disk = ((val != null) ? val.syncDisk : null);
Show(((Component)sq).transform, disk);
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[BADGE] " + ex.GetType().Name + ": " + ex.Message));
}
}
internal static void ApplyShop(ShopSelectButtonController b)
{
try
{
if (!((Object)(object)b == (Object)null) && Plugin.BadgeInstalled.Value)
{
SyncDiskPreset disk = null;
if (b.sellMode && b.sellInteractable != null)
{
disk = b.sellInteractable.syncDisk;
}
Show(((Component)b).transform, disk);
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[BADGE] shop " + ex.GetType().Name + ": " + ex.Message));
}
}
private static void Show(Transform t, SyncDiskPreset disk)
{
bool flag = (SoCustomComparison)(object)disk != (SoCustomComparison)null && ShopLabel.Installed(disk);
Transform val = t.Find("SDLInstalledBadge");
if ((Object)(object)val == (Object)null)
{
if (!flag)
{
return;
}
val = Make(t);
if ((Object)(object)val == (Object)null)
{
return;
}
}
if (((Component)val).gameObject.activeSelf != flag)
{
((Component)val).gameObject.SetActive(flag);
}
if (flag && !told)
{
told = true;
Plugin.L.LogInfo((object)("[BADGE] marked an installed disk: " + ((Object)disk).name));
}
}
private static Transform Make(Transform parent)
{
//IL_001c: 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_0038: 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_0066: 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)
//IL_0090: 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_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)sprite == (Object)null)
{
sprite = MakeSprite();
}
GameObject val = new GameObject("SDLInstalledBadge");
Image obj = val.AddComponent<Image>();
obj.sprite = sprite;
((Graphic)obj).raycastTarget = false;
RectTransform component = val.GetComponent<RectTransform>();
((Transform)component).SetParent(parent, false);
component.anchorMin = new Vector2(1f, 1f);
component.anchorMax = new Vector2(1f, 1f);
component.pivot = new Vector2(0f, 1f);
component.sizeDelta = new Vector2(20f, 20f);
component.anchoredPosition = new Vector2(-2f, -2f);
((Transform)component).localScale = new Vector3(-1f, 1f, 1f);
val.AddComponent<LayoutElement>().ignoreLayout = true;
val.transform.SetAsLastSibling();
return val.transform;
}
private static Sprite MakeSprite()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_00cf: 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)
//IL_008b: 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_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = new Texture2D(48, 48, (TextureFormat)4, false);
Color val2 = default(Color);
((Color)(ref val2))..ctor(1f, 0.82f, 0.1f, 1f);
Color val3 = default(Color);
((Color)(ref val3))..ctor(0f, 0f, 0f, 0f);
for (int i = 0; i < 48; i++)
{
for (int j = 0; j < 48; j++)
{
float num = Mathf.Clamp01(((float)(i - j) + 1f) / 1.5f);
val.SetPixel(j, i, (Color)((num <= 0f) ? val3 : new Color(val2.r, val2.g, val2.b, num)));
}
}
((Texture)val).filterMode = (FilterMode)1;
((Texture)val).wrapMode = (TextureWrapMode)1;
val.Apply();
return Sprite.Create(val, new Rect(0f, 0f, 48f, 48f), new Vector2(0f, 1f), 100f);
}
}
[BepInPlugin("sm3gm.sod.disklabels", "Sync Disk Labels", "1.4.0")]
public class Plugin : BasePlugin
{
public const string VER = "1.4.0";
internal static ManualLogSource L;
internal static ConfigEntry<bool> MarkInstalled;
internal static ConfigEntry<bool> BadgeInstalled;
public override void Load()
{
L = ((BasePlugin)this).Log;
DiskSorter.Bind(((BasePlugin)this).Config);
BadgeInstalled = ((BasePlugin)this).Config.Bind<bool>("Inventory", "MarkInstalled", true, "In your inventory, put a small yellow triangle in the top right corner of a sync disk you already have installed.");
MarkInstalled = ((BasePlugin)this).Config.Bind<bool>("Shop", "MarkInstalled", true, "In a shop's buy list, grey out and mark sync disks you already have installed.");
try
{
Harmony.CreateAndPatchAll(typeof(SortAfterUpdate), (string)null);
Harmony.CreateAndPatchAll(typeof(SortOnOpen), (string)null);
((BasePlugin)this).AddComponent<SortWatch>();
}
catch (Exception ex)
{
L.LogWarning((object)("[SORT] patch failed: " + ex.Message));
}
Harmony.CreateAndPatchAll(typeof(UpdateContentPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(SetupPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(HoverStartPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(HoverEndPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(InspectSetupPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(InspectSetNamePatch), (string)null);
try
{
Harmony.CreateAndPatchAll(typeof(ShopTextPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(ShopTooltipPatch), (string)null);
}
catch (Exception ex2)
{
L.LogWarning((object)("[SHOP] patch failed: " + ex2.GetType().Name + " " + ex2.Message));
}
try
{
Harmony.CreateAndPatchAll(typeof(InspectComposePatch), (string)null);
Harmony.CreateAndPatchAll(typeof(InspectGetPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(InspectConstructPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(InspectLoadContentPatch), (string)null);
}
catch (Exception ex3)
{
L.LogWarning((object)("[SDL] text patches failed: " + ex3.GetType().Name + " " + ex3.Message));
}
try
{
Harmony.CreateAndPatchAll(typeof(LookAtPatch), (string)null);
}
catch (Exception ex4)
{
L.LogWarning((object)("[LOOK] patch failed: " + ex4.GetType().Name + " " + ex4.Message));
}
L.LogInfo((object)"Sync Disk Labels 1.4.0 loaded, 5 hooks registered, text patches on.");
}
}
internal static class Labeler
{
private const string Dict = "evidence.syncdisks";
private static readonly Dictionary<string, string> Cache = new Dictionary<string, string>();
private static readonly HashSet<string> FiredHooks = new HashSet<string>();
internal static void Apply(InventorySquareController sq, string hook)
{
ApplyLabel(sq, hook);
ApplyMark(sq);
}
private static void ApplyMark(InventorySquareController sq)
{
try
{
if ((Object)(object)sq == (Object)null || !Plugin.BadgeInstalled.Value)
{
return;
}
Interactable val = ((sq.slot != null) ? sq.slot.GetInteractable() : null);
SyncDiskPreset val2 = ((val != null) ? val.syncDisk : null);
if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null || !ShopLabel.Installed(val2))
{
return;
}
object prop = GetProp(sq, "text");
if (prop == null)
{
return;
}
PropertyInfo property = prop.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
if (!(property == null) && property.CanWrite)
{
string text = property.GetValue(prop, null) as string;
if (!string.IsNullOrEmpty(text) && !text.Contains("(installed)"))
{
property.SetValue(prop, text + " <color=#E0B040>(installed)</color>", null);
}
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[LABEL] mark failed: " + ex.GetType().Name + ": " + ex.Message));
}
}
private static void ApplyLabel(InventorySquareController sq, string hook)
{
try
{
if (FiredHooks.Add(hook))
{
Plugin.L.LogInfo((object)("[LABEL] hook " + hook + " fired for the first time"));
}
if ((Object)(object)sq == (Object)null)
{
return;
}
InstalledBadge.Apply(sq);
InventorySlot slot = sq.slot;
if (slot == null)
{
return;
}
Interactable interactable = slot.GetInteractable();
if (interactable == null)
{
return;
}
SyncDiskPreset syncDisk = interactable.syncDisk;
if ((SoCustomComparison)(object)syncDisk == (SoCustomComparison)null)
{
return;
}
string text = Lookup(((Object)syncDisk).name);
if (text == null)
{
return;
}
object prop = GetProp(sq, "text");
if (prop == null)
{
return;
}
PropertyInfo property = prop.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
if (!(property == null) && property.CanWrite)
{
string text2 = property.GetValue(prop, null) as string;
string name = interactable.GetName();
if (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(name) && text2.Contains(name))
{
property.SetValue(prop, text2.Replace(name, text), null);
}
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[LABEL] error in " + hook + ": " + ex.GetType().Name + ": " + ex.Message));
}
}
private static string Lookup(string key)
{
if (string.IsNullOrEmpty(key))
{
return null;
}
if (Cache.TryGetValue(key, out var value))
{
return value;
}
string text = null;
try
{
text = Strings.Get("evidence.syncdisks", key, (Casing)0, false, true, false, (Human)null);
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[LABEL] Strings.Get threw for " + key + ": " + ex.GetType().Name + ": " + ex.Message));
}
string text2 = ((string.IsNullOrEmpty(text) || text == key || text.Contains(key)) ? null : text);
Cache[key] = text2;
Plugin.L.LogInfo((object)("[LABEL] lookup evidence.syncdisks / " + key + " -> '" + (text ?? "null") + "'" + ((text2 == null) ? " (not used, label left as is)" : "")));
return text2;
}
private static object GetProp(object o, string prop)
{
if (o == null)
{
return null;
}
PropertyInfo property = o.GetType().GetProperty(prop, BindingFlags.Instance | BindingFlags.Public);
if (!(property == null))
{
return property.GetValue(o, null);
}
return null;
}
}
internal static class ShopLabel
{
private static int logged;
private const string Tag = " <color=#E0B040>(installed)</color>";
private static int marks;
internal static void Apply(ShopSelectButtonController b)
{
try
{
if ((Object)(object)b == (Object)null)
{
return;
}
InstalledBadge.ApplyShop(b);
SyncDiskPreset syncDisk = b.syncDisk;
if ((SoCustomComparison)(object)syncDisk == (SoCustomComparison)null && b.sellInteractable != null)
{
syncDisk = b.sellInteractable.syncDisk;
}
if ((SoCustomComparison)(object)syncDisk == (SoCustomComparison)null)
{
return;
}
string text = InspectText.DiskName(syncDisk);
if (text == null)
{
return;
}
object obj = InspectText.Prop(b, "text");
if (obj == null)
{
return;
}
string text2 = InspectText.Prop(obj, "text") as string;
if (string.IsNullOrEmpty(text2))
{
return;
}
if (text2.Contains(text))
{
Mark(b, syncDisk, obj, text2);
return;
}
string text3 = null;
try
{
if (b.sellInteractable != null)
{
text3 = b.sellInteractable.GetName();
}
}
catch
{
}
string text4 = null;
string[] array = new string[4] { text3, "SyncDisk", "Sync Disk", "Sync disk" };
foreach (string text5 in array)
{
if (!string.IsNullOrEmpty(text5) && text2.Contains(text5))
{
text4 = text2.Replace(text5, text);
break;
}
}
if (logged < 12)
{
logged++;
Plugin.L.LogInfo((object)("[SHOP] " + (b.sellMode ? "sell" : "buy") + " '" + text2.Replace("\n", " ") + "' -> " + ((text4 == null) ? "no generic name found" : ("'" + text4.Replace("\n", " ") + "'"))));
}
if (text4 != null)
{
InspectText.SetProp(obj, "text", text4);
}
Mark(b, syncDisk, obj, text4 ?? text2);
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SHOP] label failed: " + ex.GetType().Name + " " + ex.Message));
}
}
private static void Mark(ShopSelectButtonController b, SyncDiskPreset disk, object txt, string cur)
{
if (cur.Contains("(installed)") || !Installed(disk))
{
return;
}
if (b.sellMode)
{
if (Plugin.BadgeInstalled.Value)
{
InspectText.SetProp(txt, "text", cur + " <color=#E0B040>(installed)</color>");
}
}
else if (Plugin.MarkInstalled.Value)
{
string v = "<color=#8C8C8C>" + cur + "</color> <color=#E0B040>(installed)</color>";
InspectText.SetProp(txt, "text", v);
if (marks < 6)
{
marks++;
Plugin.L.LogInfo((object)("[SHOP] marked installed: " + ((Object)disk).name));
}
}
}
internal static bool Installed(SyncDiskPreset disk)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
try
{
UpgradesController instance = UpgradesController.Instance;
if ((Object)(object)instance == (Object)null || instance.upgrades == null || (SoCustomComparison)(object)disk == (SoCustomComparison)null)
{
return false;
}
Enumerator<Upgrades> enumerator = instance.upgrades.GetEnumerator();
while (enumerator.MoveNext())
{
Upgrades current = enumerator.Current;
if (current != null && (int)current.state != 0)
{
SyncDiskPreset val = current.preset ?? current.GetPreset();
if ((SoCustomComparison)(object)val != (SoCustomComparison)null && (((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)disk).Pointer || ((Object)val).name == ((Object)disk).name))
{
return true;
}
}
}
}
catch
{
}
return false;
}
}
internal static class ShopTip
{
private static int logged;
internal static void Apply(ShopSelectButtonController b)
{
try
{
if ((Object)(object)b == (Object)null || (Object)(object)((ButtonController)b).tooltip == (Object)null)
{
return;
}
SyncDiskPreset syncDisk = b.syncDisk;
if ((SoCustomComparison)(object)syncDisk == (SoCustomComparison)null && b.sellInteractable != null)
{
syncDisk = b.sellInteractable.syncDisk;
}
if ((SoCustomComparison)(object)syncDisk == (SoCustomComparison)null)
{
return;
}
string text = InspectText.BuildBody(syncDisk);
if (string.IsNullOrEmpty(text))
{
return;
}
TooltipController tooltip = ((ButtonController)b).tooltip;
if (!(tooltip.mainText == text) || tooltip.useMainDictionaryEntry)
{
tooltip.useMainDictionaryEntry = false;
tooltip.mainText = text;
tooltip.useDetailDictionaryEntry = false;
tooltip.detailText = "";
if (logged < 6)
{
logged++;
Plugin.L.LogInfo((object)("[SHOP] tooltip " + ((Object)syncDisk).name + ": " + text.Length + " chars"));
}
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[SHOP] tooltip failed: " + ex.GetType().Name + " " + ex.Message));
}
}
}
[HarmonyPatch(typeof(InteractionController), "UpdateReadingModeText")]
public static class LookAtPatch
{
private const string Tag = " <color=#E0B040>(installed)</color>";
private static int errs;
private static void Postfix()
{
try
{
if (!Plugin.BadgeInstalled.Value)
{
return;
}
InteractionController instance = InteractionController.Instance;
object obj;
if (instance == null)
{
obj = null;
}
else
{
InteractableController currentLookingAtInteractable = instance.currentLookingAtInteractable;
obj = ((currentLookingAtInteractable != null) ? currentLookingAtInteractable.interactable : null);
}
Interactable val = (Interactable)obj;
SyncDiskPreset val2 = ((val != null) ? val.syncDisk : null);
if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null || !ShopLabel.Installed(val2))
{
return;
}
InterfaceControls instance2 = InterfaceControls.Instance;
TextMeshProUGUI val3 = ((instance2 != null) ? instance2.readingText : null);
if (!((Object)(object)val3 == (Object)null))
{
string text = InspectText.Prop(val3, "text") as string;
if (!string.IsNullOrEmpty(text) && !text.Contains("(installed)"))
{
int num = text.IndexOf('\n');
InspectText.SetProp(val3, "text", (num < 0) ? (text + " <color=#E0B040>(installed)</color>") : (text.Substring(0, num) + " <color=#E0B040>(installed)</color>" + text.Substring(num)));
}
}
}
catch (Exception ex)
{
if (errs++ < 3)
{
Plugin.L.LogWarning((object)("[LOOK] " + ex.GetType().Name + ": " + ex.Message));
}
}
}
}
[HarmonyPatch(typeof(ShopSelectButtonController), "UpdateTooltip")]
public static class ShopTooltipPatch
{
private static void Postfix(ShopSelectButtonController __instance)
{
ShopTip.Apply(__instance);
}
}
[HarmonyPatch(typeof(ShopSelectButtonController), "UpdateButtonText")]
public static class ShopTextPatch
{
private static void Postfix(ShopSelectButtonController __instance)
{
ShopLabel.Apply(__instance);
ShopTip.Apply(__instance);
}
}
[HarmonyPatch(typeof(InventorySquareController), "OnUpdateContent")]
public static class UpdateContentPatch
{
private static void Postfix(InventorySquareController __instance)
{
Labeler.Apply(__instance, "OnUpdateContent");
}
}
[HarmonyPatch(typeof(InventorySquareController), "Setup")]
public static class SetupPatch
{
private static void Postfix(InventorySquareController __instance)
{
Labeler.Apply(__instance, "Setup");
}
}
[HarmonyPatch(typeof(InventorySquareController), "OnHoverStart")]
public static class HoverStartPatch
{
private static void Postfix(InventorySquareController __instance)
{
Labeler.Apply(__instance, "OnHoverStart");
}
}
[HarmonyPatch(typeof(InventorySquareController), "OnHoverEnd")]
public static class HoverEndPatch
{
private static void Postfix(InventorySquareController __instance)
{
Labeler.Apply(__instance, "OnHoverEnd");
}
}
}