using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.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
{
}
}