Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LethalTraitor v1.0.2
BepInEx/plugins/Azx-LethalTraitor/LethalTraitor.dll
Decompiled 5 months agousing 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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Coroner; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalNetworkAPI; using LethalTraitor; using LethalTraitor.Helpers; using LethalTraitor.UI; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LethalTraitor")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LethalTraitor")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3f720655-fddc-48fb-ba7b-a1bc63f31f9d")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] internal static class LethalConfigCompat { [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void Register(ConfigEntry<bool> boolConfigEntry) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig")) { LethalConfigManager.SkipAutoGenFor((ConfigEntryBase)(object)boolConfigEntry); LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(boolConfigEntry, false)); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void Register(ConfigEntry<int> intConfigEntry) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig")) { LethalConfigManager.SkipAutoGenFor((ConfigEntryBase)(object)intConfigEntry); LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(intConfigEntry, false)); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void Register(ConfigEntry<float> floatConfigEntry) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig")) { LethalConfigManager.SkipAutoGenFor((ConfigEntryBase)(object)floatConfigEntry); LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(floatConfigEntry, false)); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void Register(ConfigEntry<string> stringConfigEntry) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig")) { LethalConfigManager.SkipAutoGenFor((ConfigEntryBase)(object)stringConfigEntry); LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(stringConfigEntry, false)); } } } internal static class FontLoader { private static TMP_FontAsset _cached; internal static TMP_FontAsset Load() { if ((Object)(object)_cached != (Object)null) { return _cached; } string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets", "lethaltraitorassets"); AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)("Failed to load AssetBundle at: " + text)); return null; } val.LoadAllAssets(); TMP_FontAsset val2 = val.LoadAllAssets<TMP_FontAsset>().FirstOrDefault(); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogError((object)"AssetBundle contained no TMP_FontAsset."); val.Unload(false); return null; } ((Object)val2).name = "3270"; MaterialReferenceManager.AddFontAsset(val2); if (TMP_Settings.fallbackFontAssets != null && !TMP_Settings.fallbackFontAssets.Contains(val2)) { TMP_Settings.fallbackFontAssets.Add(val2); } val.Unload(false); _cached = val2; LethalTraitor.Debug.Log("Loaded TMP font: " + ((Object)_cached).name); return _cached; } } namespace LethalTraitor { internal static class ConfigSettings { internal static ConfigEntry<int> TraitorChancePercent; internal static ConfigEntry<int> FakeWarningChanceMinPercent; internal static ConfigEntry<int> FakeWarningChanceMaxPercent; internal static ConfigEntry<string> TraitorChanceOverridesCsv; internal static ConfigEntry<string> FakeWarningChanceMinOverridesCsv; internal static ConfigEntry<string> FakeWarningChanceMaxOverridesCsv; private static Dictionary<int, int> _traitorOverrides = new Dictionary<int, int>(); private static Dictionary<int, int> _fakeWarnMinOverrides = new Dictionary<int, int>(); private static Dictionary<int, int> _fakeWarnMaxOverrides = new Dictionary<int, int>(); private static bool _normalizing; internal static int TraitorChance => TraitorChancePercent?.Value ?? 20; internal static int FakeWarningChanceMin => FakeWarningChanceMinPercent?.Value ?? 0; internal static int FakeWarningChanceMax => FakeWarningChanceMaxPercent?.Value ?? 80; internal static void Init(BaseUnityPlugin plugin) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown ConfigFile config = plugin.Config; TraitorChancePercent = config.Bind<int>("Gameplay", "TraitorChance", 20, new ConfigDescription("% chance of a traitor being selected (0-100)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); FakeWarningChanceMinPercent = config.Bind<int>("Gameplay", "FakeWarningChanceMin", 0, new ConfigDescription("% chance of receiving a fake warning (minimum)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); FakeWarningChanceMaxPercent = config.Bind<int>("Gameplay", "FakeWarningChanceMax", 80, new ConfigDescription("% chance of receiving a fake warning (maximum)\nNote: FakeWarningChanceMaxPercent + TraitorChance cannot exceed 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); TraitorChanceOverridesCsv = config.Bind<string>("Gameplay", "TraitorChanceOverrides", "", new ConfigDescription("(Optional) Exact overrides for TraitorChance based on number of players.\nExample: \"3=25, 5=30, 26=100\"\n— This would set the TraitorChance to 25% for 3 players, 30% for 5 players, and 100% for 26 players.\nAny other number of players will use the normal TraitorChance value.", (AcceptableValueBase)null, Array.Empty<object>())); FakeWarningChanceMinOverridesCsv = config.Bind<string>("Gameplay", "FakeWarningChanceMinOverrides", "", new ConfigDescription("(Optional) Exact overrides for FakeWarningChanceMin based on number of players.\nExample: \"2=10, 4=20\"\n— This would set the FakeWarningChanceMin to 10% for 2 players, and 20% for 4 players.\nAny other number of players will use the normal FakeWarningChanceMin value.", (AcceptableValueBase)null, Array.Empty<object>())); FakeWarningChanceMaxOverridesCsv = config.Bind<string>("Gameplay", "FakeWarningChanceMaxOverrides", "", new ConfigDescription("(Optional) Exact overrides for FakeWarningChanceMax based on number of players.\nExample: \"2=20, 3=30, 4=40, 5=50\"\n— This would set the FakeWarningChanceMax to 20% for 2 players, 30% for 3 players, 40% for 4 players, and 50% for 5 players.\nAny other number of players will use the normal FakeWarningChanceMax value.", (AcceptableValueBase)null, Array.Empty<object>())); LethalConfigCompat.Register(TraitorChancePercent); LethalConfigCompat.Register(FakeWarningChanceMinPercent); LethalConfigCompat.Register(FakeWarningChanceMaxPercent); LethalConfigCompat.Register(TraitorChanceOverridesCsv); LethalConfigCompat.Register(FakeWarningChanceMinOverridesCsv); LethalConfigCompat.Register(FakeWarningChanceMaxOverridesCsv); NormalizeAndEnforce(); ReparseOverrides(null, EventArgs.Empty); TraitorChancePercent.SettingChanged += delegate { NormalizeAndEnforce(); }; FakeWarningChanceMinPercent.SettingChanged += delegate { NormalizeAndEnforce(); }; FakeWarningChanceMaxPercent.SettingChanged += delegate { NormalizeAndEnforce(); }; TraitorChanceOverridesCsv.SettingChanged += ReparseOverrides; FakeWarningChanceMinOverridesCsv.SettingChanged += ReparseOverrides; FakeWarningChanceMaxOverridesCsv.SettingChanged += ReparseOverrides; static void ReparseOverrides(object _, EventArgs __) { _traitorOverrides = ParseOverrides(TraitorChanceOverridesCsv.Value); _fakeWarnMinOverrides = ParseOverrides(FakeWarningChanceMinOverridesCsv.Value); _fakeWarnMaxOverrides = ParseOverrides(FakeWarningChanceMaxOverridesCsv.Value); } } internal static void GetChances(int playerCount, out int traitor, out int min, out int max) { traitor = ApplyOverride(TraitorChance, _traitorOverrides, playerCount); min = ApplyOverride(FakeWarningChanceMin, _fakeWarnMinOverrides, playerCount); max = ApplyOverride(FakeWarningChanceMax, _fakeWarnMaxOverrides, playerCount); if (min > max) { int num = max; int num2 = min; min = num; max = num2; } int num3 = 100 - traitor; if (num3 < 0) { num3 = 0; } if (max > num3) { max = num3; } if (min > max) { min = max; } } private static int ApplyOverride(int defaultValue, Dictionary<int, int> map, int players) { if (map != null && map.TryGetValue(players, out var value)) { return Clamp01(value); } return Clamp01(defaultValue); } private static Dictionary<int, int> ParseOverrides(string csv) { Dictionary<int, int> dictionary = new Dictionary<int, int>(); if (string.IsNullOrWhiteSpace(csv)) { return dictionary; } csv = csv.Trim().Trim(new char[1] { '"' }); string[] array = csv.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0) { string[] array2 = text.Split(new char[1] { '=' }); if (array2.Length == 2 && int.TryParse(array2[0].Trim(), out var result) && int.TryParse(array2[1].Trim(), out var result2)) { dictionary[result] = Clamp01(result2); } } } return dictionary; } private static int Clamp01(int v) { if (v >= 0) { if (v <= 100) { return v; } return 100; } return 0; } private static void NormalizeAndEnforce() { if (_normalizing) { return; } _normalizing = true; try { int value = TraitorChancePercent.Value; int num = FakeWarningChanceMinPercent.Value; int num2 = FakeWarningChanceMaxPercent.Value; if (num > num2) { int num3 = num2; num2 = num; num = num3; } int num4 = 100 - value; if (num2 > num4) { num2 = num4; } if (num > num2) { num = num2; } if (TraitorChancePercent.Value != value) { TraitorChancePercent.Value = value; } if (FakeWarningChanceMinPercent.Value != num) { FakeWarningChanceMinPercent.Value = num; } if (FakeWarningChanceMaxPercent.Value != num2) { FakeWarningChanceMaxPercent.Value = num2; } } finally { _normalizing = false; } } } internal class Debug { private static readonly bool debugEnabled; internal static void Log(string message) { if (debugEnabled) { Plugin.Log.LogInfo((object)("LT Debug: " + message)); } } internal static void LogError(string message) { if (debugEnabled) { Plugin.Log.LogInfo((object)("LT Error: " + message)); } } internal static void DumpPlayers(string where) { if (!debugEnabled) { return; } NetworkManager singleton = NetworkManager.Singleton; StartOfRound instance = StartOfRound.Instance; Log($"[{where}] host={Object.op_Implicit((Object)(object)singleton) && (singleton.IsServer || singleton.IsHost)} " + "localId=" + (Object.op_Implicit((Object)(object)singleton) ? singleton.LocalClientId.ToString() : "null") + " " + $"players={(instance?.allPlayerScripts?.Count((PlayerControllerB p) => p.isPlayerControlled)).GetValueOrDefault(-1)}"); if (instance?.allPlayerScripts == null) { return; } PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!((Object)(object)val == (Object)null) && val.isPlayerControlled) { Log($" user='{val.playerUsername}' id={val.actualClientId} " + $"owner={((NetworkBehaviour)val).OwnerClientId} isOwner={((NetworkBehaviour)val).IsOwner} " + $"controlled={val.isPlayerControlled} dead={val.isPlayerDead} " + $"netObj={((NetworkBehaviour)val).NetworkObjectId}"); } } } } internal static class PlayerKiller { [CompilerGenerated] private sealed class <KillRoutine>d__2 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ulong targetClientId; public string reason; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <KillRoutine>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: { <>1__state = -1; Debug.Log($"PKill: begin target={targetClientId} reason='{reason}'"); Debug.DumpPlayers("PKill[start]"); PlayerControllerB pC = GetPC(targetClientId); Debug.Log($"PKill: server sees pcNull={(Object)(object)pC == (Object)null} dead={pC?.isPlayerDead} owner={((pC != null) ? new ulong?(((NetworkBehaviour)pC).OwnerClientId) : null)} isOwner={((pC != null) ? new bool?(((NetworkBehaviour)pC).IsOwner) : null)}"); Debug.Log($"PKill: sending DisciplineMessage -> targetId={targetClientId}"); Plugin.DisciplineMessage?.SendClients(new Plugin.DisciplinePayload { KillerId = targetClientId }); <>2__current = (object)new WaitForSecondsRealtime(0.75f); <>1__state = 1; return true; } case 1: { <>1__state = -1; PlayerControllerB pC = GetPC(targetClientId); Debug.Log($"PKill: post-Discipline check pcNull={(Object)(object)pC == (Object)null} dead={pC?.isPlayerDead}"); if (!((Object)(object)pC != (Object)null) || pC.isPlayerDead) { break; } Debug.Log("PKill: target still alive; invoking KillPlayerClientRpc via reflection as fallback."); if (!TryInvokeKillRpc(pC)) { try { pC.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 0, default(Vector3)); Debug.Log("PKill: fallback KillPlayer() called on server."); if (Type.GetType("Coroner.Plugin, Coroner") != null) { API.SetCauseOfDeath(pC, (AdvancedCauseOfDeath?)Plugin._CompanyDiscipline); } } catch (Exception arg) { Debug.LogError($"PKill: server KillPlayer fallback failed: {arg}"); } } <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 2; return true; } case 2: <>1__state = -1; Debug.DumpPlayers("PKill[end]"); break; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SelfKillRoutine>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ulong myId; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SelfKillRoutine>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } if ((Object)(object)StartOfRound.Instance == (Object)null) { <>2__current = null; <>1__state = 2; return true; } PlayerControllerB pC = GetPC(myId); Debug.Log($"DisciplineClient(match): meNull={(Object)(object)pC == (Object)null} meDead={pC?.isPlayerDead} isOwner={((pC != null) ? new bool?(((NetworkBehaviour)pC).IsOwner) : null)} owner={((pC != null) ? new ulong?(((NetworkBehaviour)pC).OwnerClientId) : null)}"); if ((Object)(object)pC == (Object)null || pC.isPlayerDead) { Debug.Log("DisciplineClient: aborting; null or already dead."); return false; } try { pC.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 0, default(Vector3)); Debug.Log("DisciplineClient: KillPlayer() invoked locally (owner)."); if (Type.GetType("Coroner.Plugin, Coroner") != null) { API.SetCauseOfDeath(pC, (AdvancedCauseOfDeath?)Plugin._CompanyDiscipline); } } catch (Exception arg) { Debug.LogError($"Discipline self-kill failed: {arg}"); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static void Kill(ulong targetClientId, string reason = "") { if ((Object)(object)Plugin.Instance == (Object)null) { Debug.LogError("PlayerKiller: Plugin.Instance is null; cannot start coroutine."); } else { ((MonoBehaviour)Plugin.Instance).StartCoroutine(KillRoutine(targetClientId, reason)); } } internal static void OnDisciplineClient(Plugin.DisciplinePayload msg) { NetworkManager singleton = NetworkManager.Singleton; Debug.Log($"DisciplineClient: nm={(Object)(object)singleton != (Object)null} isClient={((singleton != null) ? new bool?(singleton.IsClient) : null)} localId={((singleton != null) ? new ulong?(singleton.LocalClientId) : null)} msg.killerId={msg.KillerId}"); if (!((Object)(object)singleton == (Object)null) && singleton.IsClient && singleton.LocalClientId == msg.KillerId) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(SelfKillRoutine(msg.KillerId)); } } [IteratorStateMachine(typeof(<KillRoutine>d__2))] private static IEnumerator KillRoutine(ulong targetClientId, string reason) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <KillRoutine>d__2(0) { targetClientId = targetClientId, reason = reason }; } [IteratorStateMachine(typeof(<SelfKillRoutine>d__3))] private static IEnumerator SelfKillRoutine(ulong myId) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SelfKillRoutine>d__3(0) { myId = myId }; } private static bool TryInvokeKillRpc(PlayerControllerB pc) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) try { MethodInfo methodInfo = AccessTools.Method(typeof(PlayerControllerB), "KillPlayerClientRpc", Type.EmptyTypes, (Type[])null); if (methodInfo == null) { return false; } methodInfo.Invoke(pc, null); Debug.Log("PKill: KillPlayerClientRpc() invoked successfully."); if (Type.GetType("Coroner.Plugin, Coroner") != null) { API.SetCauseOfDeath(pc, (AdvancedCauseOfDeath?)Plugin._CompanyDiscipline); } return true; } catch (Exception arg) { Debug.LogError($"PKill: KillPlayerClientRpc reflection invoke failed: {arg}"); return false; } } internal static PlayerControllerB GetPC(ulong clientId) { PlayerControllerB val = StartOfRound.Instance?.allPlayerScripts?.FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB p) => (Object)(object)p != (Object)null && p.actualClientId == clientId)); Debug.Log(string.Format("GetPC({0}) -> {1} dead={2} owner={3} isOwner={4}", clientId, ((Object)(object)val != (Object)null) ? val.playerUsername : "<null>", val?.isPlayerDead, (val != null) ? new ulong?(((NetworkBehaviour)val).OwnerClientId) : null, (val != null) ? new bool?(((NetworkBehaviour)val).IsOwner) : null)); return val; } } [BepInPlugin("Azx.LethalTraitor", "Lethal Traitor", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [Serializable] public struct AssignPayload { public bool Active; public ulong KillerId; public ulong TargetId; public string KillerName; public string TargetName; public bool SendWarning; public int DisplayTraitorChancePercent; } [Serializable] public struct RevealPayload { public string KillerName; public string TargetName; public string ResultKey; public string ResultText; } [Serializable] public struct DisciplinePayload { public ulong KillerId; } [HarmonyPatch(typeof(RoundManager))] private static class RoundHooks { [HarmonyPostfix] [HarmonyPatch("LoadNewLevel")] private static void OnLoadNewLevel() { if (IsHost()) { ((MonoBehaviour)Instance).StartCoroutine(DoAssignmentAfterLandingDelay()); } } [HarmonyPrefix] [HarmonyPatch(typeof(RoundManager), "DetectElevatorIsRunning")] private static void OnShipDoorsCloseAtEndOfRound() { Debug.Log($"DetectElevatorIsRunning: {!IsHost()}, {!MissionActive}, {EarlyDisciplineApplied}"); HUDSettings.ForceHide(); if (IsHost() && MissionActive && !EarlyDisciplineApplied) { PlayerControllerB pC = GetPC(KillerId); PlayerControllerB pC2 = GetPC(TargetId); bool flag = IsAliveAndOnShip(pC); bool flag2 = IsAliveAndOnShip(pC2); Debug.Log($"DetectElevatorIsRunning (2): {KillerId}, {TargetId}, {(Object)(object)pC != (Object)null}, " + $"{!pC.isPlayerDead}, {(Object)(object)pC2 != (Object)null}, {!pC2.isPlayerDead}, " + $"{pC.isPlayerDead}, {pC.isInElevator}, {flag}, " + $"{pC2.isPlayerDead}, {pC2.isInElevator}, {flag2}"); if (flag && flag2) { Debug.Log("EOG: Pre-orbit discipline: both alive at DetectElevatorIsRunning; killing killer now."); EarlyDisciplineApplied = true; PlayerKiller.Kill(KillerId, "discipline-pre-orbit"); } } } } [HarmonyPatch(typeof(StartOfRound))] private static class SoRHooks { [HarmonyPostfix] [HarmonyPatch("EndOfGame")] private static void OnEndOfGame() { Debug.Log($"MissionActive (EOG): {MissionActive}"); if (IsHost() && MissionActive) { Debug.DumpPlayers("EOG[start]"); ulong killerId = KillerId; ulong targetId = TargetId; string killerName = KillerName; string targetName = TargetName; Debug.Log($"EOG: Snapshot: killerId={killerId} targetId={targetId} killer='{killerName}' target='{targetName}'"); PlayerControllerB pC = GetPC(killerId); PlayerControllerB pC2 = GetPC(targetId); bool flag = IsAliveAndOnShip(pC); bool flag2 = IsAliveAndOnShip(pC2); StartOfRound instance = StartOfRound.Instance; bool flag3 = (Object)(object)instance != (Object)null && instance.allPlayerScripts.Any(IsAliveAndOnShip); Debug.Log($"EOG: Flags: anyAlive={flag3} killerAlive={flag} targetAlive={flag2}"); string key; string resultText = Text.GetResultText(flag3, flag || EarlyDisciplineApplied, flag2 || EarlyDisciplineApplied, killerName, targetName, out key); RevealMessage.SendClients(new RevealPayload { KillerName = killerName, TargetName = targetName, ResultKey = key, ResultText = resultText }); Debug.Log("EOG: Reveal sent: key='" + key + "'"); Debug.DumpPlayers("EOG[before-clear]"); MissionActive = false; KillerName = (TargetName = ""); KillerId = (TargetId = 0uL); EarlyDisciplineApplied = false; Debug.Log("MissionActive (1): set to FALSE"); Debug.Log("EOG: Cleared round state."); } } } [CompilerGenerated] private sealed class <DoAssignmentAfterLandingDelay>d__20 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private StartOfRound <sor>5__2; private int <lobbyCount>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DoAssignmentAfterLandingDelay>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <sor>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown int num4; switch (<>1__state) { default: return false; case 0: <>1__state = -1; MissionActive = false; AbortSetupProcess = false; KillerId = (TargetId = 0uL); KillerName = (TargetName = ""); EarlyDisciplineApplied = false; Debug.Log("MissionActive (3): set to FALSE"); goto IL_0078; case 1: <>1__state = -1; goto IL_0078; case 2: <>1__state = -1; goto IL_0129; case 3: { <>1__state = -1; List<PlayerControllerB> list = <sor>5__2.allPlayerScripts.Where((PlayerControllerB p) => (Object)(object)p != (Object)null && p.isPlayerControlled && !p.isPlayerDead).ToList(); ConfigSettings.GetChances(<lobbyCount>5__3, out var traitor, out var min, out var max); Debug.Log($"RNG 1: {<lobbyCount>5__3}, {traitor}, {min}, {max}"); if (list.Count < 2) { AssignMessage.SendClients(new AssignPayload { Active = false, SendWarning = false }); return false; } int num = ((max >= min) ? Random.Range(min, max + 1) : min); int num2 = traitor + num; int num3 = ((<sor>5__2.currentLevel.levelID == 3) ? 180 : Random.Range(1, 101)); bool flag = num3 <= num2; bool flag2 = num3 <= traitor; Debug.Log($"RNG 2: {num}, {num2}, {num3}, {flag}, {flag2}"); if (!flag || AbortSetupProcess) { AssignMessage.SendClients(new AssignPayload { Active = false, SendWarning = false }); AbortSetupProcess = false; return false; } PlayerControllerB val = list[Random.Range(0, list.Count)]; ulong actualClientId = val.actualClientId; string playerUsername = val.playerUsername; int displayTraitorChancePercent = ((num2 > 0) ? Mathf.RoundToInt((float)traitor / (float)num2 * 100f) : 0); if (flag2) { if (list.Count >= 2) { PlayerControllerB val2; do { val2 = list[Random.Range(0, list.Count)]; } while ((Object)(object)val2 == (Object)(object)val); MissionActive = true; KillerId = val2.actualClientId; TargetId = actualClientId; KillerName = val2.playerUsername; TargetName = playerUsername; Debug.Log("MissionActive (0): set to TRUE"); AssignMessage.SendClients(new AssignPayload { Active = true, KillerId = KillerId, TargetId = TargetId, KillerName = KillerName, TargetName = TargetName, SendWarning = true, DisplayTraitorChancePercent = displayTraitorChancePercent }); return false; } flag2 = false; } AssignMessage.SendClients(new AssignPayload { Active = false, KillerId = 0uL, TargetId = actualClientId, KillerName = "", TargetName = playerUsername, SendWarning = true, DisplayTraitorChancePercent = displayTraitorChancePercent }); return false; } IL_0129: if (!StartOfRound.Instance.shipHasLanded) { <>2__current = null; <>1__state = 2; return true; } num4 = Random.Range(17, 81); Debug.Log($"landingDelay: {num4}"); <>2__current = (object)new WaitForSecondsRealtime((float)num4); <>1__state = 3; return true; IL_0078: if ((Object)(object)StartOfRound.Instance == (Object)null) { <>2__current = null; <>1__state = 1; return true; } <sor>5__2 = StartOfRound.Instance; if ((Object)(object)<sor>5__2 == (Object)null || <sor>5__2.allPlayerScripts == null) { AssignMessage.SendClients(new AssignPayload { Active = false, SendWarning = false }); return false; } <lobbyCount>5__3 = <sor>5__2.allPlayerScripts.Where((PlayerControllerB p) => (Object)(object)p != (Object)null && p.isPlayerControlled).ToList().Count; goto IL_0129; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGuid = "Azx.LethalTraitor"; public const string PluginName = "Lethal Traitor"; public const string PluginVersion = "1.0.2"; internal static ManualLogSource Log; internal static Harmony Harmony; internal static Plugin Instance; internal static bool MissionActive; internal static ulong KillerId; internal static ulong TargetId; internal static string KillerName = ""; internal static string TargetName = ""; internal static bool EarlyDisciplineApplied; internal static bool AbortSetupProcess; internal static LNetworkMessage<AssignPayload> AssignMessage; internal static LNetworkMessage<RevealPayload> RevealMessage; internal static LNetworkMessage<DisciplinePayload> DisciplineMessage; internal static AdvancedCauseOfDeath _CompanyDiscipline; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; Harmony = new Harmony("Azx.LethalTraitor"); ConfigSettings.Init((BaseUnityPlugin)(object)this); if (Type.GetType("Coroner.Plugin, Coroner") != null) { _CompanyDiscipline = API.Register("DeathOtherCompanyDiscipline"); } AssignMessage = LNetworkMessage<AssignPayload>.Connect("LethalTraitor.Assign", (Action<AssignPayload, ulong>)null, (Action<AssignPayload>)OnAssignClient, (Action<AssignPayload, ulong>)null); RevealMessage = LNetworkMessage<RevealPayload>.Connect("LethalTraitor.Reveal", (Action<RevealPayload, ulong>)null, (Action<RevealPayload>)OnRevealClient, (Action<RevealPayload, ulong>)null); DisciplineMessage = LNetworkMessage<DisciplinePayload>.Connect("LethalTraitor.Discipline", (Action<DisciplinePayload, ulong>)null, (Action<DisciplinePayload>)PlayerKiller.OnDisciplineClient, (Action<DisciplinePayload, ulong>)null); Harmony.PatchAll(); FontLoader.Load(); Log.LogInfo((object)"Lethal Traitor 1.0.2 loaded."); } private static bool IsHost() { if (Object.op_Implicit((Object)(object)NetworkManager.Singleton)) { if (!NetworkManager.Singleton.IsServer) { return NetworkManager.Singleton.IsHost; } return true; } return false; } private static bool IsAliveAndOnShip(PlayerControllerB pc) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) Bounds bounds = StartOfRound.Instance.shipBounds.bounds; bool flag = ((Bounds)(ref bounds)).Contains(((Component)pc).transform.position); Debug.Log("shipBounds: " + flag + " // isInElevator: " + pc.isInElevator); if ((Object)(object)pc != (Object)null && !pc.isPlayerDead) { if (!flag) { return pc.isInElevator; } return true; } return false; } [IteratorStateMachine(typeof(<DoAssignmentAfterLandingDelay>d__20))] private static IEnumerator DoAssignmentAfterLandingDelay() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DoAssignmentAfterLandingDelay>d__20(0); } private static void OnAssignClient(AssignPayload msg) { Debug.Log("LT LOG: OnAssignClient start."); MissionActive = msg.Active; KillerId = msg.KillerId; TargetId = msg.TargetId; KillerName = msg.KillerName ?? ""; TargetName = msg.TargetName ?? ""; Debug.Log($"MissionActive (X): {MissionActive}, {KillerId}, {TargetId}, {KillerName}, {TargetName}"); if (msg.SendWarning) { HUD.ShowTargetAssignIfLocal(msg.TargetId, msg.DisplayTraitorChancePercent); } if (MissionActive) { HUD.ShowKillerAssignIfLocal(msg.KillerId, msg.TargetName); } } private static void OnRevealClient(RevealPayload msg) { ResultPanel.Show(msg.KillerName, msg.TargetName, msg.ResultText); NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton != (Object)null) || (!singleton.IsServer && !singleton.IsHost)) { MissionActive = false; KillerName = (TargetName = ""); KillerId = (TargetId = 0uL); Debug.Log("MissionActive (2): set to FALSE"); } } internal static PlayerControllerB GetPC(ulong clientId) { return PlayerKiller.GetPC(clientId); } } } namespace LethalTraitor.UI { internal class HUD { public static void ShowKillerAssignIfLocal(ulong killerId, string targetName) { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsClient && singleton.LocalClientId == killerId) { HUDManager.Instance.DisplayTip(Text.GetAlertSubject(), Text.GetKillerAlertBody(targetName), true, false, "LC_Tip1"); HUDSettings.ShowBanner(Text.GetBannerText(targetName), 12f); } } public static void ShowTargetAssignIfLocal(ulong targetId, int percentage) { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsClient && singleton.LocalClientId == targetId) { HUDManager.Instance.DisplayTip(Text.GetAlertSubject(), Text.GetTargetAlertBody(percentage), true, false, "LC_Tip1"); } } } internal class ResultPanel : MonoBehaviour { [CompilerGenerated] private sealed class <FollowPerformanceReportLifecycle>d__36 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ResultPanel <>4__this; private float <searchDeadline>5__2; private float <reportAlphaMax>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FollowPerformanceReportLifecycle>d__36(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; ResultPanel resultPanel = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <searchDeadline>5__2 = Time.unscaledTime + 3f; goto IL_0057; case 1: <>1__state = -1; goto IL_0057; case 2: <>1__state = -1; return false; case 3: { <>1__state = -1; break; } IL_0057: if (!resultPanel.TryBindToPerformanceReport() && Time.unscaledTime < <searchDeadline>5__2) { <>2__current = null; <>1__state = 1; return true; } if ((Object)(object)resultPanel._reportGroup == (Object)null && (Object)(object)resultPanel._reportTransform == (Object)null) { <>2__current = (object)new WaitForSecondsRealtime(3f); <>1__state = 2; return true; } <reportAlphaMax>5__3 = 0f; break; } bool activeInHierarchy; if (!((Object)(object)resultPanel._reportGroup != (Object)null)) { if (!((Object)(object)resultPanel._reportTransform != (Object)null)) { goto IL_01e3; } activeInHierarchy = ((Component)resultPanel._reportTransform).gameObject.activeInHierarchy; } else { activeInHierarchy = ((Component)resultPanel._reportGroup).gameObject.activeInHierarchy; } if (activeInHierarchy) { CanvasGroup reportGroup = resultPanel._reportGroup; float num2 = ((reportGroup != null) ? reportGroup.alpha : 0f); if (num2 > <reportAlphaMax>5__3) { <reportAlphaMax>5__3 = num2; } ((Graphic)resultPanel._bgImg).color = new Color(((Graphic)resultPanel._bgImg).color.r, ((Graphic)resultPanel._bgImg).color.g, ((Graphic)resultPanel._bgImg).color.b, (num2 < 1f) ? 1f : 0f); resultPanel._group.alpha = (resultPanel.TempHide ? 0f : <reportAlphaMax>5__3); if (resultPanel.StayOpen && num2 == 0f && <reportAlphaMax>5__3 > 0f) { resultPanel.StayOpen = false; ((MonoBehaviour)resultPanel).StartCoroutine(resultPanel.GlidePanelRoutine()); } <>2__current = null; <>1__state = 3; return true; } goto IL_01e3; IL_01e3: ((TMP_Text)resultPanel._text).text = ""; resultPanel._group.alpha = 0f; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <GlidePanelRoutine>d__38 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ResultPanel <>4__this; private Vector2 <start>5__2; private Vector2 <end>5__3; private float <dur>5__4; private float <t>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GlidePanelRoutine>d__38(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; ResultPanel resultPanel = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; if ((Object)(object)resultPanel._panelRT == (Object)null) { return false; } <start>5__2 = resultPanel._panelRT.anchoredPosition; float x = resultPanel._panelRT.anchoredPosition.x; float num2 = resultPanel.GlideDownBaseDistance - resultPanel._panelH / 2f; <end>5__3 = <start>5__2 + new Vector2(0f - x, 0f - num2); <dur>5__4 = Mathf.Max(0.0001f, resultPanel.GlideDuration); <t>5__5 = 0f; break; } case 1: <>1__state = -1; break; } if (<t>5__5 < <dur>5__4) { <t>5__5 += Time.unscaledDeltaTime; float num3 = Mathf.Clamp01(<t>5__5 / <dur>5__4); float num4 = 1f - Mathf.Pow(1f - num3, 3f); resultPanel._panelRT.anchoredPosition = Vector2.LerpUnclamped(<start>5__2, <end>5__3, num4); <>2__current = null; <>1__state = 1; return true; } resultPanel._panelRT.anchoredPosition = <end>5__3; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ShowRoutine>d__35 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ResultPanel <>4__this; public string killer; public string target; public string resultText; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ShowRoutine>d__35(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; ResultPanel resultPanel = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSecondsRealtime(0.35f); <>1__state = 1; return true; case 1: <>1__state = -1; if (!resultPanel._vanillaStyleApplied) { resultPanel._vanillaStyleApplied = resultPanel.TryAdoptVanillaReportStyle(); if (!resultPanel._vanillaStyleApplied) { ((Behaviour)resultPanel._bgImg).enabled = true; ((Graphic)resultPanel._bgImg).color = new Color(0.45f, 0f, 0f, 0.55f); } } ((TMP_Text)resultPanel._text).text = Text.GetRevealMessage(killer, target, resultText); resultPanel._group.alpha = 1f; if ((Object)(object)resultPanel._panelRT != (Object)null) { resultPanel._panelRT.anchoredPosition = new Vector2(PanelPos.x, resultPanel._panelRT.anchoredPosition.y); } resultPanel.FitPanelToText(); ((MonoBehaviour)resultPanel).StartCoroutine(resultPanel.FollowPerformanceReportLifecycle()); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static ResultPanel _instance; private Canvas _canvas; private CanvasScaler _scaler; private CanvasGroup _group; private RectTransform _panelRT; private TextMeshProUGUI _text; private bool StayOpen = true; private bool TempHide; private const float BaseW = 1920f; private const float BaseH = 1080f; private static readonly Vector2 PanelPos = new Vector2(29f, -296.5f); private float _panelCenterY; private const float PANEL_W = 500f; private float _panelH = 443f; private const float PAD_L = 24f; private const float PAD_R_SUB = 28f; private const float PAD_V = 22f; private static readonly Color RedLine = new Color(1f, 0.203921f, 0.003922f, 1f); private const float BORDER = 4f; [SerializeField] private readonly float GlideDownBaseDistance = 233f; [SerializeField] private readonly float GlideDuration = 5f; private RectTransform _borderTop; private RectTransform _borderLeft; private RectTransform _borderRight; private RectTransform _borderBottom; private CanvasGroup _reportGroup; private Transform _reportTransform; private RectTransform _bgRT; private Image _bgImg; private bool _vanillaStyleApplied; private void BuildUI() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Expected O, but got Unknown //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Expected O, but got Unknown _canvas = ((Component)this).gameObject.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 10000; _group = ((Component)this).gameObject.AddComponent<CanvasGroup>(); _group.alpha = 0f; _group.blocksRaycasts = false; _group.interactable = false; _scaler = ((Component)this).gameObject.AddComponent<CanvasScaler>(); _scaler.uiScaleMode = (ScaleMode)1; _scaler.referenceResolution = new Vector2(1920f, 1080f); _scaler.screenMatchMode = (ScreenMatchMode)0; _scaler.matchWidthOrHeight = 1f; GameObject panel = new GameObject("LT_ResultPanel"); panel.transform.SetParent(((Component)this).transform, false); _panelRT = panel.AddComponent<RectTransform>(); _panelRT.anchorMin = new Vector2(0f, 1f); _panelRT.anchorMax = new Vector2(0f, 1f); _panelRT.pivot = new Vector2(0f, 1f); _panelRT.sizeDelta = new Vector2(500f, _panelH); _panelRT.anchoredPosition = PanelPos; _panelCenterY = PanelPos.y - _panelH * 0.5f; ((Component)_panelRT).gameObject.AddComponent<RectMask2D>(); _bgRT = CreateLayer(panel.transform, "LT_BG"); _bgImg = ((Component)_bgRT).gameObject.AddComponent<Image>(); ((Graphic)_bgImg).raycastTarget = false; ((Behaviour)_bgImg).enabled = false; _borderTop = MakeBorder("Top", new Vector2(500f, 4f), new Vector2(0f, 0f)); _borderLeft = MakeBorder("Left", new Vector2(4f, _panelH), new Vector2(0f, 0f)); _borderRight = MakeBorder("Right", new Vector2(4f, _panelH), new Vector2(496f, 0f)); _borderBottom = MakeBorder("Bottom", new Vector2(500f, 4f), new Vector2(0f, 0f - _panelH + 4f)); GameObject val = new GameObject("LT_ResultText"); val.transform.SetParent(panel.transform, false); RectTransform obj = val.AddComponent<RectTransform>(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 1f); obj.anchorMax = val2; obj.anchorMin = val2; obj.pivot = new Vector2(0f, 1f); obj.sizeDelta = new Vector2(472f, 10000f); obj.anchoredPosition = new Vector2(24f, -22f); _text = val.AddComponent<TextMeshProUGUI>(); ((Graphic)_text).raycastTarget = false; ((TMP_Text)_text).enableWordWrapping = true; ((TMP_Text)_text).richText = true; ((TMP_Text)_text).alignment = (TextAlignmentOptions)4097; ((TMP_Text)_text).fontStyle = (FontStyles)0; ((TMP_Text)_text).fontWeight = (FontWeight)800; ((Graphic)_text).color = RedLine; ((TMP_Text)_text).enableAutoSizing = true; ((TMP_Text)_text).fontSizeMin = 22f; ((TMP_Text)_text).fontSizeMax = 30f; ((TMP_Text)_text).characterSpacing = -3f; ((TMP_Text)_text).lineSpacing = -4f; TMP_FontAsset val3 = FontLoader.Load(); if ((Object)(object)val3 != (Object)null) { ((TMP_Text)_text).font = val3; Material val4 = new Material(((TMP_Asset)val3).material); val4.SetFloat(ShaderUtilities.ID_FaceDilate, 0.06f); ((TMP_Text)_text).fontMaterial = val4; } ((Transform)_bgRT).SetAsFirstSibling(); RectTransform MakeBorder(string name, Vector2 size, Vector2 pos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) GameObject val5 = new GameObject(name); val5.transform.SetParent(panel.transform, false); RectTransform obj2 = val5.AddComponent<RectTransform>(); Vector2 val6 = default(Vector2); ((Vector2)(ref val6))..ctor(0f, 1f); obj2.anchorMax = val6; obj2.anchorMin = val6; obj2.pivot = new Vector2(0f, 1f); obj2.sizeDelta = size; obj2.anchoredPosition = pos; Image obj3 = val5.AddComponent<Image>(); ((Graphic)obj3).color = RedLine; ((Graphic)obj3).raycastTarget = false; return obj2; } } private RectTransform CreateLayer(Transform parent, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0f, 1f); obj.anchorMax = new Vector2(0f, 1f); obj.pivot = new Vector2(0f, 1f); obj.sizeDelta = new Vector2(500f, _panelH); obj.anchoredPosition = Vector2.zero; return obj; } private bool TryAdoptVanillaReportStyle() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) try { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.endgameStatsAnimator == (Object)null) { return false; } Image val = FindFirstImage(((Component)instance.endgameStatsAnimator).transform.Find("BGBoxes")); if ((Object)(object)val != (Object)null) { CloneGraphic(val, _bgImg); _bgImg.type = (Type)1; _bgImg.preserveAspect = false; _bgImg.fillCenter = true; _bgRT.pivot = new Vector2(0.5f, 0.5f); RectTransform bgRT = _bgRT; Vector2 anchorMin = (_bgRT.anchorMax = new Vector2(0.5f, 0.5f)); bgRT.anchorMin = anchorMin; _bgRT.anchoredPosition = Vector2.zero; Canvas componentInParent = ((Component)_bgRT).GetComponentInParent<Canvas>(); Rect val3 = RectTransformUtility.PixelAdjustRect(_bgRT, componentInParent); float width = ((Rect)(ref val3)).width; if (width > 0f) { float num = (float)Screen.width / width; RectTransform bgRT2 = _bgRT; ((Transform)bgRT2).localScale = ((Transform)bgRT2).localScale * num; } ((Behaviour)_bgImg).enabled = true; } return (Object)(object)val != (Object)null; } catch { return false; } static Image FindFirstImage(Transform t) { if (!((Object)(object)t == (Object)null)) { return ((Component)t).GetComponentsInChildren<Image>(true).FirstOrDefault(); } return null; } } private static void CloneGraphic(Image src, Image dst) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) dst.sprite = src.sprite; ((Graphic)dst).material = ((Graphic)src).material; dst.type = src.type; dst.pixelsPerUnitMultiplier = src.pixelsPerUnitMultiplier; dst.preserveAspect = src.preserveAspect; dst.fillCenter = src.fillCenter; ((Graphic)dst).color = ((Graphic)src).color; ((MaskableGraphic)dst).maskable = ((MaskableGraphic)src).maskable; } private void FitPanelToText() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_text == (Object)null) && !((Object)(object)_panelRT == (Object)null)) { RectTransform val = (RectTransform)((TMP_Text)_text).transform; ((TMP_Text)_text).ForceMeshUpdate(true, true); Canvas.ForceUpdateCanvases(); _text.CalculateLayoutInputVertical(); float num = Mathf.Ceil(((TMP_Text)_text).preferredHeight); if (num < 1f) { num = 1f; } val.sizeDelta = new Vector2(val.sizeDelta.x, num); val.anchoredPosition = new Vector2(24f, -22f); float num2 = num + 44f; _ = _panelH; Vector2 anchoredPosition = _panelRT.anchoredPosition; anchoredPosition.y = _panelCenterY + num2 * 0.5f; _panelRT.anchoredPosition = anchoredPosition; _panelH = num2; _panelRT.sizeDelta = new Vector2(500f, _panelH); _borderLeft.sizeDelta = new Vector2(4f, _panelH); _borderRight.sizeDelta = new Vector2(4f, _panelH); _borderRight.anchoredPosition = new Vector2(496f, 0f); _borderBottom.sizeDelta = new Vector2(500f, 4f); _borderBottom.anchoredPosition = new Vector2(0f, 0f - _panelH + 4f); if ((Object)(object)_bgRT != (Object)null) { _bgRT.sizeDelta = new Vector2(500f, _panelH); } } } [IteratorStateMachine(typeof(<ShowRoutine>d__35))] private IEnumerator ShowRoutine(string killer, string target, string resultText) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ShowRoutine>d__35(0) { <>4__this = this, killer = killer, target = target, resultText = resultText }; } [IteratorStateMachine(typeof(<FollowPerformanceReportLifecycle>d__36))] private IEnumerator FollowPerformanceReportLifecycle() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FollowPerformanceReportLifecycle>d__36(0) { <>4__this = this }; } private bool TryBindToPerformanceReport() { _reportGroup = null; _reportTransform = null; try { TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>(); foreach (TextMeshProUGUI val in array) { if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy && string.Equals((((TMP_Text)val).text ?? string.Empty).Trim(), "PERFORMANCE REPORT", StringComparison.OrdinalIgnoreCase)) { _reportTransform = ((TMP_Text)val).transform; _reportGroup = ((Component)val).GetComponentInParent<CanvasGroup>(true); return true; } } } catch { } return false; } [IteratorStateMachine(typeof(<GlidePanelRoutine>d__38))] private IEnumerator GlidePanelRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GlidePanelRoutine>d__38(0) { <>4__this = this }; } public static void Show(string killer, string target, string resultText) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("[LT] ResultPanelCanvas"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent<ResultPanel>(); _instance.BuildUI(); } ((MonoBehaviour)_instance).StopAllCoroutines(); _instance.StayOpen = true; _instance.TempHide = false; ((MonoBehaviour)_instance).StartCoroutine(_instance.ShowRoutine(killer, target, resultText)); } public static void HideIfShouldHide(bool tempHide = false) { if ((Object)(object)_instance == (Object)null) { return; } if (!tempHide) { if (!_instance.StayOpen) { ((MonoBehaviour)_instance).StopAllCoroutines(); ((TMP_Text)_instance._text).text = ""; _instance._group.alpha = 0f; } } else { _instance.TempHide = true; } } public static void RevealAfterTempHide() { if (!((Object)(object)_instance == (Object)null)) { _instance.TempHide = false; } } public static void ForceHide() { if (!((Object)(object)_instance == (Object)null)) { ((MonoBehaviour)_instance).StopAllCoroutines(); ((TMP_Text)_instance._text).text = ""; _instance._group.alpha = 0f; _instance.StayOpen = false; } } } internal class Text { private static readonly string alertSubject = "<b><size=110%><color=black>-PRIVATE TRANSMISSION-</color></size></b>"; private static string largeTextSize = "180"; private static string mediumTextSize = "110"; private static string smallTextSize = "70"; private static string BannerMessage(string targetName) { return "\n<size=" + largeTextSize + "%><u>SECRET TERMINATION NOTICE</u></size>\n\n<size=" + mediumTextSize + "%><material=\"3270_Body_Medium\"><cspace=-3>Do not allow <color=red>" + targetName + "</color> to leave this moon alive.</cspace></material></size>\n\n<size=" + smallTextSize + "%><material=\"3270_Body_Small\"><cspace=-2>Return with the ship's cargo as usual.</cspace></material></size>"; } private static string KillerAlertBody(string targetName) { return "<line-height=95%>\n</line-height><line-height=100%><b><size=120%><color=black>" + targetName + " must not return alive.</color></size></b></line-height>"; } private static string TargetAlertBody(int percentage) { object obj; switch (percentage) { default: obj = "a"; break; case 8: case 11: case 18: case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: obj = "an"; break; } return "<line-height=50%>\n</line-height><line-height=100%><b><size=120%><cspace=-1><color=black>There is " + (string?)obj + " " + $"<b>{percentage}%</b> chance the company will send someone to kill you today.</color></cspace></size></b></line-height>"; } public static string RevealMessage(string killerName, string targetName, string resultText) { SplitResultText(resultText, out var headline, out var details); return "<color=#00FFFF>KILLER: <b>" + killerName + "</b></color>\n\n<color=white>TARGET: <b>" + targetName + "</b></color>\n\nRESULT: <b><u>" + headline + "</u></b>\n\n" + details; } private static string ResultText(bool anyAlive, bool killerAlive, bool targetAlive, string killerName, string targetName, out string key) { if (!anyAlive) { key = "worst_failure"; return "WORST FAILURE!|<b><color=#00FFFF>" + killerName + "</color></b> didn't make sure the ship's cargo was secure. How embarrassing!"; } if (!killerAlive && targetAlive) { key = "complete_failure"; return "KILLER CRUSHED!|<b><color=white>" + targetName + "</color></b> turned the tables on the killer.\n\n<b><color=#00FFFF>" + killerName + "</color></b> was put down like a sick dog. Pathetic."; } if (killerAlive && targetAlive) { key = "failure"; return "TERMINATION FAILED!|<b><color=white>" + targetName + "</color></b> escaped alive.\n\nThe company took disciplinary action against <b><color=#00FFFF>" + killerName + "</color></b>."; } if (!killerAlive && !targetAlive) { key = "draw"; return "GREAT ASSET|<b><color=white>" + targetName + "</color></b> died.\n\n<b><color=#00FFFF>" + killerName + "</color></b> also died. The company appreciates their work ethic."; } if (killerAlive && !targetAlive) { key = "success"; return "PERFECTLY EXECUTED!|<b><color=#00FFFF>" + killerName + "</color></b> completed their mission and survived.\n\n<b><color=white>" + targetName + "</color></b> died helplessly. Just as planned."; } key = "unknown"; return "An unknown error occurred."; } internal static string GetBannerText(string targetName) { return BannerMessage(targetName); } internal static string GetAlertSubject() { return alertSubject; } internal static string GetKillerAlertBody(string targetName) { return KillerAlertBody(targetName); } internal static string GetTargetAlertBody(int percentage) { return TargetAlertBody(percentage); } internal static string GetRevealMessage(string killerName, string targetName, string resultText) { return RevealMessage(killerName, targetName, resultText); } internal static string GetResultText(bool anyAlive, bool killerAlive, bool targetAlive, string killerName, string targetName, out string key) { return ResultText(anyAlive, killerAlive, targetAlive, killerName, targetName, out key); } internal static string GetLargeTextSize() { return largeTextSize; } internal static string GetMediumTextSize() { return mediumTextSize; } internal static string GetSmallTextSize() { return smallTextSize; } private static void SplitResultText(string resultText, out string headline, out string details) { if (string.IsNullOrEmpty(resultText)) { headline = "UNKNOWN"; details = ""; return; } int num = resultText.IndexOf('|'); if (num < 0) { headline = resultText.Trim(); details = ""; } else { headline = resultText.Substring(0, num).Trim(); details = resultText.Substring(num).TrimStart(new char[1] { '|' }).Trim(); } } } internal class HUDSettings : MonoBehaviour { [CompilerGenerated] private sealed class <Run>d__20 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public HUDSettings <>4__this; public string message; public float duration; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Run>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Expected O, but got Unknown //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Expected O, but got Unknown int num = <>1__state; HUDSettings hUDSettings = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; ((TMP_Text)hUDSettings._fill).text = message; string pattern = "<size=" + Text.GetLargeTextSize() + "%>[\\s\\S]*?</size>"; string pattern2 = "<size=" + Text.GetMediumTextSize() + "%>[\\s\\S]*?</size>"; string pattern3 = "<size=" + Text.GetSmallTextSize() + "%>[\\s\\S]*?</size>"; string input = message; input = Regex.Replace(input, pattern2, (Match m) => <Run>g__Hide|20_0(m.Value)); input = Regex.Replace(input, pattern3, (Match m) => <Run>g__Hide|20_0(m.Value)); input = Regex.Replace(input, "<material=\"[^\"]+\">|</material>", ""); string input2 = message; input2 = Regex.Replace(input2, pattern, (Match m) => <Run>g__Hide|20_0(m.Value)); input2 = Regex.Replace(input2, pattern3, (Match m) => <Run>g__Hide|20_0(m.Value)); input2 = Regex.Replace(input2, "<material=\"[^\"]+\">|</material>", ""); string input3 = message; input3 = Regex.Replace(input3, pattern, (Match m) => <Run>g__Hide|20_0(m.Value)); input3 = Regex.Replace(input3, pattern2, (Match m) => <Run>g__Hide|20_0(m.Value)); input3 = Regex.Replace(input3, "<material=\"[^\"]+\">|</material>", ""); ((TMP_Text)hUDSettings._strokeLarge).text = input; ((TMP_Text)hUDSettings._strokeMed).text = input2; ((TMP_Text)hUDSettings._strokeSmall).text = input3; ((TMP_Text)hUDSettings._fill).ForceMeshUpdate(true, true); ((TMP_Text)hUDSettings._strokeLarge).ForceMeshUpdate(true, true); ((TMP_Text)hUDSettings._strokeMed).ForceMeshUpdate(true, true); ((TMP_Text)hUDSettings._strokeSmall).ForceMeshUpdate(true, true); ((TMP_Text)hUDSettings._fill).UpdateMeshPadding(); ((TMP_Text)hUDSettings._strokeLarge).UpdateMeshPadding(); ((TMP_Text)hUDSettings._strokeMed).UpdateMeshPadding(); ((TMP_Text)hUDSettings._strokeSmall).UpdateMeshPadding(); ((Graphic)hUDSettings._fill).SetMaterialDirty(); ((Graphic)hUDSettings._strokeLarge).SetMaterialDirty(); ((Graphic)hUDSettings._strokeMed).SetMaterialDirty(); ((Graphic)hUDSettings._strokeSmall).SetMaterialDirty(); ((Graphic)hUDSettings._fill).SetVerticesDirty(); ((Graphic)hUDSettings._strokeLarge).SetVerticesDirty(); ((Graphic)hUDSettings._strokeMed).SetVerticesDirty(); ((Graphic)hUDSettings._strokeSmall).SetVerticesDirty(); Canvas.ForceUpdateCanvases(); <>2__current = (object)new WaitForSecondsRealtime(7f); <>1__state = 1; return true; } case 1: { <>1__state = -1; hUDSettings.StayOpen = true; float num3 = (hUDSettings._group.alpha = 1f); <>2__current = num3; <>1__state = 2; return true; } case 2: <>1__state = -1; <>2__current = (object)new WaitForSecondsRealtime(duration); <>1__state = 3; return true; case 3: { <>1__state = -1; hUDSettings.StayOpen = false; float num3 = (hUDSettings._group.alpha = 0f); <>2__current = num3; <>1__state = 4; return true; } case 4: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static HUDSettings _instance; private Canvas _canvas; private CanvasScaler _scaler; private CanvasGroup _group; private TextMeshProUGUI _fill; private TextMeshProUGUI _strokeLarge; private TextMeshProUGUI _strokeMed; private TextMeshProUGUI _strokeSmall; private bool StayOpen; private float TempHideAlpha = -1f; private const float BaseWidth = 1920f; private const float BaseHeight = 1080f; private const float PosX = 120f; private const float PosY = 0f; private static readonly Color CyanHUD = new Color(0.55f, 0.92f, 0.95f); private const float OutlineWidth = 0.28f; private const float FaceThicken = 0.18f; private const float MinFont = 42f; private const float MaxFont = 72f; private void BuildUI() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Expected O, but got Unknown //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Expected O, but got Unknown //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Expected O, but got Unknown StayOpen = false; _canvas = ((Component)this).gameObject.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 9998; _group = ((Component)this).gameObject.AddComponent<CanvasGroup>(); _group.blocksRaycasts = false; _group.interactable = false; _group.alpha = 0f; _scaler = ((Component)this).gameObject.AddComponent<CanvasScaler>(); _canvas.pixelPerfect = true; _scaler.uiScaleMode = (ScaleMode)1; _scaler.referenceResolution = new Vector2(1920f, 1080f); _scaler.screenMatchMode = (ScreenMatchMode)0; _scaler.matchWidthOrHeight = 1f; GameObject val = new GameObject("HUDBanner_Stroke_Large"); val.transform.SetParent(((Component)this).transform, false); RectTransform obj = val.AddComponent<RectTransform>(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 0.5f); obj.anchorMax = val2; obj.anchorMin = val2; obj.pivot = new Vector2(0f, 0.5f); obj.anchoredPosition = new Vector2(125f, 0f); obj.sizeDelta = new Vector2(1550f, 420f); _strokeLarge = val.AddComponent<TextMeshProUGUI>(); ((Graphic)_strokeLarge).raycastTarget = false; ((MaskableGraphic)_strokeLarge).maskable = false; GameObject val3 = new GameObject("HUDBanner_Stroke_Medium"); val3.transform.SetParent(((Component)this).transform, false); RectTransform obj2 = val3.AddComponent<RectTransform>(); ((Vector2)(ref val2))..ctor(0f, 0.5f); obj2.anchorMax = val2; obj2.anchorMin = val2; obj2.pivot = new Vector2(0f, 0.5f); obj2.anchoredPosition = new Vector2(123f, 0f); obj2.sizeDelta = new Vector2(1550f, 420f); _strokeMed = val3.AddComponent<TextMeshProUGUI>(); ((Graphic)_strokeMed).raycastTarget = false; ((MaskableGraphic)_strokeMed).maskable = false; GameObject val4 = new GameObject("HUDBanner_Stroke_Small"); val4.transform.SetParent(((Component)this).transform, false); RectTransform obj3 = val4.AddComponent<RectTransform>(); ((Vector2)(ref val2))..ctor(0f, 0.5f); obj3.anchorMax = val2; obj3.anchorMin = val2; obj3.pivot = new Vector2(0f, 0.5f); obj3.anchoredPosition = new Vector2(123f, 0f); obj3.sizeDelta = new Vector2(1550f, 420f); _strokeSmall = val4.AddComponent<TextMeshProUGUI>(); ((Graphic)_strokeSmall).raycastTarget = false; ((MaskableGraphic)_strokeSmall).maskable = false; GameObject val5 = new GameObject("HUDBanner_Cyan"); val5.transform.SetParent(((Component)this).transform, false); RectTransform obj4 = val5.AddComponent<RectTransform>(); ((Vector2)(ref val2))..ctor(0f, 0.5f); obj4.anchorMax = val2; obj4.anchorMin = val2; obj4.pivot = new Vector2(0f, 0.5f); obj4.anchoredPosition = new Vector2(120f, 0f); obj4.sizeDelta = new Vector2(1550f, 420f); _fill = val5.AddComponent<TextMeshProUGUI>(); ((Graphic)_fill).raycastTarget = false; ((MaskableGraphic)_fill).maskable = false; val.transform.SetSiblingIndex(0); val3.transform.SetSiblingIndex(1); val4.transform.SetSiblingIndex(2); val5.transform.SetSiblingIndex(3); TMP_FontAsset f3270 = FontLoader.Load(); if ((Object)(object)f3270 != (Object)null) { ((TMP_Text)_fill).font = f3270; ((TMP_Text)_fill).fontMaterial = new Material(((TMP_Asset)f3270).material); } ApplyCommon(_fill); ((Graphic)_fill).color = CyanHUD; Material fontMaterial = ((TMP_Text)_fill).fontMaterial; fontMaterial.DisableKeyword(ShaderUtilities.Keyword_Outline); fontMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, 0f); fontMaterial.SetFloat(ShaderUtilities.ID_OutlineSoftness, 0f); fontMaterial.SetFloat(ShaderUtilities.ID_FaceDilate, 0.04f); fontMaterial.SetFloat(ShaderUtilities.ID_ScaleRatio_A, 1f); fontMaterial.SetFloat(ShaderUtilities.ID_ScaleRatio_B, 1f); fontMaterial.SetFloat(ShaderUtilities.ID_ScaleRatio_C, 1f); Material val6 = new Material(fontMaterial) { name = "3270_Body_Small" }; val6.SetFloat(ShaderUtilities.ID_FaceDilate, 0.06f); Material val7 = new Material(fontMaterial) { name = "3270_Body_Medium" }; val7.SetFloat(ShaderUtilities.ID_FaceDilate, 0.04f); MaterialReferenceManager.AddFontMaterial(TMP_TextUtilities.GetSimpleHashCode(((Object)val6).name), val6); MaterialReferenceManager.AddFontMaterial(TMP_TextUtilities.GetSimpleHashCode(((Object)val7).name), val7); if ((Object)(object)f3270 != (Object)null) { ((TMP_Text)_strokeLarge).font = f3270; ((TMP_Text)_strokeMed).font = f3270; ((TMP_Text)_strokeSmall).font = f3270; ((TMP_Text)_strokeLarge).fontMaterial = MakeBlackFaceMat(); ((TMP_Text)_strokeMed).fontMaterial = MakeBlackFaceMat(); ((TMP_Text)_strokeSmall).fontMaterial = MakeBlackFaceMat(); } ApplyCommon(_strokeLarge); ApplyCommon(_strokeMed); ApplyCommon(_strokeSmall); ((TMP_Text)_fill).extraPadding = true; TextMeshProUGUI strokeLarge = _strokeLarge; TextMeshProUGUI strokeMed = _strokeMed; bool flag2 = (((TMP_Text)_strokeSmall).extraPadding = true); bool extraPadding = (((TMP_Text)strokeMed).extraPadding = flag2); ((TMP_Text)strokeLarge).extraPadding = extraPadding; ((Graphic)_fill).SetMaterialDirty(); ((Graphic)_strokeLarge).SetMaterialDirty(); ((Graphic)_strokeMed).SetMaterialDirty(); ((Graphic)_strokeSmall).SetMaterialDirty(); ((Graphic)_fill).SetVerticesDirty(); ((Graphic)_strokeLarge).SetVerticesDirty(); ((Graphic)_strokeMed).SetVerticesDirty(); ((Graphic)_strokeSmall).SetVerticesDirty(); Canvas.ForceUpdateCanvases(); ((TMP_Text)_fill).UpdateMeshPadding(); ((TMP_Text)_strokeLarge).UpdateMeshPadding(); ((TMP_Text)_strokeMed).UpdateMeshPadding(); ((TMP_Text)_strokeSmall).UpdateMeshPadding(); ((TMP_Text)_fill).ForceMeshUpdate(true, true); ((TMP_Text)_strokeLarge).ForceMeshUpdate(true, true); ((TMP_Text)_strokeMed).ForceMeshUpdate(true, true); ((TMP_Text)_strokeSmall).ForceMeshUpdate(true, true); static void ApplyCommon(TextMeshProUGUI t) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)t).enableWordWrapping = true; ((TMP_Text)t).alignment = (TextAlignmentOptions)513; ((TMP_Text)t).margin = Vector4.zero; ((TMP_Text)t).enableAutoSizing = true; ((TMP_Text)t).fontSizeMin = 42f; ((TMP_Text)t).fontSizeMax = 72f; ((TMP_Text)t).fontStyle = (FontStyles)1; ((TMP_Text)t).fontWeight = (FontWeight)800; ((TMP_Text)t).characterSpacing = -2f; ((TMP_Text)t).lineSpacing = -4f; ((TMP_Text)t).extraPadding = true; ((TMP_Text)t).richText = true; } Material MakeBlackFaceMat() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0067: Expected O, but got Unknown Material val8 = new Material(((TMP_Asset)f3270).material); val8.DisableKeyword(ShaderUtilities.Keyword_Underlay); val8.DisableKeyword(ShaderUtilities.Keyword_Outline); val8.SetFloat(ShaderUtilities.ID_OutlineWidth, 0f); val8.SetFloat(ShaderUtilities.ID_OutlineSoftness, 0f); val8.SetFloat(ShaderUtilities.ID_FaceDilate, 0.04f); val8.SetColor(ShaderUtilities.ID_FaceColor, Color.black); return val8; } } [IteratorStateMachine(typeof(<Run>d__20))] private IEnumerator Run(string message, float duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Run>d__20(0) { <>4__this = this, message = message, duration = duration }; } public static void ShowBanner(string message, float duration) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("[LT] HUDBanner"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent<HUDSettings>(); _instance.BuildUI(); } ((MonoBehaviour)_instance).StopAllCoroutines(); ((MonoBehaviour)_instance).StartCoroutine(_instance.Run(message, duration)); } public static void HideIfShouldHide(bool tempHide = false) { if ((Object)(object)_instance == (Object)null) { return; } if (!tempHide) { if (_instance.StayOpen) { return; } ((MonoBehaviour)_instance).StopAllCoroutines(); } else { _instance.TempHideAlpha = _instance._group.alpha; } _instance._group.alpha = 0f; } public static void RevealAfterTempHide() { if (!((Object)(object)_instance == (Object)null) && !(_instance.TempHideAlpha < 0f)) { if (_instance.StayOpen) { _instance._group.alpha = _instance.TempHideAlpha; } _instance.TempHideAlpha = -1f; } } public static void ForceHide() { if (!((Object)(object)_instance == (Object)null)) { ((MonoBehaviour)_instance).StopAllCoroutines(); _instance._group.alpha = 0f; } } [CompilerGenerated] internal static string <Run>g__Hide|20_0(string s) { return "<color=#00000000>" + s + "</color>"; } } } namespace LethalTraitor.Patches { [HarmonyPatch(typeof(MenuManager))] public static class MainMenuManagerPatches { [HarmonyPostfix] [HarmonyPatch("Start")] private static void OnMainMenuStart() { HUDHelper.ForceHide(); } } [HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")] public static class QuickMenu_Open_Patch { private static void Postfix(QuickMenuManager __instance) { HUDHelper.TempHide(); } } [HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")] public static class QuickMenu_Close_Patch { private static void Postfix(QuickMenuManager __instance) { HUDHelper.Reveal(); } } [HarmonyPatch(typeof(HUDManager), "PingScan_performed")] internal static class HidePanel_OnScan { private static void Postfix(HUDManager __instance) { ResultPanel.HideIfShouldHide(); } } [HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")] internal static class HidePanel_OnOpenTerminal { private static void Postfix(Terminal __instance) { ResultPanel.HideIfShouldHide(); } } [HarmonyPatch(typeof(StartOfRound))] public static class StartOfRound_SceneLoadComplete_Patch { [HarmonyPostfix] [HarmonyPatch("SceneManager_OnLoadComplete1")] private static void Prefix(ulong clientId, string sceneName, LoadSceneMode loadSceneMode) { ResultPanel.ForceHide(); } } [HarmonyPatch] public static class PlayersFiredGameOver_Prefix { [CompilerGenerated] private sealed class <WaitForAlarm>d__2 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForAlarm>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(5f); <>1__state = 1; return true; case 1: <>1__state = -1; ResultPanel.ForceHide(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static MethodBase TargetMethod() { return AccessTools.Method(typeof(StartOfRound), "playersFiredGameOver", new Type[1] { typeof(bool) }, (Type[])null); } private static void Prefix(StartOfRound __instance, bool abridgedVersion) { ((MonoBehaviour)__instance).StartCoroutine(WaitForAlarm(__instance)); } [IteratorStateMachine(typeof(<WaitForAlarm>d__2))] private static IEnumerator WaitForAlarm(StartOfRound inst) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForAlarm>d__2(0); } } internal class PluginPatcher { [HarmonyPatch(typeof(StartOfRound))] public static class StartOfRound_ShipLeave_Patch { [HarmonyPatch("ShipLeave")] [HarmonyPostfix] private static void ShipLeavePatch() { Plugin.AbortSetupProcess = true; Debug.Log("LT Log: LEVER PULLED (ShipLeave patch)"); } } } [HarmonyPatch(typeof(PlayerControllerB))] internal static class CalmShipCorpses { [CompilerGenerated] private sealed class <FreezeCorpseIfShipMovingDelayed>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PlayerControllerB __instance; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FreezeCorpseIfShipMovingDelayed>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; Debug.Log("Corpse: DELAY"); <>2__current = (object)new WaitForSeconds(1.5f); <>1__state = 1; return true; case 1: { <>1__state = -1; Debug.Log("Corpse: START"); DeadBodyInfo deadBody = __instance.deadBody; if ((Object)(object)deadBody == (Object)null) { return false; } StartOfRound instance = StartOfRound.Instance; bool flag = (Object)(object)instance != (Object)null && (instance.shipIsLeaving || instance.inShipPhase); Debug.Log("Corpse: " + flag); if (!flag) { return false; } deadBody.parentedToShip = true; ((Component)deadBody).transform.SetParent(instance.elevatorTransform, true); deadBody.SetBodyPartsKinematic(true); Rigidbody[] bodyParts = deadBody.bodyParts; foreach (Rigidbody val in bodyParts) { if (!((Object)(object)val == (Object)null)) { val.velocity = Vector3.zero; val.angularVelocity = Vector3.zero; val.maxDepenetrationVelocity = 0.2f; val.Sleep(); } } if ((Object)(object)deadBody.grabBodyObject != (Object)null) { deadBody.grabBodyObject.grabbable = false; deadBody.grabBodyObject.grabbableToEnemies = false; } Debug.Log("Corpse: END"); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPostfix] [HarmonyPatch("SpawnDeadBody")] private static void FreezeCorpseIfShipMoving(PlayerControllerB __instance) { if ((Object)(object)__instance != (Object)null) { ((MonoBehaviour)__instance).StartCoroutine(FreezeCorpseIfShipMovingDelayed(__instance)); } } [IteratorStateMachine(typeof(<FreezeCorpseIfShipMovingDelayed>d__1))] private static IEnumerator FreezeCorpseIfShipMovingDelayed(PlayerControllerB __instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FreezeCorpseIfShipMovingDelayed>d__1(0) { __instance = __instance }; } } } namespace LethalTraitor.Helpers { internal class HUDHelper { public static void ForceHide() { HUDSettings.ForceHide(); ResultPanel.ForceHide(); } public static void TempHide() { HUDSettings.HideIfShouldHide(tempHide: true); ResultPanel.HideIfShouldHide(tempHide: true); } public static void Reveal() { HUDSettings.RevealAfterTempHide(); ResultPanel.RevealAfterTempHide(); } } }