using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using UnityEngine;
using VoiceRecognitionAPI;
using com.github.zehsteam.LethalVoice.Dependencies;
using com.github.zehsteam.LethalVoice.Helpers;
using com.github.zehsteam.MonsterHotkeys;
using com.github.zehsteam.MonsterHotkeys.Helpers;
using com.github.zehsteam.MonsterHotkeys.MonoBehaviours;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.zehsteam.LethalVoice")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Spawn Monsters and Monster Plushies when you say specific words/phrases using the MonsterHotkeys mod. Highly Configurable.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+90cc74c9e70bc5a090e414d236b01915a35937b0")]
[assembly: AssemblyProduct("LethalVoice")]
[assembly: AssemblyTitle("com.github.zehsteam.LethalVoice")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace com.github.zehsteam.LethalVoice
{
internal class ConfigManager
{
public ConfigEntry<bool> General_DisableHotkeys;
public ConfigEntry<bool> VoiceRecognition_Enabled;
public ConfigEntry<float> VoiceRecognition_Confidence;
public ConfigEntry<bool> Enemy_Enabled;
public ConfigEntry<string> Enemy_WordsToSpawnRandomEnemies;
public ConfigEntry<bool> Plushie_Enabled;
public ConfigEntry<string> Plushie_WordsToSpawnRandomPlushies;
public ConfigEntry<bool> Message_ShowRecognizedPlushiePhraseMessages;
public string[] Enemy_WordsToSpawnRandomEnemiesArray
{
get
{
return Utils.StringToArray<string>(Enemy_WordsToSpawnRandomEnemies.Value);
}
set
{
Enemy_WordsToSpawnRandomEnemies.Value = Utils.ArrayToString(value);
}
}
public string[] Plushie_WordsToSpawnRandomPlushiesArray
{
get
{
return Utils.StringToArray<string>(Plushie_WordsToSpawnRandomPlushies.Value);
}
set
{
Plushie_WordsToSpawnRandomPlushies.Value = Utils.ArrayToString(value);
}
}
public ConfigManager()
{
BindConfigs();
MigrateOldConfigSettings();
ConfigHelper.ClearUnusedEntries();
}
private void BindConfigs()
{
ConfigHelper.SkipAutoGen();
General_DisableHotkeys = ConfigHelper.Bind("General", "DisableHotkeys", defaultValue: true, "If enabled, the hotkeys from the MonsterHotkeys mod will be disabled.");
General_DisableHotkeys.SettingChanged += Plugin.Instance.OnDisableHotkeysChanged;
VoiceRecognition_Enabled = ConfigHelper.Bind("Voice Recognition", "Enabled", defaultValue: true, "If enabled, speech recognition will be active.");
VoiceRecognition_Confidence = ConfigHelper.Bind("Voice Recognition", "Confidence", 0.7f, "How difficult it will be for the speech recognition to recognize your word/phrase.", requiresRestart: false, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f));
Enemy_Enabled = ConfigHelper.Bind("Enemy", "Enabled", defaultValue: true, "If enabled, you will be able to spawn random monsters when specific words/phrases are said. (Requires VoiceRecognition to be enabled)");
Enemy_WordsToSpawnRandomEnemies = ConfigHelper.Bind("Enemy", "WordsToSpawnRandomEnemies", "alright, fuck, garbage, god, hell, kill, mate, nuts, piece, shit, wait, what, why", "The list of words/phrases you want to trigger a random monster spawn. Each word/phrase should be separated by a comma.");
Enemy_WordsToSpawnRandomEnemies.SettingChanged += Plugin.Instance.OnSpawnRandomMonsterWordsChanged;
Plushie_Enabled = ConfigHelper.Bind("Plushie", "Enabled", defaultValue: true, "If enabled, you will be able to spawn random plushies when specific words/phrases are said. (Requires VoiceRecognition to be enabled)");
Plushie_WordsToSpawnRandomPlushies = ConfigHelper.Bind("Plushie", "WordsToSpawnRandomPlushies", "ban, hate, like, messed, no, ok, rizz, stop, thank, this", "The list of words/phrases you want to trigger a random plushie spawn. Each word/phrase should be separated by a comma.");
Plushie_WordsToSpawnRandomPlushies.SettingChanged += Plugin.Instance.OnSpawnRandomPlushieWordsChanged;
Message_ShowRecognizedPlushiePhraseMessages = ConfigHelper.Bind("Message", "ShowRecognizedPlushiePhraseMessages", defaultValue: true, "If enabled, will show a message when a phrase is recognized for spawning plushies. See additional message setting in the MonsterHotkeys config file.");
}
private void MigrateOldConfigSettings()
{
foreach (KeyValuePair<ConfigDefinition, string> orphanedConfigEntry in ConfigHelper.GetOrphanedConfigEntries())
{
MigrateOldConfigSetting(orphanedConfigEntry.Key.Section, orphanedConfigEntry.Key.Key, orphanedConfigEntry.Value);
}
}
private void MigrateOldConfigSetting(string section, string key, string value)
{
StringComparison comparisonType = StringComparison.OrdinalIgnoreCase;
if (section.Equals("General Settings", comparisonType))
{
if (key.Equals("VoiceRecognitionEnabled", comparisonType))
{
ConfigHelper.SetConfigEntryValue<bool>(VoiceRecognition_Enabled, value);
return;
}
if (key.Equals("VoiceConfidence", comparisonType))
{
ConfigHelper.SetConfigEntryValue<float>(VoiceRecognition_Confidence, value);
return;
}
if (key.Equals("DisableHotkeys", comparisonType))
{
ConfigHelper.SetConfigEntryValue<bool>(General_DisableHotkeys, value);
return;
}
if (key.Equals("ShowRecognizedPlushiePhraseMessages", comparisonType))
{
ConfigHelper.SetConfigEntryValue<bool>(Message_ShowRecognizedPlushiePhraseMessages, value);
return;
}
}
if (section.Equals("Monster Settings", comparisonType) && key.Equals("SpawnRandomMonsterWords", comparisonType))
{
ConfigHelper.SetConfigEntryValue<string>(Enemy_WordsToSpawnRandomEnemies, value);
}
else if (section.Equals("Plushie Settings", comparisonType) && key.Equals("SpawnRandomPlushieWords", comparisonType))
{
ConfigHelper.SetConfigEntryValue<string>(Plushie_WordsToSpawnRandomPlushies, value);
}
}
}
[BepInPlugin("com.github.zehsteam.LethalVoice", "LethalVoice", "1.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class Plugin : BaseUnityPlugin
{
private string[] _activePhrases = Array.Empty<string>();
internal static Plugin Instance { get; private set; }
internal static ManualLogSource Logger { get; private set; }
internal static ConfigManager ConfigManager { get; private set; }
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
Logger = Logger.CreateLogSource("com.github.zehsteam.LethalVoice");
Logger.LogInfo((object)"LethalVoice has awoken!");
ConfigManager = new ConfigManager();
RegisterVoiceListener();
UpdateDisableHotkeys();
}
private void RegisterVoiceListener()
{
string[] enemy_WordsToSpawnRandomEnemiesArray = ConfigManager.Enemy_WordsToSpawnRandomEnemiesArray;
string[] plushie_WordsToSpawnRandomPlushiesArray = ConfigManager.Plushie_WordsToSpawnRandomPlushiesArray;
int num = 0;
string[] array = new string[enemy_WordsToSpawnRandomEnemiesArray.Length + plushie_WordsToSpawnRandomPlushiesArray.Length];
ReadOnlySpan<string> readOnlySpan = new ReadOnlySpan<string>(enemy_WordsToSpawnRandomEnemiesArray);
readOnlySpan.CopyTo(new Span<string>(array).Slice(num, readOnlySpan.Length));
num += readOnlySpan.Length;
ReadOnlySpan<string> readOnlySpan2 = new ReadOnlySpan<string>(plushie_WordsToSpawnRandomPlushiesArray);
readOnlySpan2.CopyTo(new Span<string>(array).Slice(num, readOnlySpan2.Length));
num += readOnlySpan2.Length;
_activePhrases = array;
Voice.RegisterPhrases(_activePhrases);
Voice.RegisterCustomHandler((EventHandler<VoiceRecognitionEventArgs>)HandleVoiceRecognitionPhrase);
}
private void HandleVoiceRecognitionPhrase(object obj, VoiceRecognitionEventArgs recognized)
{
if (ConfigManager.VoiceRecognition_Enabled.Value && !(recognized.Confidence < ConfigManager.VoiceRecognition_Confidence.Value))
{
string message = recognized.Message;
if (ConfigManager.Enemy_Enabled.Value && Utils.ArrayContains(ConfigManager.Enemy_WordsToSpawnRandomEnemiesArray, message))
{
Logger.LogInfo((object)$"Recognized phrase \"{message}\" with a confidence of {recognized.Confidence}");
SpawnRandomEnemy(message);
}
if (ConfigManager.Plushie_Enabled.Value && Utils.ArrayContains(ConfigManager.Plushie_WordsToSpawnRandomPlushiesArray, message))
{
Logger.LogInfo((object)$"Recognized phrase \"{message}\" with a confidence of {recognized.Confidence}");
SpawnRandomPlushies(message);
}
}
}
private void SpawnRandomEnemy(string phrase)
{
try
{
EnemyHelper.SpawnRandomEnemy(phrase);
}
catch (Exception arg)
{
Logger.LogError((object)$"Failed to spawn random enemy. {arg}");
}
}
private void SpawnRandomPlushies(string phrase)
{
try
{
PlushieManager instance = PlushieManager.Instance;
if (instance != null)
{
instance.SpawnRandomPlushies();
}
ShowPlushiePhraseRecognizedMessage(phrase);
}
catch (Exception arg)
{
Logger.LogError((object)$"Failed to spawn random plushies. {arg}");
}
}
public void OnSpawnRandomMonsterWordsChanged(object sender, EventArgs e)
{
string[] array = ConfigManager.Enemy_WordsToSpawnRandomEnemiesArray.Where((string x) => !Utils.ArrayContains(_activePhrases, x)).ToArray();
if (array.Length != 0)
{
Voice.RegisterPhrases(array);
}
}
public void OnSpawnRandomPlushieWordsChanged(object sender, EventArgs e)
{
string[] array = ConfigManager.Plushie_WordsToSpawnRandomPlushiesArray.Where((string x) => !Utils.ArrayContains(_activePhrases, x)).ToArray();
if (array.Length != 0)
{
Voice.RegisterPhrases(array);
}
}
private void ShowPlushiePhraseRecognizedMessage(string phrase)
{
if (!ConfigManager.Message_ShowRecognizedPlushiePhraseMessages.Value)
{
return;
}
try
{
if (!((Object)(object)PlushieManager.Instance == (Object)null) && PlushieManager.Instance.CanSpawnPlushies())
{
MessageCanvas instance = MessageCanvas.Instance;
if (instance != null)
{
instance.ShowMessage_LocalClient("Recognized phrase \"" + phrase + "\"");
}
}
}
catch (Exception arg)
{
Logger.LogError((object)$"Failed to show plushie phrase recognized message on local client.\n\n{arg}");
}
}
private void UpdateDisableHotkeys()
{
bool value = ConfigManager.General_DisableHotkeys.Value;
try
{
HotkeyListener.DisableHotkeys = value;
Logger.LogInfo((object)((value ? "Disabled" : "Enabled") + " MonsterHotkeys hotkeys."));
}
catch (Exception arg)
{
Logger.LogError((object)string.Format("Failed to {0} MonsterHotkeys hotkeys.\n\n{1}", value ? "disable" : "enable", arg));
}
}
public void OnDisableHotkeysChanged(object sender, EventArgs e)
{
UpdateDisableHotkeys();
}
}
internal static class Utils
{
public static T[] StringToArray<T>(string value)
{
if (string.IsNullOrEmpty(value))
{
return Array.Empty<T>();
}
try
{
return (from x in value.Split(',')
select (T)Convert.ChangeType(x.Trim(), typeof(T))).ToArray();
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Failed to convert string to array of type {typeof(T)}. \"{value}\". {arg}");
}
return Array.Empty<T>();
}
public static string ArrayToString<T>(T[] value)
{
if (value == null || value.Length == 0)
{
return string.Empty;
}
return string.Join(", ", value.Select((T x) => x.ToString()));
}
public static bool ArrayContains(string[] array, string value, bool matchCase = false)
{
if (value == null || value.Length == 0)
{
return false;
}
StringComparison comparisonType = ((!matchCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.CurrentCulture);
return array.Any((string x) => x.Equals(value, comparisonType));
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "com.github.zehsteam.LethalVoice";
public const string PLUGIN_NAME = "LethalVoice";
public const string PLUGIN_VERSION = "1.1.0";
}
}
namespace com.github.zehsteam.LethalVoice.Helpers
{
internal static class ConfigHelper
{
public static void SkipAutoGen()
{
if (LethalConfigProxy.Enabled)
{
LethalConfigProxy.SkipAutoGen();
}
}
public static void AddButton(string section, string name, string buttonText, string description, Action callback)
{
if (LethalConfigProxy.Enabled)
{
LethalConfigProxy.AddButton(section, name, buttonText, description, callback);
}
}
public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, bool requiresRestart = false, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
if (configFile == null)
{
configFile = ((BaseUnityPlugin)Plugin.Instance).Config;
}
ConfigEntry<T> configEntry = ((acceptableValues == null) ? configFile.Bind<T>(section, key, defaultValue, description) : configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>())));
if (settingChanged != null)
{
configEntry.SettingChanged += delegate
{
settingChanged?.Invoke(configEntry.Value);
};
}
if (LethalConfigProxy.Enabled)
{
LethalConfigProxy.AddConfig<T>(configEntry, requiresRestart);
}
return configEntry;
}
public static Dictionary<ConfigDefinition, string> GetOrphanedConfigEntries(ConfigFile configFile = null)
{
if (configFile == null)
{
configFile = ((BaseUnityPlugin)Plugin.Instance).Config;
}
PropertyInfo property = ((object)configFile).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
return (Dictionary<ConfigDefinition, string>)property.GetValue(configFile, null);
}
public static void SetConfigEntryValue<T>(ConfigEntry<T> configEntry, string value)
{
if (typeof(T) == typeof(int) && int.TryParse(value, out var result))
{
configEntry.Value = (T)(object)result;
return;
}
if (typeof(T) == typeof(float) && float.TryParse(value, out var result2))
{
configEntry.Value = (T)(object)result2;
return;
}
if (typeof(T) == typeof(double) && double.TryParse(value, out var result3))
{
configEntry.Value = (T)(object)result3;
return;
}
if (typeof(T) == typeof(bool) && bool.TryParse(value, out var result4))
{
configEntry.Value = (T)(object)result4;
return;
}
if (typeof(T) == typeof(string))
{
configEntry.Value = (T)(object)value;
return;
}
throw new InvalidOperationException($"Unsupported type: {typeof(T)}");
}
public static void ClearUnusedEntries(ConfigFile configFile = null)
{
if (configFile == null)
{
configFile = ((BaseUnityPlugin)Plugin.Instance).Config;
}
Dictionary<ConfigDefinition, string> orphanedConfigEntries = GetOrphanedConfigEntries(configFile);
if (orphanedConfigEntries != null)
{
orphanedConfigEntries.Clear();
configFile.Save();
}
}
}
}
namespace com.github.zehsteam.LethalVoice.Dependencies
{
internal static class LethalConfigProxy
{
public const string PLUGIN_GUID = "ainavt.lc.lethalconfig";
private static bool? _enabled;
public static bool Enabled
{
get
{
bool valueOrDefault = _enabled.GetValueOrDefault();
if (!_enabled.HasValue)
{
valueOrDefault = Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");
_enabled = valueOrDefault;
}
return _enabled.Value;
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void SkipAutoGen()
{
LethalConfigManager.SkipAutoGen();
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void AddConfig<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
{
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Expected O, but got Unknown
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected O, but got Unknown
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Expected O, but got Unknown
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Expected O, but got Unknown
AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
if (acceptableValues != null)
{
if (acceptableValues is AcceptableValueRange<float> || acceptableValues is AcceptableValueRange<int>)
{
AddConfigSlider<T>(configEntry, requiresRestart);
return;
}
if (acceptableValues is AcceptableValueList<string>)
{
AddConfigDropdown<T>(configEntry, requiresRestart);
return;
}
}
if (!(configEntry is ConfigEntry<string> val))
{
if (!(configEntry is ConfigEntry<bool> val2))
{
if (!(configEntry is ConfigEntry<float> val3))
{
if (!(configEntry is ConfigEntry<int> val4))
{
throw new NotSupportedException($"Unsupported type: {typeof(T)}");
}
LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(val4, requiresRestart));
}
else
{
LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(val3, requiresRestart));
}
}
else
{
LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(val2, requiresRestart));
}
}
else
{
LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(val, requiresRestart));
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void AddConfigSlider<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
if (!(configEntry is ConfigEntry<float> val))
{
if (!(configEntry is ConfigEntry<int> val2))
{
throw new NotSupportedException($"Slider not supported for type: {typeof(T)}");
}
LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(val2, requiresRestart));
}
else
{
LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(val, requiresRestart));
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void AddConfigDropdown<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
if (configEntry is ConfigEntry<string> val)
{
LethalConfigManager.AddConfigItem((BaseConfigItem)new TextDropDownConfigItem(val, requiresRestart));
return;
}
throw new NotSupportedException($"Dropdown not supported for type: {typeof(T)}");
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void AddButton(string section, string name, string buttonText, string description, Action callback)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
LethalConfigManager.AddConfigItem((BaseConfigItem)new GenericButtonConfigItem(section, name, description, buttonText, (GenericButtonHandler)delegate
{
callback?.Invoke();
}));
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}