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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LCLadderMod.Audio;
using LCLadderMod.Networking;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
[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("com.yoshikabir.LCLadderMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+025ba2a1869596c7811a1c02363edb4650e497f6")]
[assembly: AssemblyProduct("LCLadderMod")]
[assembly: AssemblyTitle("com.yoshikabir.LCLadderMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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 LCLadderMod
{
[BepInPlugin("com.yoshikabir.LCLadderMod", "LCLadderMod", "1.0.0")]
public class LCLadderModBase : BaseUnityPlugin
{
public static LCLadderModBase Instance { get; private set; }
internal static ManualLogSource Logger { get; private set; }
internal static Harmony? Harmony { get; set; }
private void Awake()
{
Logger = Logger.CreateLogSource("com.yoshikabir.LCLadderMod");
Instance = this;
Patch();
Logger.LogInfo((object)"com.yoshikabir.LCLadderMod v1.0.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("com.yoshikabir.LCLadderMod");
}
if (!AudioController.LoadAudioClips())
{
Logger.LogError((object)"No Audio. Not running the patcher.");
return;
}
Logger.LogDebug((object)"Patching...");
Harmony.PatchAll();
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!");
}
}
internal static class Utils
{
public static PlayerControllerB? localPlayer => StartOfRound.Instance?.localPlayerController;
public static NetworkManager networkManager => NetworkManager.Singleton;
public static bool isClient => networkManager.IsClient;
public static bool isServer => networkManager.IsServer;
public static bool isHost => networkManager.IsHost;
public static bool GetPlayer(ulong clientId, out PlayerControllerB? playerController)
{
playerController = null;
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
if (val.actualClientId == clientId)
{
playerController = val;
break;
}
}
return (Object)(object)playerController != (Object)null;
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "com.yoshikabir.LCLadderMod";
public const string PLUGIN_NAME = "LCLadderMod";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace LCLadderMod.Patches
{
[HarmonyPatch(typeof(InteractTrigger))]
internal class InteractTriggerPatch
{
internal static float curTime;
[HarmonyPatch("SetUsingLadderOnLocalClient")]
[HarmonyPostfix]
private static void AddAudioToLadder(bool isUsing)
{
LCLadderModBase.Logger.LogDebug((object)$"Ladder grab event called! isUsing: {isUsing}");
if (isUsing)
{
AudioController.StartAudioLocal();
}
else
{
AudioController.StopAudioLocal();
}
}
}
}
namespace LCLadderMod.Networking
{
[HarmonyPatch]
public static class SyncLadderAudio
{
[CompilerGenerated]
private static class <>O
{
public static HandleNamedMessageDelegate <0>__SyncAudioServerRPC;
public static HandleNamedMessageDelegate <1>__SyncAudioClientRPC;
}
[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
[HarmonyPostfix]
public static void Init()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
LCLadderModBase.Logger.LogInfo((object)"Registering Network RPCs");
if (Utils.isServer)
{
CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
object obj = <>O.<0>__SyncAudioServerRPC;
if (obj == null)
{
HandleNamedMessageDelegate val = SyncAudioServerRPC;
<>O.<0>__SyncAudioServerRPC = val;
obj = (object)val;
}
customMessagingManager.RegisterNamedMessageHandler("com.yoshikabir.LCLadderMod.SyncAudioServerRPC", (HandleNamedMessageDelegate)obj);
}
else if (Utils.isClient)
{
CustomMessagingManager customMessagingManager2 = NetworkManager.Singleton.CustomMessagingManager;
object obj2 = <>O.<1>__SyncAudioClientRPC;
if (obj2 == null)
{
HandleNamedMessageDelegate val2 = SyncAudioClientRPC;
<>O.<1>__SyncAudioClientRPC = val2;
obj2 = (object)val2;
}
customMessagingManager2.RegisterNamedMessageHandler("com.yoshikabir.LCLadderMod.SyncAudioClientRPC", (HandleNamedMessageDelegate)obj2);
}
}
public static void SendAudioToServer(float time, bool start)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: 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 (Utils.isClient)
{
if (Utils.isServer)
{
SendAudioToClients(Utils.localPlayer, time, start);
return;
}
int num = 5;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(num, (Allocator)2, -1);
((FastBufferWriter)(ref val)).WriteValue<float>(ref time, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteValue<bool>(ref start, default(ForPrimitives));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("com.yoshikabir.LCLadderMod.SyncAudioServerRPC", 0uL, val, (NetworkDelivery)3);
}
}
private static void SyncAudioServerRPC(ulong clientId, FastBufferReader reader)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
if (!Utils.isServer)
{
return;
}
if (!Utils.GetPlayer(clientId, out PlayerControllerB playerController))
{
LCLadderModBase.Logger.LogWarning((object)$"Could not find player with ClientId {clientId} to start/stop sound!");
}
float num = default(float);
((FastBufferReader)(ref reader)).ReadValue<float>(ref num, default(ForPrimitives));
bool flag = default(bool);
((FastBufferReader)(ref reader)).ReadValue<bool>(ref flag, default(ForPrimitives));
if (Utils.isClient && clientId != Utils.localPlayer?.actualClientId)
{
LCLadderModBase.Logger.LogDebug((object)$"Server Receieved play sound from client {clientId} with time {num} and start {flag}!");
if (flag)
{
AudioController.StartAudioOnPlayer(playerController, num);
}
else
{
AudioController.StopAudioOnPlayer(playerController);
}
}
SendAudioToClients(playerController, num, flag);
}
public static void SendAudioToClients(PlayerControllerB soundProducer, float time, bool start)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (Utils.isServer && !((Object)(object)soundProducer == (Object)null))
{
int num = 13;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(num, (Allocator)2, -1);
((FastBufferWriter)(ref val)).WriteValue<ulong>(ref soundProducer.actualClientId, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteValue<float>(ref time, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteValue<bool>(ref start, default(ForPrimitives));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("com.yoshikabir.LCLadderMod.SyncAudioClientRPC", val, (NetworkDelivery)3);
}
}
private static void SyncAudioClientRPC(ulong clientId, FastBufferReader reader)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: 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_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
if (!Utils.isClient || Utils.isServer)
{
return;
}
ulong num = default(ulong);
((FastBufferReader)(ref reader)).ReadValue<ulong>(ref num, default(ForPrimitives));
float num2 = default(float);
((FastBufferReader)(ref reader)).ReadValue<float>(ref num2, default(ForPrimitives));
bool flag = default(bool);
((FastBufferReader)(ref reader)).ReadValue<bool>(ref flag, default(ForPrimitives));
if (num == Utils.localPlayer?.actualClientId)
{
LCLadderModBase.Logger.LogDebug((object)"No need to start/stop sound on calling client.");
return;
}
if (!Utils.GetPlayer(num, out PlayerControllerB playerController))
{
LCLadderModBase.Logger.LogWarning((object)$"Could not find player with ClientId {num} to play sound!");
return;
}
LCLadderModBase.Logger.LogDebug((object)$"Client received message to start/stop {flag} sound at time {num2} with player {num}");
if (flag)
{
AudioController.StartAudioOnPlayer(playerController, num2);
}
else
{
AudioController.StopAudioOnPlayer(playerController);
}
}
}
}
namespace LCLadderMod.Audio
{
[HarmonyPatch]
public static class AudioController
{
private static AssetBundle? AudioBundle;
private static List<AudioClip>? Sounds;
private static float curTime;
public static bool LoadAudioClips()
{
Sounds = new List<AudioClip>();
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
AudioBundle = AssetBundle.LoadFromFile(Path.Combine(directoryName, "laddersound"));
if ((Object)(object)AudioBundle == (Object)null)
{
LCLadderModBase.Logger.LogError((object)"Failed to load audio!");
return false;
}
LCLadderModBase.Logger.LogInfo((object)"Successfully loaded audio!");
Sounds = AudioBundle.LoadAllAssets<AudioClip>().ToList();
return true;
}
[HarmonyPatch(typeof(PlayerControllerB), "Awake")]
[HarmonyPostfix]
public static void InitPlayerControllerAudio(PlayerControllerB __instance)
{
if ((Object)(object)AudioBundle == (Object)null || Sounds == null || Sounds.Count == 0)
{
LCLadderModBase.Logger.LogWarning((object)"No Audio to assign to player!");
return;
}
AudioSource movementAudio = __instance.movementAudio;
((Behaviour)movementAudio).enabled = true;
movementAudio.volume = 1f;
movementAudio.dopplerLevel = 0f;
movementAudio.mute = false;
movementAudio.spatialize = false;
movementAudio.bypassEffects = true;
movementAudio.pitch = 1f;
movementAudio.loop = true;
movementAudio.clip = Sounds[0];
movementAudio.time = 0f;
}
public static void StartAudioLocal()
{
if ((Object)(object)Utils.localPlayer == (Object)null)
{
LCLadderModBase.Logger.LogWarning((object)"Cannot start audio on a non-existent localPlayer!");
return;
}
LCLadderModBase.Logger.LogInfo((object)$"Starting Audio on local player at time {curTime}!");
AudioSource movementAudio = Utils.localPlayer.movementAudio;
movementAudio.time = curTime;
movementAudio.Play();
SyncLadderAudio.SendAudioToServer(curTime, start: true);
}
public static void StopAudioLocal()
{
if ((Object)(object)Utils.localPlayer == (Object)null)
{
LCLadderModBase.Logger.LogWarning((object)"Cannot stop audio on a non-existent localPlayer!");
return;
}
LCLadderModBase.Logger.LogInfo((object)"Stopping Audio on local player!");
AudioSource movementAudio = Utils.localPlayer.movementAudio;
curTime = movementAudio.time;
movementAudio.Stop();
SyncLadderAudio.SendAudioToServer(curTime, start: false);
}
public static void StartAudioOnPlayer(PlayerControllerB soundProducer, float time)
{
if ((Object)(object)soundProducer == (Object)null)
{
LCLadderModBase.Logger.LogWarning((object)"Can't stop audio on a non-existent player.");
return;
}
LCLadderModBase.Logger.LogInfo((object)$"Playing Audio on Player Id: {soundProducer.actualClientId} at time {time}");
AudioSource movementAudio = soundProducer.movementAudio;
if (movementAudio.isPlaying)
{
movementAudio.Stop();
}
movementAudio.time = time;
movementAudio.Play();
}
public static void StopAudioOnPlayer(PlayerControllerB soundProducer)
{
if ((Object)(object)soundProducer == (Object)null)
{
LCLadderModBase.Logger.LogWarning((object)"Can't stop audio on a non-existent player.");
return;
}
LCLadderModBase.Logger.LogInfo((object)$"Stopping Audio on Player Id: {soundProducer.actualClientId}");
AudioSource movementAudio = soundProducer.movementAudio;
movementAudio.Stop();
}
}
}