using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using SoundImporter;
using SoundImporter.Managers;
using Steamworks;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UIElements;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "BetonJukebox", "1.0.0", "Xannix", null)]
[assembly: MelonGame("Jan Malitschek", "BetonBrutal")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BetonJukebox")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetonJukebox")]
[assembly: AssemblyTitle("BetonJukebox")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 SoundImporter
{
public class Core : MelonMod
{
public override void OnInitializeMelon()
{
((MelonBase)this).LoggerInstance.Msg("Initialized.");
}
}
[Serializable]
public class CustomSound
{
public string ID;
public string Path;
public string Name;
public string Category;
public string Subcategory;
}
}
namespace SoundImporter.Patches
{
[HarmonyPatch(typeof(MapEditor), "LoadMap")]
public static class OnLocalMapLoading
{
private static void Prefix(string mapName)
{
RegisterManager.ClearCustomSounds();
string text = Path.Combine(Application.persistentDataPath, "CustomMaps", mapName);
if (Directory.Exists(text))
{
SoundImporter.Managers.SoundImporter.LoadSoundsFromDirectory(text);
}
else
{
MelonLogger.Warning("Directory does not exist: " + text);
}
}
}
[HarmonyPatch(typeof(MapEditor), "LoadDownloadedMap")]
public static class OnWorkshopMapLoading
{
private static void Prefix(string mapItemID)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
RegisterManager.ClearCustomSounds();
string text = $"{SteamApps.AppInstallDir(default(AppId))}\\..\\..\\workshop\\content\\{SteamClient.AppId.Value}\\{mapItemID}";
if (Directory.Exists(text))
{
SoundImporter.Managers.SoundImporter.LoadSoundsFromDirectory(text);
}
else
{
MelonLogger.Warning("Directory does not exist: " + text);
}
}
}
[HarmonyPatch(typeof(SoundPicker), "Init")]
public static class SoundPickerInitPatch
{
public static void RefreshCategories(SoundPicker picker)
{
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Expected O, but got Unknown
if (picker == null || (Object)(object)TriggerSoundManager.Instance == (Object)null)
{
return;
}
ScrollView value = Traverse.Create((object)picker).Field<ScrollView>("categories").Value;
List<Category> value2 = Traverse.Create((object)picker).Field<List<Category>>("categoryItems").Value;
if (value == null || value2 == null)
{
return;
}
((VisualElement)value).Clear();
value2.Clear();
HashSet<string> hashSet = TriggerSoundManager.Instance.TriggerSounds.Select((TriggerSound x) => x.category).ToHashSet();
foreach (string item in hashSet)
{
Category val = new Category();
val.Populate(item);
val.onClick += delegate(string catName)
{
Traverse.Create((object)picker).Method("PopulateCategory", new object[1] { catName }).GetValue();
};
val.Select(false);
((VisualElement)value).Add((VisualElement)(object)val);
value2.Add(val);
}
if (hashSet.Count > 0)
{
Traverse.Create((object)picker).Method("PopulateCategory", new object[1] { hashSet.First() }).GetValue();
}
}
}
[HarmonyPatch(typeof(MoveTriggerScreen), "PickSound")]
public static class OnSoundMenuOpened
{
private static void Prefix()
{
UIUpdate();
}
private static void UIUpdate()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
UIDocument[] array = Object.FindObjectsOfType<UIDocument>();
UIDocument[] array2 = array;
foreach (UIDocument val in array2)
{
if (val.rootVisualElement == null)
{
continue;
}
List<SoundPicker> list = UQueryExtensions.Query<SoundPicker>(val.rootVisualElement, (string)null, (string)null).ToList();
foreach (SoundPicker item in list)
{
SoundPickerInitPatch.RefreshCategories(item);
}
}
}
}
}
namespace SoundImporter.Managers
{
public static class RegisterManager
{
private static readonly Dictionary<string, TriggerSound> LoadedCustomSounds = new Dictionary<string, TriggerSound>();
public static void RegisterCustomTriggerSound(CustomSound soundData, List<AudioClip> clips)
{
if (!((Object)(object)TriggerSoundManager.Instance == (Object)null) && clips != null && clips.Count != 0)
{
if (LoadedCustomSounds.ContainsKey(soundData.ID))
{
MelonLogger.Warning("Sounds already has " + soundData.ID + "! Skipping");
return;
}
TriggerSound val = ScriptableObject.CreateInstance<TriggerSound>();
((Object)val).name = soundData.ID;
val.soundName = soundData.Name;
val.category = soundData.Category;
val.subcategory = soundData.Subcategory;
val.sounds = clips.ToArray();
val.mixerChannel = TriggerSoundManager.Instance.defaultMixerChannel;
List<TriggerSound> list = new List<TriggerSound>(TriggerSoundManager.Instance.TriggerSounds) { val };
typeof(TriggerSoundManager).GetProperty("TriggerSounds")?.SetValue(TriggerSoundManager.Instance, list.ToArray());
LoadedCustomSounds.Add(soundData.ID, val);
Debug.Log((object)$"Sound registered: '{soundData.ID}' ({clips.Count} files)");
}
}
public static void ClearCustomSounds()
{
if (LoadedCustomSounds.Count == 0)
{
return;
}
TriggerSoundManager instance = TriggerSoundManager.Instance;
if ((Object)(object)instance != (Object)null && instance.TriggerSounds != null)
{
List<TriggerSound> list = new List<TriggerSound>(instance.TriggerSounds);
foreach (TriggerSound value in LoadedCustomSounds.Values)
{
list.Remove(value);
if (value.sounds != null)
{
AudioClip[] sounds = value.sounds;
foreach (AudioClip val in sounds)
{
Object.Destroy((Object)(object)val);
}
}
Object.Destroy((Object)(object)value);
}
typeof(TriggerSoundManager).GetProperty("TriggerSounds")?.SetValue(instance, list.ToArray());
}
LoadedCustomSounds.Clear();
Debug.Log((object)"Custom sounds cleared.");
}
}
public static class SoundImporter
{
public static void LoadSoundsFromDirectory(string mapFolderPath)
{
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Invalid comparison between Unknown and I4
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Invalid comparison between Unknown and I4
MelonLogger.Msg("Sync loading sounds for: " + mapFolderPath);
if (!Directory.Exists(mapFolderPath))
{
MelonLogger.Warning("Directory does not exist: " + mapFolderPath);
return;
}
string[] files;
try
{
files = Directory.GetFiles(mapFolderPath, "*.json", SearchOption.AllDirectories);
MelonLogger.Msg($"Found {files.Length} .json files.");
}
catch (Exception ex)
{
MelonLogger.Error("Failed to read directory: " + ex.Message);
return;
}
string[] array = files;
foreach (string text in array)
{
List<CustomSound> list = new List<CustomSound>();
try
{
string text2 = File.ReadAllText(text);
JToken val = JToken.Parse(text2);
if ((int)val.Type == 2)
{
list = val.ToObject<List<CustomSound>>();
}
else if ((int)val.Type == 1)
{
CustomSound customSound = val.ToObject<CustomSound>();
if (customSound != null)
{
list.Add(customSound);
}
}
}
catch
{
continue;
}
if (list == null || list.Count == 0)
{
continue;
}
foreach (CustomSound item in list)
{
if (string.IsNullOrEmpty(item.Name) || string.IsNullOrEmpty(item.Path))
{
MelonLogger.Warning("Skipping entry in " + text + ": Missing Name or Path.");
continue;
}
string category = (string.IsNullOrEmpty(item.Category) ? "Custom" : item.Category);
string subcategory = (string.IsNullOrEmpty(item.Subcategory) ? "Sounds" : item.Subcategory);
string text3 = Path.Combine(mapFolderPath, "Sounds", item.Path);
List<string> list2 = new List<string>();
if (File.Exists(text3) && text3.EndsWith(".ogg", StringComparison.OrdinalIgnoreCase))
{
list2.Add(text3);
}
else if (Directory.Exists(text3))
{
list2.AddRange(Directory.GetFiles(text3, "*.ogg", SearchOption.AllDirectories));
}
if (list2.Count == 0)
{
MelonLogger.Warning("No .ogg files found for sound '" + item.Name + "' at path: " + text3);
continue;
}
List<AudioClip> list3 = new List<AudioClip>();
foreach (string item2 in list2)
{
AudioClip val2 = LoadAudioClipSync(item2);
if ((Object)(object)val2 != (Object)null)
{
list3.Add(val2);
}
}
if (list3.Count > 0)
{
item.Category = category;
item.Subcategory = subcategory;
item.ID = string.Join('_', item.Name.Split(" ")).ToLower();
RegisterManager.RegisterCustomTriggerSound(item, list3);
}
}
}
}
private static AudioClip LoadAudioClipSync(string filePath)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Invalid comparison between Unknown and I4
string text = "file://" + filePath;
UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)14);
try
{
UnityWebRequestAsyncOperation val = audioClip.SendWebRequest();
while (!((AsyncOperation)val).isDone)
{
}
if ((int)audioClip.result != 1)
{
MelonLogger.Error("Failed to load " + filePath + ": " + audioClip.error);
return null;
}
AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
if ((Object)(object)content != (Object)null)
{
((Object)content).name = Path.GetFileNameWithoutExtension(filePath);
}
return content;
}
finally
{
((IDisposable)audioClip)?.Dispose();
}
}
}
}