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 BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
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("HornetAudioEditor")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+89ebe01822f494276854572a6842b749907a93e6")]
[assembly: AssemblyProduct("HornetAudioEditor")]
[assembly: AssemblyTitle("HornetAudioEditor")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.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 BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace HornetAudioEditor
{
[BepInPlugin("alphalul.HornetAudioEditor", "Hornet Audio Editor", "1.2.0")]
public class HornetAudioEditorPlugin : BaseUnityPlugin
{
private class AudioCollection
{
public HashSet<string> folders;
public ProbabilityAudioClip[] vanillaClips;
public bool includeVanillaClips;
public AudioCollection(HashSet<string> folders, bool includeVanillaClips)
{
this.folders = folders;
this.includeVanillaClips = includeVanillaClips;
base..ctor();
}
}
[HarmonyPatch(typeof(RandomAudioClipTable), "OnEnable")]
private class AudioTableOnEnable_Patch
{
[HarmonyPrefix]
private static void OnEnable_Prefix(RandomAudioClipTable __instance)
{
Instance.LoadAudioTable(__instance);
}
}
[HarmonyPatch(typeof(GameManager), "Start")]
private class GameManagerStart_Patch
{
[HarmonyPostfix]
private static void Start_Postfix()
{
((MonoBehaviour)Instance).StartCoroutine(Instance.RefreshAudioCollectionsRoutine());
}
}
[HarmonyPatch(typeof(RandomAudioClipTable), "SelectRandomClip")]
private class AudioLog_Patch
{
[HarmonyPrefix]
private static void SelectRandomClip_Prefix(RandomAudioClipTable __instance)
{
Instance.LogAudio(((Object)__instance).name);
}
}
private Dictionary<string, List<ProbabilityAudioClip>> folderClips;
private Dictionary<string, AudioCollection> audioCollections;
private string clipsPath;
private string audioCollectionsPath;
private string collectionPresetsPath;
private Harmony harmony = new Harmony("alphalul.HornetAudioEditor");
private ConfigEntry<bool> configModEnabled;
private ConfigEntry<bool> configLogAudio;
private ConfigEntry<bool> configRefreshOnSaveQuit;
public const string Id = "alphalul.HornetAudioEditor";
private static HornetAudioEditorPlugin Instance { get; set; }
public static string Name => "Hornet Audio Editor";
public static string Version => "1.2.0";
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
configModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Whether the mod is active. Set to false to disable the mod.");
configLogAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LogAudio", false, "Whether to log the name of a RandomAudioClipTable when it plays a sound. Useful for finding table names.");
configRefreshOnSaveQuit = ((BaseUnityPlugin)this).Config.Bind<bool>("Loading", "RefreshOnSaveQuit", true, "Whether to re-apply audioCollections.json upon returning to the title screen.");
if (configModEnabled.Value)
{
clipsPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Clips");
audioCollectionsPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "audioCollections.json");
collectionPresetsPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Collection Presets");
Directory.CreateDirectory(clipsPath);
harmony.PatchAll(typeof(GameManagerStart_Patch));
if (configRefreshOnSaveQuit.Value)
{
harmony.PatchAll(typeof(AudioTableOnEnable_Patch));
}
if (configLogAudio.Value)
{
harmony.PatchAll(typeof(AudioLog_Patch));
}
((MonoBehaviour)this).StartCoroutine(RefreshAudioCollectionsRoutine());
}
}
private IEnumerator RefreshAudioCollectionsRoutine()
{
if (!RetrieveAudioCollectionsData())
{
((BaseUnityPlugin)this).Logger.LogError((object)"Something is wrong with 'audioCollections.json', unable to initialize HornetAudioEditor mod.");
yield break;
}
yield return LoadClipsRoutine();
RandomAudioClipTable[] loadedAudioTables = Resources.FindObjectsOfTypeAll<RandomAudioClipTable>();
RandomAudioClipTable[] array = loadedAudioTables;
foreach (RandomAudioClipTable table in array)
{
if (audioCollections.TryGetValue(((Object)table).name, out var audioCollection))
{
ApplyClips(table, audioCollection);
}
audioCollection = null;
}
}
private IEnumerator LoadClipsRoutine()
{
foreach (string folder in folderClips.Keys)
{
List<AudioClip> streamedFolderClips = new List<AudioClip>();
string folderPath = Path.Combine(clipsPath, folder);
if (!Directory.Exists(folderPath))
{
yield break;
}
string[] collectionWavFiles = Directory.GetFiles(folderPath, "*.wav", SearchOption.TopDirectoryOnly);
string[] array = collectionWavFiles;
foreach (string wavFile in array)
{
yield return WavToAudioClipRoutine(wavFile, streamedFolderClips);
}
foreach (AudioClip clip in streamedFolderClips)
{
List<ProbabilityAudioClip> list = folderClips[folder];
ProbabilityAudioClip val = new ProbabilityAudioClip
{
Clip = clip
};
((ProbabilityBase<AudioClip>)val).Probability = 1f;
list.Add(val);
}
}
}
private IEnumerator WavToAudioClipRoutine(string wavFile, List<AudioClip> clips)
{
string uri = new Uri(wavFile).AbsoluteUri;
UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(uri, (AudioType)20);
try
{
yield return req.SendWebRequest();
AudioClip streamedClip = DownloadHandlerAudioClip.GetContent(req);
((Object)streamedClip).name = Path.GetFileNameWithoutExtension(wavFile);
streamedClip.LoadAudioData();
clips.Add(streamedClip);
}
finally
{
((IDisposable)req)?.Dispose();
}
}
private void ApplyClips(RandomAudioClipTable table, AudioCollection audioCollection)
{
List<ProbabilityAudioClip> list = new List<ProbabilityAudioClip>();
foreach (string folder in audioCollection.folders)
{
list.AddRange(folderClips[folder]);
}
if (list.Count != 0)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Applied mod to " + ((Object)table).name));
}
if (audioCollection.includeVanillaClips || list.Count == 0)
{
list.AddRange(audioCollection.vanillaClips);
}
table.clips = list.ToArray();
}
private void LoadAudioTable(RandomAudioClipTable table)
{
if (audioCollections != null && folderClips != null && audioCollections.TryGetValue(((Object)table).name, out var value))
{
value.vanillaClips = (ProbabilityAudioClip[])table.clips.Clone();
ApplyClips(table, value);
}
}
private void LogAudio(string message)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)message);
}
private bool RetrieveAudioCollectionsData()
{
//IL_0001: 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)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
JsonSerializerSettings val = new JsonSerializerSettings
{
Formatting = (Formatting)1,
NullValueHandling = (NullValueHandling)1,
DefaultValueHandling = (DefaultValueHandling)1
};
Dictionary<string, List<string>> dictionary;
if (File.Exists(audioCollectionsPath))
{
try
{
dictionary = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(File.ReadAllText(audioCollectionsPath), val);
}
catch (Exception ex)
{
Debug.LogError((object)("Hornet Audio Editor: " + ex.Message));
return false;
}
}
else
{
dictionary = new Dictionary<string, List<string>> { [""] = new List<string>(3) { "Taunt Hornet Voice", "Taunt Seriously Hornet Voice", "Hornet_poshanka" } };
string contents = JsonConvert.SerializeObject((object)dictionary, val);
File.WriteAllText(audioCollectionsPath, contents);
}
ApplyCollectionPresets(dictionary, val);
ParseRawAudioCollectionsData(dictionary);
return true;
}
private void ApplyCollectionPresets(Dictionary<string, List<string>> rawAudioCollectionsData, JsonSerializerSettings jsonSettings)
{
Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>();
foreach (List<string> value2 in rawAudioCollectionsData.Values)
{
string[] array = value2.Where((string t) => t.EndsWith(".json")).ToArray();
if (array.Length == 0)
{
continue;
}
string[] array2 = array;
foreach (string text in array2)
{
try
{
if (dictionary.TryGetValue(text, out var value))
{
value2.AddRange(value);
continue;
}
value = (dictionary[text] = JsonConvert.DeserializeObject<string[]>(File.ReadAllText(Path.Combine(collectionPresetsPath, text.TrimStart('+'))), jsonSettings));
if (text.StartsWith('+'))
{
for (int j = 0; j < value.Length; j++)
{
if (!value[j].StartsWith('+'))
{
value[j] = "+" + value[j];
}
}
}
value2.AddRange(value);
goto IL_013b;
}
catch (Exception ex)
{
Debug.LogError((object)("Hornet Audio Editor: " + ex.Message));
goto IL_013b;
}
IL_013b:
value2.Remove(text);
}
}
}
private void ParseRawAudioCollectionsData(Dictionary<string, List<string>> rawAudioCollectionsData)
{
folderClips = rawAudioCollectionsData.ToDictionary((KeyValuePair<string, List<string>> kvp) => kvp.Key, (KeyValuePair<string, List<string>> _) => new List<ProbabilityAudioClip>());
audioCollections = new Dictionary<string, AudioCollection>();
foreach (var (item, list2) in rawAudioCollectionsData)
{
foreach (string item2 in list2)
{
string key = item2.TrimStart('+');
if (audioCollections.TryGetValue(key, out var value))
{
value.folders.Add(item);
value.includeVanillaClips |= item2.StartsWith('+');
}
else
{
audioCollections[key] = new AudioCollection(new HashSet<string> { item }, item2.StartsWith('+'));
}
}
}
}
}
}