using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using OpenTheNoor.Config;
using OpenTheNoor.Managers;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OpenTheNoor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OpenTheNoor")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b58bef91-7e8e-4613-a41d-797b02584ab7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OpenTheNoor.Patches
{
[HarmonyPatch(typeof(StartOfRound))]
internal class StartOfRoundPatch
{
[HarmonyPostfix]
[HarmonyPatch("Start")]
private static void spawnNetManager(StartOfRound __instance)
{
if (((NetworkBehaviour)__instance).IsHost)
{
Object.Instantiate<GameObject>(OpenTheNoorBase.Instance.netManagerPrefab).GetComponent<NetworkObject>().Spawn(false);
}
}
}
}
namespace OpenTheNoor.Managers
{
public class NetworkManagerOpenTheNoor : NetworkBehaviour
{
public static NetworkManagerOpenTheNoor Instance;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
}
[ServerRpc(RequireOwnership = false)]
public void MakeOpenTheNoorNoiseServerRpc(NetworkBehaviourReference __door)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
MakeOpenTheNoorNoiseClientRpc(__door);
}
[ClientRpc]
public void MakeOpenTheNoorNoiseClientRpc(NetworkBehaviourReference __door)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
AudioSource doorLockSFX = ((DoorLock)NetworkBehaviourReference.op_Implicit(__door)).doorLockSFX;
if ((Object)(object)doorLockSFX != (Object)null)
{
PlayerControllerBPatch.playOpenTheNoorNoise(doorLockSFX, OpenTheNoorBase.SoundFX.ToArray());
}
}
}
}
namespace OpenTheNoor.Config
{
[Serializable]
public class Config : SyncedInstance<Config>
{
private const float VOLUME_DEFAULT = 0.5f;
private const bool PLAY_FOR_ALL_PLAYERS_DEFAULT = true;
private const float PLAY_SOUND_CHANCE_DEFAULT = 100f;
public float VOLUME;
public bool PLAY_FOR_ALL_PLAYERS;
public float PLAY_SOUND_CHANCE;
public Config(ConfigFile cfg)
{
InitInstance(this);
VOLUME = cfg.Bind<float>("ClientSide", "volume", 0.5f, "The volume that the sound will play at for you.").Value;
PLAY_FOR_ALL_PLAYERS = cfg.Bind<bool>("ServerSide", "playForAllPlayers", true, "Play the sound for other players.\nThis will allow all players to hear the sound when another player attempts to open a door.").Value;
PLAY_SOUND_CHANCE = cfg.Bind<float>("ServerSide", "playSoundChance", 100f, "The percentage chance that the sound will play.").Value;
}
public static void RequestSync()
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (!SyncedInstance<Config>.IsClient)
{
return;
}
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(SyncedInstance<Config>.IntSize, (Allocator)2, -1);
try
{
SyncedInstance<Config>.MessageManager.SendNamedMessage("Kolton12O.OpenTheNoor_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
public static void OnRequestSync(ulong clientId, FastBufferReader _)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
if (!SyncedInstance<Config>.IsHost)
{
return;
}
OpenTheNoorBase.Instance.mls.LogInfo((object)$"Config sync request received from client: {clientId}");
byte[] array = SyncedInstance<Config>.SerializeToBytes(SyncedInstance<Config>.Instance);
int num = array.Length;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<Config>.IntSize, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
SyncedInstance<Config>.MessageManager.SendNamedMessage("Kolton12O.OpenTheNoor_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
}
catch (Exception arg)
{
OpenTheNoorBase.Instance.mls.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
public static void OnReceiveSync(ulong _, FastBufferReader reader)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<Config>.IntSize))
{
OpenTheNoorBase.Instance.mls.LogError((object)"Config sync error: Could not begin reading buffer.");
return;
}
int num = default(int);
((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
{
OpenTheNoorBase.Instance.mls.LogError((object)"Config sync error: Host could not sync.");
return;
}
byte[] data = new byte[num];
((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
SyncedInstance<Config>.SyncInstance(data);
OpenTheNoorBase.Instance.mls.LogInfo((object)"Successfully synced config with host.");
}
}
[Serializable]
public class SyncedInstance<T>
{
[NonSerialized]
protected static int IntSize = 4;
internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;
internal static bool IsClient => NetworkManager.Singleton.IsClient;
internal static bool IsHost => NetworkManager.Singleton.IsHost;
public static T Default { get; private set; }
public static T Instance { get; private set; }
public static bool Synced { get; internal set; }
protected void InitInstance(T instance)
{
Default = instance;
Instance = instance;
IntSize = 4;
}
internal static void SyncInstance(byte[] data)
{
Instance = DeserializeFromBytes(data);
Synced = true;
}
internal static void RevertSync()
{
Instance = Default;
Synced = false;
}
public static byte[] SerializeToBytes(T val)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
using MemoryStream memoryStream = new MemoryStream();
try
{
binaryFormatter.Serialize(memoryStream, val);
return memoryStream.ToArray();
}
catch (Exception arg)
{
OpenTheNoorBase.Instance.mls.LogError((object)$"Error serializing instance: {arg}");
return null;
}
}
public static T DeserializeFromBytes(byte[] data)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
using MemoryStream serializationStream = new MemoryStream(data);
try
{
return (T)binaryFormatter.Deserialize(serializationStream);
}
catch (Exception arg)
{
OpenTheNoorBase.Instance.mls.LogError((object)$"Error deserializing instance: {arg}");
return default(T);
}
}
}
[HarmonyPatch(typeof(GameNetworkManager))]
internal class GameNetworkManagerPatch
{
[HarmonyPostfix]
[HarmonyPatch("Start")]
private static void AddToPrefabs(ref GameNetworkManager __instance)
{
((Component)__instance).GetComponent<NetworkManager>().AddNetworkPrefab(OpenTheNoorBase.Instance.netManagerPrefab);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
public static void PlayerLeave()
{
SyncedInstance<Config>.RevertSync();
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class PlayerControllerBPatch
{
[HarmonyPatch(typeof(PlayerControllerB), "Interact_performed")]
[HarmonyPrefix]
private static void onInteract(PlayerControllerB __instance)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)__instance.hoveringOverTrigger != (Object)null))
{
return;
}
DoorLock componentInParent = ((Component)__instance.hoveringOverTrigger).GetComponentInParent<DoorLock>();
if (!((Object)(object)componentInParent != (Object)null) || !componentInParent.isLocked)
{
return;
}
float num = Math.Max(0f, Math.Min(100f, SyncedInstance<Config>.Instance.PLAY_SOUND_CHANCE));
if (!(new Random().NextDouble() * 100.0 <= (double)num))
{
return;
}
if (SyncedInstance<Config>.Instance.PLAY_FOR_ALL_PLAYERS)
{
NetworkManagerOpenTheNoor.Instance.MakeOpenTheNoorNoiseServerRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)componentInParent));
return;
}
AudioSource doorLockSFX = componentInParent.doorLockSFX;
if ((Object)(object)doorLockSFX != (Object)null)
{
playOpenTheNoorNoise(doorLockSFX, OpenTheNoorBase.SoundFX.ToArray());
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
public static void InitializeLocalPlayer()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
if (SyncedInstance<Config>.IsHost)
{
SyncedInstance<Config>.MessageManager.RegisterNamedMessageHandler("Kolton12O.OpenTheNoor_OnRequestConfigSync", new HandleNamedMessageDelegate(Config.OnRequestSync));
SyncedInstance<Config>.Synced = true;
}
else
{
SyncedInstance<Config>.Synced = false;
SyncedInstance<Config>.MessageManager.RegisterNamedMessageHandler("Kolton12O.OpenTheNoor_OnReceiveConfigSync", new HandleNamedMessageDelegate(Config.OnReceiveSync));
Config.RequestSync();
}
}
public static void playOpenTheNoorNoise(AudioSource __audioSource, AudioClip[] sounds)
{
RoundManager.PlayRandomClip(__audioSource, sounds, true, SyncedInstance<Config>.Default.VOLUME, 0, 1000);
}
}
[BepInPlugin("Kolton12O.OpenTheNoor", "OpenTheNoor", "1.1.5")]
public class OpenTheNoorBase : BaseUnityPlugin
{
public const string MOD_GUID = "Kolton12O.OpenTheNoor";
public const string MOD_NAME = "OpenTheNoor";
public const string MOD_VERSION = "1.1.5";
private readonly Harmony harmony = new Harmony("Kolton12O.OpenTheNoor");
public static OpenTheNoorBase Instance;
internal ManualLogSource mls;
internal static List<AudioClip> SoundFX;
internal static AssetBundle Bundle;
public GameObject netManagerPrefab;
public static Config Config { get; internal set; }
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
mls = Logger.CreateLogSource("Kolton12O.OpenTheNoor");
Config = new Config(((BaseUnityPlugin)this).Config);
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
for (int i = 0; i < types.Length; i++)
{
MethodInfo[] methods = types[i].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);
}
}
}
mls.LogInfo((object)"Open The Noor has awaken!");
Bundle = AssetBundle.LoadFromFile(((BaseUnityPlugin)Instance).Info.Location.TrimEnd("OpenTheNoor.dll".ToCharArray()) + "openthenoor");
SoundFX = new List<AudioClip>();
if ((Object)(object)Bundle != (Object)null)
{
mls.LogInfo((object)"Successfully loaded asset bundle! :)");
netManagerPrefab = Bundle.LoadAsset<GameObject>("Assets/OpenTheNoor/NetworkManagerOpenTheNoor.prefab");
netManagerPrefab.AddComponent<NetworkManagerOpenTheNoor>();
SoundFX = Bundle.LoadAllAssets<AudioClip>().ToList();
}
else
{
mls.LogError((object)"Failed to load asset bundle! :(");
}
harmony.PatchAll();
}
}
}