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 HarmonyLib;
using LC_API.ServerAPI;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
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.0.0")]
public class RandomSounds : BaseUnityPlugin
{
public const string RandomSoundsDir = "RandomSounds";
public const string SeedRPCSignature = "RCPS_SeedSync";
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;
private void Awake()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
if (!((Object)(object)Instance != (Object)null))
{
Instance = this;
logger = Logger.CreateLogSource("RandomSounds");
logger.LogInfo((object)"Plugin RandomSounds is loaded!");
harmony = new Harmony("RandomSounds");
harmony.PatchAll();
CreateCustomSoundsFolder();
Networking.GetString = (Action<string, string>)Delegate.Combine(Networking.GetString, new Action<string, string>(GetSeedSync));
}
}
private void GetSeedSync(string data, string signature)
{
if (signature != "RCPS_SeedSync")
{
return;
}
string[] array = data.Split("_");
try
{
int num = int.Parse(array[0]);
int num2 = int.Parse(array[1]);
if (num != Seed || num2 != SeedOffset)
{
logger.LogInfo((object)$"Received seed {num} & offset {num2} from host.");
Seed = num;
SeedOffset = num2;
random = new Random(Seed);
for (int i = 0; i < SeedOffset; i++)
{
random.Next();
}
}
}
catch (Exception arg)
{
logger.LogWarning((object)$"Failed to parse seed data\n{arg}");
}
}
private void Start()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
LoadSounds();
GameObject val = new GameObject("RCPSPlayerJoin");
val.AddComponent<RCPSPlayerJoin>();
Object.DontDestroyOnLoad((Object)(object)val);
}
private void CreateCustomSoundsFolder()
{
string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "RandomSounds");
Directory.CreateDirectory(path);
}
public void LoadSounds()
{
string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
string path = Path.Combine(directoryName, "RandomSounds");
if (Directory.Exists(path))
{
string[] directories = Directory.GetDirectories(path);
string[] array = directories;
foreach (string audioPath in array)
{
ProcessSoundFiles(audioPath);
}
}
else
{
logger.LogInfo((object)"RandomSounds folder not found.");
}
}
private void ProcessSoundFiles(string audioPath)
{
string[] array = (from file in Directory.GetFiles(audioPath)
where AllowedExtensions.Any(file.ToLower().EndsWith)
select file).ToArray();
if (array.Length == 0)
{
return;
}
string fileName = Path.GetFileName(audioPath);
string path = Path.Combine(audioPath, "weights.json");
SoundWeight[] source = new SoundWeight[0];
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;
}
}
internal class RCPSPlayerJoin : MonoBehaviour
{
private static int playerCount = 1;
private static float lobbyCheckTimer;
private static bool wantToSyncSeed;
public void Awake()
{
}
public void Update()
{
if ((Object)(object)GameNetworkManager.Instance != (Object)null)
{
if (playerCount < GameNetworkManager.Instance.connectedPlayers)
{
lobbyCheckTimer = 4.5f;
wantToSyncSeed = true;
}
playerCount = GameNetworkManager.Instance.connectedPlayers;
}
if (lobbyCheckTimer > 0f)
{
lobbyCheckTimer -= Time.deltaTime;
}
else if (wantToSyncSeed)
{
wantToSyncSeed = false;
SyncSeed();
}
}
private static void SyncSeed()
{
if (!((Object)(object)HUDManager.Instance == (Object)null) && ((NetworkBehaviour)HUDManager.Instance).IsServer)
{
RandomSounds.Instance.logger.LogInfo((object)$"Broadcasting seed {RandomSounds.Seed} & offset {RandomSounds.SeedOffset} to other players.");
Networking.Broadcast(RandomSounds.Seed + "_" + RandomSounds.SeedOffset, "RCPS_SeedSync");
}
}
}
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;
}
ClipWeight[] array = RandomSounds.ReplacedClips[name].ToArray();
int maxValue = array.Aggregate(0, (int t, ClipWeight sw) => t + sw.weight);
AudioClip val = null;
int num = RandomSounds.random.Next(0, maxValue);
RandomSounds.SeedOffset++;
for (int i = 0; i < array.Length + 1; i++)
{
val = array[i].clip;
if (num < array[i].weight)
{
break;
}
num -= array[i].weight;
}
if ((Object)(object)val == (Object)null)
{
return original;
}
RandomSounds.Instance.logger.LogInfo((object)("Playing custom sound " + val.GetName() + " instead of " + name));
return val;
}
}
}