using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TrueFinal_Fixes")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TrueFinal_Fixes")]
[assembly: AssemblyTitle("TrueFinal_Fixes")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace TrueFinal_Fixes
{
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "TrueFinal_Fixes";
public const string PLUGIN_NAME = "TrueFinal_Fixes";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace TFAPerformanceFix
{
[BepInPlugin("com.performance.tfafixes", "TFA Comprehensive Fix", "1.6.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class PerformanceFixPlugin : BaseUnityPlugin
{
public const string PluginGuid = "com.performance.tfafixes";
public const string PluginName = "TFA Comprehensive Fix";
public const string PluginVersion = "1.6.0";
internal const string TfaHarmonyId = "com.CptPICHU.peak.truefinalascent";
private Harmony? _harmony;
private void Awake()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
_harmony = new Harmony("com.performance.tfafixes");
PatchFog();
PatchRoster();
PatchChoicePreview();
DisableKickHotkey();
DisableNameColoring();
((BaseUnityPlugin)this).Logger.LogInfo((object)"TFA Comprehensive Fix v1.6.0 loaded and operational for TFA 1.0.6 - 1.0.8+.");
}
private void OnDestroy()
{
Harmony? harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void PatchFog()
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Expected O, but got Unknown
MethodBase methodBase = AccessTools.Method(typeof(ForceFogShaderHeight), "Update", (Type[])null, (Type[])null);
MethodInfo methodInfo = AccessTools.Method(typeof(FastFogHeightPatch), "Prefix", (Type[])null, (Type[])null);
if (methodBase == null || methodInfo == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Fog optimization: Target method not found.");
return;
}
_harmony.Unpatch(methodBase, (HarmonyPatchType)1, "com.CptPICHU.peak.truefinalascent");
_harmony.Patch(methodBase, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Fog optimization: Installed fast single-pass cache.");
}
private void PatchRoster()
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
Type type = AccessTools.TypeByName("TrueFinalAscent.FinalAscentRoster");
MethodBase methodBase = ((type == null) ? null : AccessTools.Method(type, "Tick", (Type[])null, (Type[])null));
MethodInfo methodInfo = AccessTools.Method(typeof(RosterOptimization), "TickPrefix", (Type[])null, (Type[])null);
if (methodBase == null || methodInfo == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Roster optimization: Target method not found.");
return;
}
_harmony.Patch(methodBase, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Roster optimization: Throttled tick coroutine to 1.5s interval.");
}
private void PatchChoicePreview()
{
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Expected O, but got Unknown
Type type = AccessTools.TypeByName("TrueFinalAscent.AscentChoicePreview");
MethodBase methodBase = ((type == null) ? null : AccessTools.Method(type, "Bind", (Type[])null, (Type[])null));
MethodBase methodBase2 = ((type == null) ? null : AccessTools.Method(type, "LateUpdate", (Type[])null, (Type[])null));
MethodInfo methodInfo = AccessTools.Method(typeof(ChoicePreviewOptimization), "BindPostfix", (Type[])null, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(typeof(ChoicePreviewOptimization), "LateUpdatePrefix", (Type[])null, (Type[])null);
if (methodBase == null || methodBase2 == null || methodInfo == null || methodInfo2 == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Choice preview optimization: Target methods not found.");
return;
}
_harmony.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
_harmony.Patch(methodBase2, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Choice preview: Converted from per-frame poll to onValueChanged event.");
}
private void DisableKickHotkey()
{
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Expected O, but got Unknown
Type type = AccessTools.TypeByName("TrueFinalAscent.KickHotkey");
if (type == null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"KickHotkey: Component not present in this build.");
return;
}
MethodBase methodBase = AccessTools.Method(type, "Update", (Type[])null, (Type[])null);
MethodBase methodBase2 = AccessTools.Method(type, "ResetStuckKickFlags", (Type[])null, (Type[])null);
MethodInfo methodInfo = AccessTools.Method(typeof(CommonHooks), "NoOp", (Type[])null, (Type[])null);
if (methodInfo != null)
{
if (methodBase != null)
{
_harmony.Patch(methodBase, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
if (methodBase2 != null)
{
_harmony.Patch(methodBase2, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
Component component = ((Component)this).GetComponent(type);
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"KickHotkey: Disabled per-frame player array scans.");
}
private void DisableNameColoring()
{
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Expected O, but got Unknown
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(CommonHooks), "NoOp", (Type[])null, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(typeof(AudioLevelSlider), "Update", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
_harmony.Unpatch((MethodBase)methodInfo2, (HarmonyPatchType)2, "com.CptPICHU.peak.truefinalascent");
}
MethodInfo methodInfo3 = AccessTools.Method(typeof(AudioLevelSlider), "Init", (Type[])null, (Type[])null);
if (methodInfo3 != null)
{
_harmony.Unpatch((MethodBase)methodInfo3, (HarmonyPatchType)2, "com.CptPICHU.peak.truefinalascent");
}
MethodInfo methodInfo4 = AccessTools.Method(typeof(UIPlayerNames), "UpdateName", new Type[2]
{
typeof(int),
typeof(bool)
}, (Type[])null);
if (methodInfo4 != null)
{
_harmony.Unpatch((MethodBase)methodInfo4, (HarmonyPatchType)2, "com.CptPICHU.peak.truefinalascent");
}
MethodInfo methodInfo5 = AccessTools.Method(typeof(EndScreenScoutWindow), "Init", new Type[1] { typeof(Character) }, (Type[])null);
if (methodInfo5 != null)
{
_harmony.Unpatch((MethodBase)methodInfo5, (HarmonyPatchType)2, "com.CptPICHU.peak.truefinalascent");
}
Type type = AccessTools.TypeByName("TrueFinalAscent.AscentNameColor");
MethodInfo methodInfo6 = ((type != null) ? AccessTools.Method(type, "Apply", (Type[])null, (Type[])null) : null);
if (methodInfo6 != null)
{
_harmony.Patch((MethodBase)methodInfo6, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
Type type2 = AccessTools.TypeByName("TrueFinalAscent.AscentTitle");
MethodInfo methodInfo7 = ((type2 != null) ? AccessTools.Method(type2, "Paint", (Type[])null, (Type[])null) : null);
if (methodInfo7 != null)
{
_harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"Name Coloring: Completely disabled all TextMeshPro vertex recoloring routines.");
}
}
internal static class CommonHooks
{
public static bool NoOp()
{
return false;
}
}
internal static class TfaBridge
{
private static PropertyInfo? _activeProperty;
private static bool _resolved;
internal static bool IsActive
{
get
{
if (!_resolved)
{
Type type = AccessTools.TypeByName("TrueFinalAscent.FinalAscent");
_activeProperty = ((type == null) ? null : AccessTools.Property(type, "Active"));
_resolved = true;
}
bool flag = default(bool);
int num;
if (_activeProperty != null)
{
object value = _activeProperty.GetValue(null);
if (value is bool)
{
flag = (bool)value;
num = 1;
}
else
{
num = 0;
}
}
else
{
num = 0;
}
return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
}
}
}
internal static class RosterOptimization
{
private static readonly WaitForSecondsRealtime Beat = new WaitForSecondsRealtime(1.5f);
private static MethodInfo? _remember;
private static MethodInfo? _publish;
public static bool TickPrefix(ref IEnumerator __result)
{
__result = Run();
return false;
}
private static IEnumerator Run()
{
Type type = AccessTools.TypeByName("TrueFinalAscent.FinalAscentRoster");
if ((object)_remember == null)
{
_remember = ((type == null) ? null : AccessTools.Method(type, "Remember", (Type[])null, (Type[])null));
}
if ((object)_publish == null)
{
_publish = ((type == null) ? null : AccessTools.Method(type, "Publish", (Type[])null, (Type[])null));
}
float publishClock = 0f;
while (true)
{
yield return Beat;
publishClock += 1.5f;
try
{
_remember?.Invoke(null, null);
if (publishClock >= 30f)
{
publishClock = 0f;
_publish?.Invoke(null, null);
}
}
catch
{
}
}
}
}
internal static class ChoicePreviewOptimization
{
private sealed class State
{
internal TMP_Dropdown? Dropdown;
internal UnityAction<int>? Listener;
}
private static readonly Dictionary<int, State> States = new Dictionary<int, State>();
private static MethodInfo? _originalLateUpdate;
private static bool _insideRefresh;
public static void BindPostfix(MonoBehaviour __instance, TMP_Dropdown pick)
{
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)pick == (Object)null))
{
int instanceID = ((Object)__instance).GetInstanceID();
if (States.TryGetValue(instanceID, out State value) && (Object)(object)value.Dropdown != (Object)null && value.Listener != null)
{
((UnityEvent<int>)(object)value.Dropdown.onValueChanged).RemoveListener(value.Listener);
}
State state = new State
{
Dropdown = pick
};
state.Listener = delegate
{
RefreshOnce(__instance);
};
((UnityEvent<int>)(object)pick.onValueChanged).AddListener(state.Listener);
States[instanceID] = state;
RefreshOnce(__instance);
}
}
public static bool LateUpdatePrefix()
{
return _insideRefresh;
}
private static void RefreshOnce(MonoBehaviour instance)
{
if ((Object)(object)instance == (Object)null || _insideRefresh)
{
return;
}
if ((object)_originalLateUpdate == null)
{
_originalLateUpdate = AccessTools.Method(((object)instance).GetType(), "LateUpdate", (Type[])null, (Type[])null);
}
if (_originalLateUpdate == null)
{
return;
}
try
{
_insideRefresh = true;
_originalLateUpdate.Invoke(instance, null);
}
finally
{
_insideRefresh = false;
}
}
}
internal static class FastFogHeightPatch
{
private struct Candidate
{
internal ForceFogShaderHeight Component;
internal float Distance;
}
private static int _frame = -1;
private static float _localY;
private static bool _haveLocalCharacter;
private static readonly Dictionary<int, Candidate> Best = new Dictionary<int, Candidate>(8);
private static readonly Dictionary<int, ForceFogShaderHeight> Chosen = new Dictionary<int, ForceFogShaderHeight>(8);
private static readonly List<ForceFogShaderHeight> ThisFrame = new List<ForceFogShaderHeight>(64);
private static readonly List<ForceFogShaderHeight> LastFrame = new List<ForceFogShaderHeight>(64);
internal static bool Prefix(ForceFogShaderHeight __instance)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Expected I4, but got Unknown
if ((Object)(object)__instance == (Object)null || !TfaBridge.IsActive)
{
return true;
}
if (Time.frameCount != _frame)
{
BeginFrame();
}
ThisFrame.Add(__instance);
if (!_haveLocalCharacter)
{
return true;
}
ForceFogShaderHeight value;
return !Chosen.TryGetValue((int)__instance.fogType, out value) || __instance == value;
}
private static void BeginFrame()
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected I4, but got Unknown
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
_frame = Time.frameCount;
LastFrame.Clear();
LastFrame.AddRange(ThisFrame);
ThisFrame.Clear();
Chosen.Clear();
Best.Clear();
Character localCharacter = Character.localCharacter;
_haveLocalCharacter = (Object)(object)localCharacter != (Object)null;
if (!_haveLocalCharacter)
{
return;
}
_localY = localCharacter.Center.y;
for (int i = 0; i < LastFrame.Count; i++)
{
ForceFogShaderHeight val = LastFrame[i];
if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled)
{
int key = (int)val.fogType;
float num = Mathf.Abs(((Component)val).transform.position.y - _localY);
if (!Best.TryGetValue(key, out var value) || num < value.Distance)
{
Best[key] = new Candidate
{
Component = val,
Distance = num
};
Chosen[key] = val;
}
}
}
}
}
}