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.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LCHideAndSeekMod.Core;
using LethalConfig;
using LethalConfig.ConfigItems;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LCHideAndSeekMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LCHideAndSeekMod")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2c31fa94-da26-4c78-be27-a22e4a8196e8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LCHideAndSeekMod
{
[BepInPlugin("Tibnan.LCHideAndSeekMod", "LCHideAndSeekMod", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ModBase : BaseUnityPlugin
{
private const string guid = "Tibnan.LCHideAndSeekMod";
private const string modName = "LCHideAndSeekMod";
private const string version = "1.0.0";
public static ManualLogSource mls;
private readonly Harmony harmony = new Harmony("Tibnan.LCHideAndSeekMod");
public static ModBase Instance;
public static Font ModFont;
public static ConfigFile ModConfig = new ConfigFile("Tibnan.LCHideAndSeekMod", true);
public void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
mls = Logger.CreateLogSource("LCHideAndSeekMod");
harmony.PatchAll(Assembly.GetExecutingAssembly());
AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lcrm"));
ModFont = val.LoadAsset<Font>("Assets\\lcrm\\PerfectDOSVGA437.ttf");
ConfigProcessor.AddConfigItems();
mls.LogInfo((object)"LC Hide and Seek mod loaded.");
}
}
}
namespace LCHideAndSeekMod.Patches
{
[HarmonyPatch(typeof(HUDManager))]
internal class HUDManagerPatch
{
[HarmonyPatch("ApplyPenalty")]
[HarmonyPrefix]
public static bool StopPenalty(HUDManager __instance)
{
return false;
}
[HarmonyPatch("AddTextToChatOnServer")]
[HarmonyPrefix]
public static bool StopTextChatSrv(HUDManager __instance)
{
return false;
}
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update(ref HUDElement ___Clock)
{
if (ConfigProcessor.Config.AlwaysShowClock)
{
___Clock.targetAlpha = 1f;
}
if (ConfigProcessor.Config.QuickRefreshClock)
{
TimeOfDay.Instance.RefreshClockUI();
}
return true;
}
[HarmonyPatch("DisplayDaysLeft")]
[HarmonyPrefix]
public static bool StopDisplayDaysLeft(HUDManager __instance)
{
return false;
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class PlayerControllerBPatch
{
[HarmonyPatch("ConnectClientToPlayerObject")]
[HarmonyPostfix]
public static void Setup(PlayerControllerB __instance)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Expected O, but got Unknown
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Expected O, but got Unknown
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Expected O, but got Unknown
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Expected O, but got Unknown
((Component)__instance).gameObject.AddComponent<CustomUI>();
if (!NetworkManager.Singleton.IsServer)
{
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Tibnan.hnsmod_ClientReceivesRoleMSG", new HandleNamedMessageDelegate(GameManager.SetRole));
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Tibnan.hnsmod_ClientRefreshPlayerComps", new HandleNamedMessageDelegate(GameManager.RefreshPlayerComps));
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Tibnan.hnsmod_ShowRoles", new HandleNamedMessageDelegate(GameManager.ShowRoles));
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Tibnan.hnsmod_EndGame", new HandleNamedMessageDelegate(GameManager.EndGameClient));
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Tibnan.hnsmod_ShotgunSpawned", new HandleNamedMessageDelegate(GameManager.GrabShotgunIfSeeker));
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Tibnan.hnsmod_ClientReceivesBroadcastMsg", new HandleNamedMessageDelegate(CustomUI.ProcessBroadcastMessage));
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Tibnan.hnsmod_RecalcTime", new HandleNamedMessageDelegate(GameManager.RecalcTime));
}
if (ConfigProcessor.Config.DisplayWarning)
{
HUDManager.Instance.DisplayTip("Caution", "Playing Hide n Seek. Several core gameplay features disabled.", false, false, "LC_Tip1");
}
}
[HarmonyPatch("KillPlayer")]
[HarmonyPrefix]
public static bool StopKillPlayer()
{
return ConfigProcessor.Config.CanSeekerDie;
}
}
[HarmonyPatch(typeof(RoundManager))]
internal class RoundManagerPatch
{
[HarmonyPatch("SpawnEnemyFromVent")]
[HarmonyPrefix]
public static bool StopSpawnEnemyFromVent(RoundManager __instance)
{
return false;
}
[HarmonyPatch("SpawnEnemyOnServer")]
[HarmonyPrefix]
public static bool StopSpawnEnemyOnServer(RoundManager __instance)
{
return false;
}
[HarmonyPatch("SpawnDaytimeEnemiesOutside")]
[HarmonyPrefix]
public static bool StopSpawnDaytimeEnemiesOutside(RoundManager __instance)
{
return false;
}
[HarmonyPatch("BeginEnemySpawning")]
[HarmonyPrefix]
public static bool StopBeginEnemySpawning(RoundManager __instance)
{
return false;
}
[HarmonyPatch("SpawnEnemiesOutside")]
[HarmonyPrefix]
public static bool StopSpawnEnemiesOutside(RoundManager __instance)
{
return false;
}
}
[HarmonyPatch(typeof(ShotgunItem))]
internal class ShotgunItemPatch
{
[HarmonyPatch("ShootGun")]
[HarmonyPostfix]
public static void ResetShells(ShotgunItem __instance)
{
__instance.shellsLoaded = 2;
}
}
[HarmonyPatch(typeof(StartMatchLever))]
internal class StartMatchLeverPatch
{
[HarmonyPatch("LeverAnimation")]
[HarmonyPrefix]
public static bool CheckPlayerCount()
{
ModBase.mls.LogWarning((object)("Checking player count..." + (StartOfRound.Instance.connectedPlayersAmount + 1)));
bool flag = StartOfRound.Instance.connectedPlayersAmount > 0;
if (!flag)
{
((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<CustomUI>().ShowLocalMessage("<color=red>At least 2 players are required to start.</color>", 2);
}
return flag;
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal class StartOfRoundPatch
{
[HarmonyPatch("StartGame")]
[HarmonyPostfix]
public static void StartHNS(StartOfRound __instance)
{
StartOfRound.Instance.currentLevel.Enemies.ForEach(delegate(SpawnableEnemyWithRarity x)
{
x.enemyType.spawningDisabled = true;
});
if (NetworkManager.Singleton.IsServer)
{
GameManager.StartGame(StartOfRound.Instance.connectedPlayersAmount);
}
}
[HarmonyPatch("EndOfGameClientRpc")]
[HarmonyPostfix]
public static void ResetPlayers(StartOfRound __instance)
{
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
HNSPlayerComponent component = ((Component)val).gameObject.GetComponent<HNSPlayerComponent>();
if ((Object)(object)component != (Object)null)
{
component.Role = PlayerRole.None;
}
}
TimeOfDay.Instance.timeUntilDeadline = 3240f;
}
[HarmonyPatch("ShipLeaveAutomatically")]
[HarmonyPostfix]
public static void GrabShipLeaveTime(ref bool leavingOnMidnight)
{
GameManager.Instance.ShipLeavingTime = Utils.CalcTime(TimeOfDay.Instance.normalizedTimeOfDay + (leavingOnMidnight ? 0f : 0.1f), TimeOfDay.Instance.numberOfHours);
GameManager.Instance.ShipLeavingEarly = true;
}
}
[HarmonyPatch(typeof(Terminal))]
internal class TerminalPatch
{
private protected static readonly Regex randomRegex = new Regex("(?i)r(a)?n(d)?o(m)?|rand|rnd");
[HarmonyPatch("OnSubmit")]
[HarmonyPrefix]
public static bool CheckForModKeyword(Terminal __instance)
{
if (StartOfRound.Instance.inShipPhase)
{
string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).ToLower();
ModBase.mls.LogInfo((object)"PARSED SENTENCE:");
ModBase.mls.LogInfo((object)text);
if (randomRegex.IsMatch(text))
{
int num = new Random().Next(1, 13);
while (num == 11 || num == 3)
{
num = new Random().Next(1, 13);
}
StartOfRound.Instance.ChangeLevelServerRpc(num, __instance.groupCredits);
__instance.screenText.text = "";
__instance.QuitTerminal(true);
return false;
}
return true;
}
return true;
}
}
[HarmonyPatch(typeof(TimeOfDay))]
internal class TimeOfDayPatch
{
[HarmonyPatch("UpdateProfitQuotaCurrentTime")]
[HarmonyPrefix]
public static bool StopUpdateProfitQuotaCurrentTime(TimeOfDay __instance)
{
return false;
}
}
}
namespace LCHideAndSeekMod.Core
{
internal class ConfigProcessor
{
private bool startShipEarly = true;
private bool uiShow = true;
private bool displayWarning = true;
private bool alwaysShowClock = true;
private bool quickRefreshClock = true;
private bool canSeekerDie = true;
public static ConfigProcessor Config;
public bool StartShipEarly
{
get
{
return startShipEarly;
}
set
{
startShipEarly = value;
}
}
public bool UIShow
{
get
{
return uiShow;
}
set
{
uiShow = value;
}
}
public bool DisplayWarning
{
get
{
return displayWarning;
}
set
{
displayWarning = value;
}
}
public bool AlwaysShowClock
{
get
{
return alwaysShowClock;
}
set
{
alwaysShowClock = value;
}
}
public bool QuickRefreshClock
{
get
{
return quickRefreshClock;
}
set
{
quickRefreshClock = value;
}
}
public bool CanSeekerDie
{
get
{
return canSeekerDie;
}
set
{
canSeekerDie = value;
}
}
public static void AddConfigItems()
{
//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Expected O, but got Unknown
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Expected O, but got Unknown
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ee: Expected O, but got Unknown
//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Expected O, but got Unknown
//IL_0203: Unknown result type (might be due to invalid IL or missing references)
//IL_020a: Expected O, but got Unknown
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Expected O, but got Unknown
ConfigEntry<bool> leaveConfig = ModBase.ModConfig.Bind<bool>("Gameplay", "Start Ship Early", true, "Makes the ship leave early when only 1 hider is left.");
leaveConfig.SettingChanged += delegate
{
Config.StartShipEarly = leaveConfig.Value;
};
ConfigEntry<bool> UIShowConfig = ModBase.ModConfig.Bind<bool>("Gameplay", "Show Custom UI Elements", true, "Shows UI elements related to current player role and game status.");
UIShowConfig.SettingChanged += delegate
{
Config.UIShow = UIShowConfig.Value;
};
ConfigEntry<bool> displayWarn = ModBase.ModConfig.Bind<bool>("Gameplay", "Display Gamemode Warning", true, "Displays a warning when entering the game.");
displayWarn.SettingChanged += delegate
{
Config.DisplayWarning = displayWarn.Value;
};
ConfigEntry<bool> alwaysShowClock = ModBase.ModConfig.Bind<bool>("Gameplay", "Always Show Clock", true, "Always shows the clock, even in the facility.");
alwaysShowClock.SettingChanged += delegate
{
Config.AlwaysShowClock = alwaysShowClock.Value;
};
ConfigEntry<bool> quickRefreshClock = ModBase.ModConfig.Bind<bool>("Gameplay", "Swift Clock Refresh", true, "Refresh the clock every second instead of every 4 seconds.");
quickRefreshClock.SettingChanged += delegate
{
Config.QuickRefreshClock = quickRefreshClock.Value;
};
ConfigEntry<bool> seekerDeathConfig = ModBase.ModConfig.Bind<bool>("Gameplay", "Allow Seeker Death", true, "Allows the seeker to die.");
seekerDeathConfig.SettingChanged += delegate
{
Config.CanSeekerDie = seekerDeathConfig.Value;
};
Config = new ConfigProcessor
{
startShipEarly = leaveConfig.Value,
uiShow = UIShowConfig.Value,
displayWarning = displayWarn.Value,
alwaysShowClock = alwaysShowClock.Value,
quickRefreshClock = quickRefreshClock.Value,
canSeekerDie = seekerDeathConfig.Value
};
BoolCheckBoxConfigItem val = new BoolCheckBoxConfigItem(leaveConfig, false);
BoolCheckBoxConfigItem val2 = new BoolCheckBoxConfigItem(UIShowConfig, false);
BoolCheckBoxConfigItem val3 = new BoolCheckBoxConfigItem(displayWarn, false);
BoolCheckBoxConfigItem val4 = new BoolCheckBoxConfigItem(alwaysShowClock, false);
BoolCheckBoxConfigItem val5 = new BoolCheckBoxConfigItem(quickRefreshClock, false);
BoolCheckBoxConfigItem val6 = new BoolCheckBoxConfigItem(seekerDeathConfig, false);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val2);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val3);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val4);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val5);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val6);
}
}
internal class CustomUI : NetworkBehaviour
{
private GameObject canvasObject;
private GameObject canvasTextObject;
private Text canvasText;
private Coroutine fadeCoroutine;
private PlayerControllerB ownerPlayer;
private bool updateOverridden = false;
private HNSPlayerComponent localHNSComponent;
private void Awake()
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Expected O, but got Unknown
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: 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)
canvasObject = new GameObject();
canvasObject.transform.parent = ((Component)this).transform;
((Object)canvasObject).name = "CustomUICanvas";
Canvas val = canvasObject.AddComponent<Canvas>();
canvasObject.SetActive(false);
val.renderMode = (RenderMode)0;
canvasObject.AddComponent<CanvasScaler>();
CanvasGroup val2 = canvasObject.AddComponent<CanvasGroup>();
val2.blocksRaycasts = false;
canvasObject.AddComponent<GraphicRaycaster>();
canvasTextObject = new GameObject();
((Object)canvasTextObject).name = "CustomUICanvasText";
Text val3 = (canvasText = canvasTextObject.AddComponent<Text>());
Transform transform = canvasTextObject.transform;
Rect rect = ((Component)val).GetComponent<RectTransform>().rect;
float num = ((Rect)(ref rect)).width / 2f - 20f;
rect = ((Component)val).GetComponent<RectTransform>().rect;
transform.localPosition = new Vector3(num, ((Rect)(ref rect)).height / 2f - 75f, 0f);
val3.text = "";
val3.font = ModBase.ModFont;
val3.alignment = (TextAnchor)7;
((Graphic)val3).rectTransform.sizeDelta = new Vector2(500f, 400f);
val3.fontSize = 26;
((Component)val3).transform.parent = canvasObject.transform;
val3.supportRichText = true;
ownerPlayer = GameNetworkManager.Instance.localPlayerController;
((MonoBehaviour)this).StartCoroutine(WaitForHNSComponent());
}
private IEnumerator WaitForHNSComponent()
{
yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)((Component)ownerPlayer).gameObject.GetComponent<HNSPlayerComponent>() != (Object)null));
ModBase.mls.LogInfo((object)"Assigning hns comp to ui");
localHNSComponent = ((Component)ownerPlayer).gameObject.GetComponent<HNSPlayerComponent>();
}
public static void BroadcastMessage(string msg, int fadeDuration = 0, bool includeServer = true)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
if (NetworkManager.Singleton.IsServer)
{
char[] array = msg.ToCharArray();
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(4 + 2 * array.Length + 4, (Allocator)2, -1);
int num = array.Length;
((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
for (int i = 0; i < array.Length; i++)
{
((FastBufferWriter)(ref val)).WriteValueSafe<char>(ref array[i], default(ForPrimitives));
}
((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref fadeDuration, default(ForPrimitives));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("Tibnan.hnsmod_ClientReceivesBroadcastMsg", val, (NetworkDelivery)2);
if (includeServer)
{
CustomUI component = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<CustomUI>();
component.ShowLocalMessage(msg, fadeDuration);
}
}
}
public static void BroadcastMessage(string msg, int fadeDuration = 0, bool includeServer = true, params ulong[] clients)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
if (NetworkManager.Singleton.IsServer)
{
char[] array = msg.ToCharArray();
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(4 + 2 * array.Length + 4, (Allocator)2, -1);
int num = array.Length;
((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
for (int i = 0; i < array.Length; i++)
{
((FastBufferWriter)(ref val)).WriteValueSafe<char>(ref array[i], default(ForPrimitives));
}
((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref fadeDuration, default(ForPrimitives));
foreach (ulong num2 in clients)
{
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Tibnan.hnsmod_ClientReceivesBroadcastMsg", num2, val, (NetworkDelivery)2);
}
if (includeServer)
{
CustomUI component = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<CustomUI>();
component.ShowLocalMessage(msg, fadeDuration);
}
}
}
public static void ProcessBroadcastMessage(ulong _, FastBufferReader reader)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
string text = "";
int num = default(int);
((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
char c = default(char);
for (int i = 0; i < num; i++)
{
((FastBufferReader)(ref reader)).ReadValueSafe<char>(ref c, default(ForPrimitives));
text += c;
}
int duration = default(int);
((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref duration, default(ForPrimitives));
CustomUI component = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<CustomUI>();
component.ShowLocalMessage(text, duration);
}
private void Update()
{
if (!updateOverridden && ConfigProcessor.Config.UIShow && GameManager.Instance.GameRunning)
{
if (localHNSComponent.Role == PlayerRole.Hider)
{
SetText($"<color=white>Round {GameManager.RoundCount}: Hiders left: {GameManager.Instance.HidersCount}</color>", overrideUpdate: false);
Show(show: true);
}
else if (localHNSComponent.Role == PlayerRole.Seeker && TimeOfDay.Instance.shipLeavingAlertCalled)
{
SetText($"<color=red>Round {GameManager.RoundCount}: Hiders left: {GameManager.Instance.HidersCount}\nShip leaving at: {GameManager.Instance.ShipLeavingTime}</color>", overrideUpdate: false);
Show(show: true);
}
}
}
public void WaitUntilFadeThenDo(Action action, int duration = -1)
{
((MonoBehaviour)this).StartCoroutine(WaitForFade(action, duration));
}
private IEnumerator WaitForFade(Action action, int duration)
{
FadeOut(duration);
yield return (object)new WaitUntil((Func<bool>)(() => !canvasObject.activeInHierarchy));
action();
}
public void SetText(string text, bool overrideUpdate = true)
{
canvasText.text = text;
updateOverridden = overrideUpdate;
}
public void Show(bool show)
{
canvasObject.SetActive(show);
}
public void FadeOut(int duration = -1)
{
if (duration != -1)
{
if (fadeCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(fadeCoroutine);
}
fadeCoroutine = ((MonoBehaviour)this).StartCoroutine(FadeTextOutCoroutine(duration));
}
}
public void ShowLocalMessage(string msg, int duration = 0)
{
SetText(msg);
Show(show: true);
FadeOut(duration);
}
private IEnumerator FadeTextOutCoroutine(int duration)
{
float alpha = 1f;
((Graphic)canvasText).canvasRenderer.SetAlpha(alpha);
yield return (object)new WaitForSeconds((float)duration);
while (alpha > 0f)
{
alpha -= 0.01f;
((Graphic)canvasText).canvasRenderer.SetAlpha(alpha);
yield return null;
}
Show(show: false);
((Graphic)canvasText).canvasRenderer.SetAlpha(1f);
updateOverridden = false;
}
}
internal class GameManager : MonoBehaviour
{
private enum GameState
{
WaitingForPlayers,
InGame,
GameOver
}
private enum GameResult
{
None,
HiderWin,
SeekerWin,
Draw
}
private GameObject obj;
private PlayerControllerB seeker;
private List<PlayerControllerB> hiders = new List<PlayerControllerB>();
private GameState gameState = GameState.WaitingForPlayers;
private GameResult gameResult = GameResult.None;
private bool shipLeavingEarly = false;
private bool twoPlayerMode;
private string shipLeavingTime = "";
private List<PlayerControllerB> activePlayers = new List<PlayerControllerB>();
public static GameManager Instance = new GameManager();
public static int RoundCount = 1;
public bool GameRunning => gameState == GameState.InGame;
public int HidersCount
{
get
{
if (NetworkManager.Singleton.IsServer)
{
return hiders.Count;
}
return hiders.Count((PlayerControllerB x) => !x.isPlayerDead && !x.disconnectedMidGame);
}
}
public string ShipLeavingTime
{
get
{
return shipLeavingTime;
}
set
{
shipLeavingTime = value;
}
}
public bool ShipLeavingEarly
{
get
{
return shipLeavingEarly;
}
set
{
shipLeavingEarly = value;
}
}
public void Update()
{
switch (gameState)
{
case GameState.WaitingForPlayers:
break;
case GameState.InGame:
hiders.RemoveAll((PlayerControllerB x) => x.isPlayerDead || x.disconnectedMidGame);
if (seeker.isPlayerDead || seeker.disconnectedMidGame)
{
gameResult = GameResult.HiderWin;
if (hiders.Count < 1)
{
gameResult = GameResult.Draw;
}
gameState = GameState.GameOver;
}
else if (hiders.Count < 1)
{
gameResult = GameResult.SeekerWin;
gameState = GameState.GameOver;
}
if (StartOfRound.Instance.shipIsLeaving || StartOfRound.Instance.shipLeftAutomatically)
{
gameResult = GameResult.HiderWin;
gameState = GameState.GameOver;
}
if (ConfigProcessor.Config.StartShipEarly && hiders.Count == 1 && !shipLeavingEarly && !twoPlayerMode)
{
MakeShipLeaveEarly();
}
break;
case GameState.GameOver:
Instance.StopGame();
break;
}
}
private void MakeShipLeaveEarly()
{
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
TimeOfDay.Instance.SetShipLeaveEarlyClientRpc(TimeOfDay.Instance.normalizedTimeOfDay + 0.1f, 0);
shipLeavingTime = Utils.CalcTime(TimeOfDay.Instance.normalizedTimeOfDay + 0.1f, TimeOfDay.Instance.numberOfHours);
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Tibnan.hnsmod_RecalcTime", seeker.playerClientId, val, (NetworkDelivery)2);
shipLeavingEarly = true;
}
private void StopGame()
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
if (gameState == GameState.GameOver)
{
ModBase.mls.LogInfo((object)("SENDING END MESSAGE WITH RESULT " + gameResult));
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
((FastBufferWriter)(ref val)).WriteValueSafe<GameResult>(ref gameResult, default(ForEnums));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("Tibnan.hnsmod_EndGame", val, (NetworkDelivery)2);
StartOfRound.Instance.EndGameClientRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId);
gameState = GameState.WaitingForPlayers;
EndGame(gameResult);
}
}
private void GrantSeekerShotgun()
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
GameObject val = Object.Instantiate<GameObject>(StartOfRound.Instance.allItemsList.itemsList.Find((Item x) => x.itemName == "Shotgun").spawnPrefab, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position, Quaternion.identity);
NetworkObject component = val.GetComponent<NetworkObject>();
val.SetActive(true);
component.Spawn(false);
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
if (((Component)localPlayerController).gameObject.GetComponent<HNSPlayerComponent>().Role == PlayerRole.Seeker)
{
ModBase.mls.LogInfo((object)"Grabbing shotgun on server");
Traverse val2 = Traverse.Create((object)localPlayerController);
val2.Field("currentlyGrabbingObject").SetValue((object)val.GetComponent<GrabbableObject>());
object? value = typeof(PlayerControllerB).GetField("currentlyGrabbingObject", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(localPlayerController);
((GrabbableObject)((value is GrabbableObject) ? value : null)).InteractItem();
typeof(PlayerControllerB).GetMethod("GrabObjectServerRpc", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(localPlayerController, new object[1] { (object)new NetworkObjectReference(component) });
MethodInfo method = typeof(PlayerControllerB).GetMethod("GrabObject", BindingFlags.Instance | BindingFlags.NonPublic);
IEnumerator enumerator = (IEnumerator)method.Invoke(localPlayerController, null);
((MonoBehaviour)this).StartCoroutine(enumerator);
}
FastBufferWriter val3 = default(FastBufferWriter);
((FastBufferWriter)(ref val3))..ctor(8, (Allocator)2, -1);
ulong networkObjectId = component.NetworkObjectId;
((FastBufferWriter)(ref val3)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("Tibnan.hnsmod_ShotgunSpawned", val3, (NetworkDelivery)2);
}
public static void StartGame(int playerCount)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
Instance.obj = new GameObject("HNSManager");
Instance = Instance.obj.AddComponent<GameManager>();
Instance.twoPlayerMode = playerCount == 1;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val2 in allPlayerScripts)
{
if ((val2.isPlayerControlled || val2.isPlayerDead) && (Object)(object)((Component)val2).gameObject.GetComponent<HNSPlayerComponent>() == (Object)null)
{
((Component)val2).gameObject.AddComponent<HNSPlayerComponent>();
}
}
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("Tibnan.hnsmod_ClientRefreshPlayerComps", val, (NetworkDelivery)2);
Instance.activePlayers = StartOfRound.Instance.allPlayerScripts.ToList().FindAll((PlayerControllerB x) => (Object)(object)((Component)x).gameObject.GetComponent<HNSPlayerComponent>() != (Object)null);
Instance.seeker = Instance.activePlayers.ElementAt(new Random().Next(0, Instance.activePlayers.Count));
((Component)Instance.seeker).GetComponent<HNSPlayerComponent>().Role = PlayerRole.Seeker;
ModBase.mls.LogWarning((object)("Choosing seeker: " + Instance.seeker.playerUsername + " " + ((Component)Instance.seeker).gameObject.GetComponent<HNSPlayerComponent>().Role));
SendRoleMessage(Instance.seeker.playerClientId, PlayerRole.Seeker);
Instance.activePlayers.ForEach(delegate(PlayerControllerB x)
{
HNSPlayerComponent component3 = ((Component)x).gameObject.GetComponent<HNSPlayerComponent>();
if (component3.Role != PlayerRole.Seeker)
{
component3.Role = PlayerRole.Hider;
Instance.hiders.Add(x);
SendRoleMessage(x.playerClientId, PlayerRole.Hider);
}
ModBase.mls.LogWarning((object)(x.playerUsername + " " + component3.Role));
});
Instance.GrantSeekerShotgun();
Instance.gameState = GameState.InGame;
if (ConfigProcessor.Config.UIShow)
{
CustomUI component = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<CustomUI>();
HNSPlayerComponent component2 = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<HNSPlayerComponent>();
component.ShowLocalMessage((component2.Role == PlayerRole.Seeker) ? "<color=red>You are a seeker.</color>" : "<color=white>You are a hider.</color>", 10);
}
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("Tibnan.hnsmod_ShowRoles", val, (NetworkDelivery)2);
}
private static void SendRoleMessage(ulong id, PlayerRole role)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(12, (Allocator)2, -1);
((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref id, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteValueSafe<PlayerRole>(ref role, default(ForEnums));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("Tibnan.hnsmod_ClientReceivesRoleMSG", val, (NetworkDelivery)2);
}
public static void SetRole(ulong _, FastBufferReader reader)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: 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)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
ulong num = default(ulong);
((FastBufferReader)(ref reader)).ReadValue<ulong>(ref num, default(ForPrimitives));
PlayerRole playerRole = default(PlayerRole);
((FastBufferReader)(ref reader)).ReadValue<PlayerRole>(ref playerRole, default(ForEnums));
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[num];
((Component)val).GetComponent<HNSPlayerComponent>().Role = playerRole;
ModBase.mls.LogError((object)(val.playerUsername + " " + ((Component)val).gameObject.GetComponent<HNSPlayerComponent>().Role));
if (playerRole == PlayerRole.Seeker)
{
Instance.seeker = val;
}
else
{
Instance.hiders.Add(val);
}
}
private void ShowEndGameMessage(GameResult result)
{
CustomUI component = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<CustomUI>();
HNSPlayerComponent component2 = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<HNSPlayerComponent>();
Object.FindObjectsOfType<HNSPlayerComponent>().ToList().ForEach(delegate(HNSPlayerComponent x)
{
ModBase.mls.LogWarning((object)(x.player.playerUsername + " " + x.Role));
});
switch (result)
{
case GameResult.Draw:
component.ShowLocalMessage("<color=yellow>The game result was a draw!</color>", 5);
break;
case GameResult.SeekerWin:
if (component2.Role == PlayerRole.Seeker)
{
component.ShowLocalMessage("<color=green>You won as the seeker!</color>", 5);
}
else
{
component.ShowLocalMessage("<color=red>The seeker won this round!</color>", 5);
}
break;
case GameResult.HiderWin:
if (component2.Role == PlayerRole.Hider)
{
component.ShowLocalMessage("<color=green>You won as one of the hiders!</color>", 5);
}
else
{
component.ShowLocalMessage("<color=red>The hiders won this round!</color>", 5);
}
break;
}
}
public static void EndGameClient(ulong _, FastBufferReader reader)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
GameResult result = default(GameResult);
((FastBufferReader)(ref reader)).ReadValueSafe<GameResult>(ref result, default(ForEnums));
Instance.gameState = GameState.WaitingForPlayers;
Instance.EndGame(result);
}
private void EndGame(GameResult result)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
foreach (PlayerControllerB activePlayer in Instance.activePlayers)
{
if ((Object)(object)activePlayer != (Object)null && !activePlayer.isPlayerDead)
{
activePlayer.DropAllHeldItems(true, false);
activePlayer.TeleportPlayer(StartOfRound.Instance.playerSpawnPositions[(uint)activePlayer.playerClientId].position, false, 0f, false, true);
}
}
if (NetworkManager.Singleton.IsServer)
{
ShotgunItem[] array = Object.FindObjectsOfType<ShotgunItem>();
ShotgunItem[] array2 = array;
foreach (ShotgunItem val in array2)
{
((NetworkBehaviour)val).NetworkObject.Despawn(true);
}
}
if (ConfigProcessor.Config.UIShow)
{
Instance.ShowEndGameMessage(result);
((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<CustomUI>().WaitUntilFadeThenDo(delegate
{
RoundCount++;
}, 5);
}
else
{
RoundCount++;
}
hiders.Clear();
shipLeavingTime = "";
}
public static void RefreshPlayerComps(ulong _, FastBufferReader __)
{
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
if ((val.isPlayerControlled || val.isPlayerDead) && (Object)(object)((Component)val).gameObject.GetComponent<HNSPlayerComponent>() == (Object)null)
{
((Component)val).gameObject.AddComponent<HNSPlayerComponent>();
Instance.activePlayers.Add(val);
}
}
}
public static void ShowRoles(ulong _, FastBufferReader __)
{
if (ConfigProcessor.Config.UIShow)
{
CustomUI component = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<CustomUI>();
HNSPlayerComponent component2 = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<HNSPlayerComponent>();
component.ShowLocalMessage((component2.Role == PlayerRole.Seeker) ? "<color=red>You are a seeker.</color>" : "<color=white>You are a hider.</color>", 10);
}
Instance.gameState = GameState.InGame;
}
public static void GrabShotgunIfSeeker(ulong _, FastBufferReader reader)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
ulong key = default(ulong);
((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref key, default(ForPrimitives));
NetworkObject val = NetworkManager.Singleton.SpawnManager.SpawnedObjects[key];
GameObject gameObject = ((Component)val).gameObject;
ModBase.mls.LogError((object)((Object)gameObject).name);
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
if (((Component)localPlayerController).gameObject.GetComponent<HNSPlayerComponent>().Role == PlayerRole.Seeker)
{
ModBase.mls.LogInfo((object)"Trying to grab spawned shotgun on client");
Traverse val2 = Traverse.Create((object)localPlayerController);
val2.Field("currentlyGrabbingObject").SetValue((object)gameObject.GetComponent<GrabbableObject>());
object? value = typeof(PlayerControllerB).GetField("currentlyGrabbingObject", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(localPlayerController);
((GrabbableObject)((value is GrabbableObject) ? value : null)).InteractItem();
typeof(PlayerControllerB).GetMethod("GrabObjectServerRpc", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(localPlayerController, new object[1] { (object)new NetworkObjectReference(val) });
MethodInfo method = typeof(PlayerControllerB).GetMethod("GrabObject", BindingFlags.Instance | BindingFlags.NonPublic);
IEnumerator enumerator = (IEnumerator)method.Invoke(localPlayerController, null);
((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(enumerator);
}
}
public static void RecalcTime(ulong _, FastBufferReader __)
{
Instance.shipLeavingTime = Utils.CalcTime(TimeOfDay.Instance.normalizedTimeOfDay + 0.1f, TimeOfDay.Instance.numberOfHours);
}
}
public enum PlayerRole
{
Hider,
Seeker,
None
}
internal class HNSPlayerComponent : MonoBehaviour
{
public PlayerRole Role = PlayerRole.None;
public PlayerControllerB player;
public void Awake()
{
player = ((Component)this).GetComponent<PlayerControllerB>();
}
}
internal static class Utils
{
public static string CalcTime(float timeNormalized, float numberOfHours)
{
int num = (int)(timeNormalized * (60f * numberOfHours)) + 360;
int num2 = (int)Mathf.Floor((float)(num / 60));
if (num2 >= 24)
{
return "12:00 AM";
}
string text = ((num2 >= 12) ? "PM" : "AM");
if (num2 > 12)
{
num2 %= 12;
}
int num3 = num % 60;
return $"{num2:00}:{num3:00}".TrimStart(new char[1] { '0' }) + text;
}
}
}