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 ImpostorMod v1.0.7
ImpostorMod.dll
Decompiled 28 minutes agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ImpostorMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ImpostorMod")] [assembly: AssemblyTitle("ImpostorMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ImpostorMod { internal static class ImpostorCommands { private const string Prefix = "/impostor"; private static void Say(string msg) { if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.AddChatMessage("[ImpostorMod] " + msg, "", -1, false); } } internal static bool TryHandle(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return false; } string text = raw.Trim(); if (!text.StartsWith("/impostor", StringComparison.OrdinalIgnoreCase)) { return false; } if (text.Length > "/impostor".Length && !char.IsWhiteSpace(text["/impostor".Length])) { return false; } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer) { Say("Tylko host moze uzywac komend."); return true; } string[] array = text.Substring("/impostor".Length).Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string text2 = ((array.Length != 0) ? array[0].ToLowerInvariant() : "help"); string text3 = ((array.Length > 1) ? array[1].ToLowerInvariant() : null); switch (text2) { case "help": Say("/impostor status - pokaz ustawienia"); Say("/impostor number <n> - liczba impostorow"); Say("/impostor on | off - wlacz/wylacz role"); Say("/impostor norepeat on | off - bez powtorek z rzedu"); Say("/impostor reveal on | off - pokaz impostorow po rundzie"); Say("/impostor revealdelay <s> - opoznienie po dotarciu na orbite"); Say("/impostor sabotage on | off - sabotaze impostora"); Say("/impostor cooldown <s> - odnowienie sabotazy"); Say("/impostor uses <n> - uzyc sabotazy na impostora/runde"); Say("/impostor roll - wylosuj role od nowa (po ladowaniu)"); break; case "status": Say("Role: " + (Plugin.Enabled.Value ? "WLACZONE" : "wylaczone") + ", " + $"impostorow: {Plugin.ImpostorCount.Value}, " + "bez powtorek: " + (Plugin.NoRepeat.Value ? "tak" : "nie") + ", pokaz impostorow po rundzie: " + (Plugin.RevealEnabled.Value ? "tak" : "nie") + " " + $"(opoznienie {Plugin.RevealDelay.Value}s)"); Say("Sabotaze: " + (Plugin.SabotageEnabled.Value ? "WLACZONE" : "wylaczone") + ", " + $"odnowienie {Plugin.SabotageCooldown.Value}s, " + $"uzyc na runde {Plugin.SabotageMaxUses.Value}"); break; case "number": { if (text3 == null || !int.TryParse(text3, out var result4) || result4 < 0 || result4 > 16) { Say("Uzycie: /impostor number <0-16>"); break; } Plugin.ImpostorCount.Value = result4; Say($"Liczba impostorow: {result4} (od nastepnego ladowania lub po /impostor roll)."); break; } case "on": Plugin.Enabled.Value = true; Say("Role WLACZONE (od nastepnego ladowania)."); break; case "off": Plugin.Enabled.Value = false; Plugin.ClearRolesForAll(); Say("Role WYLACZONE."); break; case "norepeat": if (text3 != "on" && text3 != "off") { Say("Uzycie: /impostor norepeat on|off"); break; } Plugin.NoRepeat.Value = text3 == "on"; Say("Bez powtorek z rzedu: " + (Plugin.NoRepeat.Value ? "tak" : "nie")); break; case "reveal": if (text3 != "on" && text3 != "off") { Say("Uzycie: /impostor reveal on|off"); break; } Plugin.RevealEnabled.Value = text3 == "on"; Say("Pokazywanie impostorow po rundzie: " + (Plugin.RevealEnabled.Value ? "tak" : "nie")); break; case "revealdelay": { if (text3 == null || !int.TryParse(text3, out var result2) || result2 < 0 || result2 > 60) { Say("Uzycie: /impostor revealdelay <0-60>"); break; } Plugin.RevealDelay.Value = result2; Say($"Komunikat o impostorach pojawi sie {result2}s po dotarciu na orbite."); break; } case "sabotage": if (text3 != "on" && text3 != "off") { Say("Uzycie: /impostor sabotage on|off"); break; } Plugin.SabotageEnabled.Value = text3 == "on"; Say("Sabotaze: " + (Plugin.SabotageEnabled.Value ? "WLACZONE" : "wylaczone") + " (od nastepnego ladowania)."); break; case "cooldown": { if (text3 == null || !int.TryParse(text3, out var result) || result < 0 || result > 600) { Say("Uzycie: /impostor cooldown <0-600>"); break; } Plugin.SabotageCooldown.Value = result; Say($"Odnowienie sabotazy: {result}s."); break; } case "uses": { if (text3 == null || !int.TryParse(text3, out var result3) || result3 < 0 || result3 > 20) { Say("Uzycie: /impostor uses <0-20>"); break; } Plugin.SabotageMaxUses.Value = result3; Say($"Uzyc sabotazy na impostora: {result3} (od nastepnego ladowania)."); break; } case "roll": if (!Plugin.Enabled.Value) { Say("Role sa wylaczone. Wpisz /impostor on."); break; } if ((Object)(object)StartOfRound.Instance == (Object)null || !StartOfRound.Instance.shipHasLanded) { Say("Losowanie od nowa dziala tylko, gdy statek stoi na ksiezycu."); break; } Plugin.AssignRoles(); Say("Wylosowano role od nowa."); break; default: Say("Nieznana komenda. Wpisz /impostor help"); break; } return true; } } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] internal static class ChatSubmitPatch { [HarmonyPrefix] private static void Prefix(HUDManager __instance) { try { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && val.isTypingChat && ImpostorCommands.TryHandle(__instance.chatTextField.text)) { __instance.chatTextField.text = ""; } } catch (Exception ex) { Plugin.Log.LogError((object)("Blad komendy czatu: " + ex)); } } } public enum Role : byte { Worker = 0, Impostor = 1, None = byte.MaxValue } [BepInPlugin("pl.impostormod.lethalcompany", "ImpostorMod", "1.0.7")] public class Plugin : BaseUnityPlugin { private class SabState { public int Uses; public float NextAt; } [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRoleMessage; public static HandleNamedMessageDelegate <1>__OnRevealMessage; public static Func<ulong, string> <2>__NameOf; public static HandleNamedMessageDelegate <3>__OnSabotageRequest; public static HandleNamedMessageDelegate <4>__OnEffectMessage; public static HandleNamedMessageDelegate <5>__OnStatusMessage; } public const string PluginGuid = "pl.impostormod.lethalcompany"; public const string PluginName = "ImpostorMod"; public const string PluginVersion = "1.0.7"; private const string MsgName = "pl.impostormod.lethalcompany.role"; private const string RevealMsgName = "pl.impostormod.lethalcompany.reveal"; internal static Plugin Instance; internal static ManualLogSource Log; internal static ConfigEntry<int> ImpostorCount; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> NoRepeat; internal static ConfigEntry<bool> RevealEnabled; internal static ConfigEntry<int> RevealDuration; internal static ConfigEntry<int> RevealDelay; internal static ConfigEntry<int> FontSize; internal static ConfigEntry<int> OffsetY; internal static Role LocalRole = Role.None; private static readonly Random Rng = new Random(Guid.NewGuid().GetHashCode()); internal static readonly HashSet<ulong> LastImpostors = new HashSet<ulong>(); internal static bool RoundActive; internal static List<string> RoundImpostorNames = new List<string>(); private static bool _hostSeenLanded; private static bool _awaitOrbit; private static float _leftAt; private static float _orbitAt; private const string SabotageMsgName = "pl.impostormod.lethalcompany.sabotage"; private const string EffectMsgName = "pl.impostormod.lethalcompany.effect"; private const string StatusMsgName = "pl.impostormod.lethalcompany.status"; private const byte ReqBlackout = 0; private const byte ReqDoor = 1; private const byte ReqPush = 2; private const byte FxBlackoutOn = 0; private const byte FxBlackoutOff = 1; private const byte FxDoorClose = 2; private const byte FxDoorOpen = 3; private const byte FxPush = 4; internal static ConfigEntry<bool> SabotageEnabled; internal static ConfigEntry<int> SabotageCooldown; internal static ConfigEntry<int> SabotageMaxUses; internal static ConfigEntry<int> BlackoutDuration; internal static ConfigEntry<int> DoorDuration; internal static ConfigEntry<float> PushForce; internal static ConfigEntry<float> PushRange; internal static ConfigEntry<Key> BlackoutKey; internal static ConfigEntry<Key> DoorKey; internal static ConfigEntry<Key> PushKey; internal static int SabUsesLeft = -1; internal static float SabCooldownUntil; private static readonly Dictionary<ulong, SabState> SabStates = new Dictionary<ulong, SabState>(); private static float _blackoutEnd; private static float _doorEnd; private void Awake() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; ImpostorCount = ((BaseUnityPlugin)this).Config.Bind<int>("Roles", "ImpostorCount", 1, new ConfigDescription("Ilu graczy ma zostac losowo wybranych na impostora w kazdej rundzie. Zawsze zostanie przynajmniej 1 pracownik (gdy gra wiecej niz 1 osoba). Liczy sie tylko config HOSTA.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 16), Array.Empty<object>())); Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Roles", "Enabled", true, "Czy losowanie rol jest wlaczone (liczy sie config HOSTA). Mozna zmieniac komenda /impostor on|off."); NoRepeat = ((BaseUnityPlugin)this).Config.Bind<bool>("Roles", "NoRepeatImpostor", false, "Jesli true, osoba bedaca impostorem w poprzedniej rundzie nie zostanie nim ponownie (o ile jest kto inny do wylosowania). Komenda /impostor norepeat on|off."); RevealEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Reveal", "RevealEnabled", true, "Czy po odlocie statku pokazac wszystkim, kto byl impostorem (liczy sie config HOSTA). Komenda /impostor reveal on|off."); RevealDelay = ((BaseUnityPlugin)this).Config.Bind<int>("Reveal", "RevealDelay", 3, new ConfigDescription("Ile sekund PO dotarciu statku na orbite czekac z pokazaniem impostorow (liczy sie config HOSTA). Komenda /impostor revealdelay <sekundy>.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); RevealDuration = ((BaseUnityPlugin)this).Config.Bind<int>("Reveal", "RevealDuration", 8, "Przez ile sekund komunikat o impostorach jest widoczny na srodku ekranu (lokalnie)."); FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "FontSize", 36, "Rozmiar napisu z rola na ekranie (lokalnie, kazdy gracz ustawia sobie sam)."); OffsetY = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "OffsetY", 10, "Odleglosc napisu od gornej krawedzi ekranu w pikselach."); BindSabotageConfig(); new Harmony("pl.impostormod.lethalcompany").PatchAll(); Log.LogInfo((object)"ImpostorMod 1.0.7 zaladowany."); } internal static void RegisterHandler() { //IL_0033: 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_003e: Expected O, but got Unknown //IL_005e: 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_0069: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && singleton.CustomMessagingManager != null) { CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; object obj = <>O.<0>__OnRoleMessage; if (obj == null) { HandleNamedMessageDelegate val = OnRoleMessage; <>O.<0>__OnRoleMessage = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("pl.impostormod.lethalcompany.role", (HandleNamedMessageDelegate)obj); CustomMessagingManager customMessagingManager2 = singleton.CustomMessagingManager; object obj2 = <>O.<1>__OnRevealMessage; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnRevealMessage; <>O.<1>__OnRevealMessage = val2; obj2 = (object)val2; } customMessagingManager2.RegisterNamedMessageHandler("pl.impostormod.lethalcompany.reveal", (HandleNamedMessageDelegate)obj2); RegisterSabotageHandlers(singleton); } } private static void OnRoleMessage(ulong senderClientId, FastBufferReader reader) { if (senderClientId == 0L) { byte role = default(byte); ((FastBufferReader)(ref reader)).ReadByteSafe(ref role); ApplyRole((Role)role); } } private static void OnRevealMessage(ulong senderClientId, FastBufferReader reader) { if (senderClientId == 0L) { string payload = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref payload, false); RoleHud.ShowReveal(payload); } } private static void ApplyRole(Role role) { if (role == Role.None) { LocalRole = Role.None; RoleHud.OnNewRole(); return; } LocalRole = role; OnRoleApplied(); RoleHud.OnNewRole(); Log.LogInfo((object)$"Otrzymano role: {role}"); if (!((Object)(object)HUDManager.Instance == (Object)null)) { if (role == Role.Impostor) { HUDManager.Instance.DisplayTip("ROLA: IMPOSTOR (v1.0.7)", "Jestes impostorem. Nikt inny o tym nie wie.", true, false, "LC_Tip1"); } else { HUDManager.Instance.DisplayTip("ROLA: PRACOWNIK (v1.0.7)", "Jestes pracownikiem.", false, false, "LC_Tip1"); } } } private unsafe static void SendRole(ulong clientId, Role role) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (clientId == singleton.LocalClientId) { ApplyRole(role); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(1, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteByteSafe((byte)role); singleton.CustomMessagingManager.SendNamedMessage("pl.impostormod.lethalcompany.role", clientId, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } internal static List<ulong> GetPlayerIds() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return new List<ulong>(); } return (from p in instance.allPlayerScripts where (Object)(object)p != (Object)null && (p.isPlayerControlled || p.isPlayerDead) select p.actualClientId).Distinct().ToList(); } internal static void AssignRoles() { if (!Enabled.Value) { return; } List<ulong> playerIds = GetPlayerIds(); if (playerIds.Count == 0) { return; } int num = ((playerIds.Count <= 1) ? 1 : (playerIds.Count - 1)); int num2 = Mathf.Clamp(ImpostorCount.Value, 0, num); List<ulong> source = playerIds; if (NoRepeat.Value) { List<ulong> list = playerIds.Where((ulong i) => !LastImpostors.Contains(i)).ToList(); if (list.Count >= num2) { source = list; } } List<ulong> list2 = source.ToList(); for (int num3 = list2.Count - 1; num3 > 0; num3--) { int num4 = Rng.Next(num3 + 1); List<ulong> list3 = list2; int index = num3; List<ulong> list4 = list2; int index2 = num4; ulong value = list2[num4]; ulong value2 = list2[num3]; list3[index] = value; list4[index2] = value2; } HashSet<ulong> hashSet = new HashSet<ulong>(list2.Take(num2)); LastImpostors.Clear(); foreach (ulong item in hashSet) { LastImpostors.Add(item); } RoundImpostorNames = hashSet.Select(NameOf).ToList(); RoundActive = true; _hostSeenLanded = false; _awaitOrbit = false; foreach (ulong item2 in playerIds) { SendRole(item2, hashSet.Contains(item2) ? Role.Impostor : Role.Worker); } InitSabotage(hashSet); Log.LogDebug((object)$"Rozlosowano role: graczy={playerIds.Count}, impostorow={num2}."); } internal static string NameOf(ulong id) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null) { PlayerControllerB val = ((IEnumerable<PlayerControllerB>)instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => (Object)(object)x != (Object)null && x.actualClientId == id)); if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.playerUsername)) { return val.playerUsername; } } return "Gracz " + id; } internal static void CancelRound(bool broadcastEffects = false) { ClearEffects(broadcastEffects); RoundActive = false; _hostSeenLanded = false; _awaitOrbit = false; } internal static void HostTick() { SabotageTick(); NetworkManager singleton = NetworkManager.Singleton; StartOfRound instance = StartOfRound.Instance; if (_awaitOrbit) { if ((Object)(object)singleton == (Object)null || !singleton.IsServer || (Object)(object)instance == (Object)null) { _awaitOrbit = false; return; } float unscaledTime = Time.unscaledTime; if (_orbitAt < 0f && instance.inShipPhase && !instance.shipHasLanded) { _orbitAt = unscaledTime; } bool num = _orbitAt >= 0f && unscaledTime - _orbitAt >= (float)RevealDelay.Value; bool flag = unscaledTime - _leftAt > 45f; if (num || flag) { _awaitOrbit = false; if (RevealEnabled.Value) { SendReveal(); } } } else if (!RoundActive) { _hostSeenLanded = false; } else if (!((Object)(object)singleton == (Object)null) && singleton.IsServer && !((Object)(object)instance == (Object)null)) { if (instance.shipHasLanded) { _hostSeenLanded = true; } else if (_hostSeenLanded) { RoundActive = false; _hostSeenLanded = false; ClearEffects(broadcast: true); _awaitOrbit = true; _leftAt = Time.unscaledTime; _orbitAt = -1f; } } } private unsafe static void SendReveal() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; string text = string.Join("|", RoundImpostorNames); FastBufferWriter val = default(FastBufferWriter); foreach (ulong playerId in GetPlayerIds()) { if (playerId == singleton.LocalClientId) { RoleHud.ShowReveal(text); continue; } ((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize(text, false), (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(text, false); singleton.CustomMessagingManager.SendNamedMessage("pl.impostormod.lethalcompany.reveal", playerId, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } } internal static void ClearRolesForAll() { CancelRound(broadcastEffects: true); foreach (ulong playerId in GetPlayerIds()) { SendRole(playerId, Role.None); } } private void BindSabotageConfig() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown SabotageEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Sabotage", "SabotageEnabled", true, "Czy impostor moze uzywac sabotazy (liczy sie config HOSTA). Komenda /impostor sabotage on|off."); SabotageCooldown = ((BaseUnityPlugin)this).Config.Bind<int>("Sabotage", "Cooldown", 60, new ConfigDescription("Czas odnowienia miedzy sabotazami (sekundy, liczy sie config HOSTA). Komenda /impostor cooldown <s>.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 600), Array.Empty<object>())); SabotageMaxUses = ((BaseUnityPlugin)this).Config.Bind<int>("Sabotage", "MaxUsesPerRound", 3, new ConfigDescription("Ile sabotazy moze uzyc KAZDY impostor w jednej rundzie (liczy sie config HOSTA). Komenda /impostor uses <n>.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>())); BlackoutDuration = ((BaseUnityPlugin)this).Config.Bind<int>("Sabotage", "BlackoutDuration", 10, new ConfigDescription("Ile sekund trwa zgaszenie swiatel (HOST).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>())); DoorDuration = ((BaseUnityPlugin)this).Config.Bind<int>("Sabotage", "DoorDuration", 8, new ConfigDescription("Ile sekund drzwi statku zostaja zamkniete (HOST).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>())); PushForce = ((BaseUnityPlugin)this).Config.Bind<float>("Sabotage", "PushForce", 1000f, "Sila popchniecia (HOST). Wieksza = dalej odrzuca."); PushRange = ((BaseUnityPlugin)this).Config.Bind<float>("Sabotage", "PushRange", 3.5f, "Maksymalna odleglosc od impostora, z jakiej mozna popchnac najblizszego gracza (HOST)."); BlackoutKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Sabotage", "BlackoutKey", (Key)36, "Klawisz: zgaszenie swiatel (lokalnie)."); DoorKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Sabotage", "DoorKey", (Key)16, "Klawisz: zamkniecie drzwi statku (lokalnie)."); PushKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Sabotage", "PushKey", (Key)17, "Klawisz: popchniecie najblizszego gracza (lokalnie)."); } private static void RegisterSabotageHandlers(NetworkManager nm) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown CustomMessagingManager customMessagingManager = nm.CustomMessagingManager; object obj = <>O.<3>__OnSabotageRequest; if (obj == null) { HandleNamedMessageDelegate val = OnSabotageRequest; <>O.<3>__OnSabotageRequest = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("pl.impostormod.lethalcompany.sabotage", (HandleNamedMessageDelegate)obj); object obj2 = <>O.<4>__OnEffectMessage; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnEffectMessage; <>O.<4>__OnEffectMessage = val2; obj2 = (object)val2; } customMessagingManager.RegisterNamedMessageHandler("pl.impostormod.lethalcompany.effect", (HandleNamedMessageDelegate)obj2); object obj3 = <>O.<5>__OnStatusMessage; if (obj3 == null) { HandleNamedMessageDelegate val3 = OnStatusMessage; <>O.<5>__OnStatusMessage = val3; obj3 = (object)val3; } customMessagingManager.RegisterNamedMessageHandler("pl.impostormod.lethalcompany.status", (HandleNamedMessageDelegate)obj3); } internal static void OnRoleApplied() { SabUsesLeft = -1; SabCooldownUntil = 0f; } internal static void HandleSabotageKeys() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current == null) { return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val == (Object)null) && !val.isTypingChat && !val.isPlayerDead && !Refl.GetBool(val, "inTerminalMenu")) { if (((ButtonControl)current[BlackoutKey.Value]).wasPressedThisFrame) { RequestSabotage(0); } else if (((ButtonControl)current[DoorKey.Value]).wasPressedThisFrame) { RequestSabotage(1); } else if (((ButtonControl)current[PushKey.Value]).wasPressedThisFrame) { RequestSabotage(2); } } } private static void Tip(string text) { if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip("SABOTAZ", text, false, false, "LC_Tip1"); } } internal unsafe static void RequestSabotage(byte type) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || SabUsesLeft == 255) { return; } float unscaledTime = Time.unscaledTime; if (SabUsesLeft == 0) { Tip("Wykorzystales wszystkie sabotaze w tej rundzie."); return; } if (unscaledTime < SabCooldownUntil) { Tip("Odnowienie: " + Mathf.CeilToInt(SabCooldownUntil - unscaledTime) + " s"); return; } if (singleton.IsServer) { TryExecuteSabotage(singleton.LocalClientId, type); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(1, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteByteSafe(type); singleton.CustomMessagingManager.SendNamedMessage("pl.impostormod.lethalcompany.sabotage", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } internal static string SabotageHint() { //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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (SabUsesLeft < 0 || SabUsesLeft == 255) { return ""; } float num = SabCooldownUntil - Time.unscaledTime; string text = ((SabUsesLeft == 0) ? "brak uzyc" : ((num > 0f) ? ("odnowienie " + Mathf.CeilToInt(num) + " s") : "gotowe")); return "\n<size=45%><color=#FFFFFF>[" + ((object)BlackoutKey.Value/*cast due to .constrained prefix*/).ToString() + "] Ciemnosc [" + ((object)DoorKey.Value/*cast due to .constrained prefix*/).ToString() + "] Drzwi [" + ((object)PushKey.Value/*cast due to .constrained prefix*/).ToString() + "] Popchniecie\nSabotaze: " + SabUsesLeft + " | " + text + "</color></size>"; } private static void ApplyStatus(byte uses, float cooldown, string text) { SabUsesLeft = uses; SabCooldownUntil = Time.unscaledTime + Mathf.Max(0f, cooldown); if (!string.IsNullOrEmpty(text)) { Tip(text); } } private static void OnStatusMessage(ulong sender, FastBufferReader reader) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (sender == 0L) { byte uses = default(byte); ((FastBufferReader)(ref reader)).ReadByteSafe(ref uses); float cooldown = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref cooldown, default(ForPrimitives)); string text = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false); ApplyStatus(uses, cooldown, text); } } private static void OnEffectMessage(ulong sender, FastBufferReader reader) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) if (sender == 0L) { byte type = default(byte); ((FastBufferReader)(ref reader)).ReadByteSafe(ref type); float x = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref x, default(ForPrimitives)); float z = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref z, default(ForPrimitives)); ApplyEffect(type, x, z); } } internal static void InitSabotage(HashSet<ulong> impostors) { ClearEffects(broadcast: true); SabStates.Clear(); foreach (ulong impostor in impostors) { SabStates[impostor] = new SabState { Uses = SabotageMaxUses.Value, NextAt = 0f }; SendStatus(impostor, SabotageEnabled.Value ? ((byte)SabotageMaxUses.Value) : byte.MaxValue, 0f, ""); } } private static void OnSabotageRequest(ulong sender, FastBufferReader reader) { NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && singleton.IsServer) { byte type = default(byte); ((FastBufferReader)(ref reader)).ReadByteSafe(ref type); TryExecuteSabotage(sender, type); } } private static PlayerControllerB PlayerById(ulong id) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return null; } return ((IEnumerable<PlayerControllerB>)instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB p) => (Object)(object)p != (Object)null && p.actualClientId == id)); } private static void Reply(ulong id, SabState st, string text) { float cooldown = Mathf.Max(0f, st.NextAt - Time.unscaledTime); SendStatus(id, (byte)Mathf.Max(0, st.Uses), cooldown, text); } internal static void TryExecuteSabotage(ulong id, byte type) { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_024c: 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) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!RoundActive || !LastImpostors.Contains(id) || !SabStates.TryGetValue(id, out var value) || !SabotageEnabled.Value) { return; } StartOfRound instance = StartOfRound.Instance; PlayerControllerB val = PlayerById(id); if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null || val.isPlayerDead) { return; } if (!instance.shipHasLanded) { Reply(id, value, "Sabotaz mozliwy tylko, gdy statek stoi na ksiezycu."); return; } if (value.Uses <= 0) { Reply(id, value, "Wykorzystales wszystkie sabotaze w tej rundzie."); return; } float unscaledTime = Time.unscaledTime; if (unscaledTime < value.NextAt) { Reply(id, value, "Odnowienie: " + Mathf.CeilToInt(value.NextAt - unscaledTime) + " s"); return; } string text; switch (type) { default: return; case 0: if (_blackoutEnd > 0f) { Reply(id, value, "Swiatla sa juz zgaszone."); return; } _blackoutEnd = unscaledTime + (float)BlackoutDuration.Value; BroadcastEffect(0, 0f, 0f); text = "Zgaszono swiatla."; break; case 1: if (_doorEnd > 0f) { Reply(id, value, "Drzwi statku sa juz zamkniete."); return; } _doorEnd = unscaledTime + (float)DoorDuration.Value; BroadcastEffect(2, 0f, 0f); text = "Zamknieto drzwi statku."; break; case 2: { PlayerControllerB val2 = null; float num = PushRange.Value; Vector3 position = ((Component)val).transform.position; PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts; foreach (PlayerControllerB val3 in allPlayerScripts) { if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)val) && val3.isPlayerControlled && !val3.isPlayerDead) { float num2 = Vector3.Distance(((Component)val3).transform.position, position); if (num2 <= num) { val2 = val3; num = num2; } } } if ((Object)(object)val2 == (Object)null) { Reply(id, value, "Nikogo nie ma w poblizu."); return; } Vector3 val4 = ((Component)val2).transform.position - position; val4.y = 0f; if (((Vector3)(ref val4)).sqrMagnitude < 0.01f) { val4 = ((Component)val).transform.forward; } val4 = ((Vector3)(ref val4)).normalized * PushForce.Value; SendEffect(val2.actualClientId, 4, val4.x, val4.z); text = "Popchnieto: " + val2.playerUsername; break; } } value.Uses--; value.NextAt = unscaledTime + (float)SabotageCooldown.Value; Reply(id, value, text); } internal static void SabotageTick() { if (_blackoutEnd <= 0f && _doorEnd <= 0f) { return; } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer) { _blackoutEnd = 0f; _doorEnd = 0f; return; } float unscaledTime = Time.unscaledTime; if (_blackoutEnd > 0f && unscaledTime >= _blackoutEnd) { _blackoutEnd = 0f; BroadcastEffect(1, 0f, 0f); } if (_doorEnd > 0f && unscaledTime >= _doorEnd) { _doorEnd = 0f; BroadcastEffect(3, 0f, 0f); } } internal static void ClearEffects(bool broadcast) { try { if (_blackoutEnd > 0f) { _blackoutEnd = 0f; if (broadcast) { BroadcastEffect(1, 0f, 0f); } } if (_doorEnd > 0f) { _doorEnd = 0f; if (broadcast) { BroadcastEffect(3, 0f, 0f); } } } catch (Exception ex) { Log.LogError((object)("Blad konczenia efektow: " + ex)); } } private unsafe static void SendStatus(ulong id, byte uses, float cooldown, string text) { //IL_0044: 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) //IL_0065: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; text = text ?? ""; if (id == singleton.LocalClientId) { ApplyStatus(uses, cooldown, text); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(5 + FastBufferWriter.GetWriteSize(text, false), (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteByteSafe(uses); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref cooldown, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(text, false); singleton.CustomMessagingManager.SendNamedMessage("pl.impostormod.lethalcompany.status", id, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private unsafe static void SendEffect(ulong id, byte type, float x, float z) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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) NetworkManager singleton = NetworkManager.Singleton; if (id == singleton.LocalClientId) { ApplyEffect(type, x, z); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(9, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteByteSafe(type); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref x, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref z, default(ForPrimitives)); singleton.CustomMessagingManager.SendNamedMessage("pl.impostormod.lethalcompany.effect", id, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private static void BroadcastEffect(byte type, float x, float z) { foreach (ulong playerId in GetPlayerIds()) { SendEffect(playerId, type, x, z); } } private static void ApplyEffect(byte type, float x, float z) { try { switch (type) { case 0: SetPower(on: false); break; case 1: SetPower(on: true); break; case 2: SetDoor(closed: true); break; case 3: SetDoor(closed: false); break; case 4: Push(x, z); break; } } catch (Exception ex) { Log.LogError((object)("Blad efektu " + type + ": " + ex)); } } private static void SetPower(bool on) { RoundManager instance = RoundManager.Instance; if ((Object)(object)instance != (Object)null && (!on || !Refl.GetBool(instance, "powerOffPermanently"))) { Refl.Call(instance, "SwitchPower", on); } StartOfRound instance2 = StartOfRound.Instance; if ((Object)(object)instance2 != (Object)null) { Refl.Call(Refl.GetField(instance2, "shipRoomLights"), "SetShipLightsBoolean", on); } } private static void SetDoor(bool closed) { Type type = AccessTools.TypeByName("HangarShipDoor"); if (type == null) { Refl.Warn("Nie znaleziono klasy HangarShipDoor."); return; } Refl.Call(Object.FindObjectOfType(type), "PlayDoorAnimation", closed); } private static void Push(float x, float z) { //IL_004a: 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) //IL_0047: 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_0059: 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) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val == (Object)null) && !val.isPlayerDead) { Vector3 val2 = ((Refl.GetField(val, "externalForces") is Vector3 val3) ? val3 : Vector3.zero); Refl.SetField(val, "externalForces", val2 + new Vector3(x, 0f, z)); } } } internal static class RoleHud { private static TextMeshProUGUI _text; private static bool _seenLanded; private static bool _loggedCreated; private static TextMeshProUGUI _revealText; private static float _revealUntil; private static string _revealPending; internal static void OnNewRole() { _seenLanded = false; } internal static void Tick(HUDManager hud) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) TickReveal(hud); if (Plugin.LocalRole != Role.None) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { Plugin.LocalRole = Role.None; } else if (instance.shipHasLanded) { _seenLanded = true; } else if (_seenLanded) { Plugin.LocalRole = Role.None; } } if (Plugin.LocalRole == Role.Impostor) { Plugin.HandleSabotageKeys(); } if (Plugin.LocalRole == Role.None) { if ((Object)(object)_text != (Object)null) { ((Component)_text).gameObject.SetActive(false); } return; } try { if ((Object)(object)_text == (Object)null) { Create(hud); } if (!((Object)(object)_text == (Object)null)) { bool flag = Plugin.LocalRole == Role.Impostor; ((TMP_Text)_text).text = (flag ? ("IMPOSTOR" + Plugin.SabotageHint()) : "PRACOWNIK"); ((Graphic)_text).color = (flag ? new Color(0.95f, 0.05f, 0.05f, 1f) : new Color(0.55f, 0.85f, 1f, 1f)); ((TMP_Text)_text).fontSize = Plugin.FontSize.Value; ((Component)_text).gameObject.SetActive(true); } } catch (Exception ex) { Plugin.Log.LogError((object)("Blad napisu roli: " + ex)); } } internal static void ShowReveal(string payload) { List<string> list = (from n in (payload ?? "").Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries) select n.Replace("<", "").Replace(">", "")).ToList(); string revealPending = ((list.Count != 0) ? (((list.Count == 1) ? "Impostor w tej rundzie:" : "Impostorzy w tej rundzie:") + "\n<color=#F20D0D><b>" + string.Join(", ", list) + "</b></color>") : "W tej rundzie nie bylo impostora."); _revealPending = revealPending; _revealUntil = Time.unscaledTime + (float)Mathf.Max(1, Plugin.RevealDuration.Value); } private static void TickReveal(HUDManager hud) { try { if (_revealPending == null && ((Object)(object)_revealText == (Object)null || Time.unscaledTime >= _revealUntil)) { if ((Object)(object)_revealText != (Object)null) { ((Component)_revealText).gameObject.SetActive(false); } return; } if ((Object)(object)_revealText == (Object)null) { CreateReveal(hud); } if (!((Object)(object)_revealText == (Object)null)) { if (_revealPending != null) { ((TMP_Text)_revealText).text = _revealPending; _revealPending = null; } bool active = Time.unscaledTime < _revealUntil; ((Component)_revealText).gameObject.SetActive(active); } } catch (Exception ex) { Plugin.Log.LogError((object)("Blad komunikatu o impostorach: " + ex)); _revealPending = null; } } private static void CreateReveal(HUDManager hud) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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) Transform val = (((Object)(object)hud.HUDContainer != (Object)null) ? hud.HUDContainer.transform : ((Component)hud).transform); GameObject val2 = new GameObject("ImpostorModRevealText", new Type[1] { typeof(RectTransform) }) { layer = ((Component)val).gameObject.layer }; val2.transform.SetParent(val, false); val2.transform.SetAsLastSibling(); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, 60f); component.sizeDelta = new Vector2(1200f, 300f); ((Transform)component).localScale = Vector3.one; TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>(); TMP_FontAsset val4 = null; if (hud.controlTipLines != null && hud.controlTipLines.Length != 0 && (Object)(object)hud.controlTipLines[0] != (Object)null) { val4 = ((TMP_Text)hud.controlTipLines[0]).font; } if ((Object)(object)val4 == (Object)null) { val4 = TMP_Settings.defaultFontAsset; } if ((Object)(object)val4 != (Object)null) { ((TMP_Text)val3).font = val4; } ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; ((TMP_Text)val3).fontSize = 48f; ((Graphic)val3).color = Color.white; ((TMP_Text)val3).enableWordWrapping = true; ((Graphic)val3).raycastTarget = false; ((TMP_Text)val3).overflowMode = (TextOverflowModes)0; _revealText = val3; } private static void Create(HUDManager hud) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)hud.HUDContainer != (Object)null) ? hud.HUDContainer.transform : ((Component)hud).transform); GameObject val2 = new GameObject("ImpostorModRoleText", new Type[1] { typeof(RectTransform) }) { layer = ((Component)val).gameObject.layer }; val2.transform.SetParent(val, false); val2.transform.SetAsLastSibling(); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = new Vector2(1f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(-20f, (float)(-Plugin.OffsetY.Value)); component.sizeDelta = new Vector2(700f, 180f); ((Transform)component).localScale = Vector3.one; TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>(); TMP_FontAsset val4 = null; if (hud.controlTipLines != null && hud.controlTipLines.Length != 0 && (Object)(object)hud.controlTipLines[0] != (Object)null) { val4 = ((TMP_Text)hud.controlTipLines[0]).font; } if ((Object)(object)val4 == (Object)null) { val4 = TMP_Settings.defaultFontAsset; } if ((Object)(object)val4 != (Object)null) { ((TMP_Text)val3).font = val4; } ((TMP_Text)val3).alignment = (TextAlignmentOptions)260; ((TMP_Text)val3).fontStyle = (FontStyles)1; ((TMP_Text)val3).enableWordWrapping = false; ((Graphic)val3).raycastTarget = false; ((TMP_Text)val3).overflowMode = (TextOverflowModes)0; _text = val3; if (!_loggedCreated) { _loggedCreated = true; Plugin.Log.LogInfo((object)("Utworzono napis roli (rodzic: " + ((Object)val).name + ", font: " + (((Object)(object)val4 != (Object)null) ? ((Object)val4).name : "brak") + ").")); } } } [HarmonyPatch(typeof(HUDManager), "Update")] internal static class HudUpdatePatch { [HarmonyPostfix] private static void Postfix(HUDManager __instance) { Plugin.HostTick(); RoleHud.Tick(__instance); } } [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] internal static class ConnectPatch { [HarmonyPostfix] private static void Postfix() { Plugin.RegisterHandler(); } } [HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")] internal static class LandingPatch { [HarmonyPostfix] private static void Postfix() { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsServer) { Plugin.AssignRoles(); } } } [HarmonyPatch(typeof(GameNetworkManager), "Disconnect")] internal static class DisconnectPatch { [HarmonyPostfix] private static void Postfix() { Plugin.LocalRole = Role.None; Plugin.LastImpostors.Clear(); Plugin.CancelRound(); } } internal static class Refl { private static readonly HashSet<string> Warned = new HashSet<string>(); private const BindingFlags All = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal static void Warn(string msg) { Plugin.Log.LogWarning((object)msg); if (!Warned.Add(msg)) { return; } try { if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.AddChatMessage("[ImpostorMod] " + msg, "", -1, false); } } catch { } } internal static object Call(object target, string name, params object[] args) { if (target == null) { Warn("Brak obiektu dla: " + name); return null; } Type type = target.GetType(); while (type != null) { MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != name) && methodInfo.GetParameters().Length == args.Length) { try { return methodInfo.Invoke(target, args); } catch (Exception ex) { Warn("Blad wywolania " + name + ": " + (ex.InnerException ?? ex).Message); return null; } } } type = type.BaseType; } Warn("Nie znaleziono metody " + name + " w " + target.GetType().Name + "."); return null; } private static FieldInfo FindField(object target, string name) { Type type = target.GetType(); while (type != null) { FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type = type.BaseType; } return null; } internal static object GetField(object target, string name) { if (target == null) { return null; } FieldInfo fieldInfo = FindField(target, name); if (fieldInfo == null) { Warn("Nie znaleziono pola " + name + " w " + target.GetType().Name + "."); return null; } return fieldInfo.GetValue(target); } internal static void SetField(object target, string name, object value) { if (target != null) { FieldInfo fieldInfo = FindField(target, name); if (fieldInfo == null) { Warn("Nie znaleziono pola " + name + " w " + target.GetType().Name + "."); } else { fieldInfo.SetValue(target, value); } } } internal static bool GetBool(object target, string name) { if (target == null) { return false; } FieldInfo fieldInfo = FindField(target, name); bool flag = default(bool); int num; if (fieldInfo != null) { object value = fieldInfo.GetValue(target); if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } }