#define DEBUG
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 System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DoorBreach;
using DoorBreach.Functional;
using GameNetcodeStuff;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using MalfunctioningDoors.Dependencies;
using MalfunctioningDoors.Functional;
using MalfunctioningDoors.Malfunctions;
using MalfunctioningDoors.Malfunctions.Impl;
using MalfunctioningDoors.Patches;
using Microsoft.CodeAnalysis;
using TestAccount666.MalfunctioningDoors.NetcodePatcher;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TestAccount666.MalfunctioningDoors")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Who needs working doors anyway?")]
[assembly: AssemblyFileVersion("1.12.0.0")]
[assembly: AssemblyInformationalVersion("1.12.0+33af4244669c8a9d8e515335ef0d6e9bcea10fc8")]
[assembly: AssemblyProduct("MalfunctioningDoors")]
[assembly: AssemblyTitle("TestAccount666.MalfunctioningDoors")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.12.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 MalfunctioningDoors
{
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency("TestAccount666.DoorBreach", "1.1.0")]
[BepInPlugin("TestAccount666.MalfunctioningDoors", "MalfunctioningDoors", "1.12.0")]
public class MalfunctioningDoors : BaseUnityPlugin
{
private const int GHOST_HAND_SOUNDS_SIZE = 3;
internal static Object ghostHandPrefab = null;
internal static readonly AudioClip[] GhostHandSfxList = (AudioClip[])(object)new AudioClip[3];
public static MalfunctioningDoors Instance { get; private set; } = null;
internal static ManualLogSource Logger { get; private set; } = null;
internal static Harmony? Harmony { get; set; }
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
Instance = this;
if (DependencyChecker.IsLobbyCompatibilityInstalled())
{
Logger.LogInfo((object)"Found LobbyCompatibility Mod, initializing support :)");
LobbyCompatibilitySupport.Initialize();
}
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Debug.Assert(directoryName != null, "modDirectory != null");
AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(directoryName, "ghosthand"));
ghostHandPrefab = val.LoadAsset("ghosthand");
Patch();
DoorLockPatch.InitializeConfig(((BaseUnityPlugin)this).Config);
MalfunctionalDoor.InitializeConfig(((BaseUnityPlugin)this).Config);
FetchMalfunctions();
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
Type[] array = types;
foreach (Type type in array)
{
try
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo[] array2 = methods;
foreach (MethodInfo methodInfo in array2)
{
object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
if (customAttributes.Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
catch (FileNotFoundException)
{
}
}
((MonoBehaviour)this).StartCoroutine(LoadAudioClips());
Logger.LogInfo((object)"TestAccount666.MalfunctioningDoors v1.12.0 has loaded!");
}
internal static void Patch()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
if (Harmony == null)
{
Harmony = new Harmony("TestAccount666.MalfunctioningDoors");
}
Logger.LogDebug((object)"Patching...");
Harmony.PatchAll(typeof(DoorLockPatch));
Harmony.PatchAll(typeof(RoundManagerPatch));
Logger.LogDebug((object)"Finished patching!");
}
internal static void Unpatch()
{
Logger.LogDebug((object)"Unpatching...");
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
Logger.LogDebug((object)"Finished unpatching!");
}
private static void FetchMalfunctions()
{
MalfunctionGenerator.MalfunctionDictionary.Clear();
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
IEnumerable<Type> enumerable = types.Where(Predicate);
foreach (Type item in enumerable)
{
MalfunctionAttribute malfunctionAttribute = (MalfunctionAttribute)item.GetCustomAttribute(typeof(MalfunctionAttribute), inherit: false);
int value = malfunctionAttribute.weight;
MethodInfo method = item.GetMethod("OverrideWeight", BindingFlags.Static | BindingFlags.Public);
if ((object)method != null)
{
value = (int)method.Invoke(null, new object[1] { ((BaseUnityPlugin)Instance).Config });
}
item.GetMethod("InitializeConfig", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { ((BaseUnityPlugin)Instance).Config });
MalfunctionGenerator.MalfunctionDictionary.Add(item, value);
}
}
private static bool Predicate(ICustomAttributeProvider type)
{
return type.GetCustomAttributes(typeof(MalfunctionAttribute), inherit: false).Length != 0;
}
private static IEnumerator LoadAudioClips()
{
string assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Logger.LogInfo((object)"Loading Sounds...");
Debug.Assert(assemblyDirectory != null, "assemblyDirectory != null");
string audioPath2 = Path.Combine(assemblyDirectory, "sounds");
audioPath2 = (Directory.Exists(audioPath2) ? audioPath2 : Path.Combine(assemblyDirectory));
LoadGhostHandAudioClips(audioPath2);
yield break;
}
private static void LoadGhostHandAudioClips(string audioPath)
{
Logger.LogInfo((object)"Loading Ghost Hand Sounds...");
string text = Path.Combine(audioPath, "GhostHandSounds");
text = (Directory.Exists(text) ? text : Path.Combine(audioPath));
for (int i = 1; i <= 3; i++)
{
int num = i - 1;
AudioClip val = LoadAudioClipFromFile(new Uri(Path.Combine(text, $"GhostHand{i}.wav")), $"GhostHand{i}");
if (val == null)
{
Logger.LogInfo((object)$"Failed to load clip 'GhostHand{i}'!");
continue;
}
GhostHandSfxList[num] = val;
Logger.LogInfo((object)("Loaded clip '" + ((Object)val).name + "'!"));
}
}
private static AudioClip? LoadAudioClipFromFile(Uri filePath, string name)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Invalid comparison between Unknown and I4
UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(filePath, (AudioType)20);
try
{
UnityWebRequestAsyncOperation val = audioClip.SendWebRequest();
while (!((AsyncOperation)val).isDone)
{
Thread.Sleep(100);
}
if ((int)audioClip.result != 1)
{
Logger.LogError((object)("Failed to load AudioClip: " + audioClip.error));
return null;
}
AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
((Object)content).name = name;
return content;
}
finally
{
((IDisposable)audioClip)?.Dispose();
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "TestAccount666.MalfunctioningDoors";
public const string PLUGIN_NAME = "MalfunctioningDoors";
public const string PLUGIN_VERSION = "1.12.0";
}
}
namespace MalfunctioningDoors.Patches
{
[HarmonyPatch(typeof(DoorLock))]
public static class DoorLockPatch
{
public static Random syncedRandom = new Random();
private static int _malfunctioningDoorChance = 30;
public static void InitializeConfig(ConfigFile configFile)
{
_malfunctioningDoorChance = configFile.Bind<int>("1. General", "1. Malfunctional Door Chance", 30, "Defines the chance that a door can be malfunctional").Value;
}
[HarmonyPatch("Awake")]
[HarmonyPostfix]
[HarmonyAfter(new string[] { "TestAccount666.DoorBreach" })]
public static void AfterAwake(DoorLock __instance)
{
Type malfunctionalDoorType = typeof(DormantMalfunction);
if (syncedRandom.Next(0, 100) < _malfunctioningDoorChance)
{
malfunctionalDoorType = MalfunctionGenerator.GenerateMalfunctionalDoor(syncedRandom);
}
AddMalfunction(__instance, malfunctionalDoorType);
}
[HarmonyPatch("UnlockDoorSyncWithServer")]
[HarmonyPostfix]
public static void AfterUnlockDoorSyncWithServer(DoorLock __instance)
{
MalfunctionalDoor component = ((Component)__instance).gameObject.GetComponent<MalfunctionalDoor>();
if (component != null && component.ShouldExecute())
{
component.UseKey();
}
}
internal static void AddMalfunction(DoorLock? doorLock, Type malfunctionalDoorType)
{
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Expected O, but got Unknown
if (doorLock == null)
{
return;
}
if (!malfunctionalDoorType.IsSubclassOf(typeof(MalfunctionalDoor)))
{
throw new ArgumentException("Type '" + malfunctionalDoorType.FullName + "'");
}
MalfunctionalDoor malfunctionalDoor = (MalfunctionalDoor)(object)((Component)doorLock).gameObject.AddComponent(malfunctionalDoorType);
((UnityEvent<PlayerControllerB>)(object)doorLock.doorTrigger.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate(PlayerControllerB playerControllerB)
{
if (playerControllerB != null && malfunctionalDoor.ShouldExecute())
{
malfunctionalDoor.UseInteract(playerControllerB);
}
});
InteractTrigger val = ((Component)doorLock).gameObject.AddComponent<InteractTrigger>();
val.touchTrigger = true;
val.interactable = true;
val.onInteract = new InteractEvent();
((UnityEvent<PlayerControllerB>)(object)val.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate(PlayerControllerB playerControllerB)
{
if (playerControllerB != null && malfunctionalDoor.ShouldExecute())
{
malfunctionalDoor.TouchInteract(playerControllerB);
}
});
}
}
[HarmonyPatch(typeof(RoundManager))]
public static class RoundManagerPatch
{
[HarmonyPatch("GenerateNewLevelClientRpc")]
[HarmonyPrefix]
public static void BeforeGenerateNewLevelClientRpc(int randomSeed)
{
DoorLockPatch.syncedRandom = new Random(randomSeed);
}
}
}
namespace MalfunctioningDoors.Malfunctions
{
public abstract class MalfunctionalDoor : MonoBehaviour
{
private static int _changeMalfunctionChance = 30;
protected DoorLock? doorLock;
private bool _destroy;
private void Awake()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
EventHandler.doorBreach = (DoorBreachEvent)Delegate.Combine((Delegate?)(object)EventHandler.doorBreach, (Delegate?)new DoorBreachEvent(DestroyMalfunctions));
}
private void DestroyMalfunctions(DoorBreachEventArguments doorBreachEventArguments)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Invalid comparison between Unknown and I4
EventHandler.doorBreach = (DoorBreachEvent)Delegate.Remove((Delegate?)(object)EventHandler.doorBreach, (Delegate?)new DoorBreachEvent(DestroyMalfunctions));
if ((int)doorBreachEventArguments.doorBreachMode == 0)
{
return;
}
DoorLock? obj = doorLock;
MalfunctionalDoor[] array = ((obj != null) ? ((Component)obj).GetComponents<MalfunctionalDoor>() : null);
if (array == null)
{
array = Array.Empty<MalfunctionalDoor>();
}
MalfunctionalDoor[] array2 = array;
foreach (MalfunctionalDoor malfunctionalDoor in array2)
{
if (malfunctionalDoor != null)
{
Object.Destroy((Object)(object)malfunctionalDoor);
}
}
}
private void Start()
{
((MonoBehaviour)this).StartCoroutine(RollChangeMalfunctionChance());
}
private void OnDestroy()
{
_destroy = true;
}
protected bool IsDestroyed()
{
return _destroy;
}
public abstract void TouchInteract(PlayerControllerB playerControllerB);
public abstract void UseInteract(PlayerControllerB playerControllerB);
public static void InitializeConfig(ConfigFile configFile)
{
_changeMalfunctionChance = configFile.Bind<int>("1. General", "2. Malfunction Change Chance", 30, "Defines the chance, if a malfunction is changed").Value;
}
public abstract void UseKey();
public abstract bool ShouldExecute();
private IEnumerator RollChangeMalfunctionChance()
{
while (true)
{
yield return (object)new WaitForSeconds(60f);
yield return (object)new WaitForEndOfFrame();
if (_destroy)
{
yield break;
}
if (doorLock != null)
{
int chance = DoorLockPatch.syncedRandom.Next(0, 100);
if (chance <= _changeMalfunctionChance)
{
break;
}
}
}
DoorLockPatch.AddMalfunction(malfunctionalDoorType: MalfunctionGenerator.GenerateMalfunctionalDoor(DoorLockPatch.syncedRandom), doorLock: doorLock);
Object.Destroy((Object)(object)this);
}
}
[AttributeUsage(AttributeTargets.Class)]
public class MalfunctionAttribute : Attribute
{
internal readonly int weight;
public MalfunctionAttribute(int weight = 1)
{
this.weight = weight;
base..ctor();
}
}
public class MalfunctionDictionary : Dictionary<Type, int>
{
public new void Add(Type key, int value)
{
if (!key.IsSubclassOf(typeof(MalfunctionalDoor)))
{
throw new InvalidOperationException("MalfunctionDictionary can only contain sub-types of " + typeof(MalfunctionalDoor).FullName + "!");
}
base.Add(key, value);
}
}
public static class MalfunctionGenerator
{
public static readonly MalfunctionDictionary MalfunctionDictionary = new MalfunctionDictionary();
public static Type GenerateMalfunctionalDoor(Random random)
{
int num = random.Next(1000, 9999);
HashSet<KeyValuePair<Type, int>> hashSet = FisherYatesShuffle(MalfunctionDictionary, random).ToHashSet();
while (num > 0)
{
foreach (KeyValuePair<Type, int> item in hashSet)
{
num -= item.Value;
if (num > 0)
{
continue;
}
return item.Key;
}
}
MalfunctioningDoors.Logger.LogError((object)"Couldn't find any malfunctional door type, falling back to CloseMalfunction as default!");
return typeof(CloseMalfunction);
}
private static IEnumerable<KeyValuePair<TKey, TValue>> FisherYatesShuffle<TKey, TValue>(Dictionary<TKey, TValue> dictionary, Random random)
{
List<KeyValuePair<TKey, TValue>> list = dictionary.ToList();
int num = list.Count;
while (num > 1)
{
num--;
int num2 = random.Next(num + 1);
List<KeyValuePair<TKey, TValue>> list2 = list;
int index = num2;
int index2 = num;
KeyValuePair<TKey, TValue> value = list[num];
KeyValuePair<TKey, TValue> value2 = list[num2];
list2[index] = value;
list[index2] = value2;
}
return list;
}
}
}
namespace MalfunctioningDoors.Malfunctions.Impl
{
[Malfunction(100)]
public class CloseMalfunction : MalfunctionalDoor
{
private static int _lockChance = 30;
private static int _lockWhenCloseChance = 80;
private static int _openCloseAfterTwoSecondsChance = 40;
private static int _malfunctionChance = 20;
private Random _syncedRandom = null;
private void Start()
{
doorLock = ((Component)this).GetComponent<DoorLock>();
_syncedRandom = DoorLockPatch.syncedRandom;
}
public static int OverrideWeight(ConfigFile configFile)
{
return configFile.Bind<int>("2. Close Malfunction", "1. Malfunction Weight", 100, "Defines the weight of a malfunction. The higher, the more likely it is to appear").Value;
}
public new static void InitializeConfig(ConfigFile configFile)
{
_malfunctionChance = configFile.Bind<int>("2. Close Malfunction", "2. Malfunction Chance", 20, "Defines the chance, if a malfunction is executed").Value;
_lockChance = configFile.Bind<int>("2. Close Malfunction", "3. Lock Chance", 30, "Defines the chance, if a door will be locked").Value;
_lockWhenCloseChance = configFile.Bind<int>("2. Close Malfunction", "4. Lock When Close Chance", 80, "Defines the chance, if a door will be locked after closing (The 'Lock Chance' will be rolled first)").Value;
_openCloseAfterTwoSecondsChance = configFile.Bind<int>("2. Close Malfunction", "5. Open Close After Two Seconds Chance", 40, "Defines the chance, if a door will open/close after two seconds after being opened/closed ('Malfunction Chance' will be rolled first)").Value;
}
public override void TouchInteract(PlayerControllerB playerControllerB)
{
if (doorLock == null || !doorLock.isDoorOpened || ((Component)doorLock).GetComponent<WaitingForDoorToBeClosed>() != null)
{
return;
}
int num = _syncedRandom.Next(0, 100);
if (num >= _lockChance)
{
return;
}
int num2 = _syncedRandom.Next(0, 100);
if (num2 < _lockWhenCloseChance)
{
WaitingForDoorToBeClosed waitingForDoorToBeClosed = ((Component)doorLock).gameObject.AddComponent<WaitingForDoorToBeClosed>();
((MonoBehaviour)waitingForDoorToBeClosed).StartCoroutine(WaitingForDoorToBeClosed.WaitForDoorToBeClosed(doorLock));
return;
}
MalfunctioningDoors.Logger.LogInfo((object)"Locking door <:)");
doorLock.LockDoor(30f);
DoorLocker component = ((Component)doorLock).gameObject.GetComponent<DoorLocker>();
if (component == null)
{
MalfunctioningDoors.Logger.LogFatal((object)"No DoorLocker found?!");
}
else
{
component.LockDoorServerRpc();
}
}
public override void UseInteract(PlayerControllerB playerControllerB)
{
PlayerControllerB playerControllerB2 = playerControllerB;
if (doorLock == null)
{
return;
}
int num = _syncedRandom.Next(0, 100);
DoorLocker doorLocker = ((Component)doorLock).gameObject.GetComponent<DoorLocker>();
if (doorLocker == null)
{
MalfunctioningDoors.Logger.LogFatal((object)"No DoorLocker found?!");
return;
}
bool open = !doorLock.isDoorOpened;
if (num >= _openCloseAfterTwoSecondsChance)
{
doorLocker.SetDoorOpenServerRpc((int)playerControllerB2.playerClientId, open);
return;
}
((MonoBehaviour)this).StartCoroutine(DelayedTask(2f, delegate
{
if (doorLock.isDoorOpened)
{
doorLocker.SetDoorOpenServerRpc((int)playerControllerB2.playerClientId, open);
}
}));
}
public override void UseKey()
{
}
public override bool ShouldExecute()
{
return _syncedRandom.Next(0, 100) < _malfunctionChance && !IsDestroyed();
}
private static IEnumerator DelayedTask(float delay, Action action)
{
yield return (object)new WaitForSeconds(delay);
yield return (object)new WaitForEndOfFrame();
action();
}
}
internal class WaitingForDoorToBeClosed : MonoBehaviour
{
private static bool _done;
private void Update()
{
if (_done)
{
_done = false;
Object.Destroy((Object)(object)this);
}
}
internal static IEnumerator WaitForDoorToBeClosed(DoorLock doorLock)
{
MalfunctioningDoors.Logger.LogInfo((object)"Waiting for door to be closed :)");
while (doorLock.isDoorOpened)
{
yield return (object)new WaitForSeconds(1f);
}
yield return (object)new WaitForEndOfFrame();
MalfunctioningDoors.Logger.LogInfo((object)"Locking door <:)");
doorLock.LockDoor(30f);
DoorLocker doorLocker = ((Component)doorLock).gameObject.GetComponent<DoorLocker>();
if (doorLocker == null)
{
MalfunctioningDoors.Logger.LogFatal((object)"No DoorLocker found?!");
yield break;
}
doorLocker.LockDoorServerRpc();
_done = true;
}
}
[Malfunction(100)]
public class DormantMalfunction : MalfunctionalDoor
{
public override void TouchInteract(PlayerControllerB playerControllerB)
{
}
public override void UseInteract(PlayerControllerB playerControllerB)
{
}
public override void UseKey()
{
}
public override bool ShouldExecute()
{
return false;
}
}
[Malfunction(65)]
public class EatKeyMalfunction : MalfunctionalDoor
{
private static int _malfunctionChance = 65;
private Random _syncedRandom = null;
private void Start()
{
doorLock = ((Component)this).GetComponent<DoorLock>();
_syncedRandom = DoorLockPatch.syncedRandom;
((MonoBehaviour)this).StartCoroutine(LockDoorRoutine());
}
public static int OverrideWeight(ConfigFile configFile)
{
return configFile.Bind<int>("3. Eat Key Malfunction", "1. Malfunction Weight", 65, "Defines the weight of a malfunction. The higher, the more likely it is to appear").Value;
}
public new static void InitializeConfig(ConfigFile configFile)
{
_malfunctionChance = configFile.Bind<int>("3. Eat Key Malfunction", "2. Malfunction Chance", 65, "Defines the chance, if a malfunction is executed").Value;
}
public override void TouchInteract(PlayerControllerB playerControllerB)
{
}
public override void UseInteract(PlayerControllerB playerControllerB)
{
}
public override void UseKey()
{
((MonoBehaviour)this).StartCoroutine(LockDoorRoutine());
}
private IEnumerator LockDoorRoutine()
{
yield return (object)new WaitForEndOfFrame();
yield return (object)new WaitUntil((Func<bool>)(() => doorLock != null));
if (doorLock != null)
{
doorLock.LockDoor(30f);
DoorLocker doorLocker = ((Component)doorLock).gameObject.GetComponent<DoorLocker>();
if (doorLocker == null)
{
MalfunctioningDoors.Logger.LogFatal((object)"No DoorLocker found?!");
}
else
{
doorLocker.LockDoorServerRpc();
}
}
}
public override bool ShouldExecute()
{
return _syncedRandom.Next(0, 100) < _malfunctionChance && !IsDestroyed();
}
}
[Malfunction(75)]
public class GhostHandMalfunction : MalfunctionalDoor
{
private static int _malfunctionChance = 86;
private Random _syncedRandom = null;
private void Start()
{
doorLock = ((Component)this).GetComponent<DoorLock>();
_syncedRandom = DoorLockPatch.syncedRandom;
}
public static int OverrideWeight(ConfigFile configFile)
{
return configFile.Bind<int>("4. Ghost Hand Malfunction", "1. Malfunction Weight", 75, "Defines the weight of a malfunction. The higher, the more likely it is to appear").Value;
}
public new static void InitializeConfig(ConfigFile configFile)
{
_malfunctionChance = configFile.Bind<int>("4. Ghost Hand Malfunction", "2. Malfunction Chance", 86, "Defines the chance, if a malfunction is executed").Value;
}
public override void TouchInteract(PlayerControllerB playerControllerB)
{
//IL_0079: 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)
if (doorLock != null && !doorLock.isDoorOpened)
{
DoorLocker component = ((Component)doorLock).gameObject.GetComponent<DoorLocker>();
if (component == null)
{
MalfunctioningDoors.Logger.LogFatal((object)"No DoorLocker found?!");
return;
}
component.SetDoorOpenServerRpc((int)playerControllerB.playerClientId, true);
PlayGhostHandSound();
CreateGhostHand((Component)(object)playerControllerB);
playerControllerB.DamagePlayer(10, true, true, (CauseOfDeath)1, 1, false, playerControllerB.velocityLastFrame);
Landmine.SpawnExplosion(((Component)doorLock).transform.position, false, 0f, 0f, 50, 15f, (GameObject)null, false);
}
}
private static void CreateGhostHand(Component playerControllerB)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: 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_0031: 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_008f: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
Vector3 position = playerControllerB.transform.position;
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(position.x, position.y + 1f, position.z);
Object obj = Object.Instantiate(MalfunctioningDoors.ghostHandPrefab, val, new Quaternion(0f, 0f, 0f, 0f));
GameObject val2 = (GameObject)(object)((obj is GameObject) ? obj : null);
if (val2 == null)
{
MalfunctioningDoors.Logger.LogFatal((object)"Something went wrong while trying to instantiate the GhostHands!");
return;
}
val2.transform.LookAt(playerControllerB.transform);
Transform transform = val2.transform;
transform.rotation *= Quaternion.Euler(0f, 90f, 0f);
val2.transform.position = val;
Transform transform2 = val2.transform;
transform2.localScale *= 1.8f;
GhostHandRotator ghostHandRotator = val2.AddComponent<GhostHandRotator>();
ghostHandRotator.playerControllerTransform = playerControllerB.transform;
}
public override void UseInteract(PlayerControllerB playerControllerB)
{
}
public override void UseKey()
{
}
public override bool ShouldExecute()
{
return _syncedRandom.Next(0, 100) <= _malfunctionChance && !IsDestroyed();
}
private void PlayGhostHandSound()
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
int num = _syncedRandom.Next(0, MalfunctioningDoors.GhostHandSfxList.Length);
AudioClip val = MalfunctioningDoors.GhostHandSfxList[num];
MalfunctioningDoors.Logger.LogDebug((object)$"Playing clip '{((Object)val).name}' ({num})");
GameObject val2 = new GameObject("TemporaryGhostHandAudio");
AudioSource val3 = val2.AddComponent<AudioSource>();
val3.clip = val;
val3.volume = 2f;
val3.Play();
Object.Destroy((Object)(object)val2, val.length);
}
}
[Malfunction(80)]
public class NoYouMalfunction : MalfunctionalDoor
{
private static int _malfunctionChance = 35;
private Random _syncedRandom = null;
private void Start()
{
doorLock = ((Component)this).GetComponent<DoorLock>();
_syncedRandom = DoorLockPatch.syncedRandom;
}
public static int OverrideWeight(ConfigFile configFile)
{
return configFile.Bind<int>("6. No You", "1. Malfunction Weight", 80, "Defines the weight of a malfunction. The higher, the more likely it is to appear").Value;
}
public new static void InitializeConfig(ConfigFile configFile)
{
_malfunctionChance = configFile.Bind<int>("6. No You", "2. Malfunction Chance", 35, "Defines the chance, if a malfunction is executed").Value;
}
public override void TouchInteract(PlayerControllerB playerControllerB)
{
}
public override void UseInteract(PlayerControllerB playerControllerB)
{
if (doorLock != null)
{
int num = 1;
if (_syncedRandom.Next(0, 2) > 0)
{
num = -num;
}
((MonoBehaviour)this).StartCoroutine(StartRotation(playerControllerB, num));
playerControllerB.JumpToFearLevel(1f, true);
DoorLocker component = ((Component)doorLock).gameObject.GetComponent<DoorLocker>();
if (component == null)
{
MalfunctioningDoors.Logger.LogFatal((object)"No DoorLocker found?!");
}
else
{
component.SetDoorOpenServerRpc((int)playerControllerB.playerClientId, !doorLock.isDoorOpened);
}
}
}
private static IEnumerator StartRotation(PlayerControllerB playerControllerB, float direction)
{
float terminate = 1f;
Quaternion startRotation = ((Component)playerControllerB).transform.rotation;
float targetRotationY = ((Quaternion)(ref startRotation)).eulerAngles.y + 90f * direction;
float currentAngle2 = ((Quaternion)(ref startRotation)).eulerAngles.y;
float rotationSpeed = 0f;
while (Quaternion.Angle(startRotation, ((Component)playerControllerB).transform.rotation) < 90f)
{
terminate -= Time.deltaTime;
if (terminate <= 0f)
{
break;
}
float num = rotationSpeed;
if (!(num < 10f))
{
if (num > 5f)
{
rotationSpeed -= Time.deltaTime * 5f;
}
}
else
{
rotationSpeed += Time.deltaTime * 10f;
}
currentAngle2 += rotationSpeed * Time.deltaTime * 240f * direction;
currentAngle2 = ((direction > 0f) ? Mathf.Clamp(currentAngle2, ((Quaternion)(ref startRotation)).eulerAngles.y, targetRotationY) : Mathf.Clamp(currentAngle2, targetRotationY, ((Quaternion)(ref startRotation)).eulerAngles.y));
Vector3 position = ((Component)playerControllerB).transform.position;
Quaternion val = Quaternion.Euler(0f, currentAngle2, 0f);
playerControllerB.TeleportPlayer(position, true, ((Quaternion)(ref val)).eulerAngles.y, false, true);
yield return (object)new WaitForEndOfFrame();
}
}
public override void UseKey()
{
}
public override bool ShouldExecute()
{
return _syncedRandom.Next(0, 100) <= _malfunctionChance && !IsDestroyed();
}
}
[Malfunction(150)]
public class RandomOpenCloseMalfunction : MalfunctionalDoor
{
private static int _malfunctionChance = 40;
private Random _syncedRandom = null;
private bool _waiting;
private void Start()
{
doorLock = ((Component)this).GetComponent<DoorLock>();
_syncedRandom = DoorLockPatch.syncedRandom;
}
private void Update()
{
if (_waiting)
{
return;
}
((MonoBehaviour)this).StartCoroutine(StartWaiting());
if (doorLock == null)
{
return;
}
int num = _syncedRandom.Next(0, 100);
if (num < _malfunctionChance)
{
DoorLocker component = ((Component)doorLock).gameObject.GetComponent<DoorLocker>();
if (component == null)
{
MalfunctioningDoors.Logger.LogFatal((object)"No DoorLocker found?!");
return;
}
bool flag = !doorLock.isDoorOpened;
component.SetDoorOpenServerRpc(ActionSource.ToInt((Source)(-665)), flag);
}
}
public static int OverrideWeight(ConfigFile configFile)
{
return configFile.Bind<int>("5. Random Open Close Malfunction", "1. Malfunction Weight", 150, "Defines the weight of a malfunction. The higher, the more likely it is to appear").Value;
}
public new static void InitializeConfig(ConfigFile configFile)
{
_malfunctionChance = configFile.Bind<int>("5. Random Open Close Malfunction", "2. Malfunction Chance", 40, "Defines the chance, if a malfunction is executed").Value;
}
public override void TouchInteract(PlayerControllerB playerControllerB)
{
}
public override void UseInteract(PlayerControllerB playerControllerB)
{
}
public override void UseKey()
{
}
public override bool ShouldExecute()
{
return false;
}
private IEnumerator StartWaiting()
{
_waiting = true;
yield return (object)new WaitForSeconds((float)_syncedRandom.Next(5, 30));
_waiting = false;
}
}
}
namespace MalfunctioningDoors.Functional
{
public class GhostHandRotator : MonoBehaviour
{
internal Transform? playerControllerTransform;
private void Start()
{
((MonoBehaviour)this).StartCoroutine(DestroyLater(3f));
}
private void Update()
{
//IL_002e: 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)
if (Object.op_Implicit((Object)(object)playerControllerTransform))
{
((Component)this).transform.LookAt(playerControllerTransform);
Transform transform = ((Component)this).transform;
transform.rotation *= Quaternion.Euler(0f, 90f, 0f);
}
}
private IEnumerator DestroyLater(float waitForSeconds)
{
yield return (object)new WaitForSeconds(waitForSeconds);
yield return (object)new WaitForEndOfFrame();
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
}
namespace MalfunctioningDoors.Dependencies
{
internal static class DependencyChecker
{
internal static bool IsLobbyCompatibilityInstalled()
{
return Chainloader.PluginInfos.Values.Any((PluginInfo metadata) => metadata.Metadata.GUID.Contains("LobbyCompatibility"));
}
}
internal static class LobbyCompatibilitySupport
{
internal static void Initialize()
{
PluginHelper.RegisterPlugin("TestAccount666.MalfunctioningDoors", new Version("1.12.0"), (CompatibilityLevel)2, (VersionStrictness)2);
}
}
}
namespace TestAccount666.MalfunctioningDoors.NetcodePatcher
{
[AttributeUsage(AttributeTargets.Module)]
internal class NetcodePatchedAssemblyAttribute : Attribute
{
}
}