using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("DPS_Overlay")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DPS_Overlay")]
[assembly: AssemblyTitle("DPS_Overlay")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("com.zelevlin.dps", "DPS_Overlay", "1.0.0")]
public sealed class Plugin : BasePlugin
{
internal static ManualLogSource LogSrc;
internal static Harmony Harmony;
internal static bool EnableUnitBaseSetHitResultHook = true;
internal static Type FindTypeByName(string fullName)
{
string[] array = new string[8] { "UnityEditor", "BepInEx", "0Harmony", "Harmony", "System", "mscorlib", "netstandard", "Mono." };
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
string name = assembly.GetName().Name;
bool flag = false;
string[] array2 = array;
foreach (string value in array2)
{
if (name.StartsWith(value, StringComparison.OrdinalIgnoreCase))
{
flag = true;
break;
}
}
if (flag)
{
continue;
}
try
{
Type type = assembly.GetType(fullName, throwOnError: false);
if (type != null)
{
return type;
}
}
catch
{
}
}
return null;
}
public override void Load()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
LogSrc = ((BasePlugin)this).Log;
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loaded ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("DPS_Overlay");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
}
log.LogInfo(val);
try
{
FileLogger.Init();
FileLogger.LogInfo("Loaded DPS_Overlay v1.0.0");
}
catch
{
}
try
{
Harmony = new Harmony("com.zelevlin.dps");
PatchCanvasPulse();
if (EnableUnitBaseSetHitResultHook)
{
PatchUnitBaseSetHitResult();
}
else
{
LogSrc.LogInfo((object)"UnitBase.setHitResult hook disabled by flag");
FileLogger.LogInfo("UnitBase.setHitResult hook disabled by flag");
}
LogSrc.LogInfo((object)"Init finished");
FileLogger.LogInfo("Init finished");
}
catch (Exception ex)
{
ManualLogSource logSrc = LogSrc;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(18, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Load() exception: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
}
logSrc.LogError(val2);
FileLogger.LogError($"Load() exception: {ex}");
}
}
private static void PatchCanvasPulse()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(CanvasUpdateRegistry), "PerformUpdate", (Type[])null, (Type[])null);
if (methodInfo == null)
{
LogSrc.LogWarning((object)"CanvasUpdateRegistry.PerformUpdate not found");
FileLogger.LogWarning("CanvasUpdateRegistry.PerformUpdate not found");
return;
}
HarmonyMethod val = new HarmonyMethod(typeof(Pulse).GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public));
Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
LogSrc.LogInfo((object)"Patched pulse: CanvasUpdateRegistry.PerformUpdate()");
FileLogger.LogInfo("Patched pulse: CanvasUpdateRegistry.PerformUpdate()");
}
private static void PatchUnitBaseSetHitResult()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Expected O, but got Unknown
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Expected O, but got Unknown
string[] obj = new string[2] { "P2.Game.Unit.UnitBase", "P2S.Game.Unit.UnitBase" };
Type type = null;
string[] array = obj;
bool flag = default(bool);
for (int i = 0; i < array.Length; i++)
{
type = FindTypeByName(array[i]);
if (type != null)
{
ManualLogSource logSrc = LogSrc;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Found UnitBase: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.FullName);
}
logSrc.LogInfo(val);
FileLogger.LogInfo("Found UnitBase: " + type.FullName);
break;
}
}
if (type == null)
{
LogSrc.LogWarning((object)"UnitBase type not found, skipping UnitBase.setHitResult hook");
FileLogger.LogWarning("UnitBase type not found, skipping UnitBase.setHitResult hook");
return;
}
int num = 0;
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (!methodInfo.Name.Equals("setHitResult", StringComparison.Ordinal))
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters != null && parameters.Length == 1 && parameters[0].ParameterType.Name.Contains("HitResult", StringComparison.Ordinal))
{
HarmonyMethod val2 = new HarmonyMethod(typeof(DamageHooks).GetMethod("UnitBaseSetHitResult_Postfix", BindingFlags.Static | BindingFlags.Public));
Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
num++;
ManualLogSource logSrc2 = LogSrc;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Patched FINAL dmg (backup): ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodInfo.DeclaringType.FullName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodInfo.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(parameters[0].ParameterType.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
}
logSrc2.LogInfo(val);
FileLogger.LogInfo($"Patched FINAL dmg (backup): {methodInfo.DeclaringType.FullName}.{methodInfo.Name}({parameters[0].ParameterType.Name})");
}
}
if (num == 0)
{
LogSrc.LogWarning((object)"No matching UnitBase.setHitResult(HitResult) methods patched");
}
FileLogger.LogWarning("No matching UnitBase.setHitResult(HitResult) methods patched");
}
}
public static class Pulse
{
private struct DmgEvt
{
public float t;
public int dmg;
public bool crit;
public DmgEvt(float t, int dmg, bool crit)
{
this.t = t;
this.dmg = dmg;
this.crit = crit;
}
}
private const float WindowSeconds = 1f;
private const float ZeroDelaySeconds = 2.5f;
private static bool EnableTabToggle = false;
public const bool REQUIRE_HITINFO_ISENEMY_TRUE = true;
private static bool _created;
private static GameObject _canvasGo;
private static Text _text;
private static float _lastUiUpdate;
private static bool _wasInBattle;
private static bool _forceShowOverlay;
private static Type _inputTypeCached;
private static Type _keyCodeTypeCached;
private static bool _inputTypesAttempted;
private static readonly List<DmgEvt> _events = new List<DmgEvt>();
private static int _last1Damage;
private static bool _last1Crit;
private static int _last2Damage;
private static bool _last2Crit;
private static float _peakDps;
private static float _lastNonZeroDps;
private static float _lastDamageTime;
private static int _top1Hit;
private static bool _top1Crit;
private static int _top2Hit;
private static bool _top2Crit;
public static void AddFinalDamage(int damage, bool isCrit, bool isShield)
{
if (damage > 0)
{
float realtimeSinceStartup = Time.realtimeSinceStartup;
_events.Add(new DmgEvt(realtimeSinceStartup, damage, isCrit));
_last2Damage = _last1Damage;
_last2Crit = _last1Crit;
_last1Damage = damage;
_last1Crit = isCrit;
if (damage > _top1Hit)
{
_top2Hit = _top1Hit;
_top2Crit = _top1Crit;
_top1Hit = damage;
_top1Crit = isCrit;
}
else if (damage > _top2Hit && damage != _top1Hit)
{
_top2Hit = damage;
_top2Crit = isCrit;
}
_lastDamageTime = realtimeSinceStartup;
}
}
private static void ResetStats()
{
_events.Clear();
_last1Damage = 0;
_last1Crit = false;
_last2Damage = 0;
_last2Crit = false;
_peakDps = 0f;
_lastNonZeroDps = 0f;
_lastDamageTime = 0f;
_top1Hit = 0;
_top1Crit = false;
_top2Hit = 0;
_top2Crit = false;
_lastUiUpdate = 0f;
}
private static float GetDps(float now)
{
float num = now - 1f;
int num2 = 0;
while (num2 < _events.Count)
{
if (_events[num2].t < num)
{
_events.RemoveAt(num2);
}
else
{
num2++;
}
}
int num3 = 0;
for (int i = 0; i < _events.Count; i++)
{
num3 += _events[i].dmg;
}
return (float)num3 / 1f;
}
public static void Postfix()
{
//IL_0422: Unknown result type (might be due to invalid IL or missing references)
//IL_0429: Expected O, but got Unknown
try
{
if (!_created)
{
if (!TryCreateOverlay())
{
return;
}
_created = true;
Plugin.LogSrc.LogInfo((object)"Overlay created");
FileLogger.LogInfo("Overlay created");
}
if (EnableTabToggle)
{
try
{
if (!_inputTypesAttempted)
{
_inputTypesAttempted = true;
_inputTypeCached = Plugin.FindTypeByName("UnityEngine.Input");
_keyCodeTypeCached = Plugin.FindTypeByName("UnityEngine.KeyCode");
if (_inputTypeCached == null || _keyCodeTypeCached == null)
{
FileLogger.LogWarning($"Input types not found: Input={_inputTypeCached == null}, KeyCode={_keyCodeTypeCached == null}");
}
}
if (_inputTypeCached != null && _keyCodeTypeCached != null)
{
FieldInfo field = _keyCodeTypeCached.GetField("Tab", BindingFlags.Static | BindingFlags.Public);
if (field != null)
{
object value = field.GetValue(null);
MethodInfo method = _inputTypeCached.GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { _keyCodeTypeCached }, null);
if (method != null)
{
try
{
object obj = method.Invoke(null, new object[1] { value });
bool flag = default(bool);
int num;
if (obj is bool)
{
flag = (bool)obj;
num = 1;
}
else
{
num = 0;
}
if (((uint)num & (flag ? 1u : 0u)) != 0)
{
_forceShowOverlay = !_forceShowOverlay;
Plugin.LogSrc.LogInfo((object)("ForceShowOverlay toggled: " + _forceShowOverlay));
FileLogger.LogInfo("ForceShowOverlay toggled: " + _forceShowOverlay);
}
}
catch (Exception ex)
{
FileLogger.LogWarning("GetKeyDown invoke failed: " + ex.Message);
}
}
}
}
}
catch
{
}
}
bool flag2 = GameStateHelper.IsInBattle();
if (_forceShowOverlay)
{
flag2 = true;
}
if (!flag2)
{
if (_wasInBattle)
{
ResetStats();
}
_wasInBattle = false;
if ((Object)(object)_canvasGo != (Object)null)
{
_canvasGo.SetActive(false);
}
return;
}
_wasInBattle = true;
if ((Object)(object)_canvasGo != (Object)null)
{
_canvasGo.SetActive(true);
}
float realtimeSinceStartup = Time.realtimeSinceStartup;
if ((Object)(object)_text != (Object)null && realtimeSinceStartup - _lastUiUpdate > 0.1f)
{
_lastUiUpdate = realtimeSinceStartup;
float dps = GetDps(realtimeSinceStartup);
if (dps > 0.0001f)
{
_lastNonZeroDps = dps;
_lastDamageTime = realtimeSinceStartup;
}
float value2 = ((!(dps > 0.0001f)) ? ((realtimeSinceStartup - _lastDamageTime < 2.5f) ? _lastNonZeroDps : 0f) : dps);
if (dps > _peakDps)
{
_peakDps = dps;
}
_text.text = $"DPS: {value2:0.0} PEAK: {_peakDps:0.0}\nlast: {_last1Damage} (crit={_last1Crit})\nprev: {_last2Damage} (crit={_last2Crit})\nTOP1: {_top1Hit} (crit={_top1Crit})\nTOP2: {_top2Hit} (crit={_top2Crit})";
}
}
catch (Exception ex2)
{
ManualLogSource logSrc = Plugin.LogSrc;
bool flag3 = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag3);
if (flag3)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Pulse.Postfix exception: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex2);
}
logSrc.LogError(val);
FileLogger.LogError($"Pulse.Postfix exception: {ex2}");
}
}
private static bool TryCreateOverlay()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: 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_0097: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
_canvasGo = new GameObject("DpsCanvas");
_canvasGo.layer = 5;
Object.DontDestroyOnLoad((Object)(object)_canvasGo);
Canvas obj = _canvasGo.AddComponent<Canvas>();
obj.renderMode = (RenderMode)0;
obj.sortingOrder = 32767;
_canvasGo.AddComponent<CanvasScaler>();
_canvasGo.AddComponent<GraphicRaycaster>();
GameObject val = new GameObject("DpsText")
{
layer = 5
};
val.transform.SetParent(_canvasGo.transform, false);
_text = val.AddComponent<Text>();
_text.fontSize = 36;
((Graphic)_text).color = Color.white;
_text.alignment = (TextAnchor)3;
((Graphic)_text).raycastTarget = false;
Font val2 = Resources.GetBuiltinResource<Font>("Arial.ttf");
if ((Object)(object)val2 == (Object)null)
{
Plugin.LogSrc.LogWarning((object)"Built-in Arial.ttf is null. Trying fallbacks.");
FileLogger.LogWarning("Built-in Arial.ttf is null. Trying fallbacks.");
try
{
val2 = Font.CreateDynamicFontFromOSFont("Arial", 26);
if ((Object)(object)val2 != (Object)null)
{
Plugin.LogSrc.LogInfo((object)"Using OS font fallback: Arial");
FileLogger.LogInfo("Using OS font fallback: Arial");
}
}
catch
{
}
try
{
if ((Object)(object)val2 == (Object)null && (Object)(object)GUI.skin != (Object)null)
{
Font font = GUI.skin.font;
if ((Object)(object)font != (Object)null)
{
val2 = font;
Plugin.LogSrc.LogInfo((object)"Using GUI.skin.font as fallback");
FileLogger.LogInfo("Using GUI.skin.font as fallback");
}
}
}
catch
{
}
if ((Object)(object)val2 == (Object)null)
{
Plugin.LogSrc.LogWarning((object)"No font found — overlay will be created but text may be invisible.");
FileLogger.LogWarning("No font found — overlay will be created but text may be invisible.");
}
}
_text.font = val2;
RectTransform rectTransform = ((Graphic)_text).rectTransform;
rectTransform.anchorMin = new Vector2(0f, 0.5f);
rectTransform.anchorMax = new Vector2(0f, 0.5f);
rectTransform.pivot = new Vector2(0f, 0.5f);
rectTransform.anchoredPosition = new Vector2(50f, 0f);
rectTransform.sizeDelta = new Vector2(950f, 260f);
_text.text = "DPS: 0.0";
return true;
}
}
public static class DamageHooks
{
private const bool EnableDump = false;
private const float DumpIntervalSeconds = 1f;
private const int DumpMaxDepth = 3;
private const string PlayerTypeToken = "PlayerType";
private const int TroopTypePlayer = 0;
private static float _lastDumpTime;
private static readonly string[] RelevantNameKeywords = new string[4] { "troopType", "playerType", "playerId", "isEnemy" };
private static readonly string[] DrillDownMemberNames = new string[16]
{
"info", "pUnitSquad", "pParentActor", "pActorStatus", "squadInfo", "squadCtrl", "squadAddingParam", "tpdSquadCtrlTarget", "pSquadCtrlFuncBaseParam", "pTargetSquad",
"pUnitTroop", "pTargetTroop", "pSquadCharaParam", "pCharaParam", "charaParam", "baseParam"
};
public static void UnitBaseSetHitResult_Postfix(object __instance, object[] __args)
{
try
{
if (!Plugin.EnableUnitBaseSetHitResultHook || __args == null || __args.Length < 1)
{
return;
}
bool? flag = TryGetBool(__instance, "isEnemy");
if (flag.HasValue && !flag.Value)
{
return;
}
if (!flag.HasValue)
{
int? num = TryGetTroopTypeFromUnitBase(__instance);
if (num.HasValue && num.Value != 0)
{
return;
}
}
object obj = __args[0];
if (TryGetBool(obj, "isHit") ?? true)
{
int valueOrDefault = TryGetInt(obj, "damage").GetValueOrDefault();
if (valueOrDefault > 0)
{
float realtimeSinceStartup = Time.realtimeSinceStartup;
bool valueOrDefault2 = TryGetBool(obj, "isCritical").GetValueOrDefault();
bool valueOrDefault3 = TryGetBool(obj, "isShield").GetValueOrDefault();
Pulse.AddFinalDamage(valueOrDefault, valueOrDefault2, valueOrDefault3);
}
}
}
catch
{
}
}
private static int? TryGetInt(object obj, string name)
{
if (obj == null)
{
return null;
}
Type type = obj.GetType();
FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
try
{
return Convert.ToInt32(field.GetValue(obj));
}
catch
{
}
}
PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.GetIndexParameters().Length == 0)
{
try
{
return Convert.ToInt32(property.GetValue(obj, null));
}
catch
{
}
}
try
{
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (fieldInfo.Name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf(fieldInfo.Name, StringComparison.OrdinalIgnoreCase) >= 0)
{
try
{
return Convert.ToInt32(fieldInfo.GetValue(obj));
}
catch
{
}
}
}
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.GetIndexParameters().Length == 0 && (propertyInfo.Name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf(propertyInfo.Name, StringComparison.OrdinalIgnoreCase) >= 0))
{
try
{
return Convert.ToInt32(propertyInfo.GetValue(obj, null));
}
catch
{
}
}
}
}
catch
{
}
return null;
}
private static int? TryGetTroopTypeFromUnitBase(object unitBase)
{
object obj = TryGetObjectByName(unitBase, "info");
int? num = TryGetInt(TryGetObjectByName(obj, "pSquadCharaParam"), "troopType");
if (num.HasValue)
{
return num.Value;
}
num = TryGetInt(TryGetObjectByName(obj, "charaParam"), "troopType");
if (num.HasValue)
{
return num.Value;
}
object obj2 = TryGetObjectByName(unitBase, "pUnitSquad") ?? TryGetObjectByName(unitBase, "pParentActor");
object obj3 = TryGetObjectByName(obj2, "squadInfo");
num = TryGetInt(TryGetObjectByName(obj3, "pCharaParam"), "troopType");
if (num.HasValue)
{
return num.Value;
}
num = TryGetInt(TryGetObjectByName(obj3, "charaParam"), "troopType");
if (num.HasValue)
{
return num.Value;
}
object obj4 = TryGetObjectByName(obj2, "pUnitTroop") ?? TryGetObjectByName(obj2, "pTargetTroop");
num = TryGetInt(obj4, "troopType");
if (num.HasValue)
{
return num.Value;
}
return TryGetInt(obj4, "troop");
}
private static void DumpRelevantTree(string label, object obj)
{
DumpRelevantTreeInternal(label, obj, 0);
}
private static void DumpRelevantTreeInternal(string label, object obj, int depth)
{
DumpRelevantMembers(label, obj);
DumpMembersByTypeName(label, obj, "PlayerType");
if (obj == null || depth >= 3)
{
return;
}
for (int i = 0; i < DrillDownMemberNames.Length; i++)
{
object obj2 = TryGetObjectByName(obj, DrillDownMemberNames[i]);
if (obj2 != null)
{
DumpRelevantTreeInternal(label + "." + DrillDownMemberNames[i], obj2, depth + 1);
}
}
}
private static void DumpRelevantMembers(string label, object obj)
{
//IL_0336: Unknown result type (might be due to invalid IL or missing references)
//IL_033d: Expected O, but got Unknown
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Expected O, but got Unknown
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
//IL_0243: Expected O, but got Unknown
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Expected O, but got Unknown
if (obj == null)
{
return;
}
bool flag2 = default(bool);
try
{
Type type = obj.GetType();
bool flag = false;
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int i = 0; i < fields.Length; i++)
{
if (!IsRelevantName(fields[i].Name))
{
continue;
}
object obj2 = null;
try
{
obj2 = fields[i].GetValue(obj);
}
catch
{
}
BepInExInfoLogInterpolatedStringHandler val;
if (!flag)
{
flag = true;
ManualLogSource logSrc = Plugin.LogSrc;
val = new BepInExInfoLogInterpolatedStringHandler(7, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" type: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.FullName);
}
logSrc.LogInfo(val);
FileLogger.LogInfo(label + " type: " + type.FullName);
}
ManualLogSource logSrc2 = Plugin.LogSrc;
val = new BepInExInfoLogInterpolatedStringHandler(12, 4, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" field: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fields[i].FieldType.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fields[i].Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" = ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(obj2);
}
logSrc2.LogInfo(val);
FileLogger.LogInfo($"{label} field: {fields[i].FieldType.Name} {fields[i].Name} = {obj2}");
}
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int j = 0; j < properties.Length; j++)
{
if (properties[j].GetIndexParameters().Length != 0 || !IsRelevantName(properties[j].Name))
{
continue;
}
object obj4 = null;
try
{
obj4 = properties[j].GetValue(obj, null);
}
catch
{
}
BepInExInfoLogInterpolatedStringHandler val;
if (!flag)
{
flag = true;
ManualLogSource logSrc3 = Plugin.LogSrc;
val = new BepInExInfoLogInterpolatedStringHandler(7, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" type: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.FullName);
}
logSrc3.LogInfo(val);
FileLogger.LogInfo(label + " type: " + type.FullName);
}
ManualLogSource logSrc4 = Plugin.LogSrc;
val = new BepInExInfoLogInterpolatedStringHandler(11, 4, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" prop: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(properties[j].PropertyType.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(properties[j].Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" = ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(obj4);
}
logSrc4.LogInfo(val);
FileLogger.LogInfo($"{label} prop: {properties[j].PropertyType.Name} {properties[j].Name} = {obj4}");
}
}
catch (Exception ex)
{
ManualLogSource logSrc5 = Plugin.LogSrc;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("DumpRelevantMembers exception: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
}
logSrc5.LogError(val2);
FileLogger.LogError($"DumpRelevantMembers exception: {ex}");
}
}
private static void DumpMembersByTypeName(string label, object obj, string typeToken)
{
//IL_0340: Unknown result type (might be due to invalid IL or missing references)
//IL_0347: Expected O, but got Unknown
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Expected O, but got Unknown
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
//IL_0246: Unknown result type (might be due to invalid IL or missing references)
//IL_024d: Expected O, but got Unknown
//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Expected O, but got Unknown
if (obj == null || string.IsNullOrEmpty(typeToken))
{
return;
}
bool flag2 = default(bool);
try
{
Type type = obj.GetType();
bool flag = false;
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int i = 0; i < fields.Length; i++)
{
if (!IsTypeNameMatch(fields[i].FieldType, typeToken))
{
continue;
}
object obj2 = null;
try
{
obj2 = fields[i].GetValue(obj);
}
catch
{
}
BepInExInfoLogInterpolatedStringHandler val;
if (!flag)
{
flag = true;
ManualLogSource logSrc = Plugin.LogSrc;
val = new BepInExInfoLogInterpolatedStringHandler(7, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" type: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.FullName);
}
logSrc.LogInfo(val);
FileLogger.LogInfo(label + " type: " + type.FullName);
}
ManualLogSource logSrc2 = Plugin.LogSrc;
val = new BepInExInfoLogInterpolatedStringHandler(12, 4, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" field: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fields[i].FieldType.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fields[i].Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" = ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(obj2);
}
logSrc2.LogInfo(val);
FileLogger.LogInfo($"{label} field: {fields[i].FieldType.Name} {fields[i].Name} = {obj2}");
}
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int j = 0; j < properties.Length; j++)
{
if (properties[j].GetIndexParameters().Length != 0 || !IsTypeNameMatch(properties[j].PropertyType, typeToken))
{
continue;
}
object obj4 = null;
try
{
obj4 = properties[j].GetValue(obj, null);
}
catch
{
}
BepInExInfoLogInterpolatedStringHandler val;
if (!flag)
{
flag = true;
ManualLogSource logSrc3 = Plugin.LogSrc;
val = new BepInExInfoLogInterpolatedStringHandler(7, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" type: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.FullName);
}
logSrc3.LogInfo(val);
FileLogger.LogInfo(label + " type: " + type.FullName);
}
ManualLogSource logSrc4 = Plugin.LogSrc;
val = new BepInExInfoLogInterpolatedStringHandler(11, 4, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" prop: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(properties[j].PropertyType.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(properties[j].Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" = ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(obj4);
}
logSrc4.LogInfo(val);
FileLogger.LogInfo($"{label} prop: {properties[j].PropertyType.Name} {properties[j].Name} = {obj4}");
}
}
catch (Exception ex)
{
ManualLogSource logSrc5 = Plugin.LogSrc;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("DumpMembersByTypeName exception: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
}
logSrc5.LogError(val2);
FileLogger.LogError($"DumpMembersByTypeName exception: {ex}");
}
}
private static bool IsTypeNameMatch(Type t, string token)
{
if (t == null || string.IsNullOrEmpty(token))
{
return false;
}
t = UnwrapNullableType(t);
if (t == null)
{
return false;
}
string obj = t.Name ?? string.Empty;
string text = t.FullName ?? string.Empty;
if (obj.IndexOf(token, StringComparison.OrdinalIgnoreCase) < 0)
{
return text.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0;
}
return true;
}
private static Type UnwrapNullableType(Type t)
{
if (t != null && t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return Nullable.GetUnderlyingType(t) ?? t;
}
return t;
}
private static bool IsRelevantName(string name)
{
if (string.IsNullOrEmpty(name))
{
return false;
}
for (int i = 0; i < RelevantNameKeywords.Length; i++)
{
if (name.IndexOf(RelevantNameKeywords[i], StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
return false;
}
private static object TryGetObjectByName(object obj, string name)
{
if (obj == null || string.IsNullOrEmpty(name))
{
return null;
}
Type type = obj.GetType();
string text = NormalizeName(name);
try
{
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int i = 0; i < fields.Length; i++)
{
if (!(NormalizeName(fields[i].Name) != text))
{
try
{
return fields[i].GetValue(obj);
}
catch
{
return null;
}
}
}
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int j = 0; j < properties.Length; j++)
{
if (properties[j].GetIndexParameters().Length == 0 && !(NormalizeName(properties[j].Name) != text))
{
try
{
return properties[j].GetValue(obj, null);
}
catch
{
return null;
}
}
}
}
catch
{
}
return null;
}
private static string NormalizeName(string name)
{
return name.Replace("_", string.Empty).ToLowerInvariant();
}
private static bool? TryGetBool(object obj, string name)
{
if (obj == null)
{
return null;
}
Type type = obj.GetType();
FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
try
{
return Convert.ToBoolean(field.GetValue(obj));
}
catch
{
}
}
PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.GetIndexParameters().Length == 0)
{
try
{
return Convert.ToBoolean(property.GetValue(obj, null));
}
catch
{
}
}
try
{
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (fieldInfo.Name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf(fieldInfo.Name, StringComparison.OrdinalIgnoreCase) >= 0)
{
try
{
return Convert.ToBoolean(fieldInfo.GetValue(obj));
}
catch
{
}
}
}
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.GetIndexParameters().Length == 0 && (propertyInfo.Name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf(propertyInfo.Name, StringComparison.OrdinalIgnoreCase) >= 0))
{
try
{
return Convert.ToBoolean(propertyInfo.GetValue(obj, null));
}
catch
{
}
}
}
}
catch
{
}
return null;
}
}
public static class GameStateHelper
{
private static bool _initialized;
private static Type _gameType;
private static Type _gameStatusType;
private static Func<object, object> _getInstance;
private static Func<object, bool?> _getBoolBattle;
private static Func<object, int?> _getPhaseInt;
private static Func<object, string> _getPhaseString;
private static float _lastCheckedTime;
private static bool _lastValue;
private static bool _noGameStateFound;
private const int GamePhaseReadyPlayStart = 11;
private const int GamePhasePlayEnd = 14;
public static bool IsInBattle()
{
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
float realtimeSinceStartup = Time.realtimeSinceStartup;
if (realtimeSinceStartup - _lastCheckedTime < 0.2f)
{
return _lastValue;
}
_lastCheckedTime = realtimeSinceStartup;
if (!_initialized)
{
Initialize();
}
object arg = null;
if (!_noGameStateFound && _getInstance != null)
{
try
{
arg = _getInstance(null);
}
catch
{
}
}
if (!_noGameStateFound && _getBoolBattle != null)
{
try
{
bool? flag = _getBoolBattle(arg);
if (flag.HasValue)
{
_lastValue = flag.Value;
return _lastValue;
}
}
catch
{
}
}
if (!_noGameStateFound && _getPhaseString != null)
{
try
{
string text = _getPhaseString(arg);
if (!string.IsNullOrEmpty(text) && (text.IndexOf("battle", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("combat", StringComparison.OrdinalIgnoreCase) >= 0))
{
_lastValue = true;
return _lastValue;
}
}
catch
{
}
}
if (!_noGameStateFound && _getPhaseInt != null)
{
try
{
int? num = _getPhaseInt(arg);
if (num.HasValue && num.Value >= 11 && num.Value <= 14)
{
_lastValue = true;
return _lastValue;
}
}
catch
{
}
}
try
{
Scene activeScene = SceneManager.GetActiveScene();
string name = ((Scene)(ref activeScene)).name;
if (!string.IsNullOrEmpty(name) && (name.IndexOf("battle", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("stage", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("play", StringComparison.OrdinalIgnoreCase) >= 0))
{
_lastValue = true;
return _lastValue;
}
}
catch
{
}
_lastValue = false;
return false;
}
private static void Initialize()
{
_initialized = true;
string[] obj = new string[2] { "P2.Game.Game", "P2S.Game.Game" };
Func<object, object> func = null;
Func<object, int?> func2 = null;
string[] array = obj;
foreach (string fullName in array)
{
Type type = Plugin.FindTypeByName(fullName);
if (type == null)
{
continue;
}
_gameType = type;
PropertyInfo gameProp = type.GetProperty("pGame_g", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (gameProp != null)
{
func = delegate
{
try
{
return gameProp.GetValue(null, null);
}
catch
{
return null;
}
};
}
else
{
FieldInfo gameField = type.GetField("pGame_g", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (gameField != null)
{
func = delegate
{
try
{
return gameField.GetValue(null);
}
catch
{
return null;
}
};
}
}
PropertyInfo phaseProp2 = type.GetProperty("gamePhase_", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetProperty("gamePhase", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (phaseProp2 != null)
{
func2 = delegate(object inst)
{
if (inst == null)
{
return null;
}
try
{
object value4 = phaseProp2.GetValue(inst, null);
return (value4 == null) ? null : new int?(Convert.ToInt32(value4));
}
catch
{
return null;
}
};
}
else
{
FieldInfo phaseField2 = type.GetField("gamePhase_", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("gamePhase", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (phaseField2 != null)
{
func2 = delegate(object inst)
{
if (inst == null)
{
return null;
}
try
{
object value3 = phaseField2.GetValue(inst);
return (value3 == null) ? null : new int?(Convert.ToInt32(value3));
}
catch
{
return null;
}
};
}
}
if (func != null && func2 != null)
{
break;
}
}
if (func != null && func2 != null)
{
_getInstance = func;
_getPhaseInt = func2;
_noGameStateFound = false;
return;
}
array = new string[5] { "P2.GameSystem.GameStatus", "P2S.GameSystem.GameStatus", "P2.GameSystem.GameSystem", "P2.GameSystem.GameManager", "P2.GameSystem.GameStatusManager" };
foreach (string fullName2 in array)
{
Type type2 = Plugin.FindTypeByName(fullName2);
if (type2 == null)
{
continue;
}
_gameStatusType = type2;
PropertyInfo prop = type2.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (prop != null)
{
_getInstance = delegate
{
try
{
return prop.GetValue(null, null);
}
catch
{
return null;
}
};
}
else
{
FieldInfo field = type2.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetField("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
_getInstance = delegate
{
try
{
return field.GetValue(null);
}
catch
{
return null;
}
};
}
}
PropertyInfo boolMember = type2.GetProperty("isInBattle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetProperty("isBattle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetProperty("inBattle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (boolMember != null)
{
_getBoolBattle = delegate(object inst)
{
if (inst == null)
{
return null;
}
try
{
object value2 = boolMember.GetValue(inst, null);
return (value2 == null) ? null : new bool?(Convert.ToBoolean(value2));
}
catch
{
return null;
}
};
}
else
{
FieldInfo boolField = type2.GetField("isInBattle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetField("isBattle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetField("inBattle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (boolField != null)
{
_getBoolBattle = delegate(object inst)
{
if (inst == null)
{
return null;
}
try
{
object value = boolField.GetValue(inst);
return (value == null) ? null : new bool?(Convert.ToBoolean(value));
}
catch
{
return null;
}
};
}
}
PropertyInfo phaseProp = type2.GetProperty("phase", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetProperty("state", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetProperty("gamePhase", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (phaseProp != null)
{
_getPhaseString = delegate(object inst)
{
if (inst == null)
{
return null;
}
try
{
return phaseProp.GetValue(inst, null)?.ToString();
}
catch
{
return null;
}
};
}
else
{
FieldInfo phaseField = type2.GetField("phase", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetField("state", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type2.GetField("gamePhase", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (phaseField != null)
{
_getPhaseString = delegate(object inst)
{
if (inst == null)
{
return null;
}
try
{
return phaseField.GetValue(inst)?.ToString();
}
catch
{
return null;
}
};
}
}
if (_getInstance != null || _getBoolBattle != null || _getPhaseString != null)
{
break;
}
}
if (_gameType == null && _gameStatusType == null && _getInstance == null && _getBoolBattle == null && _getPhaseString == null && _getPhaseInt == null)
{
_noGameStateFound = true;
}
}
}
public static class FileLogger
{
public static void Init()
{
}
public static void LogInfo(string msg)
{
}
public static void LogWarning(string msg)
{
}
public static void LogError(string msg)
{
}
}
namespace DPS_OverlayGenerated;
internal static class ModInfo
{
public const string GUID = "com.zelevlin.dps";
public const string NAME = "DPS_Overlay";
public const string VERSION = "1.0.0";
}