using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using OPJosMod.ReviveCompany;
using OPJosMod.ReviveCompany.CustomRpc;
using ReservedItemSlotCore.Patches;
using SpectatorChat.API;
using SpectatorChat.Other;
using SpectatorChat.Patch.Chat;
using SpectatorChat.Patch.HUD;
using SpectatorChat.Patch.Other;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
[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("Build")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("5.0.1")]
[assembly: AssemblyInformationalVersion("3.0.0")]
[assembly: AssemblyProduct("SpectatorChat")]
[assembly: AssemblyTitle("SpectatorChat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("5.0.1.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 SpectatorChat
{
[BepInPlugin("Kaguya.SpectatorChat", "SpectatorChat", "1.1.8")]
[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.*/)]
[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
{
public class InputKey : LcInputActions
{
[InputAction("<Keyboard>/r", Name = "ToggleDeathBox")]
public InputAction ToggleDeathBoxKey { get; set; }
}
private const string ModGuid = "Kaguya.SpectatorChat";
private const string ModName = "SpectatorChat";
private const string ModVersion = "1.1.8";
private static readonly List<string> ModId = new List<string>();
private readonly Harmony _harmony = new Harmony("Kaguya.SpectatorChat");
private static Plugin Instance;
public static ManualLogSource mls;
internal static InputKey InputActionInstance = new InputKey();
public static ConfigEntry<bool> ShowClock { get; private set; }
public static ConfigEntry<bool> CanLivingPlayerReceiveMessage { get; private set; }
public static ConfigEntry<float> CoroutineDelay { get; private set; }
public static bool KeyPressed { get; set; }
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
mls = Logger.CreateLogSource("Kaguya.SpectatorChat");
mls.LogInfo((object)"SpectatorChat has loaded.");
LoadConfigs();
PatchAll();
LogPatchInfo();
}
private void LoadSpecificPatch()
{
ModId.Add("OpJosMod.ReviveCompany");
ModId.Add("FlipMods.ReservedItemSlotCore");
((MonoBehaviour)this).StartCoroutine(WaitForDependentMod());
}
private IEnumerator WaitForDependentMod()
{
float startTime = Time.time;
float timeout = 120f;
if (!GlobalVariables.Init)
{
GlobalVariables.Init = true;
while (Time.time - startTime <= timeout)
{
Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
int num = 0;
foreach (string key in pluginInfos.Keys)
{
if (key == "OpJosMod.ReviveCompany")
{
_harmony.PatchAll(typeof(ReviveCompanyPatch));
num++;
mls.LogInfo((object)("Detected " + key + ", Proceeding PostPatch..."));
}
else if (key == "FlipMods.ReservedItemSlotCore")
{
GlobalVariables.InitReservedItem = true;
num++;
mls.LogInfo((object)("Detected " + key + ", Proceeding..."));
}
}
mls.LogInfo((object)$"Mod found. Totally {num} Extra method were executed.");
yield return (object)new WaitForSeconds(10f);
}
}
mls.LogInfo((object)"Timeout reached or canceled.");
}
private void PatchAll()
{
_harmony.PatchAll(typeof(EnableChatPatch));
_harmony.PatchAll(typeof(SubmitChatPatch));
_harmony.PatchAll(typeof(HUDPatch));
_harmony.PatchAll(typeof(AddPlayerChatMessagePatch));
_harmony.PatchAll(typeof(HUDManagerPostfixPatch));
_harmony.PatchAll(typeof(KillPlayerPostfixPatch));
_harmony.PatchAll(typeof(HideHUDPostfixPatch));
_harmony.PatchAll(typeof(SetShipReadyToLandPostfix));
_harmony.PatchAll(typeof(KeyPatch));
LoadSpecificPatch();
}
private void LoadConfigs()
{
ShowClock = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "ShowClock", true, "Show the clock for spectator players.");
CanLivingPlayerReceiveMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "CanLivingPlayerReceiveMessage", false, "Can living player receive dead player's message.");
CoroutineDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "CoroutineDelay", 1f, "How long will the coroutine delay.");
mls.LogInfo((object)$"Plugin loaded with config: ShowClock: {ShowClock.Value}, CanLivingPlayerReceiveMessage: {CanLivingPlayerReceiveMessage.Value}, CoroutineDelay: {CoroutineDelay.Value}");
}
private void LogPatchInfo()
{
mls.LogInfo((object)HarmonyAPI.GetPatchInfoAsString(_harmony, AccessTools.Method(typeof(HUDManager), "Awake", (Type[])null, (Type[])null)));
mls.LogInfo((object)HarmonyAPI.GetPatchInfoAsString(_harmony, AccessTools.Method(typeof(HUDManager), "EnableChat_performed", (Type[])null, (Type[])null)));
mls.LogInfo((object)HarmonyAPI.GetPatchInfoAsString(_harmony, AccessTools.Method(typeof(HUDManager), "SubmitChat_performed", (Type[])null, (Type[])null)));
mls.LogInfo((object)HarmonyAPI.GetPatchInfoAsString(_harmony, AccessTools.Method(typeof(PlayerControllerB), "KillPlayer", (Type[])null, (Type[])null)));
mls.LogInfo((object)HarmonyAPI.GetPatchInfoAsString(_harmony, AccessTools.Method(typeof(PlayerControllerB), "Update", (Type[])null, (Type[])null)));
mls.LogInfo((object)HarmonyAPI.GetPatchInfoAsString(_harmony, AccessTools.Method(typeof(HUDManager), "HideHUD", (Type[])null, (Type[])null)));
mls.LogInfo((object)HarmonyAPI.GetPatchInfoAsString(_harmony, AccessTools.Method(typeof(StartOfRound), "SetShipReadyToLand", (Type[])null, (Type[])null)));
mls.LogInfo((object)HarmonyAPI.GetPatchInfoAsString(_harmony, AccessTools.Method(typeof(CompleteRecievedTasks), "RevivePlayer", (Type[])null, (Type[])null)));
}
}
}
namespace SpectatorChat.Patch.Other
{
internal static class HideHUDPostfixPatch
{
[HarmonyPatch(typeof(HUDManager), "HideHUD")]
private static void Postfix(HUDManager __instance)
{
HarmonyAPI.LogCallingMethod("HideHUD");
if (Generic.Instance.IsCoroutineNull())
{
return;
}
try
{
if (Generic.Instance.StopPermanentTransparent())
{
Plugin.mls.LogInfo((object)("Routine stopped successfully. Player " + GlobalVariables.PlayerControllerInstance.playerUsername));
}
else
{
Plugin.mls.LogInfo((object)("Routine stopped failed. Player " + GlobalVariables.PlayerControllerInstance.playerUsername));
}
}
catch (Exception ex)
{
Plugin.mls.LogError((object)(ex.StackTrace + ex.Message));
throw;
}
}
}
internal static class KillPlayerPostfixPatch
{
[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
private static void Postfix(PlayerControllerB __instance)
{
HarmonyAPI.LogCallingMethod("KillPlayer");
if (((NetworkBehaviour)__instance).IsOwner && Generic.Instance.StartPermanentTransparent())
{
GlobalVariables.PlayerControllerInstance.bleedingHeavily = false;
GlobalVariables.PlayerControllerInstance.criticallyInjured = false;
HUDManager.Instance.HUDAnimator.SetTrigger("revealHud");
Plugin.mls.LogInfo((object)("Routine start successfully. Player " + __instance.playerUsername));
}
}
}
internal static class ReviveCompanyPatch
{
[HarmonyPatch(typeof(CompleteRecievedTasks), "RevivePlayer")]
private static bool Prefix(ref string playerIdString)
{
HarmonyAPI.LogCallingMethod("RevivePlayer");
if (int.TryParse(playerIdString, out var result))
{
GeneralUtil.RevivePlayer(result);
if (Generic.IsInstanceOwner(playerIdString))
{
Plugin.mls.LogInfo((object)$"Player {GlobalVariables.PlayerControllerInstance.playerUsername} has been revived and IsInstanceOwner: {Generic.IsInstanceOwner(playerIdString)}");
Generic.ClearSpectatorUI(GlobalVariables.HUDManagerInstance);
if (Generic.Instance.StopPermanentTransparent())
{
Plugin.mls.LogInfo((object)("Routine stopped successfully. Player " + GlobalVariables.PlayerControllerInstance.playerUsername));
}
else
{
Plugin.mls.LogInfo((object)("Routine stopped failed. Player " + GlobalVariables.PlayerControllerInstance.playerUsername));
}
}
}
else
{
Plugin.mls.LogError((object)("Error: Invalid player ID '" + playerIdString + "' did not revive"));
}
return false;
}
}
}
namespace SpectatorChat.Patch.HUD
{
[HarmonyPatch(typeof(HUDManager), "Awake")]
internal static class HUDManagerPostfixPatch
{
private static void Postfix(HUDManager __instance)
{
HUDManager __instance2 = __instance;
HarmonyAPI.LogCallingMethod("HUDManager.Awake");
GlobalVariables.HUDManagerInstance = __instance2;
if (GlobalVariables.InitReservedItem)
{
ReservedItemUI.InitReservedItemUI();
}
if (Plugin.ShowClock.Value)
{
GlobalVariables.HUDElements = __instance2.HUDElements.Where((HUDElement element) => element != __instance2.HUDElements[1] && element != __instance2.HUDElements[5]).ToArray();
}
else
{
GlobalVariables.HUDElements = __instance2.HUDElements.Where((HUDElement element) => element != __instance2.HUDElements[1]).ToArray();
}
}
}
[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
internal static class HUDPatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
HarmonyAPI.LogCallingMethod("KillPlayer");
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
MethodInfo hideHUDMethod = typeof(HUDManager).GetMethod("HideHUD");
Plugin.mls.LogInfo((object)"Processing KillPlayer method...");
int num;
try
{
num = list.FindLastIndex((CodeInstruction i) => i.opcode == OpCodes.Callvirt && i.operand is MethodInfo methodInfo && methodInfo.Equals(hideHUDMethod));
Plugin.mls.LogInfo((object)$"Index: {num} Code: {list[num]} found.");
num -= 2;
}
catch (Exception ex)
{
Plugin.mls.LogError((object)(ex.Message + ex.StackTrace));
throw;
}
try
{
Plugin.mls.LogInfo((object)"Patching following codes...");
for (int j = 0; j <= 2; j++)
{
Plugin.mls.LogInfo((object)$"Index: {num + j}, Code: {list[num + j]}");
list[num + j].opcode = OpCodes.Nop;
}
Plugin.mls.LogInfo((object)"Patched codes:");
for (int k = 0; k <= 2; k++)
{
Plugin.mls.LogInfo((object)$"Index: {num + k}, Code: {list[num + k]}");
}
}
catch (Exception ex2)
{
Plugin.mls.LogError((object)(ex2.Message + ex2.StackTrace));
throw;
}
finally
{
Plugin.mls.LogInfo((object)"Patch success. No any fatal error were raised.");
}
foreach (CodeInstruction item in list)
{
yield return item;
}
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
internal static class KeyPatch
{
internal static void Postfix(PlayerControllerB __instance)
{
if ((!((NetworkBehaviour)__instance).IsOwner || (!__instance.isPlayerControlled && !__instance.isPlayerDead) || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject)) && !__instance.isTestingPlayer)
{
return;
}
if ((Object)(object)GlobalVariables.PlayerControllerInstance != (Object)(object)__instance || (Object)(object)GlobalVariables.PlayerControllerInstance == (Object)null)
{
Plugin.mls.LogInfo((object)$"Player instance has changed due to {(Object)(object)GlobalVariables.PlayerControllerInstance != (Object)(object)__instance} or {(Object)(object)GlobalVariables.PlayerControllerInstance == (Object)null}");
GlobalVariables.PlayerControllerInstance = __instance;
}
if (__instance.isPlayerDead && Plugin.InputActionInstance.ToggleDeathBoxKey.WasPressedThisFrame())
{
if (!Plugin.KeyPressed)
{
Generic.ToggleSpectatorBoxUI(GlobalVariables.HUDManagerInstance, isVisable: false);
Plugin.KeyPressed = true;
}
else
{
Generic.ToggleSpectatorBoxUI(GlobalVariables.HUDManagerInstance, isVisable: true);
Plugin.KeyPressed = false;
}
}
}
}
[HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")]
internal static class SetShipReadyToLandPostfix
{
private static void Postfix()
{
HarmonyAPI.LogCallingMethod("StartOfRound.SetShipReadyToLand");
Generic.ClearSpectatorUI(GlobalVariables.HUDManagerInstance);
}
}
}
namespace SpectatorChat.Patch.Chat
{
[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")]
internal static class AddPlayerChatMessagePatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
HarmonyAPI.LogCallingMethod("AddPlayerChatMessageClientRpc");
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
Label label = generator.DefineLabel();
FieldInfo targetField = typeof(PlayerControllerB).GetField("isPlayerDead");
Plugin.mls.LogInfo((object)"Processing AddPlayerChatMessageClientRpc method...");
int num;
try
{
num = list.FindLastIndex((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldfld && instruction.operand is FieldInfo fieldInfo && fieldInfo.Equals(targetField));
Plugin.mls.LogInfo((object)$"Index: {num} Code: {list[num]} found.");
num -= 9;
Plugin.mls.LogInfo((object)$"Got previous IL Code: {list[num]}.");
}
catch (Exception ex)
{
Plugin.mls.LogError((object)(ex.Message + ex.StackTrace));
throw;
}
try
{
Plugin.mls.LogInfo((object)"Patching following codes...");
for (int i = 0; i <= 11; i++)
{
Plugin.mls.LogInfo((object)$"Index: {num + i}, Code: {list[num + i]}");
list[num + i].opcode = OpCodes.Nop;
}
Plugin.mls.LogInfo((object)"Patched codes:");
for (int j = 0; j <= 11; j++)
{
Plugin.mls.LogInfo((object)$"Index: {num + j}, Code: {list[num + j]}");
}
}
catch (Exception ex2)
{
Plugin.mls.LogError((object)(ex2.Message + ex2.StackTrace));
throw;
}
finally
{
Plugin.mls.LogInfo((object)"Patch success. No any fatal error were raised.");
}
Plugin.mls.LogInfo((object)"Now processing patch 2...");
try
{
num = list.FindLastIndex((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldloc_0);
Plugin.mls.LogInfo((object)$"Index: {num} Code: {list[num]} found.");
num++;
Plugin.mls.LogInfo((object)$"Got next IL Code: {list[num]}.");
list[num + 1].opcode = OpCodes.Nop;
num++;
list.InsertRange(num, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[4]
{
new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.PropertyGetter(typeof(Plugin), "CanLivingPlayerReceiveMessage")),
new CodeInstruction(OpCodes.Brtrue_S, (object)label),
new CodeInstruction(OpCodes.Ret, (object)null),
CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Nop, (object)null), new Label[1] { label })
});
}
catch (Exception ex3)
{
Plugin.mls.LogError((object)(ex3.Message + ex3.StackTrace));
throw;
}
finally
{
Plugin.mls.LogInfo((object)"Patch success. No any fatal error were raised.");
}
foreach (CodeInstruction item in list)
{
yield return item;
}
}
}
[HarmonyPatch(typeof(HUDManager), "EnableChat_performed")]
internal static class EnableChatPatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
HarmonyAPI.LogCallingMethod("EnableChat_performed");
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo targetField = typeof(PlayerControllerB).GetField("isPlayerDead");
Plugin.mls.LogInfo((object)"Processing EnableChat_performed method...");
int num;
try
{
num = list.FindLastIndex((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldfld && instruction.operand is FieldInfo fieldInfo && fieldInfo.Equals(targetField));
Plugin.mls.LogInfo((object)$"Index: {num} Code: {list[num]} found.");
num -= 2;
Plugin.mls.LogInfo((object)$"Got previous IL Code: {list[num]}.");
}
catch (Exception ex)
{
Plugin.mls.LogError((object)(ex.Message + ex.StackTrace));
throw;
}
try
{
Plugin.mls.LogInfo((object)"Patching following codes...");
for (int i = 0; i <= 4; i++)
{
Plugin.mls.LogInfo((object)$"Index: {num + i}, Code: {list[num + i]}");
list[num + i].opcode = OpCodes.Nop;
}
Plugin.mls.LogInfo((object)"Patched codes:");
for (int j = 0; j <= 4; j++)
{
Plugin.mls.LogInfo((object)$"Index: {num + j}, Code: {list[num + j]}");
}
}
catch (Exception ex2)
{
Plugin.mls.LogError((object)(ex2.Message + ex2.StackTrace));
throw;
}
finally
{
Plugin.mls.LogInfo((object)"Patch success. No any fatal error were raised.");
}
foreach (CodeInstruction item in list)
{
yield return item;
}
}
}
[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
internal static class SubmitChatPatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
HarmonyAPI.LogCallingMethod("SubmitChat_performed");
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo targetField = typeof(PlayerControllerB).GetField("isPlayerDead");
Plugin.mls.LogInfo((object)"Processing SubmitChat_performed method...");
int num;
try
{
num = list.FindLastIndex((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldfld && instruction.operand is FieldInfo fieldInfo && fieldInfo.Equals(targetField));
Plugin.mls.LogInfo((object)$"Index: {num} Code: {list[num]} found.");
num -= 2;
Plugin.mls.LogInfo((object)$"Got previous IL Code: {list[num]}.");
}
catch (Exception ex)
{
Plugin.mls.LogError((object)(ex.Message + ex.StackTrace));
throw;
}
try
{
Plugin.mls.LogInfo((object)"Patching following codes...");
for (int i = 0; i <= 4; i++)
{
Plugin.mls.LogInfo((object)$"Index: {num + i}, Code: {list[num + i]}");
list[num + i].opcode = OpCodes.Nop;
}
Plugin.mls.LogInfo((object)"Patched codes:");
for (int j = 0; j <= 4; j++)
{
Plugin.mls.LogInfo((object)$"Index: {num + j}, Code: {list[num + j]}");
}
}
catch (Exception ex2)
{
Plugin.mls.LogError((object)(ex2.Message + ex2.StackTrace));
throw;
}
finally
{
Plugin.mls.LogInfo((object)"Patch success. No any fatal error were raised.");
}
foreach (CodeInstruction item in list)
{
yield return item;
}
}
}
}
namespace SpectatorChat.Other
{
public static class DebugTestClass
{
public static void PrintAllVariables()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("Global Variables State:");
stringBuilder.AppendLine($"Init: {GlobalVariables.Init}");
stringBuilder.AppendLine($"InitReservedItem: {GlobalVariables.InitReservedItem}");
stringBuilder.AppendLine("HUDElements: " + ((GlobalVariables.HUDElements != null) ? "Initialized" : "Null"));
stringBuilder.AppendLine("HUDManagerInstance: " + (((Object)(object)GlobalVariables.HUDManagerInstance != (Object)null) ? "Initialized" : "Null"));
stringBuilder.AppendLine("ReservedItemSlot: " + ((GlobalVariables.ReservedItemSlots != null) ? "Initialized" : "Null"));
stringBuilder.AppendLine("PlayerControllerInstance: " + (((Object)(object)GlobalVariables.PlayerControllerInstance != (Object)null) ? "Initialized" : "Null"));
stringBuilder.AppendLine("CoroutineCancellationTokenSource: " + ((GlobalVariables.CoroutineCancellationTokenSource != null) ? "Initialized" : "Null"));
Plugin.mls.LogInfo((object)stringBuilder.ToString());
}
}
public class GlobalVariables
{
public static CancellationTokenSource? CoroutineCancellationTokenSource;
public static bool Init { get; set; }
public static bool InitReservedItem { get; set; }
public static List<Image>? ReservedItemSlots { get; set; }
public static HUDElement[]? HUDElements { get; set; }
public static HUDManager? HUDManagerInstance { get; set; }
public static PlayerControllerB? PlayerControllerInstance { get; set; }
}
public class ReservedItemUI
{
public static void InitReservedItemUI()
{
if (Generic.IsModLoaded("FlipMods.ReservedItemSlotCore"))
{
GlobalVariables.ReservedItemSlots = HUDPatcher.reservedItemSlots;
}
else
{
GlobalVariables.ReservedItemSlots = null;
}
}
public static void SwitchReservedItemUI(bool hide)
{
if (GlobalVariables.ReservedItemSlots == null)
{
return;
}
if (hide)
{
foreach (Image reservedItemSlot in GlobalVariables.ReservedItemSlots)
{
((Behaviour)reservedItemSlot).enabled = false;
}
}
foreach (Image reservedItemSlot2 in GlobalVariables.ReservedItemSlots)
{
((Behaviour)reservedItemSlot2).enabled = true;
}
}
}
}
namespace SpectatorChat.API
{
public class Generic : MonoBehaviour
{
private static Generic? instance;
private Coroutine? _permanentTransparentCoroutine;
public static Generic Instance
{
get
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)instance == (Object)null)
{
instance = new GameObject("SpectatorChatGeneric").AddComponent<Generic>();
}
return instance;
}
}
private void Awake()
{
if ((Object)(object)instance == (Object)null)
{
instance = this;
}
else
{
instance = null;
}
}
public static bool IsInstanceOwner(string userId)
{
try
{
return ulong.Parse(userId) == GlobalVariables.PlayerControllerInstance.playerClientId;
}
catch (Exception ex)
{
Plugin.mls.LogError((object)(ex.Message + ex.StackTrace));
return false;
}
}
public bool IsCoroutineNull()
{
if (_permanentTransparentCoroutine == null)
{
return true;
}
return false;
}
public bool StartPermanentTransparent()
{
Plugin.mls.LogInfo((object)"StartPermanentTransparent() has been called.");
if (_permanentTransparentCoroutine == null)
{
Plugin.mls.LogInfo((object)"Trying to start the coroutine.");
GlobalVariables.CoroutineCancellationTokenSource = new CancellationTokenSource();
_permanentTransparentCoroutine = ((MonoBehaviour)this).StartCoroutine(PermanentTransparentCoroutine(GlobalVariables.HUDElements, GlobalVariables.CoroutineCancellationTokenSource));
return true;
}
return false;
}
public bool StopPermanentTransparent()
{
Plugin.mls.LogInfo((object)"StopPermanentTransparent() has been called.");
DebugTestClass.PrintAllVariables();
if (_permanentTransparentCoroutine != null && GlobalVariables.CoroutineCancellationTokenSource != null)
{
Plugin.mls.LogInfo((object)"Trying to stop the coroutine.");
GlobalVariables.CoroutineCancellationTokenSource.Cancel();
GlobalVariables.CoroutineCancellationTokenSource = null;
_permanentTransparentCoroutine = null;
return true;
}
return false;
}
public static bool IsModLoaded(string guid)
{
return Chainloader.PluginInfos.ContainsKey(guid);
}
private IEnumerator PermanentTransparentCoroutine(HUDElement[] elements, CancellationTokenSource coroutineCancellationTokenSource)
{
while (!coroutineCancellationTokenSource.IsCancellationRequested)
{
try
{
foreach (HUDElement val in elements)
{
if (val.canvasGroup.alpha != 0f)
{
val.canvasGroup.alpha = 0f;
}
}
if (IsModLoaded("FlipMods.ReservedItemSlotCore"))
{
ReservedItemUI.SwitchReservedItemUI(hide: true);
}
}
catch (Exception ex)
{
Plugin.mls.LogError((object)(ex.Message + ex.StackTrace));
}
yield return Plugin.CoroutineDelay.Value;
}
if (IsModLoaded("FlipMods.ReservedItemSlotCore"))
{
ReservedItemUI.SwitchReservedItemUI(hide: false);
}
_permanentTransparentCoroutine = null;
}
public static void ToggleSpectatorBoxUI(HUDManager instance, bool isVisable)
{
try
{
if (isVisable)
{
for (int i = 0; i < instance.spectatingPlayerBoxes.Count; i++)
{
((Component)instance.spectatingPlayerBoxes.ElementAt(i).Key).gameObject.SetActive(true);
}
}
else
{
for (int j = 0; j < instance.spectatingPlayerBoxes.Count; j++)
{
((Component)instance.spectatingPlayerBoxes.ElementAt(j).Key).gameObject.SetActive(false);
}
}
}
catch (Exception ex)
{
Plugin.mls.LogError((object)(ex.Message + ex.StackTrace));
throw;
}
}
public static void ClearSpectatorUI(HUDManager instance)
{
Plugin.mls.LogInfo((object)"Method ClearSpectatorUI called.");
for (int i = 0; i < instance.spectatingPlayerBoxes.Count; i++)
{
((Component)instance.spectatingPlayerBoxes.ElementAt(i).Key).gameObject.SetActive(false);
instance.boxesAdded--;
}
instance.yOffsetAmount = 0f;
instance.hasGottenPlayerSteamProfilePictures = false;
instance.hasLoadedSpectateUI = false;
instance.spectatingPlayerBoxes.Clear();
if (instance.spectatingPlayerBoxes.Count != 0)
{
Plugin.mls.LogInfo((object)"Error. spectatingPlayerBoxes not empty.");
}
}
}
public static class HarmonyAPI
{
public static string GetPatchInfoAsString(Harmony harmony, MethodInfo methodInfo)
{
MethodInfo methodInfo2 = methodInfo;
StringBuilder stringBuilder = new StringBuilder();
foreach (MethodBase item in from method in harmony.GetPatchedMethods()
where method == methodInfo2
select method)
{
stringBuilder.AppendLine("Method " + item.DeclaringType.FullName + "." + item.Name + " is patched by:");
Patches patchInfo = Harmony.GetPatchInfo(item);
foreach (Patch prefix in patchInfo.Prefixes)
{
stringBuilder.AppendLine("- Prefix: " + prefix.owner);
}
foreach (Patch postfix in patchInfo.Postfixes)
{
stringBuilder.AppendLine("- Postfix: " + postfix.owner);
}
foreach (Patch transpiler in patchInfo.Transpilers)
{
stringBuilder.AppendLine("- Transpiler: " + transpiler.owner);
}
}
return stringBuilder.ToString();
}
public static void LogCallingMethod(string patchName)
{
try
{
StackFrame[] frames = new StackTrace().GetFrames();
if (frames != null && frames.Length > 1)
{
MethodBase method = frames[1].GetMethod();
Type? declaringType = method.DeclaringType;
string text = declaringType?.Namespace;
string text2 = declaringType?.Name;
Plugin.mls.LogInfo((object)("Patch " + patchName + " called by: " + text + "." + text2 + "." + method.Name));
}
else
{
Plugin.mls.LogWarning((object)("Unable to determine calling method for patch: " + patchName));
}
}
catch (Exception ex)
{
Plugin.mls.LogError((object)("An error occurred while logging calling method for patch " + patchName + ": " + ex.Message));
}
}
}
}