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.Cryptography;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using NAudio.Wave;
using Newtonsoft.Json;
using Photon.Pun;
using Photon.Voice.Unity;
using REPOSoundBoard.Config;
using REPOSoundBoard.Core;
using REPOSoundBoard.Core.Exceptions;
using REPOSoundBoard.Core.Hotkeys;
using REPOSoundBoard.Core.Media;
using REPOSoundBoard.Core.Media.Converter;
using REPOSoundBoard.Patches;
using REPOSoundBoard.UI;
using REPOSoundBoard.UI.Components;
using REPOSoundBoard.UI.Utils;
using UnityEngine;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("REPOSoundBoard")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ddae80319bf38fc5190635a3e7c05f831b16ba45")]
[assembly: AssemblyProduct("REPOSoundBoard")]
[assembly: AssemblyTitle("REPOSoundBoard")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace REPOSoundBoard
{
[BepInPlugin("com.moli.repo-soundboard", "REPOSoundBoard", "0.2.0")]
public class REPOSoundBoard : BaseUnityPlugin
{
public const string GUID = "com.moli.repo-soundboard";
public const string NAME = "REPOSoundBoard";
public const string VERSION = "0.2.0";
private static readonly Harmony _harmony = new Harmony("com.moli.repo-soundboard");
public static ManualLogSource Logger;
public HotkeyManager HotkeyManager;
public SoundBoard SoundBoard;
public SoundBoardUI UI;
public static REPOSoundBoard Instance { get; private set; }
public AppConfig Config { get; private set; }
private void Awake()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
if (!((Object)(object)Instance != (Object)null))
{
Instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
Config = AppConfig.LoadConfig();
GameObject val = new GameObject("REPOSoundBoardMod");
((Object)val).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)val);
HotkeyManager = val.AddComponent<HotkeyManager>();
SoundBoard = val.AddComponent<SoundBoard>();
SoundBoard.LoadConfig(Config.SoundBoard);
UI = val.AddComponent<SoundBoardUI>();
Config.UiHotkey.OnPressed(delegate
{
UI.Visible = !UI.Visible;
});
HotkeyManager.RegisterHotkey(Config.UiHotkey);
_harmony.PatchAll(typeof(ChatManagerPatch));
_harmony.PatchAll(typeof(PlayerVoiceChatPatch));
_harmony.PatchAll(typeof(MenuCursorPatch));
}
}
public void SaveConfig()
{
SoundBoardConfig soundBoardConfig = new SoundBoardConfig();
soundBoardConfig.Enabled = SoundBoard.Instance.Enabled;
soundBoardConfig.StopHotkey = SoundBoard.Instance.StopHotkey;
foreach (SoundButton soundButton in SoundBoard.Instance.SoundButtons)
{
soundBoardConfig.SoundButtons.Add(soundButton.CreateConfig());
}
Config.SoundBoard = soundBoardConfig;
Config.SaveToFile();
}
}
}
namespace REPOSoundBoard.UI
{
public class SoundBoardUI : MonoBehaviour
{
public static SoundBoardUI Instance;
private bool _isVisible;
private const float DefaultWindowGap = 20f;
private IMGUIWindow _generalSettingsWindow;
private GeneralSettingsUI _generalSettingsUI;
private const float GeneralSettingsWindowWidth = 340f;
private const float GeneralSettingsWindowHeight = 60f;
private IMGUIWindow _soundButtonsWindow;
private SoundButtonsUI _soundButtonsUI;
private const float SoundButtonsWindowWidth = 600f;
private const float SoundButtonsWindowHeight = 650f;
public bool Visible
{
get
{
return _isVisible;
}
set
{
_isVisible = value;
if (_isVisible)
{
UnlockCursor();
}
else
{
LockCursor();
}
}
}
public void Start()
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
float num = 960f;
float num2 = Mathf.Max(60f, 650f);
_generalSettingsUI = new GeneralSettingsUI();
_generalSettingsWindow = new IMGUIWindow("General Settings", new Rect(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, 340f, 60f), delegate
{
_generalSettingsUI.Draw();
});
_soundButtonsUI = new SoundButtonsUI();
_soundButtonsWindow = new IMGUIWindow("Sound Buttons", new Rect(((float)Screen.width - num) / 2f + 340f + 20f, ((float)Screen.height - num2) / 2f, 600f, 650f), delegate
{
_soundButtonsUI.Draw();
});
}
private void Update()
{
if (Visible)
{
InputManager.instance.DisableAiming();
InputManager.instance.DisableMovement();
}
}
private void OnGUI()
{
if (_isVisible)
{
Cursor.lockState = (CursorLockMode)0;
Cursor.visible = true;
_generalSettingsWindow.Draw();
_soundButtonsWindow.Draw();
}
}
private void UnlockCursor()
{
MenuCursorPatch.HideInGameCursor = true;
Cursor.lockState = (CursorLockMode)0;
Cursor.visible = true;
}
private void LockCursor()
{
MenuCursorPatch.HideInGameCursor = false;
Cursor.lockState = (CursorLockMode)1;
Cursor.visible = false;
}
private void OnDestroy()
{
REPOSoundBoard.Instance.SaveConfig();
}
}
}
namespace REPOSoundBoard.UI.Utils
{
public static class HotkeySelectorUtils
{
private static readonly List<KeyCode> _disallowedKeys;
public static List<KeyCode> PossibleKeys { get; }
static HotkeySelectorUtils()
{
_disallowedKeys = new List<KeyCode>
{
(KeyCode)323,
(KeyCode)324,
(KeyCode)311,
(KeyCode)312,
(KeyCode)310,
(KeyCode)309
};
PossibleKeys = UnityInput.Current.SupportedKeyCodes.Where((KeyCode code) => !_disallowedKeys.Contains(code)).ToList();
}
public static List<KeyCode> GetPressedKeys()
{
return ((IEnumerable<KeyCode>)PossibleKeys).Where((Func<KeyCode, bool>)Input.GetKey).ToList();
}
}
public class IMGUITabs
{
private string[] tabs;
private int selectedTab;
private Action<int>[] tabContents;
private GUIStyle tabStyle;
private GUIStyle activeTabStyle;
public int SelectedTab => selectedTab;
public IMGUITabs(string[] tabs, Action<int>[] tabContents)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
this.tabs = tabs;
this.tabContents = tabContents;
tabStyle = new GUIStyle(GUI.skin.button);
activeTabStyle = new GUIStyle(GUI.skin.button);
activeTabStyle.normal.background = activeTabStyle.active.background;
}
public void SetStyles(GUIStyle tabStyle, GUIStyle activeTabStyle)
{
this.tabStyle = tabStyle;
this.activeTabStyle = activeTabStyle;
}
public void Draw()
{
IMGUIUtils.HorizontalGroup(delegate
{
for (int i = 0; i < tabs.Length; i++)
{
bool flag = i == selectedTab;
if (GUILayout.Button(tabs[i], flag ? activeTabStyle : tabStyle, Array.Empty<GUILayoutOption>()))
{
selectedTab = i;
}
}
});
IMGUIUtils.BoxGroup(delegate
{
if (selectedTab >= 0 && selectedTab < tabContents.Length)
{
tabContents[selectedTab]?.Invoke(selectedTab);
}
});
}
}
public class IMGUIUtils
{
public static readonly GUIStyle DisabledTextStyle;
public static readonly GUIStyle HeadingStyle;
static IMGUIUtils()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected O, but got Unknown
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
DisabledTextStyle = GUI.skin.label;
DisabledTextStyle.normal.textColor = new Color(120f, 120f, 120f);
HeadingStyle = new GUIStyle(GUI.skin.label);
HeadingStyle.normal.textColor = Color.white;
HeadingStyle.fontSize = 15;
}
public static void HorizontalGroup(Action guiAction)
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
guiAction?.Invoke();
GUILayout.EndHorizontal();
}
public static void VerticalGroup(Action guiAction)
{
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
guiAction?.Invoke();
GUILayout.EndVertical();
}
public static Vector2 ScrollGroup(Vector2 scrollPosition, Action guiAction, GUIStyle style = null)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
Vector2 result = GUILayout.BeginScrollView(scrollPosition, style ?? GUI.skin.scrollView);
guiAction?.Invoke();
GUILayout.EndScrollView();
return result;
}
public static void BoxGroup(Action guiAction, GUIStyle style = null)
{
GUILayout.BeginVertical(style ?? GUI.skin.box, Array.Empty<GUILayoutOption>());
guiAction?.Invoke();
GUILayout.EndVertical();
}
public static void AreaGroup(Rect rect, Action guiAction)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginArea(rect);
guiAction?.Invoke();
GUILayout.EndArea();
}
public static void WithColor(Color color, Action guiAction)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
Color color2 = GUI.color;
GUI.color = color;
guiAction?.Invoke();
GUI.color = color2;
}
public static void WithContentColor(Color color, Action guiAction)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
Color contentColor = GUI.contentColor;
GUI.contentColor = color;
guiAction?.Invoke();
GUI.contentColor = contentColor;
}
public static void WithBackgroundColor(Color color, Action guiAction)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
Color backgroundColor = GUI.backgroundColor;
GUI.backgroundColor = color;
guiAction?.Invoke();
GUI.backgroundColor = backgroundColor;
}
public static void WithEnabled(bool enabled, Action guiAction)
{
bool enabled2 = GUI.enabled;
GUI.enabled = enabled;
guiAction?.Invoke();
GUI.enabled = enabled2;
}
public static float LabeledSlider(string label, float value, float leftValue, float rightValue)
{
HorizontalGroup(delegate
{
GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.ExpandWidth(false),
GUILayout.Height(20f)
});
value = GUILayout.HorizontalSlider(value, leftValue, rightValue, Array.Empty<GUILayoutOption>());
GUILayout.Label(value.ToString("F2"), (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Width(50f),
GUILayout.Height(20f)
});
});
return value;
}
public static string LabeledTextField(string label, string text)
{
HorizontalGroup(delegate
{
GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
text = GUILayout.TextField(text, Array.Empty<GUILayoutOption>());
});
return text;
}
public static bool LabeledToggle(string label, bool value)
{
HorizontalGroup(delegate
{
GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
value = GUILayout.Toggle(value, "", Array.Empty<GUILayoutOption>());
});
return value;
}
public static bool LabeledHotkeyInput(string label, Hotkey hotkey, bool selecting)
{
HorizontalGroup(delegate
{
GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
if (!selecting)
{
if (hotkey.Keys.Count == 0)
{
GUILayout.Label("No hotkey selected", DisabledTextStyle, Array.Empty<GUILayoutOption>());
}
else
{
GUILayout.Label(string.Join(" + ", hotkey.Keys), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
}
if (GUILayout.Button("Change", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
selecting = true;
GUIUtility.keyboardControl = 0;
}
}
else
{
if (HotkeySelectorUtils.GetPressedKeys().Count == 0)
{
GUILayout.Label("Start pressing keys...", DisabledTextStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
}
else
{
GUILayout.Label(string.Join(" + ", HotkeySelectorUtils.GetPressedKeys()), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
if (GUILayout.Button("Apply", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
hotkey.Keys = HotkeySelectorUtils.GetPressedKeys();
selecting = false;
}
}
if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
selecting = false;
}
}
});
return selecting;
}
public static string LabeledPathInput(string label, string originalPath, string inputPath, ref bool changing, Action<string> pathChanged)
{
bool localChanging = changing;
HorizontalGroup(delegate
{
GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
if (!localChanging)
{
GUILayout.Label(originalPath, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
if (GUILayout.Button("Change", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
localChanging = true;
}
}
else
{
inputPath = GUILayout.TextField(inputPath.Replace("\"", ""), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
if (GUILayout.Button("Apply", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
pathChanged?.Invoke(inputPath);
localChanging = false;
}
if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
inputPath = originalPath;
localChanging = false;
}
}
});
changing = localChanging;
return inputPath;
}
public static bool ConfirmButton(string buttonText, string confirmationText, ref bool confirmationShown)
{
bool result = false;
bool localConfirmationShown = confirmationShown;
if (!localConfirmationShown)
{
if (GUILayout.Button(buttonText, Array.Empty<GUILayoutOption>()))
{
localConfirmationShown = true;
}
}
else
{
HorizontalGroup(delegate
{
GUILayout.Label(confirmationText, Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Yes", Array.Empty<GUILayoutOption>()))
{
result = true;
localConfirmationShown = false;
}
if (GUILayout.Button("No", Array.Empty<GUILayoutOption>()))
{
localConfirmationShown = false;
}
});
}
confirmationShown = localConfirmationShown;
return result;
}
}
public class IMGUIWindow
{
private Rect _windowRect;
private string _title;
private Action<int> _drawContent;
private bool _isDraggable = true;
private int _id;
private static int _nextId;
public Rect WindowRect => _windowRect;
public IMGUIWindow(string title, Rect initialRect, Action<int> drawContent)
{
//IL_0015: 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)
_title = title;
_windowRect = initialRect;
_drawContent = drawContent;
_id = _nextId++;
}
public void SetDraggable(bool isDraggable)
{
_isDraggable = isDraggable;
}
public void Draw()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
//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)
if (_isDraggable)
{
_windowRect = GUILayout.Window(_id, _windowRect, new WindowFunction(WindowFunction), _title, Array.Empty<GUILayoutOption>());
return;
}
IMGUIUtils.AreaGroup(_windowRect, delegate
{
GUILayout.Label(_title, GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
_drawContent?.Invoke(_id);
});
}
private void WindowFunction(int windowId)
{
_drawContent?.Invoke(windowId);
if (_isDraggable)
{
GUI.DragWindow();
}
}
}
}
namespace REPOSoundBoard.UI.Components
{
public class GeneralSettingsUI
{
private bool _selectionStopHotkey;
public void Draw()
{
SoundBoard.Instance.Enabled = IMGUIUtils.LabeledToggle("Global enabled:", SoundBoard.Instance.Enabled);
_selectionStopHotkey = IMGUIUtils.LabeledHotkeyInput("Stop hotkey:", SoundBoard.Instance.StopHotkey, _selectionStopHotkey);
IMGUIUtils.HorizontalGroup(delegate
{
if (GUILayout.Button("Save changes", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
{
REPOSoundBoard.Instance.SaveConfig();
}
if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
{
SoundBoardUI.Instance.Visible = false;
}
});
}
}
public class SoundButtonsUI
{
private string _search = string.Empty;
private Vector2 _scrollPosition = Vector2.zero;
private List<SoundButtonUI> _soundButtonUis;
private SoundButtonUI _buttonToDelete;
public SoundButtonsUI()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
_soundButtonUis = SoundBoard.Instance.SoundButtons.Select(delegate(SoundButton button)
{
SoundButtonUI soundButtonUI = new SoundButtonUI(button);
soundButtonUI.OnDeleteClicked += HandleDeleteButtonPress;
return soundButtonUI;
}).ToList();
}
private void HandleDeleteButtonPress(SoundButtonUI buttonUI)
{
_buttonToDelete = buttonUI;
}
private void HandleCurrentDeletion()
{
if (_buttonToDelete != null)
{
_soundButtonUis.Remove(_buttonToDelete);
SoundBoard.Instance.RemoveSoundButton(_buttonToDelete.SoundButton);
}
}
public void Draw()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
HandleCurrentDeletion();
_search = IMGUIUtils.LabeledTextField("Search:", _search).ToLower();
_scrollPosition = IMGUIUtils.ScrollGroup(_scrollPosition, delegate
{
foreach (SoundButtonUI item in _soundButtonUis.Where((SoundButtonUI buttonUI) => buttonUI.SoundButton.Name.ToLower().Contains(_search)))
{
item.Draw();
}
});
if (GUILayout.Button("Add new sound button", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
{
SoundButton soundButton = new SoundButton();
SoundButtonUI soundButtonUI = new SoundButtonUI(soundButton, editing: true);
soundButtonUI.OnDeleteClicked += HandleDeleteButtonPress;
SoundBoard.Instance.AddSoundButton(soundButton);
_soundButtonUis.Insert(0, soundButtonUI);
}
}
}
public class SoundButtonUI
{
private static GUIStyle _pathStyle;
private static GUIStyle _disabledButtonLabelStyle;
private bool _isEditing;
private bool _isEditingHotkey;
private bool _changingPath;
private string _pathInput;
private static GUIStyle PathStyle
{
get
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
if (_pathStyle == null)
{
_pathStyle = new GUIStyle(GUI.skin.label);
_pathStyle.normal.textColor = new Color(0.6f, 0.6f, 0.6f);
_pathStyle.fontStyle = (FontStyle)2;
_pathStyle.fontSize = 12;
}
return _pathStyle;
}
}
private static GUIStyle DisabledButtonLabelStyle
{
get
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
if (_disabledButtonLabelStyle == null)
{
_disabledButtonLabelStyle = new GUIStyle(GUI.skin.label);
_disabledButtonLabelStyle.normal.textColor = new Color(0.6f, 0.6f, 0.6f);
}
return _disabledButtonLabelStyle;
}
}
public SoundButton SoundButton { get; }
[CanBeNull]
public event Action<SoundButtonUI> OnDeleteClicked;
public SoundButtonUI(SoundButton soundButton, bool editing = false)
{
SoundButton = soundButton;
_isEditing = editing;
_pathInput = SoundButton.Clip?.OriginalPath ?? string.Empty;
}
public void Draw()
{
IMGUIUtils.BoxGroup(delegate
{
DrawState();
if (!_isEditing)
{
DrawDetailUI();
}
else
{
DrawEditUI();
}
});
}
private static Color GetStateColor(MediaClip.MediaClipState state)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//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)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: 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_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
return (Color)(state switch
{
MediaClip.MediaClipState.Idle => Color.white,
MediaClip.MediaClipState.Converting => Color.yellow,
MediaClip.MediaClipState.Converted => Color.white,
MediaClip.MediaClipState.FailedToConvert => Color.red,
MediaClip.MediaClipState.Loading => Color.cyan,
MediaClip.MediaClipState.Loaded => Color.green,
MediaClip.MediaClipState.FailedToLoad => Color.red,
_ => Color.white,
});
}
private void DrawState()
{
if (SoundButton.Clip != null && SoundButton.Clip.State != MediaClip.MediaClipState.Loaded)
{
IMGUIUtils.HorizontalGroup(delegate
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
GUILayout.Label("State:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
GUIStyle val = new GUIStyle(GUI.skin.label);
val.normal.textColor = GetStateColor(SoundButton.Clip.State);
GUILayout.Label(SoundButton.Clip.StateMessage, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
});
}
}
private void DrawDetailUI()
{
IMGUIUtils.HorizontalGroup(delegate
{
if (SoundButton.Enabled)
{
GUILayout.Label(SoundButton.Name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
}
else
{
GUILayout.Label(SoundButton.Name + " [disabled]", DisabledButtonLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
}
if (GUILayout.Button((SoundButton.Hotkey.Keys.Count == 0) ? "[no hotkey]" : string.Join(" + ", SoundButton.Hotkey.Keys), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
{
SoundBoard.Instance.Play(SoundButton, ignoreEnabledChecks: true);
}
if (GUILayout.Button("Edit", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }))
{
_isEditing = true;
}
if (GUILayout.Button("Delete", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
this.OnDeleteClicked?.Invoke(this);
}
});
if (SoundButton.Clip == null)
{
GUILayout.Label("No file selected...", PathStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
}
else
{
GUILayout.Label(SoundButton.Clip.OriginalPath, PathStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
}
}
private void DrawEditUI()
{
IMGUIUtils.VerticalGroup(delegate
{
SoundButton.Name = IMGUIUtils.LabeledTextField("Name:", SoundButton.Name);
_isEditingHotkey = IMGUIUtils.LabeledHotkeyInput("Hotkey:", SoundButton.Hotkey, _isEditingHotkey);
SoundButton.Enabled = IMGUIUtils.LabeledToggle("Enabled:", SoundButton.Enabled);
SoundButton.Volume = IMGUIUtils.LabeledSlider("Volume:", SoundButton.Volume, 0f, 1f);
_pathInput = IMGUIUtils.LabeledPathInput("Path:", SoundButton.Clip?.OriginalPath ?? string.Empty, _pathInput, ref _changingPath, OnPathChanged);
if (GUILayout.Button("Done", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
{
_isEditing = false;
}
});
}
private void OnPathChanged(string path)
{
if (SoundButton.Clip != null)
{
SoundButton.Clip.DeleteCacheFile();
}
SoundButton.Clip = new MediaClip(path);
((MonoBehaviour)SoundBoard.Instance).StartCoroutine(SoundButton.LoadClip());
}
}
}
namespace REPOSoundBoard.Patches
{
public static class ChatManagerPatch
{
[HarmonyPatch(typeof(ChatManager), "StateInactive")]
[HarmonyPrefix]
public static bool BeforeStateInactive(ref string ___chatMessage, ref bool ___chatActive)
{
if (SoundBoardUI.Instance.Visible)
{
((SemiUI)ChatUI.instance).Hide();
___chatMessage = "";
___chatActive = false;
return false;
}
return true;
}
}
public class MenuCursorPatch
{
public static bool HideInGameCursor;
[HarmonyPatch(typeof(CursorManager), "Update")]
[HarmonyPrefix]
public static bool BeforeCursorManagerUpdate()
{
return !HideInGameCursor;
}
[HarmonyPatch(typeof(CursorManager), "Unlock")]
[HarmonyPrefix]
public static bool BeforeCursorManagerUnlock()
{
return !HideInGameCursor;
}
}
public class PlayerVoiceChatPatch
{
[HarmonyPatch(typeof(PlayerVoiceChat), "Start")]
[HarmonyPostfix]
public static void PostStart(PlayerVoiceChat __instance, ref Recorder ___recorder, ref PhotonView ___photonView)
{
if (___photonView.IsMine)
{
REPOSoundBoard.Instance.SoundBoard.ChangeRecorder(___recorder);
}
}
}
}
namespace REPOSoundBoard.Core
{
public class SoundBoard : MonoBehaviour
{
[CompilerGenerated]
private sealed class <StopAfterEnd>d__20 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public SoundButton soundButton;
public SoundBoard <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <StopAfterEnd>d__20(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
int num = <>1__state;
SoundBoard soundBoard = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
if (soundButton.Clip == null)
{
return false;
}
<>2__current = (object)new WaitForSeconds(soundButton.Clip.AudioClip.length);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
soundBoard.StopCurrent();
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public static SoundBoard Instance;
public Hotkey StopHotkey;
private Recorder _recorder;
private AudioSource _audioSource;
private bool _isPlaying;
private bool _enabled;
private SoundButton _currentSoundButton;
private Coroutine _stopAfterEndCoroutine;
public List<SoundButton> SoundButtons { get; } = new List<SoundButton>();
public bool Enabled
{
get
{
return _enabled;
}
set
{
_enabled = value;
}
}
private void Start()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
_audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
}
public void LoadConfig(SoundBoardConfig config)
{
_enabled = config.Enabled;
StopHotkey = config.StopHotkey;
StopHotkey.OnPressed(StopCurrent);
REPOSoundBoard.Instance.HotkeyManager.RegisterHotkey(config.StopHotkey);
foreach (SoundButtonConfig soundButton2 in config.SoundButtons)
{
if (soundButton2.Hotkey != null && soundButton2.Path != null)
{
SoundButton soundButton = SoundButton.FromConfig(soundButton2);
((MonoBehaviour)this).StartCoroutine(soundButton.LoadClip());
AddSoundButton(soundButton);
}
}
}
public void AddSoundButton(SoundButton soundButton)
{
soundButton.Hotkey.OnPressed(delegate
{
Play(soundButton);
});
REPOSoundBoard.Instance.HotkeyManager.RegisterHotkey(soundButton.Hotkey);
SoundButtons.Add(soundButton);
string text = ((soundButton.Hotkey != null) ? string.Join(" + ", soundButton.Hotkey.Keys) : "none");
REPOSoundBoard.Logger.LogInfo((object)("Sound Button registered: " + soundButton.Name + ", with hotkey: " + text + " and path: " + soundButton.Clip?.OriginalPath));
}
public void RemoveSoundButton(SoundButton soundButton)
{
SoundButtons.Remove(soundButton);
REPOSoundBoard.Instance.HotkeyManager.UnregisterHotkey(soundButton.Hotkey);
}
public void ChangeRecorder(Recorder recorder)
{
StopCurrent();
_recorder = recorder;
}
public void Play(SoundButton soundButton, bool ignoreEnabledChecks = false)
{
StopCurrent();
if ((ignoreEnabledChecks || (((Behaviour)this).enabled && soundButton.Enabled)) && soundButton.Clip != null && soundButton.Clip.IsReady)
{
_isPlaying = true;
_currentSoundButton = soundButton;
_audioSource.clip = soundButton.Clip.AudioClip;
_audioSource.volume = soundButton.Volume;
_audioSource.Play();
if ((Object)(object)_recorder != (Object)null)
{
_recorder.TransmitEnabled = false;
_recorder.SourceType = (InputSourceType)1;
_recorder.AudioClip = soundButton.Clip.AudioClip;
_recorder.TransmitEnabled = true;
}
_stopAfterEndCoroutine = ((MonoBehaviour)this).StartCoroutine(StopAfterEnd(soundButton));
}
}
[IteratorStateMachine(typeof(<StopAfterEnd>d__20))]
private IEnumerator StopAfterEnd(SoundButton soundButton)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <StopAfterEnd>d__20(0)
{
<>4__this = this,
soundButton = soundButton
};
}
private void StopCurrent()
{
if (_isPlaying)
{
if (_stopAfterEndCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_stopAfterEndCoroutine);
_stopAfterEndCoroutine = null;
}
_audioSource.Stop();
if ((Object)(object)_recorder != (Object)null)
{
_recorder.SourceType = (InputSourceType)0;
_recorder.AudioClip = null;
_recorder.TransmitEnabled = true;
}
_isPlaying = false;
_currentSoundButton = null;
}
}
}
public class SoundButton
{
public string Name;
public bool Enabled;
public float Volume;
public Hotkey Hotkey;
[CanBeNull]
public MediaClip Clip;
public SoundButton()
{
Name = string.Empty;
Enabled = true;
Volume = 1f;
Hotkey = new Hotkey();
}
public static SoundButton FromConfig(SoundButtonConfig config)
{
return new SoundButton
{
Name = config.Name,
Enabled = config.Enabled,
Volume = config.Volume,
Hotkey = config.Hotkey,
Clip = new MediaClip(config.Path)
};
}
public SoundButtonConfig CreateConfig()
{
return new SoundButtonConfig
{
Name = Name,
Volume = Volume,
Hotkey = Hotkey,
Path = Clip?.OriginalPath,
Enabled = Enabled
};
}
public IEnumerator LoadClip()
{
return Clip?.Load();
}
}
}
namespace REPOSoundBoard.Core.Media
{
public static class CacheFileHelper
{
private static readonly string CacheDirectory = Path.Combine(Paths.PluginPath, "Moli-REPOSoundBoard-0.2.0/_cache");
public static void DeleteFromCache(string fileName)
{
File.Delete(Path.Combine(CacheDirectory, fileName));
}
public static string GetFullCachePath(string cacheFileName)
{
return Path.Combine(CacheDirectory, cacheFileName);
}
public static bool ExistsInCache(string cacheFileName)
{
return File.Exists(GetFullCachePath(cacheFileName));
}
public static string GetCacheFilePath(string originalFilePath, string cacheExtension = ".cache")
{
return Path.Combine(CacheDirectory, GetCacheFileName(originalFilePath, cacheExtension));
}
public static void EnsureCacheDirectoryExists()
{
if (!Directory.Exists(CacheDirectory))
{
Directory.CreateDirectory(CacheDirectory);
}
}
public static string GetCacheFileName(string originalFilePath, string cacheExtension = ".cache")
{
using SHA256 sHA = SHA256.Create();
byte[] bytes = Encoding.UTF8.GetBytes(originalFilePath);
return BitConverter.ToString(sHA.ComputeHash(bytes)).Replace("-", "").ToLowerInvariant() + cacheExtension;
}
}
public class MediaClip
{
public enum MediaClipState
{
Idle,
Converting,
Converted,
FailedToConvert,
Loading,
Loaded,
FailedToLoad
}
[CompilerGenerated]
private sealed class <Convert>d__30 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public MediaClip <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <Convert>d__30(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
MediaClip CS$<>8__locals0 = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
CS$<>8__locals0.SetState(MediaClipState.Converting, "Converting media file...");
CS$<>8__locals0._conversionComplete = false;
CS$<>8__locals0._conversionException = null;
ThreadPool.QueueUserWorkItem(delegate
{
try
{
IMediaConverter converterForFile = MediaConverterFactory.GetConverterForFile(CS$<>8__locals0.OriginalPath);
if (converterForFile != null)
{
CacheFileHelper.EnsureCacheDirectoryExists();
converterForFile.Convert(CS$<>8__locals0.OriginalPath, CS$<>8__locals0._cachePath, ConversionOptions.Default);
CS$<>8__locals0._isConverted = true;
}
}
catch (Exception conversionException)
{
CS$<>8__locals0._conversionException = conversionException;
}
finally
{
CS$<>8__locals0._conversionComplete = true;
}
});
break;
case 1:
<>1__state = -1;
break;
}
if (!CS$<>8__locals0._conversionComplete)
{
<>2__current = null;
<>1__state = 1;
return true;
}
if (CS$<>8__locals0._conversionException != null)
{
string message = ((CS$<>8__locals0._conversionException is AudioConversionException) ? CS$<>8__locals0._conversionException.Message : "Failed to convert to .wav. Check logs for more information.");
CS$<>8__locals0.SetState(MediaClipState.FailedToConvert, message);
string text = "Failed to convert to .wav. Error " + CS$<>8__locals0._conversionException.Message + ". File: " + CS$<>8__locals0.OriginalPath;
REPOSoundBoard.Logger.LogError((object)text);
return false;
}
if (MediaConverterFactory.GetConverterForFile(CS$<>8__locals0.OriginalPath) == null)
{
CS$<>8__locals0.SetState(MediaClipState.FailedToConvert, "Failed to convert to .wav. Invalid file format.");
REPOSoundBoard.Logger.LogWarning((object)("Unsupported file format: " + CS$<>8__locals0.OriginalPath));
return false;
}
CS$<>8__locals0.SetState(MediaClipState.Converted, "Successfully converted to .wav. Waiting to load...");
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <Load>d__28 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public MediaClip <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <Load>d__28(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
MediaClip mediaClip = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
if (mediaClip.HasError || mediaClip.State == MediaClipState.Loaded)
{
return false;
}
if (!File.Exists(mediaClip.OriginalPath))
{
mediaClip.SetState(MediaClipState.FailedToLoad, "Failed to load. Could not find file.");
return false;
}
if (!mediaClip._isConverted)
{
<>2__current = mediaClip.Convert();
<>1__state = 1;
return true;
}
goto IL_0085;
case 1:
<>1__state = -1;
if (!mediaClip._isConverted)
{
return false;
}
goto IL_0085;
case 2:
{
<>1__state = -1;
return false;
}
IL_0085:
<>2__current = mediaClip.LoadAudioClip();
<>1__state = 2;
return true;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <LoadAudioClip>d__31 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public MediaClip <>4__this;
private UnityWebRequest <www>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadAudioClip>d__31(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<www>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Invalid comparison between Unknown and I4
try
{
int num = <>1__state;
MediaClip mediaClip = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
mediaClip.SetState(MediaClipState.Loading, "Loading clip...");
<www>5__2 = UnityWebRequestMultimedia.GetAudioClip(mediaClip._cachePath, (AudioType)20);
<>1__state = -3;
<>2__current = <www>5__2.SendWebRequest();
<>1__state = 1;
return true;
case 1:
<>1__state = -3;
if ((int)<www>5__2.result == 1)
{
mediaClip.AudioClip = DownloadHandlerAudioClip.GetContent(<www>5__2);
mediaClip.SetState(MediaClipState.Loaded, "Sound button loaded successfully.");
}
else
{
string text = "Failed to load media: " + <www>5__2.error + ". Path: " + mediaClip.OriginalPath + ". Cache Path: " + mediaClip._cachePath;
REPOSoundBoard.Logger.LogError((object)text);
mediaClip.SetState(MediaClipState.FailedToLoad, "Failed to load. Check logs for more information.");
}
<>m__Finally1();
<www>5__2 = null;
return false;
}
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<www>5__2 != null)
{
((IDisposable)<www>5__2).Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private readonly string _cachePath;
private readonly string _cacheFileName;
private bool _isConverted;
private bool _conversionComplete;
private Exception _conversionException;
public MediaClipState State { get; private set; }
public string StateMessage { get; private set; }
public string OriginalPath { get; private set; }
public AudioClip AudioClip { get; private set; }
public bool IsReady => State == MediaClipState.Loaded;
public bool HasError
{
get
{
if (State != MediaClipState.FailedToConvert)
{
return State == MediaClipState.FailedToLoad;
}
return true;
}
}
public MediaClip(string path)
{
OriginalPath = path;
_cacheFileName = CacheFileHelper.GetCacheFileName(path, ".wav");
_cachePath = CacheFileHelper.GetFullCachePath(_cacheFileName);
_isConverted = CacheFileHelper.ExistsInCache(_cacheFileName);
SetState(MediaClipState.Idle, "Waiting for instructions...");
}
public void DeleteCacheFile()
{
CacheFileHelper.DeleteFromCache(_cacheFileName);
SetState(MediaClipState.Idle, "Cache file deleted. Waiting for conversion to start...");
}
[IteratorStateMachine(typeof(<Load>d__28))]
public IEnumerator Load()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <Load>d__28(0)
{
<>4__this = this
};
}
private void SetState(MediaClipState state, string message)
{
State = state;
StateMessage = message;
}
[IteratorStateMachine(typeof(<Convert>d__30))]
private IEnumerator Convert()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <Convert>d__30(0)
{
<>4__this = this
};
}
[IteratorStateMachine(typeof(<LoadAudioClip>d__31))]
private IEnumerator LoadAudioClip()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadAudioClip>d__31(0)
{
<>4__this = this
};
}
}
}
namespace REPOSoundBoard.Core.Media.Converter
{
public class AiffConverter : IMediaConverter
{
public static bool IsCompatible(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
string text = Path.GetExtension(path)?.ToLowerInvariant();
if (!string.IsNullOrEmpty(text))
{
return text == ".aiff";
}
return false;
}
public void Convert(string sourcePath, string targetPath, ConversionOptions options)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
if (!File.Exists(sourcePath))
{
throw new FileNotFoundException("Source file " + sourcePath + " not found");
}
AiffFileReader val = new AiffFileReader(sourcePath);
try
{
MediaFoundationResampler val2 = new MediaFoundationResampler((IWaveProvider)(object)val, new WaveFormat(options.SampleRate, options.BitsPerSample, options.ChannelCount));
val2.ResamplerQuality = 60;
WaveFileWriter.CreateWaveFile(targetPath, (IWaveProvider)(object)val2);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
}
public struct ConversionOptions
{
public int SampleRate;
public int ChannelCount;
public int BitsPerSample;
public string AudioCodec;
public static ConversionOptions Default = new ConversionOptions
{
SampleRate = 48000,
ChannelCount = 1,
BitsPerSample = 16,
AudioCodec = "pcm_s16le"
};
}
public interface IMediaConverter
{
static bool IsCompatible(string path)
{
return false;
}
void Convert(string sourcePath, string targetPath, ConversionOptions options);
}
public static class MediaConverterFactory
{
public static IMediaConverter GetConverterForFile(string path)
{
if (WavConverter.IsCompatible(path))
{
return new WavConverter();
}
if (Mp3Converter.IsCompatible(path))
{
return new Mp3Converter();
}
if (AiffConverter.IsCompatible(path))
{
return new AiffConverter();
}
if (VideoConverter.IsCompatible(path))
{
return new VideoConverter();
}
return null;
}
}
public class Mp3Converter : IMediaConverter
{
public static bool IsCompatible(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
string text = Path.GetExtension(path)?.ToLowerInvariant();
if (!string.IsNullOrEmpty(text))
{
return text == ".mp3";
}
return false;
}
public void Convert(string sourcePath, string targetPath, ConversionOptions options)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
if (!File.Exists(sourcePath))
{
throw new FileNotFoundException("Source file " + sourcePath + " not found");
}
AudioFileReader val = new AudioFileReader(sourcePath);
try
{
MediaFoundationResampler val2 = new MediaFoundationResampler((IWaveProvider)(object)val, new WaveFormat(options.SampleRate, options.BitsPerSample, options.ChannelCount));
val2.ResamplerQuality = 60;
WaveFileWriter.CreateWaveFile(targetPath, (IWaveProvider)(object)val2);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
}
public class VideoConverter : IMediaConverter
{
private static readonly string[] _supportedExtensions = new string[5] { ".mp4", ".webm", ".avi", ".mov", ".ogg" };
private static bool? _isFfmpegInstalled;
private static TimeSpan _ffmpegTimeout = TimeSpan.FromSeconds(30.0);
public static bool IsCompatible(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
string value = Path.GetExtension(path)?.ToLowerInvariant();
if (!string.IsNullOrEmpty(value))
{
return _supportedExtensions.Contains(value);
}
return false;
}
private string BuildFfmpegArguments(string sourcePath, string targetPath, ConversionOptions options)
{
return $"-i \"{sourcePath}\" -vn -acodec {options.AudioCodec} -ar {options.SampleRate} -ac {options.ChannelCount} \"{targetPath}\"";
}
public void Convert(string sourcePath, string targetPath, ConversionOptions options)
{
if (!IsFfmpegInstalled())
{
throw new AudioConversionException("Failed to convert video file. ffmpeg is not installed.");
}
if (!File.Exists(sourcePath))
{
throw new FileNotFoundException("Source file " + sourcePath + " not found");
}
RunFfmpegProcess(sourcePath, targetPath, options);
}
private void RunFfmpegProcess(string sourcePath, string targetPath, ConversionOptions options)
{
string arguments = BuildFfmpegArguments(sourcePath, targetPath, options);
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = arguments,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
using Process process = new Process
{
StartInfo = startInfo
};
StringBuilder errorOutput = new StringBuilder();
process.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
errorOutput.AppendLine(e.Data);
}
};
if (!process.Start())
{
throw new AudioConversionException("Failed to start FFmpeg process");
}
process.BeginErrorReadLine();
process.WaitForExit((int)_ffmpegTimeout.TotalMilliseconds);
if (!process.HasExited)
{
try
{
process.Kill();
}
catch
{
}
throw new AudioConversionException("FFmpeg process timed out");
}
if (process.ExitCode != 0)
{
string arg = errorOutput.ToString();
REPOSoundBoard.Logger.LogError((object)$"FFmpeg exited with error code {process.ExitCode}. Error: {arg}");
throw new AudioConversionException($"FFmpeg failed with exit code {process.ExitCode}: {arg}");
}
if (!File.Exists(targetPath))
{
throw new AudioConversionException("FFmpeg completed but the output file was not created");
}
}
private static bool IsFfmpegInstalled()
{
if (!_isFfmpegInstalled.HasValue)
{
try
{
using Process process = Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = "-version",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
});
if (process == null)
{
_isFfmpegInstalled = false;
}
else
{
process.WaitForExit(2000);
_isFfmpegInstalled = process.ExitCode == 0 || process.ExitCode == 1;
}
}
catch
{
_isFfmpegInstalled = false;
}
}
return _isFfmpegInstalled.Value;
}
}
public class WavConverter : IMediaConverter
{
public static bool IsCompatible(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
string text = Path.GetExtension(path)?.ToLowerInvariant();
if (!string.IsNullOrEmpty(text))
{
return text == ".wav";
}
return false;
}
public void Convert(string sourcePath, string targetPath, ConversionOptions options)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
if (!File.Exists(sourcePath))
{
throw new FileNotFoundException("Source file " + sourcePath + " not found");
}
AudioFileReader val = new AudioFileReader(sourcePath);
try
{
MediaFoundationResampler val2 = new MediaFoundationResampler((IWaveProvider)(object)val, new WaveFormat(options.SampleRate, options.BitsPerSample, options.ChannelCount));
val2.ResamplerQuality = 60;
WaveFileWriter.CreateWaveFile(targetPath, (IWaveProvider)(object)val2);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
}
}
namespace REPOSoundBoard.Core.Hotkeys
{
public class Hotkey
{
[JsonProperty(/*Could not decode attribute arguments.*/)]
public List<KeyCode> Keys { get; set; }
[CanBeNull]
[JsonIgnore]
private Action Callback { get; set; }
[JsonIgnore]
public bool IsPressed { get; set; }
[JsonConstructor]
public Hotkey()
{
Keys = new List<KeyCode>();
}
public Hotkey(KeyCode key, [CanBeNull] Action callback)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Keys = new List<KeyCode> { key };
Callback = callback;
}
public Hotkey(List<KeyCode> keys, [CanBeNull] Action callback)
{
Keys = new List<KeyCode>(keys);
Callback = callback;
}
public Hotkey OnPressed(Action callback)
{
Callback = callback;
return this;
}
public void Trigger()
{
if (Callback != null)
{
Callback();
}
}
public string ConcatKeys()
{
return string.Join(" + ", Keys);
}
}
public class HotkeyManager : MonoBehaviour
{
private List<Hotkey> _hotkeys = new List<Hotkey>();
public void RegisterHotkey(Hotkey hotkey)
{
_hotkeys.Add(hotkey);
}
public void UnregisterHotkey(Hotkey hotkey)
{
_hotkeys.Remove(hotkey);
}
public void Update()
{
foreach (Hotkey hotkey in _hotkeys)
{
if (hotkey.Keys.Count != 0)
{
if (hotkey.IsPressed)
{
HandlePressedHotkey(hotkey);
}
else
{
HandleReleasedHotkey(hotkey);
}
}
}
}
private static void HandlePressedHotkey(Hotkey hotkey)
{
if (hotkey.Keys.Any((KeyCode key) => !Input.GetKey(key)))
{
hotkey.IsPressed = false;
}
}
private static void HandleReleasedHotkey(Hotkey hotkey)
{
if (hotkey.Keys.All((KeyCode key) => Input.GetKey(key)))
{
hotkey.IsPressed = true;
hotkey.Trigger();
}
}
}
}
namespace REPOSoundBoard.Core.Exceptions
{
public class AudioConversionException : Exception
{
public AudioConversionException(string message)
: base(message)
{
}
}
}
namespace REPOSoundBoard.Config
{
public class AppConfig
{
private static string _configFilePath;
public Hotkey UiHotkey;
public SoundBoardConfig SoundBoard;
public AppConfig()
{
_configFilePath = Path.Combine(Paths.ConfigPath, "Moli.REPOSoundBoard.json");
UiHotkey = new Hotkey((KeyCode)285, null);
SoundBoard = new SoundBoardConfig();
}
public static AppConfig LoadConfig()
{
AppConfig result = new AppConfig();
try
{
result = ConfigSerializer.DeserializeConfig(File.ReadAllText(_configFilePath));
return result;
}
catch (Exception ex)
{
REPOSoundBoard.Logger.LogWarning((object)("Failed to read config file" + ex.Message));
return result;
}
}
public void SaveToFile()
{
string contents = ConfigSerializer.SerializeConfig(this);
File.WriteAllText(_configFilePath, contents);
}
}
public class ConfigSerializer
{
public static string SerializeConfig(AppConfig config)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Expected O, but got Unknown
JsonSerializerSettings val = new JsonSerializerSettings
{
Formatting = (Formatting)1,
NullValueHandling = (NullValueHandling)1
};
return JsonConvert.SerializeObject((object)config, val);
}
public static AppConfig DeserializeConfig(string json)
{
return JsonConvert.DeserializeObject<AppConfig>(json);
}
}
public class SoundBoardConfig
{
public bool Enabled = true;
public Hotkey StopHotkey = new Hotkey((KeyCode)104, null);
public List<SoundButtonConfig> SoundButtons = new List<SoundButtonConfig>();
}
public class SoundButtonConfig
{
public string Name;
public bool Enabled = true;
public string Path;
public float Volume = 0.75f;
public Hotkey Hotkey;
}
}