using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HavenDevTools.API;
using HavenDevTools.Config;
using HavenDevTools.Integrations;
using HavenDevTools.Services;
using HavenDevTools.UI;
using Microsoft.CodeAnalysis;
using SunhavenMods.Shared;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Wish;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("HavenDevTools")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5c08b5aa5d0be9c4b93df77f697dc55d5ac97088")]
[assembly: AssemblyProduct("HavenDevTools")]
[assembly: AssemblyTitle("HavenDevTools")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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]
[Microsoft.CodeAnalysis.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]
[Microsoft.CodeAnalysis.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 SunhavenMods.Shared
{
public static class ConfigFileHelper
{
public static ConfigFile CreateNamedConfig(string pluginGuid, string configFileName, Action<string> logWarning = null)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
string text = Path.Combine(Paths.ConfigPath, configFileName);
string text2 = Path.Combine(Paths.ConfigPath, pluginGuid + ".cfg");
try
{
if (!File.Exists(text) && File.Exists(text2))
{
File.Copy(text2, text);
}
}
catch (Exception ex)
{
logWarning?.Invoke("[Config] Migration to " + configFileName + " failed: " + ex.Message);
}
return new ConfigFile(text, true);
}
public static bool ReplacePluginConfig(BaseUnityPlugin plugin, ConfigFile newConfig, Action<string> logWarning = null)
{
if ((Object)(object)plugin == (Object)null || newConfig == null)
{
return false;
}
try
{
Type typeFromHandle = typeof(BaseUnityPlugin);
PropertyInfo property = typeFromHandle.GetProperty("Config", BindingFlags.Instance | BindingFlags.Public);
if (property != null && property.CanWrite)
{
property.SetValue(plugin, newConfig, null);
return true;
}
FieldInfo field = typeFromHandle.GetField("<Config>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
field.SetValue(plugin, newConfig);
return true;
}
FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (fieldInfo.FieldType == typeof(ConfigFile))
{
fieldInfo.SetValue(plugin, newConfig);
return true;
}
}
}
catch (Exception ex)
{
logWarning?.Invoke("[Config] ReplacePluginConfig failed: " + ex.Message);
}
return false;
}
}
public static class VersionChecker
{
public class VersionCheckResult
{
public bool Success { get; set; }
public bool UpdateAvailable { get; set; }
public string CurrentVersion { get; set; }
public string LatestVersion { get; set; }
public string ModName { get; set; }
public string NexusUrl { get; set; }
public string Changelog { get; set; }
public string ErrorMessage { get; set; }
}
public class ModHealthSnapshot
{
public string PluginGuid { get; set; }
public DateTime LastCheckUtc { get; set; }
public int ExceptionCount { get; set; }
public string LastError { get; set; }
}
private class VersionCheckRunner : MonoBehaviour
{
private ManualLogSource _pluginLog;
public void StartCheck(string pluginGuid, string currentVersion, ManualLogSource pluginLog, Action<VersionCheckResult> onComplete)
{
_pluginLog = pluginLog;
((MonoBehaviour)this).StartCoroutine(CheckVersionCoroutine(pluginGuid, currentVersion, onComplete));
}
private void LogInfo(string message)
{
ManualLogSource pluginLog = _pluginLog;
if (pluginLog != null)
{
pluginLog.LogInfo((object)("[VersionChecker] " + message));
}
}
private void LogWarningMsg(string message)
{
ManualLogSource pluginLog = _pluginLog;
if (pluginLog != null)
{
pluginLog.LogWarning((object)("[VersionChecker] " + message));
}
}
private void LogErrorMsg(string message)
{
ManualLogSource pluginLog = _pluginLog;
if (pluginLog != null)
{
pluginLog.LogError((object)("[VersionChecker] " + message));
}
}
private IEnumerator CheckVersionCoroutine(string pluginGuid, string currentVersion, Action<VersionCheckResult> onComplete)
{
VersionCheckResult result = new VersionCheckResult
{
CurrentVersion = currentVersion
};
UnityWebRequest www = UnityWebRequest.Get("https://azraelgodking.github.io/SunhavenMod/versions.json");
try
{
www.timeout = 10;
yield return www.SendWebRequest();
if ((int)www.result == 2 || (int)www.result == 3)
{
result.Success = false;
result.ErrorMessage = "Network error: " + www.error;
RecordHealthError(pluginGuid, result.ErrorMessage);
LogWarningMsg(result.ErrorMessage);
onComplete?.Invoke(result);
Object.Destroy((Object)(object)((Component)this).gameObject);
yield break;
}
try
{
string text = www.downloadHandler.text;
Match match = GetModPattern(pluginGuid).Match(text);
if (!match.Success)
{
result.Success = false;
result.ErrorMessage = "Mod '" + pluginGuid + "' not found in versions.json";
RecordHealthError(pluginGuid, result.ErrorMessage);
LogWarningMsg(result.ErrorMessage);
onComplete?.Invoke(result);
Object.Destroy((Object)(object)((Component)this).gameObject);
yield break;
}
string value = match.Groups[1].Value;
result.LatestVersion = ExtractJsonString(value, "version");
result.ModName = ExtractJsonString(value, "name");
result.NexusUrl = ExtractJsonString(value, "nexus");
result.Changelog = ExtractJsonString(value, "changelog");
if (string.IsNullOrEmpty(result.LatestVersion))
{
result.Success = false;
result.ErrorMessage = "Could not parse version from response";
RecordHealthError(pluginGuid, result.ErrorMessage);
LogWarningMsg(result.ErrorMessage);
onComplete?.Invoke(result);
Object.Destroy((Object)(object)((Component)this).gameObject);
yield break;
}
result.Success = true;
result.UpdateAvailable = CompareVersions(currentVersion, result.LatestVersion) < 0;
if (result.UpdateAvailable)
{
LogInfo("Update available for " + result.ModName + ": " + currentVersion + " -> " + result.LatestVersion);
}
else
{
LogInfo(result.ModName + " is up to date (v" + currentVersion + ")");
}
}
catch (Exception ex)
{
result.Success = false;
result.ErrorMessage = "Parse error: " + ex.Message;
RecordHealthError(pluginGuid, result.ErrorMessage);
LogErrorMsg(result.ErrorMessage);
}
}
finally
{
((IDisposable)www)?.Dispose();
}
onComplete?.Invoke(result);
Object.Destroy((Object)(object)((Component)this).gameObject);
}
private string ExtractJsonString(string json, string key)
{
Match match = ExtractFieldRegex.Match(json);
while (match.Success)
{
if (string.Equals(match.Groups["key"].Value, key, StringComparison.Ordinal))
{
return match.Groups["value"].Value;
}
match = match.NextMatch();
}
return null;
}
}
private const string VersionsUrl = "https://azraelgodking.github.io/SunhavenMod/versions.json";
private static readonly Dictionary<string, ModHealthSnapshot> HealthByPluginGuid = new Dictionary<string, ModHealthSnapshot>(StringComparer.OrdinalIgnoreCase);
private static readonly object HealthLock = new object();
private static readonly Dictionary<string, Regex> ModPatternCache = new Dictionary<string, Regex>(StringComparer.Ordinal);
private static readonly object ModPatternCacheLock = new object();
private static readonly Regex ExtractFieldRegex = new Regex("\"(?<key>[^\"]+)\"\\s*:\\s*(?:\"(?<value>[^\"]*)\"|null)", RegexOptions.Compiled);
public static void CheckForUpdate(string pluginGuid, string currentVersion, ManualLogSource logger = null, Action<VersionCheckResult> onComplete = null)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
TouchHealth(pluginGuid);
VersionCheckRunner versionCheckRunner = new GameObject("VersionChecker").AddComponent<VersionCheckRunner>();
Object.DontDestroyOnLoad((Object)(object)((Component)versionCheckRunner).gameObject);
SceneRootSurvivor.TryRegisterPersistentRunnerGameObject(((Component)versionCheckRunner).gameObject);
versionCheckRunner.StartCheck(pluginGuid, currentVersion, logger, onComplete);
}
public static ModHealthSnapshot GetHealthSnapshot(string pluginGuid)
{
if (string.IsNullOrWhiteSpace(pluginGuid))
{
return null;
}
lock (HealthLock)
{
if (!HealthByPluginGuid.TryGetValue(pluginGuid, out ModHealthSnapshot value))
{
return null;
}
return new ModHealthSnapshot
{
PluginGuid = value.PluginGuid,
LastCheckUtc = value.LastCheckUtc,
ExceptionCount = value.ExceptionCount,
LastError = value.LastError
};
}
}
public static int CompareVersions(string v1, string v2)
{
if (string.IsNullOrEmpty(v1) || string.IsNullOrEmpty(v2))
{
return 0;
}
v1 = v1.TrimStart('v', 'V');
v2 = v2.TrimStart('v', 'V');
int num = v1.IndexOfAny(new char[2] { '-', '+' });
if (num >= 0)
{
v1 = v1.Substring(0, num);
}
int num2 = v2.IndexOfAny(new char[2] { '-', '+' });
if (num2 >= 0)
{
v2 = v2.Substring(0, num2);
}
string[] array = v1.Split(new char[1] { '.' });
string[] array2 = v2.Split(new char[1] { '.' });
int num3 = Math.Max(array.Length, array2.Length);
for (int i = 0; i < num3; i++)
{
int result;
int num4 = ((i < array.Length && int.TryParse(array[i], out result)) ? result : 0);
int result2;
int num5 = ((i < array2.Length && int.TryParse(array2[i], out result2)) ? result2 : 0);
if (num4 < num5)
{
return -1;
}
if (num4 > num5)
{
return 1;
}
}
return 0;
}
private static void TouchHealth(string pluginGuid)
{
if (string.IsNullOrWhiteSpace(pluginGuid))
{
return;
}
lock (HealthLock)
{
if (!HealthByPluginGuid.TryGetValue(pluginGuid, out ModHealthSnapshot value))
{
value = new ModHealthSnapshot
{
PluginGuid = pluginGuid
};
HealthByPluginGuid[pluginGuid] = value;
}
value.LastCheckUtc = DateTime.UtcNow;
}
}
private static void RecordHealthError(string pluginGuid, string errorMessage)
{
if (string.IsNullOrWhiteSpace(pluginGuid))
{
return;
}
lock (HealthLock)
{
if (!HealthByPluginGuid.TryGetValue(pluginGuid, out ModHealthSnapshot value))
{
value = new ModHealthSnapshot
{
PluginGuid = pluginGuid
};
HealthByPluginGuid[pluginGuid] = value;
}
value.LastCheckUtc = DateTime.UtcNow;
value.ExceptionCount++;
value.LastError = errorMessage;
}
}
private static Regex GetModPattern(string pluginGuid)
{
lock (ModPatternCacheLock)
{
if (!ModPatternCache.TryGetValue(pluginGuid, out Regex value))
{
value = new Regex("\"" + Regex.Escape(pluginGuid) + "\"\\s*:\\s*\\{([^}]+)\\}", RegexOptions.Compiled | RegexOptions.Singleline);
ModPatternCache[pluginGuid] = value;
}
return value;
}
}
}
public static class VersionCheckerExtensions
{
public static void NotifyUpdateAvailable(this VersionChecker.VersionCheckResult result, ManualLogSource logger = null)
{
if (!result.UpdateAvailable)
{
return;
}
string text = result.ModName + " update available: v" + result.LatestVersion;
try
{
Type type = ReflectionHelper.FindWishType("NotificationStack");
if (type != null)
{
Type type2 = ReflectionHelper.FindType("SingletonBehaviour`1", "Wish");
if (type2 != null)
{
object obj = type2.MakeGenericType(type).GetProperty("Instance")?.GetValue(null);
if (obj != null)
{
MethodInfo method = type.GetMethod("SendNotification", new Type[5]
{
typeof(string),
typeof(int),
typeof(int),
typeof(bool),
typeof(bool)
});
if (method != null)
{
method.Invoke(obj, new object[5] { text, 0, 1, false, true });
return;
}
}
}
}
}
catch (Exception ex)
{
if (logger != null)
{
logger.LogWarning((object)("Failed to send native notification: " + ex.Message));
}
}
if (logger != null)
{
logger.LogWarning((object)("[UPDATE AVAILABLE] " + text));
}
if (!string.IsNullOrEmpty(result.NexusUrl) && logger != null)
{
logger.LogWarning((object)("Download at: " + result.NexusUrl));
}
}
}
public static class SceneRootSurvivor
{
private static readonly object Lock = new object();
private static readonly List<string> NoKillSubstrings = new List<string>();
private static Harmony _harmony;
public static void TryRegisterPersistentRunnerGameObject(GameObject go)
{
if (!((Object)(object)go == (Object)null))
{
TryAddNoKillListSubstring(((Object)go).name);
}
}
public static void TryAddNoKillListSubstring(string nameSubstring)
{
if (string.IsNullOrEmpty(nameSubstring))
{
return;
}
lock (Lock)
{
bool flag = false;
for (int i = 0; i < NoKillSubstrings.Count; i++)
{
if (string.Equals(NoKillSubstrings[i], nameSubstring, StringComparison.OrdinalIgnoreCase))
{
flag = true;
break;
}
}
if (!flag)
{
NoKillSubstrings.Add(nameSubstring);
}
}
EnsurePatched();
}
private static void EnsurePatched()
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: 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_009d: Expected O, but got Unknown
//IL_00a3: Expected O, but got Unknown
if (_harmony != null)
{
return;
}
lock (Lock)
{
if (_harmony == null)
{
MethodInfo methodInfo = AccessTools.Method(typeof(Scene), "GetRootGameObjects", Type.EmptyTypes, (Type[])null);
if (!(methodInfo == null))
{
string text = typeof(SceneRootSurvivor).Assembly.GetName().Name ?? "Unknown";
Harmony val = new Harmony("SunhavenMods.SceneRootSurvivor." + text);
val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(SceneRootSurvivor), "OnGetRootGameObjectsPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
_harmony = val;
}
}
}
}
private static void OnGetRootGameObjectsPostfix(ref GameObject[] __result)
{
if (__result == null || __result.Length == 0)
{
return;
}
List<string> list;
lock (Lock)
{
if (NoKillSubstrings.Count == 0)
{
return;
}
list = new List<string>(NoKillSubstrings);
}
List<GameObject> list2 = new List<GameObject>(__result);
for (int i = 0; i < list.Count; i++)
{
string noKill = list[i];
list2.RemoveAll((GameObject a) => (Object)(object)a != (Object)null && ((Object)a).name.IndexOf(noKill, StringComparison.OrdinalIgnoreCase) >= 0);
}
__result = list2.ToArray();
}
}
public static class ReflectionHelper
{
public static readonly BindingFlags AllBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
public static Type FindType(string typeName, params string[] namespaces)
{
string typeName2 = typeName;
Type type = AccessTools.TypeByName(typeName2);
if (type != null)
{
return type;
}
for (int i = 0; i < namespaces.Length; i++)
{
type = AccessTools.TypeByName(namespaces[i] + "." + typeName2);
if (type != null)
{
return type;
}
}
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
try
{
type = assembly.GetTypes().FirstOrDefault((Type t) => t.Name == typeName2 || t.FullName == typeName2);
if (type != null)
{
return type;
}
}
catch (ReflectionTypeLoadException)
{
}
}
return null;
}
public static Type FindWishType(string typeName)
{
return FindType(typeName, "Wish");
}
public static object GetStaticValue(Type type, string memberName)
{
if (type == null)
{
return null;
}
try
{
PropertyInfo property = type.GetProperty(memberName, AllBindingFlags);
if (property != null && property.GetMethod != null && property.GetIndexParameters().Length == 0)
{
return property.GetValue(null);
}
}
catch (AmbiguousMatchException)
{
return null;
}
FieldInfo field = type.GetField(memberName, AllBindingFlags);
if (field != null)
{
return field.GetValue(null);
}
return null;
}
public static object GetSingletonInstance(Type type)
{
if (type == null)
{
return null;
}
string[] array = new string[5] { "Instance", "instance", "_instance", "Singleton", "singleton" };
foreach (string memberName in array)
{
object staticValue = GetStaticValue(type, memberName);
if (staticValue != null)
{
return staticValue;
}
}
return null;
}
public static object GetInstanceValue(object instance, string memberName)
{
if (instance == null)
{
return null;
}
Type type = instance.GetType();
while (type != null)
{
PropertyInfo property = type.GetProperty(memberName, AllBindingFlags);
if (property != null && property.GetMethod != null)
{
return property.GetValue(instance);
}
FieldInfo field = type.GetField(memberName, AllBindingFlags);
if (field != null)
{
return field.GetValue(instance);
}
type = type.BaseType;
}
return null;
}
public static bool SetInstanceValue(object instance, string memberName, object value)
{
if (instance == null)
{
return false;
}
Type type = instance.GetType();
while (type != null)
{
PropertyInfo property = type.GetProperty(memberName, AllBindingFlags);
if (property != null && property.SetMethod != null)
{
property.SetValue(instance, value);
return true;
}
FieldInfo field = type.GetField(memberName, AllBindingFlags);
if (field != null)
{
field.SetValue(instance, value);
return true;
}
type = type.BaseType;
}
return false;
}
public static object InvokeMethod(object instance, string methodName, params object[] args)
{
if (instance == null)
{
return null;
}
Type type = instance.GetType();
Type[] array = args?.Select((object a) => a?.GetType() ?? typeof(object)).ToArray() ?? Type.EmptyTypes;
MethodInfo methodInfo = AccessTools.Method(type, methodName, array, (Type[])null);
if (methodInfo == null)
{
methodInfo = type.GetMethod(methodName, AllBindingFlags);
}
if (methodInfo == null)
{
return null;
}
return methodInfo.Invoke(instance, args);
}
public static object InvokeStaticMethod(Type type, string methodName, params object[] args)
{
if (type == null)
{
return null;
}
Type[] array = args?.Select((object a) => a?.GetType() ?? typeof(object)).ToArray() ?? Type.EmptyTypes;
MethodInfo methodInfo = AccessTools.Method(type, methodName, array, (Type[])null);
if (methodInfo == null)
{
methodInfo = type.GetMethod(methodName, AllBindingFlags);
}
if (methodInfo == null)
{
return null;
}
return methodInfo.Invoke(null, args);
}
public static FieldInfo[] GetAllFields(Type type)
{
if (type == null)
{
return Array.Empty<FieldInfo>();
}
FieldInfo[] fields = type.GetFields(AllBindingFlags);
IEnumerable<FieldInfo> second;
if (!(type.BaseType != null) || !(type.BaseType != typeof(object)))
{
second = Enumerable.Empty<FieldInfo>();
}
else
{
IEnumerable<FieldInfo> allFields = GetAllFields(type.BaseType);
second = allFields;
}
return fields.Concat(second).Distinct().ToArray();
}
public static PropertyInfo[] GetAllProperties(Type type)
{
if (type == null)
{
return Array.Empty<PropertyInfo>();
}
PropertyInfo[] properties = type.GetProperties(AllBindingFlags);
IEnumerable<PropertyInfo> second;
if (!(type.BaseType != null) || !(type.BaseType != typeof(object)))
{
second = Enumerable.Empty<PropertyInfo>();
}
else
{
IEnumerable<PropertyInfo> allProperties = GetAllProperties(type.BaseType);
second = allProperties;
}
return (from p in properties.Concat(second)
group p by p.Name into g
select g.First()).ToArray();
}
public static T TryGetValue<T>(object instance, string memberName, T defaultValue = default(T))
{
try
{
object instanceValue = GetInstanceValue(instance, memberName);
if (instanceValue is T result)
{
return result;
}
if (instanceValue != null && typeof(T).IsAssignableFrom(instanceValue.GetType()))
{
return (T)instanceValue;
}
return defaultValue;
}
catch
{
return defaultValue;
}
}
}
public static class ItemSearch
{
private static readonly ManualLogSource _log = Logger.CreateLogSource("ItemSearch");
private static object _dbInstance;
private static FieldInfo _dictField;
public static string FormatDisplay(string name, int itemId)
{
if (string.IsNullOrEmpty(name))
{
return $"#{itemId}";
}
return $"{name} (#{itemId})";
}
public static List<KeyValuePair<int, string>> SearchItems(string query, int maxResults = 50)
{
List<KeyValuePair<int, string>> list = new List<KeyValuePair<int, string>>();
if (string.IsNullOrEmpty(query) || query.Trim().Length < 2)
{
return list;
}
try
{
Dictionary<int, ItemSellInfo> itemDictionary = GetItemDictionary();
if (itemDictionary == null)
{
return list;
}
string text = query.Trim().ToLowerInvariant();
int result;
bool flag = int.TryParse(query.Trim(), out result);
List<KeyValuePair<int, string>> list2 = new List<KeyValuePair<int, string>>();
List<KeyValuePair<int, string>> list3 = new List<KeyValuePair<int, string>>();
List<KeyValuePair<int, string>> list4 = new List<KeyValuePair<int, string>>();
foreach (KeyValuePair<int, ItemSellInfo> item2 in itemDictionary)
{
int key = item2.Key;
string text2 = item2.Value?.name;
if (!string.IsNullOrEmpty(text2))
{
KeyValuePair<int, string> item = new KeyValuePair<int, string>(key, text2);
string text3 = text2.ToLowerInvariant();
if (flag && key == result)
{
list2.Add(item);
}
else if (text3 == text)
{
list2.Add(item);
}
else if (text3.StartsWith(text))
{
list3.Add(item);
}
else if (text3.Contains(text))
{
list4.Add(item);
}
else if (flag && key.ToString().Contains(query.Trim()))
{
list4.Add(item);
}
}
}
list3.Sort((KeyValuePair<int, string> a, KeyValuePair<int, string> b) => string.Compare(a.Value, b.Value, StringComparison.OrdinalIgnoreCase));
list4.Sort((KeyValuePair<int, string> a, KeyValuePair<int, string> b) => string.Compare(a.Value, b.Value, StringComparison.OrdinalIgnoreCase));
list.AddRange(list2);
list.AddRange(list3);
list.AddRange(list4);
if (list.Count > maxResults)
{
list.RemoveRange(maxResults, list.Count - maxResults);
}
}
catch (Exception ex)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogDebug((object)("[ItemSearch] SearchItems error: " + ex.Message));
}
}
return list;
}
public static string GetItemName(int itemId)
{
try
{
Dictionary<int, ItemSellInfo> itemDictionary = GetItemDictionary();
if (itemDictionary == null || !itemDictionary.ContainsKey(itemId))
{
return null;
}
return itemDictionary[itemId]?.name;
}
catch (Exception ex)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogDebug((object)$"[ItemSearch] GetItemName({itemId}): {ex.Message}");
}
return null;
}
}
public static ItemSellInfo GetItemSellInfo(int itemId)
{
try
{
Dictionary<int, ItemSellInfo> itemDictionary = GetItemDictionary();
if (itemDictionary != null && itemDictionary.TryGetValue(itemId, out var value))
{
return value;
}
}
catch (Exception ex)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogDebug((object)$"[ItemSearch] GetItemSellInfo({itemId}): {ex.Message}");
}
}
return null;
}
private static Dictionary<int, ItemSellInfo> GetItemDictionary()
{
try
{
if (_dbInstance != null)
{
object dbInstance = _dbInstance;
Object val = (Object)((dbInstance is Object) ? dbInstance : null);
if (val == null || !(val == (Object)null))
{
goto IL_005b;
}
}
_dbInstance = null;
_dictField = null;
_dbInstance = GetSingletonInstance("Wish.ItemInfoDatabase");
if (_dbInstance != null)
{
_dictField = _dbInstance.GetType().GetField("allItemSellInfos", BindingFlags.Instance | BindingFlags.Public);
}
goto IL_005b;
IL_005b:
if (_dbInstance == null || _dictField == null)
{
return null;
}
return _dictField.GetValue(_dbInstance) as Dictionary<int, ItemSellInfo>;
}
catch (Exception ex)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogDebug((object)("[ItemSearch] GetItemDictionary: " + ex.Message));
}
return null;
}
}
private static object GetSingletonInstance(string typeName)
{
try
{
Type type = AccessTools.TypeByName("Wish.SingletonBehaviour`1");
if (type == null)
{
return null;
}
Type type2 = AccessTools.TypeByName(typeName);
if (type2 == null)
{
return null;
}
return type.MakeGenericType(type2).GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)?.GetValue(null);
}
catch (Exception ex)
{
ManualLogSource log = _log;
if (log != null)
{
log.LogDebug((object)("[ItemSearch] GetSingletonInstance(" + typeName + "): " + ex.Message));
}
return null;
}
}
}
public static class TextInputFocusGuard
{
private const float DefaultPollIntervalSeconds = 0.25f;
private static float _nextPollTime = -1f;
private static bool _cachedDefer;
private static bool _tmpTypeLookupDone;
private static Type _tmpInputFieldType;
private static bool _qcLookupDone;
private static Type _qcType;
private static PropertyInfo _qcInstanceProp;
private static PropertyInfo _qcIsActiveProp;
private static FieldInfo _qcIsActiveField;
public static bool ShouldDeferModHotkeys(ManualLogSource debugLog = null, float pollIntervalSeconds = 0.25f)
{
float realtimeSinceStartup = Time.realtimeSinceStartup;
if (realtimeSinceStartup < _nextPollTime)
{
return _cachedDefer;
}
_nextPollTime = realtimeSinceStartup + Mathf.Max(0.05f, pollIntervalSeconds);
bool flag = false;
try
{
if (GUIUtility.keyboardControl != 0)
{
flag = true;
}
if (!flag)
{
EventSystem current = EventSystem.current;
GameObject val = ((current != null) ? current.currentSelectedGameObject : null);
if ((Object)(object)val != (Object)null)
{
if ((Object)(object)val.GetComponent<InputField>() != (Object)null)
{
flag = true;
}
else if (TryGetTmpInputField(val))
{
flag = true;
}
}
}
if (!flag && IsQuantumConsoleActive(debugLog))
{
flag = true;
}
}
catch (Exception ex)
{
if (debugLog != null)
{
debugLog.LogDebug((object)("[TextInputFocusGuard] " + ex.Message));
}
}
_cachedDefer = flag;
return flag;
}
private static bool TryGetTmpInputField(GameObject go)
{
if (!_tmpTypeLookupDone)
{
_tmpTypeLookupDone = true;
_tmpInputFieldType = AccessTools.TypeByName("TMPro.TMP_InputField");
}
if (_tmpInputFieldType == null)
{
return false;
}
return (Object)(object)go.GetComponent(_tmpInputFieldType) != (Object)null;
}
private static bool IsQuantumConsoleActive(ManualLogSource debugLog)
{
try
{
if (!_qcLookupDone)
{
_qcLookupDone = true;
_qcType = AccessTools.TypeByName("QFSW.QC.QuantumConsole");
if (_qcType != null)
{
_qcInstanceProp = AccessTools.Property(_qcType, "Instance");
_qcIsActiveProp = AccessTools.Property(_qcType, "IsActive");
_qcIsActiveField = AccessTools.Field(_qcType, "isActive") ?? AccessTools.Field(_qcType, "_isActive");
}
}
if (_qcType == null)
{
return false;
}
object obj = _qcInstanceProp?.GetValue(null);
if (obj == null)
{
return false;
}
if (_qcIsActiveProp != null && _qcIsActiveProp.PropertyType == typeof(bool))
{
return (bool)_qcIsActiveProp.GetValue(obj);
}
if (_qcIsActiveField != null && _qcIsActiveField.FieldType == typeof(bool))
{
return (bool)_qcIsActiveField.GetValue(obj);
}
}
catch (Exception ex)
{
if (debugLog != null)
{
debugLog.LogDebug((object)("[TextInputFocusGuard] Quantum Console focus check failed: " + ex.Message));
}
}
return false;
}
}
}
namespace HavenDevTools
{
[BepInPlugin("com.azraelgodking.havendevtools", "Haven Dev Tools", "1.2.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private static ItemInspector _staticItemInspector;
private static CurrencyTracker _staticCurrencyTracker;
private static BundleInspector _staticBundleInspector;
private static RaceModifierTracker _staticRaceModifierTracker;
private static DebugWindow _staticDebugWindow;
private static DebugOverlay _staticDebugOverlay;
private static CommandConsole _staticCommandConsole;
private static LogViewerPanel _staticLogViewer;
private static GameObject _persistentRunner;
private static PersistentRunner _persistentRunnerComponent;
internal static KeyCode StaticToggleKey = (KeyCode)292;
internal static KeyCode StaticOverlayToggleKey = (KeyCode)287;
private static readonly HashSet<string> _authorizedSteamIdHashes = new HashSet<string> { "Tr4eyf86yKRu6fhNQjQOrO/ZnwasQaY/fgKV0PcnoGA=" };
private static bool _isAuthorized;
private static string _currentSteamId;
private static string _currentPlayerName;
private Harmony _harmony;
private bool _applicationQuitting;
public static Plugin Instance { get; private set; }
public static ManualLogSource Log { get; private set; }
public static ConfigFile ConfigFile { get; private set; }
public static bool HasTheVault { get; private set; }
public static bool HasSMUT { get; private set; }
public static bool HasHavensBirthright { get; private set; }
public static bool HasSenpaisChest { get; private set; }
public static bool HasBirthdayReminder { get; private set; }
public static bool HasSunhavenTodo { get; private set; }
public static bool HasHavensAlmanac { get; private set; }
public static bool HasTrinketFortune { get; private set; }
public static bool IsAuthorized => _isAuthorized;
public static string CurrentPlayerName => _currentPlayerName;
private void Awake()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Expected O, but got Unknown
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
ConfigFile = CreateNamedConfig();
ConfigFileHelper.ReplacePluginConfig((BaseUnityPlugin)(object)this, ConfigFile, (Action<string>)Log.LogWarning);
Log.LogInfo((object)"Loading Haven Dev Tools v1.2.2");
try
{
ModConfig.Initialize(ConfigFile);
StaticToggleKey = ModConfig.ToggleKey.Value;
StaticOverlayToggleKey = ModConfig.OverlayToggleKey.Value;
CreatePersistentRunner();
DetectInstalledMods();
ModConfig.SyncTheVaultFullVaultInspectorToPlugin();
_staticItemInspector = new ItemInspector();
_staticCurrencyTracker = new CurrencyTracker();
_staticBundleInspector = new BundleInspector();
_staticRaceModifierTracker = new RaceModifierTracker();
_staticCommandConsole = new CommandConsole();
_staticLogViewer = new LogViewerPanel();
CreateUIComponents();
_harmony = new Harmony("com.azraelgodking.havendevtools");
PatchPlayerInit();
SceneManager.sceneLoaded += OnSceneLoaded;
if (ModConfig.CheckForUpdates.Value)
{
VersionChecker.CheckForUpdate("com.azraelgodking.havendevtools", "1.2.2", Log, delegate(VersionChecker.VersionCheckResult result)
{
result.NotifyUpdateAvailable(Log);
});
}
Log.LogInfo((object)"Haven Dev Tools loaded successfully!");
Log.LogInfo((object)$"Press {ModConfig.ToggleKey.Value} to open the debug window (requires authorization)");
Log.LogInfo((object)$"Press {ModConfig.OverlayToggleKey.Value} to toggle the overlay");
Log.LogInfo((object)$"Detected mods - TheVault: {HasTheVault}, SMUT: {HasSMUT}, Birthright: {HasHavensBirthright}, SenpaisChest: {HasSenpaisChest}, Birthday: {HasBirthdayReminder}, Todo: {HasSunhavenTodo}, Almanac: {HasHavensAlmanac}, TrinketFortune: {HasTrinketFortune}");
}
catch (Exception arg)
{
Log.LogError((object)string.Format("Failed to load {0}: {1}", "Haven Dev Tools", arg));
}
}
private static ConfigFile CreateNamedConfig()
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
string text = Path.Combine(Paths.ConfigPath, "HavenDevTools.cfg");
string text2 = Path.Combine(Paths.ConfigPath, "com.azraelgodking.havendevtools.cfg");
try
{
if (!File.Exists(text) && File.Exists(text2))
{
File.Copy(text2, text);
}
}
catch (Exception ex)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogWarning((object)("[Config] Migration to HavenDevTools.cfg failed: " + ex.Message));
}
}
return new ConfigFile(text, true);
}
private void CreatePersistentRunner()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
if (!((Object)(object)_persistentRunner != (Object)null) || !((Object)(object)_persistentRunnerComponent != (Object)null))
{
_persistentRunner = new GameObject("HavenDevTools_PersistentRunner");
Object.DontDestroyOnLoad((Object)(object)_persistentRunner);
((Object)_persistentRunner).hideFlags = (HideFlags)61;
SceneRootSurvivor.TryRegisterPersistentRunnerGameObject(_persistentRunner);
_persistentRunnerComponent = _persistentRunner.AddComponent<PersistentRunner>();
Log.LogInfo((object)"[PersistentRunner] Created hidden persistent runner");
}
}
private void CreateUIComponents()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("HavenDevTools_UI");
Object.DontDestroyOnLoad((Object)val);
_staticDebugWindow = val.AddComponent<DebugWindow>();
_staticDebugOverlay = val.AddComponent<DebugOverlay>();
Log.LogInfo((object)"UI components created");
}
public static void EnsureUIComponentsExist()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Expected O, but got Unknown
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)_persistentRunner == (Object)null || (Object)(object)_persistentRunnerComponent == (Object)null)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)"[EnsureUI] Recreating PersistentRunner...");
}
_persistentRunner = new GameObject("HavenDevTools_PersistentRunner");
Object.DontDestroyOnLoad((Object)(object)_persistentRunner);
((Object)_persistentRunner).hideFlags = (HideFlags)61;
SceneRootSurvivor.TryRegisterPersistentRunnerGameObject(_persistentRunner);
_persistentRunnerComponent = _persistentRunner.AddComponent<PersistentRunner>();
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogInfo((object)"[EnsureUI] PersistentRunner recreated");
}
}
if ((Object)(object)_staticDebugWindow == (Object)null || (Object)(object)_staticDebugOverlay == (Object)null)
{
ManualLogSource log3 = Log;
if (log3 != null)
{
log3.LogInfo((object)"[EnsureUI] Recreating UI components...");
}
GameObject val = new GameObject("HavenDevTools_UI");
Object.DontDestroyOnLoad((Object)val);
_staticDebugWindow = val.AddComponent<DebugWindow>();
_staticDebugOverlay = val.AddComponent<DebugOverlay>();
ManualLogSource log4 = Log;
if (log4 != null)
{
log4.LogInfo((object)"[EnsureUI] UI components recreated");
}
}
if (_staticItemInspector == null)
{
_staticItemInspector = new ItemInspector();
}
if (_staticCurrencyTracker == null)
{
_staticCurrencyTracker = new CurrencyTracker();
}
if (_staticBundleInspector == null)
{
_staticBundleInspector = new BundleInspector();
}
if (_staticRaceModifierTracker == null)
{
_staticRaceModifierTracker = new RaceModifierTracker();
}
if (_staticCommandConsole == null)
{
_staticCommandConsole = new CommandConsole();
}
if (_staticLogViewer == null)
{
_staticLogViewer = new LogViewerPanel();
}
}
catch (Exception ex)
{
ManualLogSource log5 = Log;
if (log5 != null)
{
log5.LogError((object)("[EnsureUI] Error recreating components: " + ex.Message));
}
}
}
private void DetectInstalledMods()
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
string? name = assemblies[i].GetName().Name;
if (name == "TheVault")
{
HasTheVault = true;
}
if (name == "SunHavenMuseumUtilityTracker")
{
HasSMUT = true;
}
if (name == "HavensBirthright")
{
HasHavensBirthright = true;
}
if (name == "SenpaisChest")
{
HasSenpaisChest = true;
}
if (name == "BirthdayReminder")
{
HasBirthdayReminder = true;
}
if (name == "SunhavenTodo")
{
HasSunhavenTodo = true;
}
if (name == "HavensAlmanac")
{
HasHavensAlmanac = true;
}
if (name == "TrinketFortune")
{
HasTrinketFortune = true;
}
}
Log.LogInfo((object)$"Mod detection complete - TheVault: {HasTheVault}, SMUT: {HasSMUT}, Birthright: {HasHavensBirthright}, SenpaisChest: {HasSenpaisChest}, Birthday: {HasBirthdayReminder}, Todo: {HasSunhavenTodo}, Almanac: {HasHavensAlmanac}, TrinketFortune: {HasTrinketFortune}");
}
private void PatchPlayerInit()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
try
{
MethodInfo methodInfo = AccessTools.Method(typeof(Player), "InitializeAsOwner", (Type[])null, (Type[])null);
if (methodInfo != null)
{
MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "OnPlayerInitialized", (Type[])null, (Type[])null);
_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Log.LogInfo((object)"Patched Player.InitializeAsOwner");
}
}
catch (Exception ex)
{
Log.LogError((object)("Failed to patch player init: " + ex.Message));
}
}
private static void OnPlayerInitialized()
{
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)"[HavenDevTools] Player initialized, ensuring UI exists and checking authorization...");
}
EnsureUIComponentsExist();
CheckAuthorization();
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
Log.LogDebug((object)("[SceneChange] Scene loaded: '" + ((Scene)(ref scene)).name + "'"));
string text = ((Scene)(ref scene)).name.ToLowerInvariant();
if (text.Contains("menu") || text.Contains("title"))
{
Log.LogDebug((object)("Menu scene detected: " + ((Scene)(ref scene)).name));
_isAuthorized = false;
_currentPlayerName = null;
}
}
private void OnApplicationQuit()
{
_applicationQuitting = true;
}
private void OnDestroy()
{
//IL_0011: 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)
SceneManager.sceneLoaded -= OnSceneLoaded;
Scene activeScene = SceneManager.GetActiveScene();
string text = ((Scene)(ref activeScene)).name ?? string.Empty;
string text2 = text.ToLowerInvariant();
if (_applicationQuitting || !Application.isPlaying || text2.Contains("menu") || text2.Contains("title"))
{
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)("[Lifecycle] Plugin OnDestroy during expected teardown (scene: " + text + ")"));
}
}
else
{
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogWarning((object)("[Lifecycle] Plugin OnDestroy outside expected teardown (scene: " + text + ")"));
}
}
}
private static void CheckAuthorization()
{
try
{
try
{
if ((Object)(object)Player.Instance != (Object)null)
{
PropertyInfo property = ((object)Player.Instance).GetType().GetProperty("PlayerName", BindingFlags.Instance | BindingFlags.Public);
if (property != null)
{
_currentPlayerName = property.GetValue(Player.Instance) as string;
}
if (string.IsNullOrEmpty(_currentPlayerName))
{
_currentPlayerName = ((Object)Player.Instance).name;
}
}
}
catch (Exception ex)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogDebug((object)("[HavenDevTools] Player name fallback: " + ex.Message));
}
_currentPlayerName = "Unknown";
}
_currentSteamId = TryGetSteamId();
if (!string.IsNullOrEmpty(_currentSteamId))
{
string text = ComputeHash(_currentSteamId);
if (_authorizedSteamIdHashes.Contains(text))
{
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogInfo((object)"[HavenDevTools] Authorized via Steam ID");
}
_isAuthorized = true;
return;
}
ManualLogSource log3 = Log;
if (log3 != null)
{
log3.LogInfo((object)("[HavenDevTools] Steam ID hash not authorized: " + text));
}
}
else
{
ManualLogSource log4 = Log;
if (log4 != null)
{
log4.LogInfo((object)"[HavenDevTools] Could not retrieve Steam ID");
}
}
ManualLogSource log5 = Log;
if (log5 != null)
{
log5.LogInfo((object)"[HavenDevTools] Not authorized - Steam ID required");
}
}
catch (Exception ex2)
{
ManualLogSource log6 = Log;
if (log6 != null)
{
log6.LogError((object)("[HavenDevTools] Authorization error: " + ex2.Message));
}
}
}
private static string TryGetSteamId()
{
try
{
Assembly assembly = null;
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly2 in assemblies)
{
string name = assembly2.GetName().Name;
if (name.Contains("rlabrecque") || name == "Steamworks.NET")
{
assembly = assembly2;
break;
}
}
if (assembly == null)
{
assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly3 in assemblies)
{
try
{
if (assembly3.GetType("Steamworks.SteamUser") != null)
{
assembly = assembly3;
break;
}
}
catch (Exception ex)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogDebug((object)("[HavenDevTools] TryGetSteamId assembly search: " + ex.Message));
}
}
}
}
if (assembly == null)
{
return null;
}
Type type = assembly.GetType("Steamworks.SteamUser");
if (type == null)
{
return null;
}
MethodInfo method = type.GetMethod("GetSteamID", BindingFlags.Static | BindingFlags.Public);
if (method == null)
{
return null;
}
object obj = method.Invoke(null, null);
if (obj == null)
{
return null;
}
string text = obj.ToString();
if (string.IsNullOrEmpty(text) || text == "0" || text.Length < 10)
{
return null;
}
return text;
}
catch (Exception ex2)
{
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogDebug((object)("[HavenDevTools] TryGetSteamId: " + ex2.Message));
}
return null;
}
}
private static string ComputeHash(string input)
{
using SHA256 sHA = SHA256.Create();
return Convert.ToBase64String(sHA.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
public static string GenerateHash(string input)
{
return ComputeHash(input);
}
public static ItemInspector GetItemInspector()
{
return _staticItemInspector;
}
public static CurrencyTracker GetCurrencyTracker()
{
return _staticCurrencyTracker;
}
public static BundleInspector GetBundleInspector()
{
return _staticBundleInspector;
}
public static RaceModifierTracker GetRaceModifierTracker()
{
return _staticRaceModifierTracker;
}
public static DebugWindow GetDebugWindow()
{
return _staticDebugWindow;
}
public static DebugOverlay GetDebugOverlay()
{
return _staticDebugOverlay;
}
public static CommandConsole GetCommandConsole()
{
return _staticCommandConsole;
}
public static LogViewerPanel GetLogViewer()
{
return _staticLogViewer;
}
public static void ToggleDebugWindow()
{
if (_isAuthorized)
{
_staticDebugWindow?.Toggle();
return;
}
CheckAuthorization();
if (_isAuthorized)
{
_staticDebugWindow?.Toggle();
}
}
public static void ToggleDebugOverlay()
{
if (_isAuthorized)
{
_staticDebugOverlay?.Toggle();
}
}
}
public class PersistentRunner : MonoBehaviour
{
private float _heartbeatTimer;
private int _heartbeatCount;
private const float HEARTBEAT_INTERVAL = 30f;
private bool _syncedTheVaultInspectorOnce;
private void Awake()
{
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[PersistentRunner] Awake - hidden persistent runner active");
}
}
private void Update()
{
if (!_syncedTheVaultInspectorOnce)
{
_syncedTheVaultInspectorOnce = true;
ModConfig.SyncTheVaultFullVaultInspectorToPlugin();
}
CheckHotkeys();
_heartbeatTimer += Time.deltaTime;
if (_heartbeatTimer >= 30f)
{
_heartbeatTimer = 0f;
_heartbeatCount++;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)string.Format("[PersistentRunner Heartbeat #{0}] Authorized: {1}, Player: {2}", _heartbeatCount, Plugin.IsAuthorized, Plugin.CurrentPlayerName ?? "none"));
}
}
}
private void CheckHotkeys()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!TextInputFocusGuard.ShouldDeferModHotkeys(Plugin.Log))
{
if (Input.GetKeyDown(Plugin.StaticToggleKey))
{
Plugin.ToggleDebugWindow();
}
if (Input.GetKeyDown(Plugin.StaticOverlayToggleKey))
{
Plugin.ToggleDebugOverlay();
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)("[PersistentRunner] Hotkey error: " + ex.Message));
}
}
}
private void OnDestroy()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
string text = (((Scene)(ref activeScene)).name ?? string.Empty).ToLowerInvariant();
if (!Application.isPlaying || text.Contains("menu") || text.Contains("title"))
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[PersistentRunner] OnDestroy during app quit/menu unload (expected).");
}
}
else
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)"[PersistentRunner] OnDestroy outside quit/menu (unexpected).");
}
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.azraelgodking.havendevtools";
public const string PLUGIN_NAME = "Haven Dev Tools";
public const string PLUGIN_VERSION = "1.2.2";
}
}
namespace HavenDevTools.UI
{
public class DebugOverlay : MonoBehaviour
{
private bool _isVisible;
private GUIStyle _overlayStyle;
private GUIStyle _labelStyle;
private GUIStyle _valueStyle;
private bool _stylesInitialized;
private float _updateTimer;
private const float UPDATE_INTERVAL = 0.5f;
private string _playerName = "";
private string _currentRace = "";
private int _gold;
private string _heldItemInfo = "";
private string _position = "";
private void Awake()
{
_isVisible = ModConfig.ShowOverlayOnStart?.Value ?? false;
}
public void Toggle()
{
_isVisible = !_isVisible;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("[DebugOverlay] " + (_isVisible ? "Shown" : "Hidden")));
}
}
public void Show()
{
_isVisible = true;
}
public void Hide()
{
_isVisible = false;
}
private void Update()
{
if (_isVisible && Plugin.IsAuthorized)
{
_updateTimer += Time.deltaTime;
if (_updateTimer >= 0.5f)
{
_updateTimer = 0f;
UpdateCachedData();
}
}
}
private void UpdateCachedData()
{
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
try
{
_playerName = Plugin.CurrentPlayerName ?? "Unknown";
_currentRace = Plugin.GetRaceModifierTracker()?.GetCurrentRace() ?? "Unknown";
_gold = Plugin.GetCurrencyTracker()?.GetGold() ?? 0;
(int, string)? tuple = Plugin.GetItemInspector()?.GetHeldItem();
_heldItemInfo = (tuple.HasValue ? $"{tuple.Value.Item2} ({tuple.Value.Item1})" : "None");
if ((Object)(object)Player.Instance != (Object)null)
{
Vector3 position = ((Component)Player.Instance).transform.position;
_position = $"({position.x:F1}, {position.y:F1})";
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[DebugOverlay] Update error: " + ex.Message));
}
}
}
private void OnGUI()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
if (_isVisible && Plugin.IsAuthorized)
{
InitializeStyles();
OverlayPositionType overlayPosition = ModConfig.GetOverlayPosition();
Rect overlayRect = GetOverlayRect(overlayPosition);
GUI.Box(overlayRect, "", _overlayStyle);
GUILayout.BeginArea(new Rect(((Rect)(ref overlayRect)).x + 8f, ((Rect)(ref overlayRect)).y + 8f, ((Rect)(ref overlayRect)).width - 16f, ((Rect)(ref overlayRect)).height - 16f));
DrawOverlayContent();
GUILayout.EndArea();
}
}
private void InitializeStyles()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0028: 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_0059: Expected O, but got Unknown
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Expected O, but got Unknown
//IL_00a0: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: 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_00d8: Expected O, but got Unknown
if (!_stylesInitialized)
{
Texture2D val = new Texture2D(1, 1);
val.SetPixel(0, 0, new Color(0.05f, 0.05f, 0.1f, 0.85f));
val.Apply();
GUIStyle val2 = new GUIStyle(GUI.skin.box);
val2.normal.background = val;
_overlayStyle = val2;
GUIStyle val3 = new GUIStyle(GUI.skin.label)
{
fontSize = 11
};
val3.normal.textColor = new Color(0.7f, 0.7f, 0.8f);
_labelStyle = val3;
GUIStyle val4 = new GUIStyle(GUI.skin.label)
{
fontSize = 11,
fontStyle = (FontStyle)1
};
val4.normal.textColor = new Color(0.9f, 0.95f, 1f);
_valueStyle = val4;
_stylesInitialized = true;
}
}
private Rect GetOverlayRect(OverlayPositionType position)
{
//IL_0049: 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_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: 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_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
float num = 220f;
ConfigEntry<bool> showPerformance = ModConfig.ShowPerformance;
float num2 = ((showPerformance == null || showPerformance.Value) ? 155 : 130);
float num3 = 10f;
return (Rect)(position switch
{
OverlayPositionType.TopLeft => new Rect(num3, num3, num, num2),
OverlayPositionType.TopRight => new Rect((float)Screen.width - num - num3, num3, num, num2),
OverlayPositionType.BottomLeft => new Rect(num3, (float)Screen.height - num2 - num3, num, num2),
OverlayPositionType.BottomRight => new Rect((float)Screen.width - num - num3, (float)Screen.height - num2 - num3, num, num2),
_ => new Rect((float)Screen.width - num - num3, num3, num, num2),
});
}
private void DrawOverlayContent()
{
GUILayout.Label("Haven Dev Tools", _valueStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(3f);
DrawRow("Player:", _playerName);
DrawRow("Race:", _currentRace);
DrawRow("Gold:", _gold.ToString("N0"));
DrawRow("Position:", _position);
DrawRow("Held:", _heldItemInfo);
ConfigEntry<bool> showPerformance = ModConfig.ShowPerformance;
if (showPerformance == null || showPerformance.Value)
{
float num = 1f / Mathf.Max(0.0001f, Time.deltaTime);
float num2 = (float)GC.GetTotalMemory(forceFullCollection: false) / 1048576f;
DrawRow("FPS:", num.ToString("F1"));
DrawRow("Memory:", $"{num2:F1} MB");
}
GUILayout.FlexibleSpace();
GUILayout.Label("F11: Window | F6: Toggle", _labelStyle, Array.Empty<GUILayoutOption>());
}
private void DrawRow(string label, string value)
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label(label, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) });
GUILayout.Label(value, _valueStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndHorizontal();
}
}
public class DebugWindow : MonoBehaviour
{
private bool _isVisible;
private Rect _windowRect;
private Vector2 _scrollPosition;
private GUIStyle _windowStyle;
private GUIStyle _headerStyle;
private GUIStyle _sectionHeaderStyle;
private GUIStyle _buttonStyle;
private GUIStyle _labelStyle;
private GUIStyle _textFieldStyle;
private GUIStyle _boxStyle;
private bool _stylesInitialized;
private int _selectedTab;
private readonly string[] _tabNames = new string[3] { "Tools", "Azrael's Mods", "Extensions" };
private int _toolsSubTab;
private readonly string[] _toolsSubTabNames = new string[6] { "Items", "Currencies", "Console", "Log", "Perf", "Utility" };
private string _itemSearchText = "";
private string _lastItemSearchQuery;
private string _itemIdInput = "";
private string _spawnAmount = "1";
private int _selectedItemId;
private string _selectedItemName = "";
private List<KeyValuePair<int, string>> _searchResults = new List<KeyValuePair<int, string>>();
private Vector2 _itemScrollPosition;
private Vector2 _currencyScrollPosition;
private int _selectedSectionIndex;
private int _selectedBundleIndex;
private Vector2 _bundleScrollPosition;
private int _selectedRaceIndex;
private Vector2 _raceScrollPosition;
private static Dictionary<string, VersionChecker.VersionCheckResult> _versionResults = new Dictionary<string, VersionChecker.VersionCheckResult>();
private static bool _isCheckingVersions;
private Vector2 _versionScrollPosition;
private static readonly (string guid, string name, string version)[] _knownMods = new(string, string, string)[12]
{
("com.azraelgodking.havendevtools", "Haven Dev Tools", "1.2.2"),
("com.azraelgodking.senpaischest", "Senpai's Chest", "2.6.2"),
("com.azraelgodking.squirrelsbirthdayreminder", "Birthday Reminder", "1.4.2"),
("com.azraelgodking.havensbirthright", "Haven's Birthright", "2.2.2"),
("com.azraelgodking.sunhavenmuseumutilitytracker", "S.M.U.T.", "2.4.2"),
("com.azraelgodking.sunhaventodo", "Sunhaven Todo", "1.4.2"),
("com.azraelgodking.thevault", "The Vault", "3.3.2"),
("com.azraelgodking.havensalmanac", "Haven's Almanac", "1.4.2"),
("com.azraelgodking.fasterraces", "Faster Races", "1.4.2"),
("com.azraelgodking.trinketfortune", "Trinket Fortune", "1.2.2"),
("com.azraelgodking.cropoptimizer", "Crop Optimizer", "1.4.2"),
("com.azraelgodking.havensrespec", "Haven's Respec", "1.3.2")
};
private const string PAUSE_ID = "HavenDevTools_Debug";
private void Awake()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
_windowRect = new Rect(50f, 50f, 500f, 600f);
}
public void Toggle()
{
if (_isVisible)
{
Hide();
}
else
{
Show();
}
}
public void Show()
{
_isVisible = true;
BlockInput();
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[DebugWindow] Shown");
}
}
public void Hide()
{
_isVisible = false;
UnblockInput();
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[DebugWindow] Hidden");
}
}
private void BlockInput()
{
try
{
if ((Object)(object)Player.Instance != (Object)null)
{
Player.Instance.AddPauseObject("HavenDevTools_Debug");
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[DebugWindow] Could not block input: " + ex.Message));
}
}
}
private void UnblockInput()
{
try
{
if ((Object)(object)Player.Instance != (Object)null)
{
Player.Instance.RemovePauseObject("HavenDevTools_Debug");
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[DebugWindow] Could not unblock input: " + ex.Message));
}
}
}
private void Update()
{
if (_isVisible && Input.GetKeyDown((KeyCode)27))
{
Hide();
}
}
private void OnGUI()
{
//IL_001e: 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_003f: Expected O, but got Unknown
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
if (_isVisible && Plugin.IsAuthorized)
{
InitializeStyles();
_windowRect = GUI.Window(((object)this).GetHashCode(), _windowRect, new WindowFunction(DrawWindow), "", _windowStyle);
}
}
private void InitializeStyles()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Expected O, but got Unknown
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Expected O, but got Unknown
//IL_0109: Expected O, but got Unknown
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: 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_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Expected O, but got Unknown
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Expected O, but got Unknown
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Expected O, but got Unknown
//IL_01fa: Expected O, but got Unknown
//IL_0205: Unknown result type (might be due to invalid IL or missing references)
//IL_020a: Unknown result type (might be due to invalid IL or missing references)
//IL_0212: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Unknown result type (might be due to invalid IL or missing references)
//IL_0236: Expected O, but got Unknown
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
//IL_0246: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0254: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Expected O, but got Unknown
//IL_026e: Unknown result type (might be due to invalid IL or missing references)
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_0284: Expected O, but got Unknown
if (!_stylesInitialized)
{
Texture2D val = new Texture2D(1, 1);
val.SetPixel(0, 0, new Color(0.08f, 0.08f, 0.12f, 0.98f));
val.Apply();
Texture2D val2 = new Texture2D(1, 1);
val2.SetPixel(0, 0, new Color(0.2f, 0.4f, 0.6f, 0.9f));
val2.Apply();
Texture2D val3 = new Texture2D(1, 1);
val3.SetPixel(0, 0, new Color(0.3f, 0.5f, 0.7f, 0.95f));
val3.Apply();
Texture2D val4 = new Texture2D(1, 1);
val4.SetPixel(0, 0, new Color(0.12f, 0.12f, 0.18f, 0.9f));
val4.Apply();
GUIStyle val5 = new GUIStyle(GUI.skin.window);
val5.normal.background = val;
val5.normal.textColor = Color.white;
val5.padding = new RectOffset(10, 10, 25, 10);
_windowStyle = val5;
GUIStyle val6 = new GUIStyle(GUI.skin.label)
{
fontSize = 18,
fontStyle = (FontStyle)1,
alignment = (TextAnchor)4
};
val6.normal.textColor = new Color(0.4f, 0.8f, 1f);
_headerStyle = val6;
GUIStyle val7 = new GUIStyle(GUI.skin.label)
{
fontSize = 14,
fontStyle = (FontStyle)1
};
val7.normal.textColor = new Color(0.8f, 0.9f, 1f);
_sectionHeaderStyle = val7;
GUIStyle val8 = new GUIStyle(GUI.skin.button)
{
fontSize = 12
};
val8.normal.background = val2;
val8.normal.textColor = Color.white;
val8.hover.background = val3;
val8.hover.textColor = Color.white;
val8.padding = new RectOffset(8, 8, 4, 4);
_buttonStyle = val8;
GUIStyle val9 = new GUIStyle(GUI.skin.label)
{
fontSize = 12
};
val9.normal.textColor = new Color(0.9f, 0.9f, 0.95f);
_labelStyle = val9;
GUIStyle val10 = new GUIStyle(GUI.skin.textField)
{
fontSize = 12
};
val10.normal.textColor = Color.white;
_textFieldStyle = val10;
GUIStyle val11 = new GUIStyle(GUI.skin.box);
val11.normal.background = val4;
_boxStyle = val11;
_stylesInitialized = true;
}
}
private void DrawWindow(int windowId)
{
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_023a: Unknown result type (might be due to invalid IL or missing references)
GUILayout.Label("Haven Dev Tools", _headerStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Player: " + Plugin.CurrentPlayerName, _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label("TheVault: " + (Plugin.HasTheVault ? "Yes" : "No"), _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
GUILayout.Label("SMUT: " + (Plugin.HasSMUT ? "Yes" : "No"), _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
GUILayout.Label("Birthright: " + (Plugin.HasHavensBirthright ? "Yes" : "No"), _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
GUILayout.Label("Senpai: " + (Plugin.HasSenpaisChest ? "Yes" : "No"), _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
GUILayout.Label("Todo: " + (Plugin.HasSunhavenTodo ? "Yes" : "No"), _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndHorizontal();
GUILayout.Space(10f);
_selectedTab = GUILayout.Toolbar(_selectedTab, _tabNames, _buttonStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
_scrollPosition = GUILayout.BeginScrollView(_scrollPosition, Array.Empty<GUILayoutOption>());
switch (_selectedTab)
{
case 0:
DrawToolsTab();
break;
case 1:
AzraelsModsPanel.Draw(_boxStyle, _buttonStyle, _labelStyle, _sectionHeaderStyle);
break;
case 2:
DrawExtensionsTab();
break;
}
GUILayout.EndScrollView();
GUILayout.Space(10f);
if (GUILayout.Button("Close (Esc)", _buttonStyle, Array.Empty<GUILayoutOption>()))
{
Hide();
}
GUI.DragWindow(new Rect(0f, 0f, 500f, 30f));
}
private void DrawExtensionsTab()
{
IReadOnlyList<IDevToolsPanel> panels = DevToolsRegistry.Panels;
if (panels.Count == 0)
{
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Extensions", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
GUILayout.Label("No extension panels registered. Mods can implement IDevToolsPanel and call DevToolsRegistry.Register() to add panels here.", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
return;
}
HashSet<string> hashSet = new HashSet<string> { "com.azraelgodking.trinketfortune" };
foreach (IDevToolsPanel item in panels)
{
if (!hashSet.Contains(item.ModGuid))
{
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label(item.DisplayName, _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
try
{
item.Draw(_boxStyle, _buttonStyle, _labelStyle);
}
catch (Exception ex)
{
GUILayout.Label("Error: " + ex.Message, _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.EndVertical();
GUILayout.Space(8f);
}
}
}
private void DrawToolsTab()
{
_toolsSubTab = GUILayout.Toolbar(_toolsSubTab, _toolsSubTabNames, _buttonStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(8f);
switch (_toolsSubTab)
{
case 0:
DrawItemsTab();
break;
case 1:
DrawCurrenciesTab();
break;
case 2:
DrawConsoleTab();
break;
case 3:
DrawLogViewerTab();
break;
case 4:
DrawPerformanceTab();
break;
case 5:
DrawUtilityTab();
break;
}
}
private void DrawConsoleTab()
{
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Command Console", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
GUILayout.Label("Type commands and press Enter. Supported: spawn, tp, time.set, reload.config", _labelStyle, Array.Empty<GUILayoutOption>());
CommandConsole commandConsole = Plugin.GetCommandConsole();
if (commandConsole != null)
{
commandConsole.Draw(_boxStyle, _buttonStyle, _labelStyle, _textFieldStyle);
}
else
{
GUILayout.Label("(Console service initializing...)", _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.EndVertical();
}
private void DrawLogViewerTab()
{
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Log Viewer", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
LogViewerPanel logViewer = Plugin.GetLogViewer();
if (logViewer != null)
{
logViewer.Draw(_boxStyle, _buttonStyle, _labelStyle);
}
else
{
GUILayout.Label("(Log viewer initializing...)", _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.EndVertical();
}
private void DrawPerformanceTab()
{
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Performance", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
float num = 1f / Mathf.Max(0.0001f, Time.deltaTime);
float num2 = (float)GC.GetTotalMemory(forceFullCollection: false) / 1048576f;
GUILayout.Label($"FPS: {num:F1}", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label($"Memory: {num2:F1} MB", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("(Also shown in overlay when ShowPerformance is enabled)", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
}
private void DrawItemsTab()
{
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Item Inspector", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
(int, string)? tuple = Plugin.GetItemInspector()?.GetHeldItem();
if (tuple.HasValue)
{
GUILayout.Label($"Held: {tuple.Value.Item2} ({tuple.Value.Item1})", _labelStyle, Array.Empty<GUILayoutOption>());
}
else
{
GUILayout.Label("Held: None", _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
GUILayout.Label("Search:", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
_itemSearchText = GUILayout.TextField(_itemSearchText, _textFieldStyle, Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Clear", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }))
{
_itemSearchText = "";
_lastItemSearchQuery = "";
_searchResults.Clear();
}
GUILayout.EndHorizontal();
if (_itemSearchText != _lastItemSearchQuery)
{
_lastItemSearchQuery = _itemSearchText;
_searchResults = ItemSearch.SearchItems(_itemSearchText);
}
if (_selectedItemId > 0)
{
GUILayout.Space(2f);
GUILayout.Label("Selected: " + ItemSearch.FormatDisplay(_selectedItemName, _selectedItemId), _labelStyle, Array.Empty<GUILayoutOption>());
}
if (_searchResults.Count > 0)
{
GUILayout.Space(4f);
float num = Mathf.Min(180, 24 + _searchResults.Count * 22);
_itemScrollPosition = GUILayout.BeginScrollView(_itemScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num) });
foreach (KeyValuePair<int, string> searchResult in _searchResults)
{
if (GUILayout.Button(ItemSearch.FormatDisplay(searchResult.Value, searchResult.Key), (searchResult.Key == _selectedItemId) ? _buttonStyle : _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }))
{
_selectedItemId = searchResult.Key;
_selectedItemName = searchResult.Value;
_itemIdInput = searchResult.Key.ToString();
}
}
GUILayout.EndScrollView();
}
else if (_itemSearchText.Length >= 2)
{
GUILayout.Space(2f);
GUILayout.Label("No items found.", _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
GUILayout.Label("Spawn:", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label("ID:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(22f) });
_itemIdInput = GUILayout.TextField(_itemIdInput, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) });
GUILayout.Label("Qty:", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) });
_spawnAmount = GUILayout.TextField(_spawnAmount, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
if (GUILayout.Button("1", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(22f) }))
{
_spawnAmount = "1";
}
if (GUILayout.Button("10", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }))
{
_spawnAmount = "10";
}
if (GUILayout.Button("99", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }))
{
_spawnAmount = "99";
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Spawn to Inventory", _buttonStyle, Array.Empty<GUILayoutOption>()) && int.TryParse(_itemIdInput, out var result) && int.TryParse(_spawnAmount, out var result2) && result2 > 0)
{
Plugin.GetItemInspector()?.SpawnItem(result, result2);
}
if (_selectedItemId > 0 && GUILayout.Button("Spawn 1", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
{
Plugin.GetItemInspector()?.SpawnItem(_selectedItemId);
}
GUILayout.EndHorizontal();
GUILayout.EndVertical();
}
private void DrawCurrenciesTab()
{
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Currency Tracker", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
CurrencyTracker currencyTracker = Plugin.GetCurrencyTracker();
if (currencyTracker == null)
{
GUILayout.Label("Currency tracker not available", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
return;
}
CurrencySummary summary = currencyTracker.GetSummary();
GUILayout.Label($"Gold: {summary.Gold:N0}", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label($"Orbs: {summary.Orbs:N0}", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label($"Tickets: {summary.Tickets:N0}", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
GUILayout.Label("Inventory Currencies:", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
_currencyScrollPosition = GUILayout.BeginScrollView(_currencyScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(120f) });
if (summary.InventoryCurrencies.Count == 0)
{
GUILayout.Label(" (none)", _labelStyle, Array.Empty<GUILayoutOption>());
}
else
{
foreach (KeyValuePair<string, int> inventoryCurrency in summary.InventoryCurrencies)
{
GUILayout.Label($" {inventoryCurrency.Key}: {inventoryCurrency.Value}", _labelStyle, Array.Empty<GUILayoutOption>());
}
}
GUILayout.EndScrollView();
if (Plugin.HasTheVault)
{
GUILayout.Space(10f);
GUILayout.Label("Vault Currencies:", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
if (summary.VaultCurrencies.Count == 0)
{
GUILayout.Label(" (vault empty)", _labelStyle, Array.Empty<GUILayoutOption>());
}
else
{
foreach (KeyValuePair<string, int> vaultCurrency in summary.VaultCurrencies)
{
GUILayout.Label($" {vaultCurrency.Key}: {vaultCurrency.Value}", _labelStyle, Array.Empty<GUILayoutOption>());
}
}
}
else
{
GUILayout.Space(5f);
GUILayout.Label("(The Vault not installed)", _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.EndVertical();
}
private void DrawBundlesTab()
{
//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Museum Bundle Inspector", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
if (!Plugin.HasSMUT)
{
GUILayout.Label("S.M.U.T. not installed", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
return;
}
BundleInspector bundleInspector = Plugin.GetBundleInspector();
if (bundleInspector == null)
{
GUILayout.Label("Bundle inspector not available", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
return;
}
DonationStats donationStats = bundleInspector.GetDonationStats();
if (donationStats.IsLoaded)
{
GUILayout.Label("Character: " + donationStats.CharacterName, _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label($"Progress: {donationStats.TotalDonated}/{donationStats.TotalItems} ({donationStats.CompletionPercent:F1}%)", _labelStyle, Array.Empty<GUILayoutOption>());
}
else
{
GUILayout.Label("Donation data not loaded", _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
List<MuseumSectionInfo> allSections = bundleInspector.GetAllSections();
if (allSections.Count == 0)
{
GUILayout.Label("No museum data available", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
return;
}
string[] array = new string[allSections.Count];
for (int i = 0; i < allSections.Count; i++)
{
array[i] = allSections[i].Name;
}
GUILayout.Label("Section:", _labelStyle, Array.Empty<GUILayoutOption>());
_selectedSectionIndex = GUILayout.SelectionGrid(_selectedSectionIndex, array, 3, _buttonStyle, Array.Empty<GUILayoutOption>());
if (_selectedSectionIndex >= allSections.Count)
{
_selectedSectionIndex = 0;
}
MuseumSectionInfo museumSectionInfo = allSections[_selectedSectionIndex];
GUILayout.Space(5f);
if (museumSectionInfo.Bundles.Count > 0)
{
string[] array2 = new string[museumSectionInfo.Bundles.Count];
for (int j = 0; j < museumSectionInfo.Bundles.Count; j++)
{
array2[j] = museumSectionInfo.Bundles[j].Name;
}
if (_selectedBundleIndex >= museumSectionInfo.Bundles.Count)
{
_selectedBundleIndex = 0;
}
GUILayout.Label("Bundle:", _labelStyle, Array.Empty<GUILayoutOption>());
_selectedBundleIndex = GUILayout.SelectionGrid(_selectedBundleIndex, array2, 2, _buttonStyle, Array.Empty<GUILayoutOption>());
MuseumBundleInfo museumBundleInfo = museumSectionInfo.Bundles[_selectedBundleIndex];
GUILayout.Space(5f);
GUILayout.Label("Items in " + museumBundleInfo.Name + ":", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
_bundleScrollPosition = GUILayout.BeginScrollView(_bundleScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(150f) });
foreach (MuseumItemInfo item in museumBundleInfo.Items)
{
string arg = (bundleInspector.HasDonated(item.Id) ? "[X]" : "[ ]");
string text = ((item.Quantity > 1) ? $" x{item.Quantity}" : "");
bool flag = item.GameItemId > 0;
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label($"{arg} {item.Name} (ID: {item.GameItemId})", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(320f) });
bool enabled = GUI.enabled;
GUI.enabled = flag;
if (GUILayout.Button(flag ? ("Spawn" + text) : "—", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }) && flag)
{
Plugin.GetItemInspector()?.SpawnItem(item.GameItemId, item.Quantity);
}
GUI.enabled = enabled;
if (!flag)
{
GUILayout.Label("(ID in Unity assets)", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
}
GUILayout.EndHorizontal();
}
GUILayout.EndScrollView();
}
GUILayout.EndVertical();
}
private void DrawRaceBonusesTab()
{
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Race Modifier Tracker", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
RaceModifierTracker raceModifierTracker = Plugin.GetRaceModifierTracker();
if (raceModifierTracker == null)
{
GUILayout.Label("Race tracker not available", _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
return;
}
string currentRace = raceModifierTracker.GetCurrentRace();
GUILayout.Label("Current Race: " + currentRace, _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
if (Plugin.HasHavensBirthright)
{
List<RaceBonusInfo> activeRaceBonuses = raceModifierTracker.GetActiveRaceBonuses();
GUILayout.Label("Active Bonuses:", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
if (activeRaceBonuses.Count == 0)
{
GUILayout.Label(" (no bonuses active)", _labelStyle, Array.Empty<GUILayoutOption>());
}
else
{
foreach (RaceBonusInfo item in activeRaceBonuses)
{
GUILayout.Label(" " + item.Type + ": " + item.GetFormattedValue(), _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label(" " + item.Description, _labelStyle, Array.Empty<GUILayoutOption>());
}
}
}
else
{
GUILayout.Label("Haven's Birthright not installed", _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
GUILayout.Label("Browse Race Bonuses:", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
List<string> allRaces = raceModifierTracker.GetAllRaces();
if (allRaces.Count > 0)
{
string[] array = allRaces.ToArray();
if (_selectedRaceIndex >= allRaces.Count)
{
_selectedRaceIndex = 0;
}
_selectedRaceIndex = GUILayout.SelectionGrid(_selectedRaceIndex, array, 4, _buttonStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
List<RaceBonusInfo> bonusesForRace = raceModifierTracker.GetBonusesForRace(allRaces[_selectedRaceIndex]);
_raceScrollPosition = GUILayout.BeginScrollView(_raceScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(150f) });
if (bonusesForRace.Count == 0)
{
GUILayout.Label(" (no bonuses defined)", _labelStyle, Array.Empty<GUILayoutOption>());
}
else
{
foreach (RaceBonusInfo item2 in bonusesForRace)
{
GUILayout.Label(" " + item2.Type + ": " + item2.GetFormattedValue(), _labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label(" " + item2.Description, _labelStyle, Array.Empty<GUILayoutOption>());
}
}
GUILayout.EndScrollView();
}
GUILayout.EndVertical();
}
private void DrawUtilityTab()
{
GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Utility", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
DrawVersionCheckerSection();
GUILayout.Space(10f);
GUILayout.Label("Config:", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Reload HavenDevTools Config", _buttonStyle, Array.Empty<GUILayoutOption>()))
{
ConfigReloader.ReloadHavenDevToolsConfig();
}
GUILayout.Space(10f);
GUILayout.Label("Logging:", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Log All Currency IDs", _buttonStyle, Array.Empty<GUILayoutOption>()))
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"=== Currency Item IDs ===");
}
foreach (KeyValuePair<string, int> currencyItemId in CurrencyTracker.CurrencyItemIds)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)$" {currencyItemId.Key}: {currencyItemId.Value}");
}
}
}
if (GUILayout.Button("Log Player Stats", _buttonStyle, Array.Empty<GUILayoutOption>()))
{
LogPlayerStats();
}
GUILayout.Space(10f);
GUILayout.Label("Authorization Hash Generator:", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Label("Use this to generate hashes for new authorized Steam IDs", _labelStyle, Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Log Current Steam ID Hash", _buttonStyle, Array.Empty<GUILayoutOption>()))
{
try
{
string text = typeof(Plugin).GetMethod("TryGetSteamId", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, null) as string;
if (!string.IsNullOrEmpty(text))
{
string text2 = Plugin.GenerateHash(text);
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)("Steam ID: " + text));
}
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogInfo((object)("Steam ID Hash: " + text2));
}
}
else
{
ManualLogSource log5 = Plugin.Log;
if (log5 != null)
{
log5.LogWarning((object)"Could not retrieve Steam ID");
}
}
}
catch (Exception ex)
{
ManualLogSource log6 = Plugin.Log;
if (log6 != null)
{
log6.LogError((object)("Error generating hash: " + ex.Message));
}
}
}
GUILayout.EndVertical();
}
private void DrawVersionCheckerSection()
{
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Expected O, but got Unknown
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0202: Expected O, but got Unknown
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Expected O, but got Unknown
GUILayout.Label("Version Checker:", _sectionHeaderStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(3f);
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUI.enabled = !_isCheckingVersions;
if (GUILayout.Button(_isCheckingVersions ? "Checking..." : "Check All Mod Versions", _buttonStyle, Array.Empty<GUILayoutOption>()))
{
CheckAllModVersions();
}
GUI.enabled = true;
if (GUILayout.Button("Test Notification", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
{
TestUpdateNotification();
}
GUILayout.EndHorizontal();
GUILayout.Space(5f);
_versionScrollPosition = GUILayout.BeginScrollView(_versionScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(140f) });
(string, string, string)[] knownMods = _knownMods;
for (int i = 0; i < knownMods.Length; i++)
{
(string, string, string) tuple = knownMods[i];
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label(tuple.Item2 + " v" + tuple.Item3, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) });
if (_versionResults.TryGetValue(tuple.Item1, out VersionChecker.VersionCheckResult value))
{
if (!value.Success)
{
GUIStyle val = new GUIStyle(_labelStyle);
val.normal.textColor = new Color(1f, 0.5f, 0.5f);
GUIStyle val2 = val;
GUILayout.Label("Error: " + value.ErrorMessage, val2, Array.Empty<GUILayoutOption>());
}
else if (value.UpdateAvailable)
{
GUIStyle val3 = new GUIStyle(_labelStyle);
val3.normal.textColor = new Color(1f, 0.9f, 0.3f);
GUIStyle val4 = val3;
GUILayout.Label("Update: v" + value.LatestVersion, val4, Array.Empty<GUILayoutOption>());
}
else
{
GUIStyle val5 = new GUIStyle(_labelStyle);
val5.normal.textColor = new Color(0.5f, 1f, 0.5f);
GUIStyle val6 = val5;
GUILayout.Label("Up to date", val6, Array.Empty<GUILayoutOption>());
}
}
else
{
GUILayout.Label("Not checked", _labelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.EndHorizontal();
}
GUILayout.EndScrollView();
}
private void CheckAllModVersions()
{
_isCheckingVersions = true;
_versionResults.Clear();
int pendingChecks = _knownMods.Length;
(string, string, string)[] knownMods = _knownMods;
for (int i = 0; i < knownMods.Length; i++)
{
(string guid, string name, string version) mod = knownMods[i];
VersionChecker.CheckForUpdate(mod.guid, mod.version, Plugin.Log, delegate(VersionChecker.VersionCheckResult result)
{
_versionResults[mod.guid] = result;
int num = pendingChecks;
pendingChecks = num - 1;
if (pendingChecks <= 0)
{
_isCheckingVersions = false;
}
if (result.Success)
{
if (result.UpdateAvailable)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("[VersionChecker] " + mod.name + ": Update available v" + result.LatestVersion));
}
}
else
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("[VersionChecker] " + mod.name + ": Up to date (v" + mod.version + ")"));
}
}
}
else
{
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogWarning((object)("[VersionChecker] " + mod.name + ": " + result.ErrorMessage));
}
}
});
}
}
private void TestUpdateNotification()
{
VersionChecker.VersionCheckResult result = new VersionChecker.VersionCheckResult
{
Success = true,
UpdateAvailable = true,
CurrentVersion = "1.0.0",
LatestVersion = "9.9.9",
ModName = "Test Mod (HavenDevTools)",
NexusUrl = "https://www.nexusmods.com/sunhaven"
};
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[VersionChecker] Testing notification system...");
}
result.NotifyUpdateAvailable(Plugin.Log);
}
private void LogPlayerStats()
{
try
{
if ((Object)(object)Player.Instance == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"Player not available");
}
return;
}
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)"=== Player Stats ===");
}
PropertyInfo[] properties = ((object)Player.Instance).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo propertyInfo in properties)
{
try
{
if (!propertyInfo.CanRead || propertyInfo.GetIndexParameters().Length != 0)
{
continue;
}
object value = propertyInfo.GetValue(Player.Instance);
if (value != null && (value is int || value is float || value is string || value is bool))
{
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)$" {propertyInfo.Name}: {value}");
}
}
}
catch (Exception ex)
{
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogDebug((object)("[DebugWindow] Player stats property iteration: " + ex.Message));
}
}
}
}
catch (Exception ex2)
{
ManualLogSource log5 = Plugin.Log;
if (log5 != null)
{
log5.LogError((object)("Error logging player stats: " + ex2.Message));
}
}
}
}
public class LogViewerPanel
{
private class LogCaptureListener : ILogListener, IDisposable
{
public void LogEvent(object sender, LogEventArgs eventArgs)
{
OnLog(eventArgs);
}
public void Dispose()
{
}
}
private class LogEntry
{
public int Level;
public string Message;
public string Source;
public DateTime Timestamp;
}
private static readonly List<LogEntry> _entries = new List<LogEntry>();
private static readonly object _lock = new object();
private Vector2 _scrollPosition;
private int _levelFilterIndex = 1;
private static readonly string[] _levelNames = new string[4] { "Debug", "Info", "Warning", "Error" };
private static bool _listenerAttached;
private static readonly LogCaptureListener _captureListener = new LogCaptureListener();
public LogViewerPanel()
{
if (!_listenerAttached)
{
Logger.Listeners.Add((ILogListener)(object)_captureListener);
_listenerAttached = true;
}
}
private static void OnLog(LogEventArgs e)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//I