using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using ArmSlider;
using HarmonyLib;
using Il2CppRUMBLE.Interactions.InteractionBase;
using Il2CppRUMBLE.Managers;
using Il2CppRUMBLE.Serialization;
using Il2CppRUMBLE.UI;
using Il2CppRUMBLE.Utilities;
using MelonLoader;
using RumbleModUI;
using SettingsUI;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Mod), "SettingsUI", "1.3.0", "MasterMischief", null)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: VerifyLoaderVersion(0, 6, 2, true)]
[assembly: AssemblyTitle("SettingsUI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SettingsUI")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("06ed8e86-e143-46b0-969e-ee4f410032bb")]
[assembly: AssemblyFileVersion("1.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.3.0.0")]
namespace SettingsUI;
public class Mod : MelonMod
{
private enum SettingType
{
MasterVolume,
SFXVolume,
MusicVolume,
VoiceVolume
}
[HarmonyPatch(typeof(AudioManager), "ApplyConfiguration")]
private static class AudioManager_ApplyConfiguration_Patch
{
private static void Postfix(AudioManager __instance, AudioConfiguration config)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
if (undoNextAudioConfig)
{
AudioConfiguration val = default(AudioConfiguration);
val.MasterVolume = (float)((ModSetting)masterVolume).Value;
val.SFXVolume = (float)((ModSetting)sfxVolume).Value;
val.MusicVolume = (float)((ModSetting)musicVolume).Value;
val.VoiceVolume = (float)((ModSetting)voiceVolume).Value;
undoNextAudioConfig = false;
configChangeFromSelf = true;
__instance.ApplyConfiguration(val);
__instance.SaveConfiguration();
}
else if (!configChangeFromSelf)
{
((ModSetting)masterVolume).SavedValueChanged -= masterVolumeChanged;
((ModSetting)sfxVolume).SavedValueChanged -= sfxVolumeChanged;
((ModSetting)musicVolume).SavedValueChanged -= musicVolumeChanged;
((ModSetting)voiceVolume).SavedValueChanged -= voiceVolumeChanged;
masterSlider.ValueChanged -= masterSliderChanged;
sfxSlider.ValueChanged -= sfxSliderChanged;
musicSlider.ValueChanged -= musicSliderChanged;
voiceSlider.ValueChanged -= voiceSliderChanged;
((ModSetting)masterVolume).SavedValue = config.MasterVolume;
((ModSetting)sfxVolume).SavedValue = config.SFXVolume;
((ModSetting)musicVolume).SavedValue = config.MusicVolume;
((ModSetting)voiceVolume).SavedValue = config.VoiceVolume;
masterSlider.Value = config.MasterVolume;
sfxSlider.Value = config.SFXVolume;
musicSlider.Value = config.MusicVolume;
voiceSlider.Value = config.VoiceVolume;
((ModSetting)masterVolume).SavedValueChanged += masterVolumeChanged;
((ModSetting)sfxVolume).SavedValueChanged += sfxVolumeChanged;
((ModSetting)musicVolume).SavedValueChanged += musicVolumeChanged;
((ModSetting)voiceVolume).SavedValueChanged += voiceVolumeChanged;
masterSlider.ValueChanged += masterSliderChanged;
sfxSlider.ValueChanged += sfxSliderChanged;
musicSlider.ValueChanged += musicSliderChanged;
voiceSlider.ValueChanged += voiceSliderChanged;
((ModSetting)masterVolume).Value = config.MasterVolume;
((ModSetting)sfxVolume).Value = config.SFXVolume;
((ModSetting)musicVolume).Value = config.MusicVolume;
((ModSetting)voiceVolume).Value = config.VoiceVolume;
UI.instance.ForceRefresh();
}
else
{
configChangeFromSelf = false;
}
}
}
private static float boostFactor = 4f;
private static float individualVolumeLimit = 2f;
private static string individualVolumesPath = "UserData/SettingsUI/IndividualVolumes.txt";
private static bool doneInit = false;
private static bool undoNextAudioConfig = false;
private static bool configChangeFromSelf = false;
private static SettingsForm settingsForm;
private static Mod audioSettings = new Mod();
private static ModSetting<float> masterVolume;
private static ModSetting<float> sfxVolume;
private static ModSetting<float> musicVolume;
private static ModSetting<float> voiceVolume;
private static Setting masterSlider;
private static Setting sfxSlider;
private static Setting musicSlider;
private static Setting voiceSlider;
private static Setting individualVolumeSlider;
private static Dictionary<string, float> individualVolumes = new Dictionary<string, float>();
private static string opponentName = "";
private static bool doSave = false;
public override void OnLateInitializeMelon()
{
UI.instance.UI_Initialized += OnUIInit;
LoadIndividualVolumes();
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
if (!doneInit && Singleton<AudioManager>.instance.ConfigLoaded)
{
Tags val = new Tags
{
DoNotSave = true
};
audioSettings.ModName = "SettingsUI";
audioSettings.ModVersion = "1.3.0";
audioSettings.SetFolder("SettingsUI");
AudioConfiguration audioConfig = Singleton<AudioManager>.instance.audioConfig;
masterVolume = audioSettings.AddToList("Master Volume", audioConfig.MasterVolume, "Master volume. 0-1 covers the normal range. >1 allows boosting beyond the normal volume limit.", val);
sfxVolume = audioSettings.AddToList("SFX Volume", audioConfig.SFXVolume, "Sound effects volume. 0-1 covers the normal range. >1 allows boosting beyond the normal volume limit.", val);
musicVolume = audioSettings.AddToList("Music Volume", audioConfig.MusicVolume, "Music volume. 0-1 covers the normal range. >1 allows boosting beyond the normal volume limit.", val);
voiceVolume = audioSettings.AddToList("Voice Volume", audioConfig.VoiceVolume, "Voice volume. 0-1 covers the normal range. >1 allows boosting beyond the normal volume limit.", val);
audioSettings.GetFromFile();
((ModSetting)masterVolume).SavedValueChanged += masterVolumeChanged;
((ModSetting)sfxVolume).SavedValueChanged += sfxVolumeChanged;
((ModSetting)musicVolume).SavedValueChanged += musicVolumeChanged;
((ModSetting)voiceVolume).SavedValueChanged += voiceVolumeChanged;
masterSlider = Slider.AddSetting("Master Volume", "Lets you adjust master volume with the arm slider. The slider's range is 0%-400%.", 0f, 1f * boostFactor, audioConfig.MasterVolume, 2);
sfxSlider = Slider.AddSetting("SFX Volume", "Lets you adjust sound effects volume with the arm slider. The slider's range is 0%-400%.", 0f, 1f * boostFactor, audioConfig.SFXVolume, 2);
musicSlider = Slider.AddSetting("Music Volume", "Lets you adjust music volume with the arm slider. The slider's range is 0%-400%.", 0f, 1f * boostFactor, audioConfig.MusicVolume, 2);
voiceSlider = Slider.AddSetting("Global Voice Volume", "Lets you adjust voice chat volume with the arm slider. The slider's range is 0%-400%.", 0f, 1f * boostFactor, audioConfig.VoiceVolume, 2);
individualVolumeSlider = Slider.AddSetting("Individual Voice Volume", "Lets you adjust the volume of individual players' voices. The slider's range is 0%-200%.", 0f, individualVolumeLimit, 1f, 2);
masterSlider.ValueChanged += masterSliderChanged;
sfxSlider.ValueChanged += sfxSliderChanged;
musicSlider.ValueChanged += musicSliderChanged;
voiceSlider.ValueChanged += voiceSliderChanged;
individualVolumeSlider.ValueChanged += individualVolumeSliderChanged;
doneInit = true;
}
if (sceneName == "Gym")
{
settingsForm = Object.FindObjectOfType<SettingsForm>();
if ((Object)(object)settingsForm != (Object)null)
{
undoNextAudioConfig = true;
}
ResetIndividualVolume();
}
else if (sceneName == "Map0" || sceneName == "Map1")
{
if (Singleton<PlayerManager>.instance.AllPlayers.Count >= 2)
{
opponentName = Singleton<PlayerManager>.instance.AllPlayers[1].Data.GeneralData.InternalUsername;
if (individualVolumes.ContainsKey(opponentName))
{
individualVolumeSlider.ValueChanged -= individualVolumeSliderChanged;
individualVolumeSlider.Value = individualVolumes[opponentName];
individualVolumeSlider.ValueChanged += individualVolumeSliderChanged;
}
else
{
individualVolumes[opponentName] = 1f;
individualVolumeSlider.Value = 1f;
}
}
else
{
ResetIndividualVolume();
}
}
else
{
ResetIndividualVolume();
}
}
private static void OnUIInit()
{
UI.instance.AddMod(audioSettings);
}
private static void ChangeSetting(SettingType type, float value)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
AudioConfiguration audioConfig = Singleton<AudioManager>.instance.audioConfig;
switch (type)
{
case SettingType.MasterVolume:
audioConfig.MasterVolume = value;
break;
case SettingType.SFXVolume:
audioConfig.SFXVolume = value;
break;
case SettingType.MusicVolume:
audioConfig.MusicVolume = value;
break;
case SettingType.VoiceVolume:
audioConfig.VoiceVolume = value;
break;
default:
MelonLogger.Warning("Tried to save invalid setting.");
break;
}
configChangeFromSelf = true;
Singleton<AudioManager>.instance.ApplyConfiguration(audioConfig);
Singleton<AudioManager>.instance.SaveConfiguration();
if ((Object)(object)settingsForm != (Object)null)
{
switch (type)
{
case SettingType.MasterVolume:
((InteractionNumericalBase)settingsForm.masterVolumeSlider).MoveToValue(((InteractionNumericalBase)settingsForm.masterVolumeSlider).ConvertToValue(Math.Min(Math.Max(value, 0f), 1f)));
break;
case SettingType.SFXVolume:
((InteractionNumericalBase)settingsForm.effectsVolumeSlider).MoveToValue(((InteractionNumericalBase)settingsForm.effectsVolumeSlider).ConvertToValue(Math.Min(Math.Max(value, 0f), 1f)));
break;
case SettingType.MusicVolume:
((InteractionNumericalBase)settingsForm.musicVolumeSlider).MoveToValue(((InteractionNumericalBase)settingsForm.musicVolumeSlider).ConvertToValue(Math.Min(Math.Max(value, 0f), 1f)));
break;
case SettingType.VoiceVolume:
((InteractionNumericalBase)settingsForm.dialogueVolumeSlider).MoveToValue(((InteractionNumericalBase)settingsForm.dialogueVolumeSlider).ConvertToValue(Math.Min(Math.Max(voiceSlider.Value, 0f), 1f)));
break;
}
}
}
private static void masterVolumeChanged(object sender, EventArgs args)
{
masterSlider.ValueChanged -= masterSliderChanged;
masterSlider.Value = ((ValueChange<float>)(object)args).Value;
masterSlider.ValueChanged += masterSliderChanged;
ChangeSetting(SettingType.MasterVolume, ((ValueChange<float>)(object)args).Value);
}
private static void sfxVolumeChanged(object sender, EventArgs args)
{
sfxSlider.ValueChanged -= sfxSliderChanged;
sfxSlider.Value = ((ValueChange<float>)(object)args).Value;
sfxSlider.ValueChanged += sfxSliderChanged;
ChangeSetting(SettingType.SFXVolume, ((ValueChange<float>)(object)args).Value);
}
private static void musicVolumeChanged(object sender, EventArgs args)
{
musicSlider.ValueChanged -= musicSliderChanged;
musicSlider.Value = ((ValueChange<float>)(object)args).Value;
musicSlider.ValueChanged += musicSliderChanged;
ChangeSetting(SettingType.MusicVolume, ((ValueChange<float>)(object)args).Value);
}
private static void voiceVolumeChanged(object sender, EventArgs args)
{
voiceSlider.ValueChanged -= voiceSliderChanged;
voiceSlider.Value = ((ValueChange<float>)(object)args).Value;
voiceSlider.ValueChanged += voiceSliderChanged;
ChangeSetting(SettingType.VoiceVolume, ((ValueChange<float>)(object)args).Value * (individualVolumes.ContainsKey(opponentName) ? individualVolumes[opponentName] : 1f));
}
private static void masterSliderChanged(object sender, ValueChangedEventArgs args)
{
((ModSetting)masterVolume).SavedValueChanged -= masterVolumeChanged;
((ModSetting)masterVolume).SavedValue = args.Value;
((ModSetting)masterVolume).SavedValueChanged += masterVolumeChanged;
ChangeSetting(SettingType.MasterVolume, args.Value);
((ModSetting)masterVolume).Value = args.Value;
UI.instance.ForceRefresh();
}
private static void sfxSliderChanged(object sender, ValueChangedEventArgs args)
{
((ModSetting)sfxVolume).SavedValueChanged -= sfxVolumeChanged;
((ModSetting)sfxVolume).SavedValue = args.Value;
((ModSetting)sfxVolume).SavedValueChanged += sfxVolumeChanged;
ChangeSetting(SettingType.SFXVolume, args.Value);
((ModSetting)sfxVolume).Value = args.Value;
UI.instance.ForceRefresh();
}
private static void musicSliderChanged(object sender, ValueChangedEventArgs args)
{
((ModSetting)musicVolume).SavedValueChanged -= musicVolumeChanged;
((ModSetting)musicVolume).SavedValue = args.Value;
((ModSetting)musicVolume).SavedValueChanged += musicVolumeChanged;
ChangeSetting(SettingType.MusicVolume, args.Value);
((ModSetting)musicVolume).Value = args.Value;
UI.instance.ForceRefresh();
}
private static void voiceSliderChanged(object sender, ValueChangedEventArgs args)
{
((ModSetting)voiceVolume).SavedValueChanged -= voiceVolumeChanged;
((ModSetting)voiceVolume).SavedValue = args.Value;
((ModSetting)voiceVolume).SavedValueChanged += voiceVolumeChanged;
ChangeSetting(SettingType.VoiceVolume, args.Value * (individualVolumes.ContainsKey(opponentName) ? individualVolumes[opponentName] : 1f));
((ModSetting)voiceVolume).Value = args.Value;
UI.instance.ForceRefresh();
}
private static void individualVolumeSliderChanged(object sender, ValueChangedEventArgs args)
{
if (opponentName != "")
{
ChangeSetting(SettingType.VoiceVolume, (float)((ModSetting)voiceVolume).SavedValue * args.Value);
individualVolumes[opponentName] = args.Value;
doSave = true;
MelonCoroutines.Start(ScheduleSaveIndividualVolumes());
}
}
private static void ResetIndividualVolume()
{
opponentName = "";
if (individualVolumeSlider != null)
{
individualVolumeSlider.ValueChanged -= individualVolumeSliderChanged;
individualVolumeSlider.Value = 1f;
individualVolumeSlider.ValueChanged += individualVolumeSliderChanged;
}
}
private static void LoadIndividualVolumes()
{
if (File.Exists(individualVolumesPath))
{
string[] array = File.ReadAllLines(individualVolumesPath);
individualVolumes.Clear();
string[] array2 = array;
foreach (string text in array2)
{
string[] array3 = text.Split(new char[1] { '=' });
if (array3.Length == 2 && float.TryParse(array3[1], out var result))
{
individualVolumes[array3[0]] = result;
}
}
}
else
{
MelonLogger.Msg("Individual volumes file not found. A new one will be created if needed.");
}
}
private static IEnumerator ScheduleSaveIndividualVolumes()
{
yield return (object)new WaitForSeconds(1f);
if (doSave)
{
SaveIndividualVolumes();
doSave = false;
}
}
private static void SaveIndividualVolumes()
{
List<string> list = new List<string>();
foreach (KeyValuePair<string, float> individualVolume in individualVolumes)
{
list.Add(individualVolume.Key + "=" + individualVolume.Value);
}
try
{
File.WriteAllLines(individualVolumesPath, list);
}
catch (Exception ex)
{
MelonLogger.Error("Failed to save individual volumes:\n" + ex);
}
}
}