using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Audio;
using BepInEx;
using BepInEx.Logging;
using MenuLib;
using MenuLib.MonoBehaviors;
using MenuLib.Structs;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Photon.Voice;
using Photon.Voice.Unity;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("NatanM")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4f8309492bba3d4fb682253d577fbb5dbba8997f")]
[assembly: AssemblyProduct("RepoSoundboard")]
[assembly: AssemblyTitle("RepoSoundboard")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.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 RepoSoundboard
{
[BepInPlugin("NatanM.RepoSoundboard", "RepoSoundboard", "1.0.2")]
public class RepoSoundboard : BaseUnityPlugin
{
private PlayerVoiceChat? _vc;
internal static RepoSoundboard Instance { get; private set; } = null;
internal static ManualLogSource Logger => Instance._logger;
internal static AudioFormat AudioFormat { get; } = new AudioFormat(48000, 1);
internal static SoundboardLoopback Loopback { get; } = new SoundboardLoopback();
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
private void Awake()
{
Instance = this;
SoundboardPool.Load();
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
RepoSoundboardMenu.Init();
Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
}
private void Update()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_vc == (Object)null)
{
_vc = Object.FindAnyObjectByType<PlayerVoiceChat>();
}
else if ((Object)(object)_vc.recorder != (Object)null && (int)_vc.recorder.SourceType == 0)
{
Logger.LogInfo((object)"Detected native audio source. Overriding...");
InitSoundboard();
}
}
private void OnGUI()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
//IL_0018: 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_0042: Invalid comparison between Unknown and I4
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
Event current = Event.current;
if ((int)current.type == 4)
{
if (RepoSoundboardMenu.IsCapturingHotKey)
{
RepoSoundboardMenu.DispatchHotKey(current.keyCode);
}
else if ((Object)(object)_vc != (Object)null && (int)_vc.recorder.SourceType == 2)
{
SoundboardPool.DispatchHotKey(current.keyCode);
}
}
}
private void InitSoundboard()
{
AudioSource val = ((Component)this).gameObject.AddComponent<AudioSource>();
val.clip = Loopback.Clip;
val.loop = true;
val.volume = 0.35f;
val.Play();
Recorder recorder = _vc.recorder;
recorder.RecordingEnabled = false;
recorder.SourceType = (InputSourceType)2;
recorder.InputFactory = () => (IAudioDesc)(object)new SoundboardMixer(_vc);
Logger.LogInfo((object)"Started recording.");
recorder.RestartRecording();
}
}
public static class RepoSoundboardMenu
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static BuilderDelegate <>9__0_0;
public static ShouldCloseMenuDelegate <>9__1_2;
public static ShouldCloseMenuDelegate <>9__4_8;
internal void <Init>b__0_0(Transform p)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
MenuAPI.CreateREPOButton("Soundboard", (Action)SpawnSoundboardMenu, p, new Vector2(120f, 90f));
}
internal bool <SpawnSoundboardMenu>b__1_2()
{
return true;
}
internal bool <CreateEntryLayout>b__4_8()
{
SoundboardPool.Save();
return true;
}
}
private static SoundboardObject? capturingHotKeyObj;
private static REPOButton? capturingHotKeyBtn;
private static readonly List<REPOElement> entryLayoutElements = new List<REPOElement>();
public static bool IsCapturingHotKey { get; set; }
public static void Init()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
object obj = <>c.<>9__0_0;
if (obj == null)
{
BuilderDelegate val = delegate(Transform p)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
MenuAPI.CreateREPOButton("Soundboard", (Action)SpawnSoundboardMenu, p, new Vector2(120f, 90f));
};
<>c.<>9__0_0 = val;
obj = (object)val;
}
MenuAPI.AddElementToSettingsMenu((BuilderDelegate)obj);
}
private static void SpawnSoundboardMenu()
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Expected O, but got Unknown
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Expected O, but got Unknown
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Expected O, but got Unknown
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Expected O, but got Unknown
SoundboardPool.Save();
if (IsCapturingHotKey)
{
RepoSoundboard.Logger.LogWarning((object)"IsCapturingHotKey didn't properly reset.");
IsCapturingHotKey = false;
}
REPOPopupPage popup = MenuAPI.CreateREPOPopupPage("Soundboard", (PresetSide)0, false, true, 0f);
popup.scrollView.scrollSpeed = 3f;
REPOPopupPage obj = popup;
Padding maskPadding = popup.maskPadding;
maskPadding.top = 35f;
obj.maskPadding = maskPadding;
REPOPopupPage obj2 = popup;
ShouldCloseMenuDelegate onEscapePressed = obj2.onEscapePressed;
object obj3 = <>c.<>9__1_2;
if (obj3 == null)
{
ShouldCloseMenuDelegate val = () => true;
<>c.<>9__1_2 = val;
obj3 = (object)val;
}
obj2.onEscapePressed = (ShouldCloseMenuDelegate)Delegate.Combine((Delegate?)(object)onEscapePressed, (Delegate?)obj3);
CreateCfgLayout(popup);
popup.AddElement((BuilderDelegate)delegate(Transform p)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
MenuAPI.CreateREPOButton("Back", (Action)delegate
{
popup.ClosePage(true);
}, p, new Vector2(66f, 10f));
});
popup.AddElement((BuilderDelegate)delegate(Transform p)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
MenuAPI.CreateREPOButton("Add", (Action)delegate
{
SoundboardObject entry = SoundboardPool.Add(new SoundboardObject
{
Name = "New Sound"
});
popup.ClosePage(true);
OpenMenuForEntry(entry);
}, p, new Vector2(150f, 10f));
});
popup.OpenPage(false);
}
private static void CreateCfgLayout(REPOPopupPage popup)
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
REPOPopupPage popup2 = popup;
for (int i = 0; i < SoundboardPool.Count; i++)
{
SoundboardObject entry = SoundboardPool.Get(i);
popup2.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform p)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
REPOButton val = MenuAPI.CreateREPOButton(entry.Name, (Action)delegate
{
popup2.ClosePage(false);
OpenMenuForEntry(entry);
}, p, default(Vector2));
return ((REPOElement)val).rectTransform;
}, 0f, 0f);
}
}
private static void OpenMenuForEntry(SoundboardObject entry)
{
//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_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Expected O, but got Unknown
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Expected O, but got Unknown
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected O, but got Unknown
REPOPopupPage popup = MenuAPI.CreateREPOPopupPage("Entry Settings", (PresetSide)0, false, true, 0f);
popup.scrollView.scrollSpeed = 3f;
REPOPopupPage obj = popup;
Padding maskPadding = popup.maskPadding;
maskPadding.top = 35f;
obj.maskPadding = maskPadding;
REPOPopupPage obj2 = popup;
obj2.onEscapePressed = (ShouldCloseMenuDelegate)Delegate.Combine((Delegate?)(object)obj2.onEscapePressed, (Delegate?)(ShouldCloseMenuDelegate)delegate
{
if (IsCapturingHotKey)
{
return false;
}
SpawnSoundboardMenu();
popup.ClosePage(true);
return false;
});
CreateEntryLayout(popup, entry);
popup.AddElement((BuilderDelegate)delegate(Transform p)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
REPOButton item = MenuAPI.CreateREPOButton("Back", (Action)delegate
{
popup.ClosePage(true);
SpawnSoundboardMenu();
}, p, new Vector2(66f, 10f));
entryLayoutElements.Add((REPOElement)(object)item);
});
popup.OpenPage(false);
}
private static void CreateEntryLayout(REPOPopupPage popup, SoundboardObject entry)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Expected O, but got Unknown
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Expected O, but got Unknown
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Expected O, but got Unknown
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Expected O, but got Unknown
SoundboardObject entry2 = entry;
REPOPopupPage popup2 = popup;
entryLayoutElements.Clear();
entry2.Stop();
popup2.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform p)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
REPOInputField val4 = MenuAPI.CreateREPOInputField("Name", (Action<string>)delegate(string s)
{
entry2.Name = s;
}, p, default(Vector2), false, "", "");
val4.inputStringSystem.SetValue(entry2.Name, false);
entryLayoutElements.Add((REPOElement)(object)val4);
return ((REPOElement)val4).rectTransform;
}, 0f, 0f);
popup2.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform p)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
REPOInputField val3 = MenuAPI.CreateREPOInputField("Path", (Action<string>)delegate(string s)
{
entry2.Path = s;
}, p, default(Vector2), false, "", "");
val3.inputStringSystem.SetValue(entry2.Path, false);
entryLayoutElements.Add((REPOElement)(object)val3);
return ((REPOElement)val3).rectTransform;
}, 0f, 0f);
popup2.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform p)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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_003b: Unknown result type (might be due to invalid IL or missing references)
KeyCode hotKey = entry2.HotKey;
REPOButton button = MenuAPI.CreateREPOButton("HotKey: " + ((object)(KeyCode)(ref hotKey)).ToString(), (Action)null, p, default(Vector2));
button.onClick = delegate
{
((TMP_Text)button.labelTMP).text = "HotKey: ...";
capturingHotKeyObj = entry2;
capturingHotKeyBtn = button;
IsCapturingHotKey = true;
RepoSoundboard.Logger.LogDebug((object)$"IsCapturingHotKey: {IsCapturingHotKey}");
foreach (REPOElement entryLayoutElement in entryLayoutElements)
{
((Behaviour)entryLayoutElement).enabled = false;
}
};
entryLayoutElements.Add((REPOElement)(object)button);
return ((REPOElement)button).rectTransform;
}, 0f, 0f);
popup2.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform p)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
REPOButton val2 = MenuAPI.CreateREPOButton("Delete", (Action)delegate
{
popup2.ClosePage(false);
SoundboardPool.Remove(entry2);
SpawnSoundboardMenu();
}, p, default(Vector2));
RectTransform rectTransform = ((REPOElement)val2).rectTransform;
((Transform)rectTransform).position = ((Transform)rectTransform).position + new Vector3(0f, 10f);
((Graphic)val2.labelTMP).color = new Color(0.8f, 0.25f, 0.25f, 1f);
entryLayoutElements.Add((REPOElement)(object)val2);
return ((REPOElement)val2).rectTransform;
}, 0f, 0f);
REPOPopupPage obj = popup2;
ShouldCloseMenuDelegate onEscapePressed = obj.onEscapePressed;
object obj2 = <>c.<>9__4_8;
if (obj2 == null)
{
ShouldCloseMenuDelegate val = delegate
{
SoundboardPool.Save();
return true;
};
<>c.<>9__4_8 = val;
obj2 = (object)val;
}
obj.onEscapePressed = (ShouldCloseMenuDelegate)Delegate.Combine((Delegate?)(object)onEscapePressed, (Delegate?)obj2);
}
public static void DispatchHotKey(KeyCode keyCode)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Invalid comparison between Unknown and I4
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
if ((int)keyCode == 27)
{
RepoSoundboard.Logger.LogDebug((object)$"Ignore set new key code: {keyCode}");
RestoreAfterHotKey();
return;
}
if ((int)keyCode == 8)
{
keyCode = (KeyCode)0;
}
RepoSoundboard.Logger.LogDebug((object)$"Set new HotKey: {keyCode}");
if (capturingHotKeyObj == null)
{
RestoreAfterHotKey();
return;
}
RepoSoundboard.Logger.LogDebug((object)(capturingHotKeyObj.UpdateHotKey(keyCode) ? "Success." : "Failed."));
RestoreAfterHotKey();
}
private static void RestoreAfterHotKey()
{
//IL_004f: 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)
IsCapturingHotKey = false;
foreach (REPOElement entryLayoutElement in entryLayoutElements)
{
((Behaviour)entryLayoutElement).enabled = true;
}
TextMeshProUGUI labelTMP = capturingHotKeyBtn.labelTMP;
KeyCode hotKey = capturingHotKeyObj.HotKey;
((TMP_Text)labelTMP).text = "HotKey: " + ((object)(KeyCode)(ref hotKey)).ToString();
}
}
public static class SoundboardAudioProvider
{
private static readonly List<SoundboardObject> _active = new List<SoundboardObject>();
public static void Push(SoundboardObject obj)
{
//IL_002a: 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)
lock (_active)
{
ISamplesProvider? provider = obj.Provider;
ResampledAudioProvider val = (ResampledAudioProvider)(object)((provider is ResampledAudioProvider) ? provider : null);
if (val != null)
{
RepoSoundboard.Logger.LogDebug((object)$"Resampling from {val.SourceFormat.SampleRate} to {val.Format.SampleRate}");
}
_active.Add(obj);
}
}
public static void Remove(SoundboardObject obj)
{
lock (_active)
{
_active.Remove(obj);
}
}
public static void Mix(float[] samples, float[] soundboardLoopback)
{
float[] array = new float[samples.Length];
lock (_active)
{
for (int num = _active.Count - 1; num >= 0; num--)
{
SoundboardObject soundboardObject = _active[num];
if (soundboardObject.Finished)
{
soundboardObject.Stop();
}
int num2 = soundboardObject.Read(array, 0, array.Length);
if (num2 == 0)
{
soundboardObject.Stop();
}
for (int i = 0; i < num2; i++)
{
samples[i] += array[i];
soundboardLoopback[i] += array[i];
}
}
}
}
}
public class SoundboardLoopback
{
private int _readIdx;
private int _writeIdx;
private int _samplesAvailable;
private readonly float[] _samples;
private readonly object _lock = new object();
public AudioClip Clip { get; }
public SoundboardLoopback()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
//IL_0068: Expected O, but got Unknown
_samples = new float[RepoSoundboard.AudioFormat.SampleRate / 2];
Clip = AudioClip.Create("SoundboardLoopback", _samples.Length, RepoSoundboard.AudioFormat.Channels, RepoSoundboard.AudioFormat.SampleRate, true, new PCMReaderCallback(OnRead), new PCMSetPositionCallback(OnSetPosition));
}
public void Push(float[] buffer)
{
lock (_lock)
{
foreach (float num in buffer)
{
_samples[_writeIdx] = num;
_writeIdx = (_writeIdx + 1) % _samples.Length;
if (_samplesAvailable < _samples.Length)
{
_samplesAvailable++;
}
else
{
_readIdx = (_readIdx + 1) % _samples.Length;
}
}
}
}
private void OnRead(float[] samples)
{
lock (_lock)
{
Array.Clear(samples, 0, samples.Length);
int num = Math.Min(samples.Length, _samplesAvailable);
for (int i = 0; i < num; i++)
{
samples[i] = _samples[_readIdx];
_readIdx = (_readIdx + 1) % _samples.Length;
}
_samplesAvailable -= num;
}
}
private void OnSetPosition(int position)
{
}
}
public class SoundboardMixer : IAudioReader<float>, IDataReader<float>, IDisposable, IAudioDesc
{
private int _lastMicPos;
public PlayerVoiceChat VoiceChat { get; }
public DeviceInfo MicrophoneDevice { get; set; }
public AudioClip? MicrophoneClip { get; private set; }
public int SamplingRate => RepoSoundboard.AudioFormat.SampleRate;
public int Channels => RepoSoundboard.AudioFormat.Channels;
public string? Error { get; private set; }
public SoundboardMixer(PlayerVoiceChat voiceChat)
{
VoiceChat = voiceChat;
base..ctor();
}
private void EnsureAudioDevice()
{
//IL_000b: 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_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: 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)
DeviceInfo microphoneDevice = VoiceChat.recorder.MicrophoneDevice;
string iDString = ((DeviceInfo)(ref microphoneDevice)).IDString;
microphoneDevice = MicrophoneDevice;
if (iDString != ((DeviceInfo)(ref microphoneDevice)).IDString)
{
_lastMicPos = 0;
MicrophoneDevice = VoiceChat.recorder.MicrophoneDevice;
microphoneDevice = MicrophoneDevice;
MicrophoneClip = Microphone.Start(((DeviceInfo)(ref microphoneDevice)).Name, true, 1, SamplingRate);
RepoSoundboard.Logger.LogInfo((object)"Microphone clip updated.");
}
}
public bool Read(float[] buffer)
{
//IL_0015: 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)
//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)
EnsureAudioDevice();
if (!((Object)(object)MicrophoneClip == (Object)null))
{
DeviceInfo microphoneDevice = MicrophoneDevice;
if (Microphone.IsRecording(((DeviceInfo)(ref microphoneDevice)).Name))
{
microphoneDevice = MicrophoneDevice;
int position = Microphone.GetPosition(((DeviceInfo)(ref microphoneDevice)).Name);
int num = position - _lastMicPos;
if (num < 0)
{
num += MicrophoneClip.samples;
}
if (num < buffer.Length)
{
return false;
}
Array.Clear(buffer, 0, buffer.Length);
MicrophoneClip.GetData(buffer, _lastMicPos);
float[] array = new float[buffer.Length];
SoundboardAudioProvider.Mix(buffer, array);
RepoSoundboard.Loopback.Push(array);
_lastMicPos = (_lastMicPos + buffer.Length) % MicrophoneClip.samples;
return true;
}
}
return false;
}
public void Dispose()
{
//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_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
DeviceInfo microphoneDevice = MicrophoneDevice;
if (Microphone.IsRecording(((DeviceInfo)(ref microphoneDevice)).Name))
{
microphoneDevice = MicrophoneDevice;
Microphone.End(((DeviceInfo)(ref microphoneDevice)).Name);
}
AudioClip? microphoneClip = MicrophoneClip;
if (microphoneClip != null)
{
microphoneClip.UnloadAudioData();
}
}
}
public class SoundboardObject
{
[JsonIgnore]
private readonly object _lock = new object();
private KeyCode _hk;
public string Name { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty;
public KeyCode HotKey
{
get
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return _hk;
}
set
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
UpdateHotKey(value);
}
}
[JsonIgnore]
public bool Finished
{
get
{
if (Provider != null)
{
return Provider.SamplePosition >= Provider.TotalSamples;
}
return true;
}
}
[JsonIgnore]
public ISamplesProvider? Provider { get; private set; }
public void Play()
{
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
try
{
lock (_lock)
{
if (Provider != null)
{
RepoSoundboard.Logger.LogDebug((object)("Sound " + Name + " restarted."));
Restart();
return;
}
RepoSoundboard.Logger.LogInfo((object)("Trying to play " + Name + " from file " + Path + "..."));
FileInfo fileInfo = new FileInfo(Path);
if (!fileInfo.Exists)
{
throw new FileNotFoundException(Path);
}
Provider = AudioProviderFactory.FromFile(fileInfo, RepoSoundboard.AudioFormat);
SoundboardAudioProvider.Push(this);
}
}
catch (Exception arg)
{
RepoSoundboard.Logger.LogWarning((object)$"Could not play \"{Name}\": {arg}");
}
}
public void Stop()
{
lock (_lock)
{
SoundboardAudioProvider.Remove(this);
((IDisposable)Provider)?.Dispose();
Provider = null;
RepoSoundboard.Logger.LogDebug((object)("Sound " + Name + " stopped."));
}
}
public void Restart()
{
lock (_lock)
{
Provider.Position = TimeSpan.Zero;
}
}
public int Read(float[] buffer, int offset, int samples)
{
lock (_lock)
{
if (Provider == null)
{
return 0;
}
return Provider.Read(buffer, offset, samples);
}
}
public bool UpdateHotKey(KeyCode newHk)
{
//IL_0021: 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_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: 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)
if (SoundboardPool.HasObject(this))
{
if (!SoundboardPool.IsHotKeyAvailableFor(newHk, this))
{
return false;
}
SoundboardPool.UpdateHk(this, HotKey, newHk);
}
_hk = newHk;
return true;
}
}
public static class SoundboardPool
{
private static readonly List<SoundboardObject> _objects = new List<SoundboardObject>();
private static readonly Dictionary<KeyCode, SoundboardObject> _keyMap = new Dictionary<KeyCode, SoundboardObject>();
public static int Count => _objects.Count;
public static SoundboardObject Add(SoundboardObject obj)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
if (!IsHotKeyAvailable(obj.HotKey))
{
RepoSoundboard.Logger.LogWarning((object)$"Found object with repeating HotKey: {obj.HotKey}");
obj.UpdateHotKey((KeyCode)0);
}
_objects.Add(obj);
if ((int)obj.HotKey != 0)
{
_keyMap.Add(obj.HotKey, obj);
}
return obj;
}
public static void Remove(SoundboardObject obj)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
_objects.Remove(obj);
_keyMap.Remove(obj.HotKey, out SoundboardObject _);
}
public static bool HasObject(SoundboardObject obj)
{
return _objects.Contains(obj);
}
public static void Save()
{
//IL_0030: 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_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Expected O, but got Unknown
try
{
FileInfo settingsFile = GetSettingsFile();
RepoSoundboard.Logger.LogDebug((object)("Saving settings to \"" + settingsFile.FullName + "\"..."));
File.WriteAllText(settingsFile.FullName, JsonConvert.SerializeObject((object)_objects, new JsonSerializerSettings
{
Converters = { (JsonConverter)(object)new HotKeyConverter() },
Formatting = (Formatting)1
}));
RepoSoundboard.Logger.LogDebug((object)"Settings saved.");
}
catch (Exception arg)
{
RepoSoundboard.Logger.LogError((object)$"Failed to write settings: {arg}");
}
}
public static void Load()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
try
{
RepoSoundboard.Logger.LogDebug((object)"Loading settings...");
_objects.Clear();
_keyMap.Clear();
FileInfo settingsFile = GetSettingsFile();
string text = File.ReadAllText(settingsFile.FullName);
List<SoundboardObject> list = JsonConvert.DeserializeObject<List<SoundboardObject>>(text, new JsonSerializerSettings
{
Converters = { (JsonConverter)(object)new HotKeyConverter() }
});
if (list != null)
{
foreach (SoundboardObject item in list)
{
Add(item);
}
}
RepoSoundboard.Logger.LogDebug((object)"Settings loaded.");
}
catch (Exception arg)
{
RepoSoundboard.Logger.LogError((object)$"Failed to read settings: {arg}");
}
}
public static SoundboardObject Get(int idx)
{
return _objects[idx];
}
public static void DispatchHotKey(KeyCode key)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
if (_keyMap.TryGetValue(key, out SoundboardObject value))
{
value.Play();
}
}
public static bool IsHotKeyAvailable(KeyCode key)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
if ((int)key != 0)
{
return !_keyMap.ContainsKey(key);
}
return true;
}
public static bool IsHotKeyAvailableFor(KeyCode key, SoundboardObject obj)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
if ((int)key == 0 || !_keyMap.TryGetValue(key, out SoundboardObject value))
{
return true;
}
return obj == value;
}
internal static void UpdateHk(SoundboardObject obj, KeyCode old, KeyCode newValue)
{
//IL_0005: 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)
_keyMap.Remove(old);
_keyMap.Add(newValue, obj);
}
internal static FileInfo GetSettingsFile()
{
try
{
Process currentProcess = Process.GetCurrentProcess();
FileInfo fileInfo = new FileInfo(currentProcess.MainModule.FileName);
return new FileInfo(Path.Combine(fileInfo.Directory.FullName, "soundboard_settings.json"));
}
catch (Exception arg)
{
RepoSoundboard.Logger.LogError((object)$"Failed to get settings file path. Defaulting to current working directory. Reason: {arg}");
return new FileInfo("soundboard_settings.json");
}
}
}
internal class HotKeyConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
//IL_0009: 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)
if (!(value is KeyCode val))
{
writer.WriteNull();
}
else
{
writer.WriteValue(((object)(KeyCode)(ref val)).ToString());
}
}
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
if (!(reader.Value is string value) || !Enum.TryParse<KeyCode>(value, out KeyCode result))
{
return (object)(KeyCode)0;
}
return result;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(KeyCode);
}
}
}