Please disclose if your mod was created primarily 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 ImpostorAmongus v0.1.0
plugins/ImpostorAmongus/Amogus.dll
Decompiled 2 years 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.Versioning; using System.Security; using System.Security.Permissions; using Amogus.API; using Amogus.Affiliations; using Amogus.Behaviours; using Amogus.NetcodePatcher; using Amogus.Patches; using Amogus.Util; using BepInEx; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; 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: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("Amogus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Amogus")] [assembly: AssemblyTitle("Amogus")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Amogus { [BepInPlugin("me.loaforc.amogus", "Amogus", "0.1.0")] public class AmogusPlugin : BaseUnityPlugin { public const string MOD_GUID = "me.loaforc.amogus"; public const string MOD_NAME = "Amogus"; public const string MOD_VERSION = "0.1.0"; internal static AmogusPlugin instance; internal static ManualLogSource logger; internal static RoleInfo Crewmate; internal static RoleInfo Impostor; private void Awake() { if (!((Object)(object)instance == (Object)null)) { return; } instance = this; logger = Logger.CreateLogSource("me.loaforc.amogus"); logger.LogInfo((object)"assets"); Assets.Init(); logger.LogInfo((object)"networking"); Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { try { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0) { methodInfo.Invoke(null, null); } } } catch (Exception ex) { logger.LogWarning((object)("CAUGHT EXCEPTION: " + ex)); logger.LogInfo((object)""); logger.LogWarning((object)"======================================================"); logger.LogWarning((object)"The error above can most likely be ignored"); logger.LogWarning((object)"======================================================"); logger.LogInfo((object)""); } } logger.LogInfo((object)"patching"); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "me.loaforc.amogus"); logger.LogInfo((object)"Registering roles."); Crewmate = new RoleInfo(AmogusAPI.Crewmate, Assets.crewmateHandler) { Name = "Crewmate", MinPlayers = 0, MaxPlayers = 999 }; Impostor = new RoleInfo(AmogusAPI.Impostor, Assets.impostorHandler) { Name = "Impostor", MinPlayers = 1, MaxPlayers = 1 }; AmogusAPI.RegisterRole(Crewmate); AmogusAPI.RegisterRole(Impostor); logger.LogInfo((object)"Amogus:0.1.0 has succesfully loaded!"); } } } namespace Amogus.Util { internal class AmogusConfig { public static bool LOG_ROLE_CHANGES = false; public static int QUOTAS_TILL_CREWMATE_WIN = 3; } internal static class Assets { internal static AssetBundle assetBundle; internal static GameObject uiPrefab; internal static GameObject handlerPrefab; internal static GameObject impostorHandler; internal static GameObject crewmateHandler; internal static GameObject bitePrefab; internal static List<GameObject> networkPrefabs = new List<GameObject>(); internal static void Init() { assetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "amogus")); uiPrefab = TryLoadAsset<GameObject>("AmogusCanvas.prefab"); handlerPrefab = TryLoadAsset<GameObject>("AmogusHandler.prefab"); impostorHandler = TryLoadAsset<GameObject>("ImpostorHandler.prefab"); crewmateHandler = TryLoadAsset<GameObject>("CrewmateHandler.prefab"); bitePrefab = TryLoadAsset<GameObject>("BitePrefab.prefab"); } private static T TryLoadAsset<T>(string name) where T : Object { AmogusPlugin.logger.LogDebug((object)("-- Loading asset: '" + name + "'")); T val = assetBundle.LoadAsset<T>(name); if ((Object)(object)val == (Object)null) { AmogusPlugin.logger.LogError((object)("FAILED TO FIND ASSET: " + name)); return default(T); } NetworkObject val2 = default(NetworkObject); if (val is GameObject && ((GameObject)/*isinst with value type is only supported in some contexts*/).TryGetComponent<NetworkObject>(ref val2)) { List<GameObject> list = networkPrefabs; object obj = val; list.Add((GameObject)((obj is GameObject) ? obj : null)); } return val; } } internal static class ExtensionMethods { internal static BaseRole GetRole(this PlayerControllerB player) { foreach (BaseRole givenRole in AmogusHandler.instance.givenRoles) { if ((Object)(object)givenRole.player == (Object)(object)player) { return givenRole; } } return null; } public static void Shuffle<T>(this IList<T> list) { Random random = new Random(Random.Range(int.MinValue, int.MaxValue)); int num = list.Count; while (num > 1) { num--; int index = random.Next(num + 1); T value = list[index]; list[index] = list[num]; list[num] = value; } } public static List<PlayerControllerB> GetConnectedPlayers(this StartOfRound startOfRound) { List<PlayerControllerB> list = new List<PlayerControllerB>(); PlayerControllerB[] allPlayerScripts = startOfRound.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.isPlayerControlled) { list.Add(val); } } return list; } } internal static class PlayerGetter { public static PlayerControllerB FromClientID(ulong clientId) { return StartOfRound.Instance.allPlayerScripts[StartOfRound.Instance.ClientPlayerList[clientId]]; } } } namespace Amogus.Roles { public class CrewmateRole : BaseRole { public override RoleInfo GetRoleInfo() { return AmogusPlugin.Crewmate; } public override string GetDescription() { return "Complete " + AmogusConfig.QUOTAS_TILL_CREWMATE_WIN + " quotas, without being killed by the impostors."; } protected override void __initializeVariables() { base.__initializeVariables(); } protected internal override string __getTypeName() { return "CrewmateRole"; } } public class ImpostorRole : BaseRole { [SerializeField] private float BiteCooldown = 1f; private float timeFromLastBite; public override RoleInfo GetRoleInfo() { return AmogusPlugin.Impostor; } public override string GetDescription() { return "Prevent the crew from completing " + AmogusConfig.QUOTAS_TILL_CREWMATE_WIN + " quotas."; } [ServerRpc] private void ImpostorBiteServerRpc(ulong clientId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Invalid comparison between Unknown and I4 //IL_00a5: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } return; } ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2755365689u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, clientId); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2755365689u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { Object.Instantiate<GameObject>(Assets.bitePrefab).GetComponent<NetworkObject>().SpawnWithOwnership(clientId, false); } } private void Update() { if (((NetworkBehaviour)this).IsOwner) { timeFromLastBite += Time.deltaTime; if (((ButtonControl)Keyboard.current.zKey).wasPressedThisFrame && timeFromLastBite >= BiteCooldown) { timeFromLastBite = 0f; ImpostorBiteServerRpc(((NetworkBehaviour)this).NetworkManager.LocalClientId); } } } protected override void __initializeVariables() { base.__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_ImpostorRole() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(2755365689u, new RpcReceiveHandler(__rpc_handler_2755365689)); } private static void __rpc_handler_2755365689(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 NetworkManager networkManager = target.NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } } else { ulong clientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref clientId); target.__rpc_exec_stage = (__RpcExecStage)1; ((ImpostorRole)(object)target).ImpostorBiteServerRpc(clientId); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "ImpostorRole"; } } } namespace Amogus.Patches { [HarmonyPatch(typeof(GameNetworkManager))] internal static class GameNetwokManagerPatch { [HarmonyPrefix] [HarmonyPatch("Start")] internal static void RegisterPrefabs() { foreach (GameObject networkPrefab in Assets.networkPrefabs) { NetworkManager.Singleton.AddNetworkPrefab(networkPrefab); } } [HarmonyPrefix] [HarmonyPatch("Disconnect")] internal static void ResetThings() { try { PlayerControllerPatch.PermDeadPlayers.Clear(); if ((Object)(object)AmogusHandler.instance != (Object)null) { AmogusHandler.instance.HandleGameOver(); if (((NetworkBehaviour)AmogusHandler.instance).IsOwner) { ((NetworkBehaviour)AmogusHandler.instance).NetworkObject.Despawn(true); } } } catch (Exception ex) { AmogusPlugin.logger.LogError((object)ex); } } } [HarmonyPatch(typeof(HUDManager))] internal static class HUDManagerPatch { [HarmonyPostfix] [HarmonyPatch("Start")] internal static void CreateCustomUI(HUDManager __instance) { Object.Instantiate<GameObject>(Assets.uiPrefab); } [HarmonyPrefix] [HarmonyPatch("HideHUD")] private static bool HideHUDPatch(bool hide) { if (GameNetworkManager.Instance.localPlayerController.isPlayerDead && !hide) { return false; } return true; } } [HarmonyPatch(typeof(PlayerControllerB))] public static class PlayerControllerPatch { internal static List<PlayerControllerB> PermDeadPlayers = new List<PlayerControllerB>(); [HarmonyPostfix] [HarmonyPatch("DamagePlayerFromOtherClientClientRpc")] internal static void CheckIfPlayerIsDeadTillNextQuota(PlayerControllerB __instance) { try { AmogusPlugin.logger.LogDebug((object)"Handling friendly fire damage..."); if ((Object)(object)__instance == (Object)null) { AmogusPlugin.logger.LogWarning((object)"Could not access victim after death!"); } else if (__instance.isPlayerDead) { PermDeadPlayers.Add(__instance); if ((Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController) { StartOfRound.Instance.SetSpectateCameraToGameOverMode(true, (PlayerControllerB)null); __instance.SetSpectatedPlayerEffects(false); } } } catch (Exception ex) { AmogusPlugin.logger.LogError((object)("failed to find if player killed otherplayer: " + ex)); AmogusPlugin.logger.LogError((object)ex.StackTrace); } } [HarmonyPrefix] [HarmonyPatch("SpectateNextPlayer")] private static bool DisallowSpectatingOtherPlayersWhenDead(PlayerControllerB __instance) { return PermDeadPlayers.Contains(__instance); } } [HarmonyPatch(typeof(StartMatchLever))] internal static class StartMatchLevelPatches { [HarmonyPostfix] [HarmonyPatch("Update")] internal static void Update(StartMatchLever __instance) { if (!__instance.leverHasBeenPulled || !StartOfRound.Instance.shipHasLanded) { return; } bool flag = true; foreach (PlayerControllerB connectedPlayer in StartOfRound.Instance.GetConnectedPlayers()) { if (!connectedPlayer.isPlayerDead && !connectedPlayer.isInElevator) { flag = false; break; } } if (!flag) { __instance.triggerScript.disabledHoverTip = "[Gather all alive players]"; } else { __instance.triggerScript.disabledHoverTip = "[Wait for ship to land]"; } __instance.triggerScript.interactable = flag; } [HarmonyPostfix] [HarmonyPatch("StartGame")] internal static void AssignRoles(StartMatchLever __instance) { if (((NetworkBehaviour)StartOfRound.Instance).IsHost) { AmogusHandler.instance.AssignRoles(); } } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatch { [HarmonyPostfix] [HarmonyPatch("Start")] internal static void CreateAmogusHandler() { if (((NetworkBehaviour)StartOfRound.Instance).IsHost) { Object.Instantiate<GameObject>(Assets.handlerPrefab).GetComponent<NetworkObject>().Spawn(false); } } [HarmonyPrefix] [HarmonyPatch("ReviveDeadPlayers")] internal static bool ohgodono(StartOfRound __instance) { //IL_0146: Unknown result type (might be due to invalid IL or missing references) AmogusPlugin.logger.LogInfo((object)"pluh"); __instance.allPlayersDead = false; for (int i = 0; i < __instance.allPlayerScripts.Length; i++) { Debug.Log((object)"Reviving players A"); __instance.allPlayerScripts[i].ResetPlayerBloodObjects(__instance.allPlayerScripts[i].isPlayerDead); if (!__instance.allPlayerScripts[i].isPlayerDead && !__instance.allPlayerScripts[i].isPlayerControlled) { continue; } __instance.allPlayerScripts[i].isClimbingLadder = false; __instance.allPlayerScripts[i].ResetZAndXRotation(); ((Collider)__instance.allPlayerScripts[i].thisController).enabled = true; __instance.allPlayerScripts[i].health = 100; __instance.allPlayerScripts[i].disableLookInput = false; Debug.Log((object)"Reviving players B"); if (__instance.allPlayerScripts[i].isPlayerDead && !PlayerControllerPatch.PermDeadPlayers.Contains(__instance.allPlayerScripts[i])) { __instance.allPlayerScripts[i].isPlayerDead = false; __instance.allPlayerScripts[i].isPlayerControlled = true; __instance.allPlayerScripts[i].isInElevator = true; __instance.allPlayerScripts[i].isInHangarShipRoom = true; __instance.allPlayerScripts[i].isInsideFactory = false; __instance.allPlayerScripts[i].wasInElevatorLastFrame = false; __instance.SetPlayerObjectExtrapolate(false); __instance.allPlayerScripts[i].TeleportPlayer(__instance.GetPlayerSpawnPosition(i, false), false, 0f, false, true); __instance.allPlayerScripts[i].setPositionOfDeadPlayer = false; __instance.allPlayerScripts[i].DisablePlayerModel(__instance.allPlayerObjects[i], true, true); ((Behaviour)__instance.allPlayerScripts[i].helmetLight).enabled = false; Debug.Log((object)"Reviving players C"); __instance.allPlayerScripts[i].Crouch(false); __instance.allPlayerScripts[i].criticallyInjured = false; if ((Object)(object)__instance.allPlayerScripts[i].playerBodyAnimator != (Object)null) { __instance.allPlayerScripts[i].playerBodyAnimator.SetBool("Limp", false); } __instance.allPlayerScripts[i].bleedingHeavily = false; __instance.allPlayerScripts[i].activatingItem = false; __instance.allPlayerScripts[i].twoHanded = false; __instance.allPlayerScripts[i].inSpecialInteractAnimation = false; __instance.allPlayerScripts[i].disableSyncInAnimation = false; __instance.allPlayerScripts[i].inAnimationWithEnemy = null; __instance.allPlayerScripts[i].holdingWalkieTalkie = false; __instance.allPlayerScripts[i].speakingToWalkieTalkie = false; Debug.Log((object)"Reviving players D"); __instance.allPlayerScripts[i].isSinking = false; __instance.allPlayerScripts[i].isUnderwater = false; __instance.allPlayerScripts[i].sinkingValue = 0f; __instance.allPlayerScripts[i].statusEffectAudio.Stop(); __instance.allPlayerScripts[i].DisableJetpackControlsLocally(); __instance.allPlayerScripts[i].health = 100; Debug.Log((object)"Reviving players E"); __instance.allPlayerScripts[i].mapRadarDotAnimator.SetBool("dead", false); if (((NetworkBehaviour)__instance.allPlayerScripts[i]).IsOwner) { HUDManager.Instance.gasHelmetAnimator.SetBool("gasEmitting", false); __instance.allPlayerScripts[i].hasBegunSpectating = false; HUDManager.Instance.RemoveSpectateUI(); HUDManager.Instance.gameOverAnimator.SetTrigger("revive"); __instance.allPlayerScripts[i].hinderedMultiplier = 1f; __instance.allPlayerScripts[i].isMovementHindered = 0; __instance.allPlayerScripts[i].sourcesCausingSinking = 0; Debug.Log((object)"Reviving players E2"); __instance.allPlayerScripts[i].reverbPreset = __instance.shipReverb; } } Debug.Log((object)"Reviving players F"); SoundManager.Instance.earsRingingTimer = 0f; __instance.allPlayerScripts[i].voiceMuffledByEnemy = false; SoundManager.Instance.playerVoicePitchTargets[i] = 1f; SoundManager.Instance.SetPlayerPitch(1f, i); if ((Object)(object)__instance.allPlayerScripts[i].currentVoiceChatIngameSettings == (Object)null) { __instance.RefreshPlayerVoicePlaybackObjects(); } if ((Object)(object)__instance.allPlayerScripts[i].currentVoiceChatIngameSettings != (Object)null) { if ((Object)(object)__instance.allPlayerScripts[i].currentVoiceChatIngameSettings.voiceAudio == (Object)null) { __instance.allPlayerScripts[i].currentVoiceChatIngameSettings.InitializeComponents(); } if ((Object)(object)__instance.allPlayerScripts[i].currentVoiceChatIngameSettings.voiceAudio == (Object)null) { return false; } ((Component)__instance.allPlayerScripts[i].currentVoiceChatIngameSettings.voiceAudio).GetComponent<OccludeAudio>().overridingLowPass = false; } Debug.Log((object)"Reviving players G"); } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; localPlayerController.bleedingHeavily = false; localPlayerController.criticallyInjured = false; localPlayerController.playerBodyAnimator.SetBool("Limp", false); localPlayerController.health = 100; HUDManager.Instance.UpdateHealthUI(100, false); localPlayerController.spectatedPlayerScript = null; ((Behaviour)HUDManager.Instance.audioListenerLowPass).enabled = false; Debug.Log((object)"Reviving players H"); __instance.SetSpectateCameraToGameOverMode(false, localPlayerController); RagdollGrabbableObject[] array = Object.FindObjectsOfType<RagdollGrabbableObject>(); for (int j = 0; j < array.Length; j++) { if (!((GrabbableObject)array[j]).isHeld) { if (((NetworkBehaviour)__instance).IsServer) { if (((NetworkBehaviour)array[j]).NetworkObject.IsSpawned) { ((NetworkBehaviour)array[j]).NetworkObject.Despawn(true); } else { Object.Destroy((Object)(object)((Component)array[j]).gameObject); } } } else if (((GrabbableObject)array[j]).isHeld && (Object)(object)((GrabbableObject)array[j]).playerHeldBy != (Object)null) { ((GrabbableObject)array[j]).playerHeldBy.DropAllHeldItems(true, false); } } DeadBodyInfo[] array2 = Object.FindObjectsOfType<DeadBodyInfo>(); for (int k = 0; k < array2.Length; k++) { Object.Destroy((Object)(object)((Component)array2[k]).gameObject); } __instance.livingPlayers = __instance.connectedPlayersAmount + 1; __instance.allPlayersDead = false; __instance.UpdatePlayerVoiceEffects(); __instance.ResetMiscValues(); return false; } [HarmonyPrefix] [HarmonyPatch("FirePlayersAfterDeadlineClientRpc")] internal static void ResetThings() { PlayerControllerPatch.PermDeadPlayers.Clear(); AmogusHandler.instance.HandleGameOver(); } [HarmonyPrefix] [HarmonyPatch("PassTimeToNextDay")] internal static void HandleNextDay() { foreach (BaseRole givenRole in AmogusHandler.instance.givenRoles) { givenRole.OnDayFinished(); } foreach (Affiliation uniqueAffiliation in AmogusHandler.instance.uniqueAffiliations) { uniqueAffiliation.OnDayFinished(); } } [HarmonyPostfix] [HarmonyPatch("SwitchCamera")] private static void CheckIfPlayerCanSpectateOthers(StartOfRound __instance, Camera newCamera) { if ((Object)(object)newCamera == (Object)(object)__instance.spectateCamera && !PlayerControllerPatch.PermDeadPlayers.Contains(GameNetworkManager.Instance.localPlayerController)) { StartOfRound.Instance.SetSpectateCameraToGameOverMode(true, (PlayerControllerB)null); } } } [HarmonyPatch(typeof(TimeOfDay))] internal static class TimeOfDayPatch { [HarmonyPrefix] [HarmonyPatch("SetNewProfitQuota")] internal static void WeekFinish() { foreach (BaseRole givenRole in AmogusHandler.instance.givenRoles) { givenRole.OnQuotaFufilled(); } foreach (Affiliation uniqueAffiliation in AmogusHandler.instance.uniqueAffiliations) { uniqueAffiliation.OnQuotaFufilled(); } } } } namespace Amogus.Behaviours { public class AmogusHandler : NetworkBehaviour { internal static AmogusHandler instance; internal List<BaseRole> givenRoles = new List<BaseRole>(); internal List<Affiliation> uniqueAffiliations = new List<Affiliation>(); internal static bool gameStarted; private void Awake() { if (((NetworkBehaviour)StartOfRound.Instance).IsHost) { if ((Object)(object)instance != (Object)null) { AmogusPlugin.logger.LogInfo((object)"instance of amogus handler already exists"); ((NetworkBehaviour)this).NetworkObject.Despawn(true); Object.Destroy((Object)(object)((Component)this).gameObject); } else { AmogusPlugin.logger.LogInfo((object)"Created AmogusHandler"); instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } } } public override void OnNetworkSpawn() { if ((Object)(object)instance == (Object)null) { instance = this; } } private void OnDisable() { if ((Object)(object)instance == (Object)(object)this) { instance = null; HandleGameOver(); } } internal void QuotaFinished() { foreach (BaseRole givenRole in givenRoles) { givenRole.OnQuotaFufilled(); } } [ClientRpc] internal void AffiliationWinsClientRpc(string winning) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Invalid comparison between Unknown and I4 //IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_00ba: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2873218868u, val, (RpcDelivery)0); bool flag = winning != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(winning, false); } ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2873218868u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost)) { AmogusUI.instance.GameOver(AmogusAPI.GetRoleInfoFromName(winning)); HandleGameOver(); } } private static List<RoleInfo> GetRandomizedRoles(List<RoleInfo> inputRoles, int numberOfPlayers) { inputRoles.Shuffle(); List<RoleInfo> list = new List<RoleInfo>(); foreach (Affiliation affiliation in inputRoles.Select((RoleInfo role) => role.Affiliation).Distinct().ToList()) { RoleInfo roleInfo = inputRoles.FirstOrDefault((RoleInfo role) => role.Affiliation == affiliation); if (roleInfo.Affiliation.Required && roleInfo != null) { list.Add(roleInfo); roleInfo.Players++; numberOfPlayers--; } } while (numberOfPlayers > 0) { RoleInfo roleInfo2 = inputRoles[Random.Range(0, inputRoles.Count)]; if (roleInfo2.Players < roleInfo2.MaxPlayers) { list.Add(roleInfo2); roleInfo2.Players++; numberOfPlayers--; } } return list; } internal void AssignRoles() { if (gameStarted) { return; } gameStarted = true; if (!((NetworkBehaviour)StartOfRound.Instance).IsHost) { return; } List<PlayerControllerB> connectedPlayers = StartOfRound.Instance.GetConnectedPlayers(); List<RoleInfo> randomizedRoles = GetRandomizedRoles(AmogusAPI.Roles.ToList(), connectedPlayers.Count); randomizedRoles.Shuffle(); connectedPlayers.Shuffle(); for (int i = 0; i < connectedPlayers.Count; i++) { PlayerControllerB val = connectedPlayers[i]; RoleInfo roleInfo = randomizedRoles[i]; if (!uniqueAffiliations.Contains(roleInfo.Affiliation)) { uniqueAffiliations.Add(roleInfo.Affiliation); } GameObject obj = Object.Instantiate<GameObject>(roleInfo.Prefab); obj.GetComponent<NetworkObject>().SpawnWithOwnership(val.actualClientId, false); obj.GetComponent<BaseRole>().player = val; } } internal void HandleGameOver() { foreach (BaseRole givenRole in givenRoles) { ((NetworkBehaviour)givenRole).NetworkObject.Despawn(true); } givenRoles.Clear(); uniqueAffiliations.Clear(); gameStarted = false; } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_AmogusHandler() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(2873218868u, new RpcReceiveHandler(__rpc_handler_2873218868)); } private static void __rpc_handler_2873218868(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_007b: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); string winning = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref winning, false); } target.__rpc_exec_stage = (__RpcExecStage)2; ((AmogusHandler)(object)target).AffiliationWinsClientRpc(winning); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "AmogusHandler"; } } public class AmogusUI : MonoBehaviour { [HideInInspector] internal static AmogusUI instance; [SerializeField] private GameObject RoleReveal; private void Awake() { instance = this; } internal void RevealRole(RoleInfo role) { ((MonoBehaviour)this).StartCoroutine(RevealRoleDelayed(role, 5)); } internal void GameOver(RoleInfo winning) { ((MonoBehaviour)this).StartCoroutine(GameOverDelayed(winning, 5)); } private IEnumerator RevealRoleDelayed(RoleInfo role, int delay) { yield return (object)new WaitForSeconds((float)delay); GameObject obj = Object.Instantiate<GameObject>(RoleReveal); obj.transform.SetParent(((Component)this).transform, false); ((Graphic)((Component)obj.transform.Find("Background")).GetComponent<Image>()).color = role.Affiliation.Color; ((TMP_Text)((Component)obj.transform.Find("Text")).GetComponent<TextMeshProUGUI>()).text = role.Name; obj.GetComponent<Animator>().SetTrigger("Play"); } private IEnumerator GameOverDelayed(RoleInfo winningRole, int delay) { StartOfRound.Instance.firingPlayersCutsceneRunning = true; if (Object.FindObjectOfType<Terminal>().terminalInUse) { Object.FindObjectOfType<Terminal>().QuitTerminal(); } StartOfRound.Instance.firedVoiceSFX = null; ((MonoBehaviour)this).StartCoroutine(StartOfRound.Instance.playersFiredGameOver(false)); yield return (object)new WaitForSeconds((float)delay); PlayerControllerPatch.PermDeadPlayers.Clear(); AmogusHandler.instance.HandleGameOver(); ((TMP_Text)HUDManager.Instance.EndOfRunStatsText).text = winningRole.Name + " win!"; StartOfRound.Instance.gameStats.daysSpent = 0; StartOfRound.Instance.gameStats.scrapValueCollected = 0; StartOfRound.Instance.gameStats.deaths = 0; StartOfRound.Instance.gameStats.allStepsTaken = 0; StartOfRound.Instance.SetDiscordStatusDetails(); } } public class BiteAttack : NetworkBehaviour { [SerializeField] private int Damage = 25; private bool localPlayerIsInside; [HideInInspector] public PlayerControllerB player { get; internal set; } public override void OnNetworkSpawn() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_003c: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) player = PlayerGetter.FromClientID(((NetworkBehaviour)this).OwnerClientId); ((Component)this).transform.position = player.cameraContainerTransform.position + player.cameraContainerTransform.forward - Vector3.up * 0.4f; ((Component)this).transform.eulerAngles = new Vector3(-90f + Random.Range(-10f, 10f), 90f, -90f + ((Component)player).transform.eulerAngles.y); } public void Bite() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (localPlayerIsInside && !player.GetRole().roleInfo.Affiliation.Friendly(GameNetworkManager.Instance.localPlayerController.GetRole().roleInfo.Affiliation)) { GameNetworkManager.Instance.localPlayerController.DamagePlayerFromOtherClientServerRpc(Damage, Vector3.zero, (int)player.playerClientId); } ((Component)this).GetComponent<AudioSource>().Play(); } public void Dispose() { if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer) { ((NetworkBehaviour)this).NetworkObject.Despawn(true); } } private void OnTriggerEnter(Collider other) { PlayerControllerB val = default(PlayerControllerB); if (((Object)((Component)other).gameObject).name == "PlayerPhysicsBox" && ((Component)((Component)other).transform.parent).TryGetComponent<PlayerControllerB>(ref val) && (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)val) { localPlayerIsInside = true; } } private void OnTriggerExit(Collider other) { PlayerControllerB val = default(PlayerControllerB); if (((Object)((Component)other).gameObject).name == "PlayerPhysicsBox" && ((Component)((Component)other).transform.parent).TryGetComponent<PlayerControllerB>(ref val) && (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)val) { localPlayerIsInside = false; } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } protected internal override string __getTypeName() { return "BiteAttack"; } } public class DestroyFunctionBehaviour : MonoBehaviour { public void DestroyMe() { Object.Destroy((Object)(object)((Component)this).gameObject); } } } namespace Amogus.API { public abstract class Affiliation { public string Name { get; private set; } public Color Color { get; private set; } internal bool Required { get; private set; } public Affiliation(string name, Color color) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) Name = name; Color = color; Required = true; } public virtual bool Friendly(Affiliation other) { return other == this; } public virtual void OnRoundStart() { } public virtual void OnRoundEnd() { } public virtual void OnQuotaFufilled() { } public virtual void OnDayFinished() { } protected void Win() { AmogusPlugin.logger.LogInfo((object)(Name + " wins!")); if (((NetworkBehaviour)StartOfRound.Instance).IsHost) { AmogusHandler.instance.AffiliationWinsClientRpc(Name); } } } public static class AmogusAPI { public static Affiliation Impostor = new ImpostorSide(); public static Affiliation Crewmate = new CrewmateSide(); private static readonly Dictionary<string, RoleInfo> roles = new Dictionary<string, RoleInfo>(); public static IReadOnlyCollection<RoleInfo> Roles => roles.Values; public static void RegisterRole(RoleInfo role) { roles[role.Name] = role; AmogusPlugin.logger.LogInfo((object)("Registered new role: " + role.Name)); } public static RoleInfo GetRoleInfoFromName(string name) { return roles[name]; } } public abstract class BaseRole : NetworkBehaviour { public string Name => roleInfo.Name; public RoleInfo roleInfo => GetRoleInfo(); public PlayerControllerB player { get; internal set; } public abstract RoleInfo GetRoleInfo(); public override void OnNetworkSpawn() { player = PlayerGetter.FromClientID(((NetworkBehaviour)this).OwnerClientId); AmogusHandler.instance.givenRoles.Add(this); OnRoundStart(); if ((Object)(object)player == (Object)(object)GameNetworkManager.Instance.localPlayerController) { AmogusUI.instance.RevealRole(roleInfo); HUDManager.Instance.AddChatMessage(Name + ":\n" + GetDescription(), ""); } } public override void OnNetworkDespawn() { OnRoundEnd(); } public virtual void OnRoundStart() { } public virtual void OnRoundEnd() { } public virtual void OnQuotaFufilled() { } public virtual void OnDayFinished() { } public virtual string GetDescription() { return Name + "hasn't provided a proper description!"; } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } protected internal override string __getTypeName() { return "BaseRole"; } } public class RoleInfo { public string Name { get; set; } public int MinPlayers { get; set; } = 1; public int MaxPlayers { get; set; } public int Players { get; internal set; } public Affiliation Affiliation { get; } internal GameObject Prefab { get; } public RoleInfo(Affiliation affiliation, GameObject prefab) { Affiliation = affiliation; Prefab = prefab; base..ctor(); } } } namespace Amogus.Affiliations { public class CrewmateSide : Affiliation { internal int quotasTillCrewmateVictory; public CrewmateSide() : base("Crewmate", new Color(0f, 0.9f, 1f)) { }//IL_0015: Unknown result type (might be due to invalid IL or missing references) public override void OnDayFinished() { foreach (PlayerControllerB connectedPlayer in StartOfRound.Instance.GetConnectedPlayers()) { if (!connectedPlayer.isPlayerDead && !connectedPlayer.GetRole().roleInfo.Affiliation.Friendly(this)) { return; } } Win(); } public override void OnRoundStart() { quotasTillCrewmateVictory = AmogusConfig.QUOTAS_TILL_CREWMATE_WIN; } public override void OnQuotaFufilled() { quotasTillCrewmateVictory--; HUDManager.Instance.AddChatMessage($"There are {quotasTillCrewmateVictory} more quota(s) untill Crewmate Victory!", ""); if (quotasTillCrewmateVictory <= 0) { Win(); } } } public class ImpostorSide : Affiliation { public ImpostorSide() : base("Impostor", new Color(1f, 0f, 0f)) { }//IL_0015: Unknown result type (might be due to invalid IL or missing references) public override void OnDayFinished() { foreach (PlayerControllerB connectedPlayer in StartOfRound.Instance.GetConnectedPlayers()) { if (!connectedPlayer.isPlayerDead && !connectedPlayer.GetRole().roleInfo.Affiliation.Friendly(this)) { return; } } Win(); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace Amogus.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }