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 Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
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("RandomSounds")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+56d7cee39c040de32967309ef2923f4f12792fdd")]
[assembly: AssemblyProduct("RandomSounds")]
[assembly: AssemblyTitle("RandomSounds")]
[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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace RandomSounds
{
[Serializable]
public struct SoundWeight
{
public string sound;
public int weight;
}
[Serializable]
public struct ClipWeight
{
public AudioClip clip;
public int weight;
public ClipWeight(AudioClip clip, int weight)
{
this.clip = clip;
this.weight = weight;
}
}
[BepInPlugin("RandomSounds", "RandomSounds", "1.4.0")]
public class RandomSounds : BaseUnityPlugin
{
public const string OriginalKey = "original";
public static readonly string[] AllowedExtensions = new string[3] { ".wav", ".mp3", ".ogg" };
public static RandomSounds Instance;
public static int Seed = new Random().Next();
public static int SeedOffset = 0;
public static Random Random = new Random(Seed);
internal ManualLogSource logger;
public Dictionary<string, string> soundPacks = new Dictionary<string, string>();
public static Dictionary<string, HashSet<ClipWeight>> ReplacedClips = new Dictionary<string, HashSet<ClipWeight>>();
private Harmony harmony;
public string RandomSoundsFolderPath => Path.Combine(Paths.PluginPath, "RandomSounds");
public string RandomSoundsFolderLegacyPath => Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "RandomSounds");
internal void Awake()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
if ((Object)(object)Instance != (Object)null)
{
return;
}
Instance = this;
try
{
logger = Logger.CreateLogSource("RandomSounds");
logger.LogInfo((object)"Plugin RandomSounds is loaded!");
harmony = new Harmony("RandomSounds");
harmony.PatchAll();
Directory.CreateDirectory(RandomSoundsFolderPath);
LoadSounds();
}
catch (Exception ex)
{
Debug.LogError((object)ex.ToString());
}
}
private void LoadSounds()
{
string path = (Directory.Exists(RandomSoundsFolderLegacyPath) ? RandomSoundsFolderLegacyPath : RandomSoundsFolderPath);
if (Directory.Exists(path))
{
string[] directories = Directory.GetDirectories(path);
string[] array = directories;
foreach (string audiosDirPath in array)
{
ProcessSoundFiles(audiosDirPath);
}
logger.LogInfo((object)"All sounds have been loaded!");
}
else
{
logger.LogInfo((object)"RandomSounds folder not found.");
}
}
private void ProcessSoundFiles(string audiosDirPath)
{
string[] array = (from file in Directory.GetFiles(audiosDirPath)
where AllowedExtensions.Any(file.ToLower().EndsWith)
select file).ToArray();
if (array.Length == 0)
{
return;
}
string fileName = Path.GetFileName(audiosDirPath);
string path = Path.Combine(audiosDirPath, "weights.json");
SoundWeight[] source = Array.Empty<SoundWeight>();
int num = array.Length;
if (File.Exists(path))
{
try
{
source = JsonConvert.DeserializeObject<SoundWeight[]>(File.ReadAllText(path));
num = source.Aggregate(0, (int t, SoundWeight sw) => t + Math.Max(sw.weight, 0));
}
catch (Exception arg)
{
logger.LogWarning((object)$"Could not parse {fileName} weights.json \n{arg}");
}
}
int num2 = num / array.Length;
int num3 = num2;
string[] array2 = array;
foreach (string soundPath in array2)
{
num3 = num2;
AudioClip audioClip = GetAudioClip(soundPath);
string clipName = audioClip.GetName();
try
{
num3 = source.First((SoundWeight sw) => sw.sound == clipName).weight;
}
catch (Exception)
{
}
AddAudioClip(fileName, audioClip, num3);
logger.LogInfo((object)$"Added {fileName}/{clipName} with weight {num3}");
}
num3 = num2;
try
{
num3 = source.First((SoundWeight sw) => sw.sound == "original").weight;
}
catch (Exception)
{
}
AddDefaultAudioWeight(fileName, num3);
}
private static void AddAudioClip(string originalName, AudioClip newClip, int weight)
{
if (string.IsNullOrEmpty(originalName))
{
Instance.logger.LogWarning((object)"Trying to replace an audio clip without original clip specified! This is not allowed.");
return;
}
if ((Object)(object)newClip == (Object)null)
{
Instance.logger.LogWarning((object)"Trying to replace an audio clip without new clip specified! This is not allowed.");
return;
}
if (ReplacedClips.ContainsKey(originalName))
{
ReplacedClips[originalName].Add(new ClipWeight(newClip, weight));
return;
}
ReplacedClips.Add(originalName, new HashSet<ClipWeight>
{
new ClipWeight(newClip, weight)
});
}
private void AddDefaultAudioWeight(string audioName, int weight)
{
logger.LogInfo((object)$"Set original audio {audioName} weight to {weight}");
if (ReplacedClips.ContainsKey(audioName))
{
ReplacedClips[audioName].Add(new ClipWeight(null, weight));
return;
}
ReplacedClips.Add(audioName, new HashSet<ClipWeight>
{
new ClipWeight(null, weight)
});
}
private static AudioClip GetAudioClip(string soundPath)
{
if (!File.Exists(soundPath))
{
Instance.logger.LogWarning((object)("Requested audio file does not exist at path " + soundPath + "!"));
return null;
}
return LoadClip(soundPath);
}
private static AudioClip LoadClip(string path)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Invalid comparison between Unknown and I4
AudioClip val = null;
UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, (AudioType)0);
try
{
audioClip.SendWebRequest();
try
{
while (!audioClip.isDone)
{
}
if ((int)audioClip.result != 1)
{
Instance.logger.LogError((object)("Failed to load AudioClip from path: " + path + "\n" + audioClip.error));
}
else
{
val = DownloadHandlerAudioClip.GetContent(audioClip);
((Object)val).name = Path.GetFileNameWithoutExtension(path);
}
}
catch (Exception ex)
{
Instance.logger.LogError((object)(ex.Message + ", " + ex.StackTrace));
}
}
finally
{
((IDisposable)audioClip)?.Dispose();
}
return val;
}
public static void SyncRandom()
{
Random = new Random(Seed);
for (int i = 0; i < SeedOffset; i++)
{
Random.Next();
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "RandomSounds";
public const string PLUGIN_NAME = "RandomSounds";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace RandomSounds.Patches
{
[HarmonyPatch(typeof(AudioSource))]
internal class AudioSourcePatch
{
[HarmonyPatch("Play", new Type[] { })]
[HarmonyPrefix]
public static void Play_Patch(AudioSource __instance)
{
__instance.clip = ReplaceClipWithNew(__instance.clip);
}
[HarmonyPatch("Play", new Type[] { typeof(ulong) })]
[HarmonyPrefix]
public static void Play_UlongPatch(AudioSource __instance)
{
__instance.clip = ReplaceClipWithNew(__instance.clip);
}
[HarmonyPatch("Play", new Type[] { typeof(double) })]
[HarmonyPrefix]
public static void Play_DoublePatch(AudioSource __instance)
{
__instance.clip = ReplaceClipWithNew(__instance.clip);
}
[HarmonyPatch("PlayDelayed", new Type[] { typeof(float) })]
[HarmonyPrefix]
public static void PlayDelayed_Patch(AudioSource __instance)
{
__instance.clip = ReplaceClipWithNew(__instance.clip);
}
[HarmonyPatch("PlayOneShotHelper", new Type[]
{
typeof(AudioSource),
typeof(AudioClip),
typeof(float)
})]
[HarmonyPrefix]
public static void PlayOneShotHelper_Patch(AudioSource source, ref AudioClip clip, float volumeScale)
{
clip = ReplaceClipWithNew(clip);
}
[HarmonyPatch("PlayClipAtPoint", new Type[]
{
typeof(AudioClip),
typeof(Vector3)
})]
[HarmonyPrefix]
public static void PlayClipAtPoint_Patch(ref AudioClip clip, Vector3 position)
{
clip = ReplaceClipWithNew(clip);
}
private static AudioClip ReplaceClipWithNew(AudioClip original)
{
if ((Object)(object)original == (Object)null)
{
return null;
}
string name = original.GetName();
if (!RandomSounds.ReplacedClips.ContainsKey(name))
{
return original;
}
HashSet<ClipWeight> hashSet = RandomSounds.ReplacedClips[name];
int num = 0;
ClipWeight[] array = new ClipWeight[hashSet.Count];
foreach (ClipWeight item in hashSet)
{
array[num] = item;
num++;
}
ClipWeight[] array2 = array;
int maxValue = array2.Aggregate(0, (int t, ClipWeight sw) => t + sw.weight);
AudioClip val = null;
int num2 = RandomSounds.Random.Next(0, maxValue);
RandomSounds.SeedOffset++;
for (int i = 0; i < array2.Length + 1; i++)
{
val = array2[i].clip;
if (num2 < array2[i].weight)
{
break;
}
num2 -= array2[i].weight;
}
if ((Object)(object)val == (Object)null)
{
RandomSounds.Instance.logger.LogInfo((object)("Playing default sound " + name));
return original;
}
RandomSounds.Instance.logger.LogInfo((object)("Playing custom sound " + val.GetName() + " instead of " + name));
return val;
}
}
}
namespace RandomSounds.Networking
{
[HarmonyPatch]
public static class SyncSeed
{
[CompilerGenerated]
private static class <>O
{
public static HandleNamedMessageDelegate <0>__OnRequestSyncServerRpc;
public static HandleNamedMessageDelegate <1>__OnRequestSyncClientRpc;
}
public static bool requestedSync = false;
public static bool isSynced = false;
public static HashSet<ulong> syncedClients = new HashSet<ulong>();
public static bool IsClient => NetworkManager.Singleton.IsClient;
public static bool IsServer => NetworkManager.Singleton.IsServer;
[HarmonyPatch(typeof(StartOfRound), "Awake")]
[HarmonyPostfix]
private static void ResetValues()
{
isSynced = false;
requestedSync = false;
}
[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
[HarmonyPostfix]
private static void Init()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0073: 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)
//IL_007e: Expected O, but got Unknown
isSynced = false;
requestedSync = false;
if (IsServer)
{
CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
object obj = <>O.<0>__OnRequestSyncServerRpc;
if (obj == null)
{
HandleNamedMessageDelegate val = OnRequestSyncServerRpc;
<>O.<0>__OnRequestSyncServerRpc = val;
obj = (object)val;
}
customMessagingManager.RegisterNamedMessageHandler("RandomSounds.OnRequestSyncServerRpc", (HandleNamedMessageDelegate)obj);
}
else if (IsClient)
{
CustomMessagingManager customMessagingManager2 = NetworkManager.Singleton.CustomMessagingManager;
object obj2 = <>O.<1>__OnRequestSyncClientRpc;
if (obj2 == null)
{
HandleNamedMessageDelegate val2 = OnRequestSyncClientRpc;
<>O.<1>__OnRequestSyncClientRpc = val2;
obj2 = (object)val2;
}
customMessagingManager2.RegisterNamedMessageHandler("RandomSounds.OnRequestSyncClientRpc", (HandleNamedMessageDelegate)obj2);
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
[HarmonyPostfix]
private static void RequestSync(PlayerControllerB __instance)
{
if (IsClient && !IsServer && !isSynced && !requestedSync && (Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController)
{
requestedSync = true;
SendSyncRequest();
}
}
public static void SendSyncRequest()
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
if (IsClient && !IsServer)
{
RandomSounds.Instance.logger.LogInfo((object)"Sending sync request to server");
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(0, (Allocator)2, -1);
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("RandomSounds.OnRequestSyncServerRpc", 0uL, val, (NetworkDelivery)3);
}
}
private static void OnRequestSyncServerRpc(ulong clientId, FastBufferReader reader)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
if (IsServer)
{
RandomSounds.Instance.logger.LogInfo((object)("Receiving sync request from client: " + clientId));
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1);
((FastBufferWriter)(ref val)).WriteValue<int>(ref RandomSounds.Seed, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteValue<int>(ref RandomSounds.SeedOffset, default(ForPrimitives));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("RandomSounds.OnRequestSyncClientRpc", clientId, val, (NetworkDelivery)3);
}
}
private static void OnRequestSyncClientRpc(ulong clientId, FastBufferReader reader)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
if (IsClient)
{
((FastBufferReader)(ref reader)).ReadValue<int>(ref RandomSounds.Seed, default(ForPrimitives));
((FastBufferReader)(ref reader)).ReadValue<int>(ref RandomSounds.SeedOffset, default(ForPrimitives));
RandomSounds.SyncRandom();
isSynced = true;
RandomSounds.Instance.logger.LogInfo((object)$"Receiving sync response from server: {RandomSounds.Seed}+{RandomSounds.SeedOffset}");
}
}
}
}