Decompiled source of VoiceCurseRu v1.1.1
plugins/VoiceCurse.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using Photon.Voice; using Photon.Voice.PUN; using Photon.Voice.Unity; using UnityEngine; using VoiceCurse.Events; using VoiceCurse.Handlers; using VoiceCurse.Interfaces; using VoiceCurse.Voice; using Vosk; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("VoiceCurse")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Russian Voice Recognition Mod")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("VoiceCurse")] [assembly: AssemblyTitle("VoiceCurse")] [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.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 BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace VoiceCurse { public class Config { public ConfigEntry<bool> EnableDebugLogs { get; private set; } public ConfigEntry<float> GlobalCooldown { get; private set; } public ConfigEntry<bool> LaunchEnabled { get; private set; } public ConfigEntry<string> LaunchKeywords { get; private set; } public ConfigEntry<float> LaunchStunDuration { get; private set; } public ConfigEntry<float> LaunchForceLowerBound { get; private set; } public ConfigEntry<float> LaunchForceHigherBound { get; private set; } public ConfigEntry<bool> AfflictionEnabled { get; private set; } public ConfigEntry<float> AfflictionMinPercent { get; private set; } public ConfigEntry<float> AfflictionMaxPercent { get; private set; } public ConfigEntry<bool> AfflictionTemperatureSwapEnabled { get; private set; } public ConfigEntry<string> AfflictionKeywordsInjury { get; private set; } public ConfigEntry<string> AfflictionKeywordsHunger { get; private set; } public ConfigEntry<string> AfflictionKeywordsCold { get; private set; } public ConfigEntry<string> AfflictionKeywordsHot { get; private set; } public ConfigEntry<string> AfflictionKeywordsPoison { get; private set; } public ConfigEntry<string> AfflictionKeywordsSpores { get; private set; } public ConfigEntry<bool> TransmuteEnabled { get; private set; } public ConfigEntry<bool> TransmuteDeathEnabled { get; private set; } public ConfigEntry<bool> TransmuteBackpackEnabled { get; private set; } public ConfigEntry<bool> TransmuteMilkEnabled { get; private set; } public ConfigEntry<bool> TransmuteCactusEnabled { get; private set; } public ConfigEntry<bool> TransmuteCoconutEnabled { get; private set; } public ConfigEntry<bool> TransmuteAppleEnabled { get; private set; } public ConfigEntry<bool> TransmuteBananaEnabled { get; private set; } public ConfigEntry<bool> TransmuteEggEnabled { get; private set; } public ConfigEntry<bool> TransmuteFruitEnabled { get; private set; } public ConfigEntry<bool> TransmuteMushroomEnabled { get; private set; } public ConfigEntry<bool> TransmuteBallEnabled { get; private set; } public ConfigEntry<bool> DeathEnabled { get; private set; } public ConfigEntry<string> DeathKeywords { get; private set; } public ConfigEntry<bool> HealEnabled { get; private set; } public ConfigEntry<string> HealKeywords { get; private set; } public ConfigEntry<float> HealCooldown { get; private set; } public ConfigEntry<float> HealAmount { get; private set; } public ConfigEntry<bool> ZombifyEnabled { get; private set; } public ConfigEntry<string> ZombifyKeywords { get; private set; } public ConfigEntry<bool> SleepEnabled { get; private set; } public ConfigEntry<string> SleepKeywords { get; private set; } public ConfigEntry<bool> DropEnabled { get; private set; } public ConfigEntry<string> DropKeywords { get; private set; } public ConfigEntry<bool> ExplodeEnabled { get; private set; } public ConfigEntry<string> ExplodeKeywords { get; private set; } public ConfigEntry<float> ExplodeRadius { get; private set; } public ConfigEntry<float> ExplodeDamage { get; private set; } public ConfigEntry<float> ExplodeStunDuration { get; private set; } public ConfigEntry<float> ExplodeForceLowerBound { get; private set; } public ConfigEntry<float> ExplodeForceHigherBound { get; private set; } public ConfigEntry<bool> SlipEnabled { get; private set; } public ConfigEntry<string> SlipKeywords { get; private set; } public ConfigEntry<float> SlipStunDuration { get; private set; } public ConfigEntry<bool> BananaBombEnabled { get; private set; } public ConfigEntry<float> BananaBombChance { get; private set; } public ConfigEntry<int> BananaBombAmount { get; private set; } public ConfigEntry<bool> SacrificeEnabled { get; private set; } public ConfigEntry<string> SacrificeKeywords { get; private set; } public ConfigEntry<float> SacrificeCooldown { get; private set; } public ConfigEntry<bool> BlindEnabled { get; private set; } public ConfigEntry<string> BlindKeywords { get; private set; } public ConfigEntry<float> BlindDuration { get; private set; } public Config(ConfigFile config) { EnableDebugLogs = config.Bind<bool>("Global", "EnableDebugLogs", true, "Включить отладочные логи для распознавания речи."); GlobalCooldown = config.Bind<float>("Global", "GlobalCooldown", 2f, "Время в секундах, которое должно пройти перед возможностью запуска другого голосового события."); LaunchEnabled = config.Bind<bool>("Event.Launch", "Enabled", true, "Включить событие 'Запуск'."); LaunchKeywords = config.Bind<string>("Event.Launch", "Keywords", "полет, вверх, прыжок, ракета, взлет, космос, лечу, пушка, небо, прыгай, выше, катапульта, запуск, подбрось, высота, подпрыгнул, летим, орбита, прыг, взлетай, ввысь, вправо, влево, назад, вперед, вперёд, поехали, гагарин, илон маск, на луну, отрыв, джетпак, парашют, пружина, батут, лифт, этаж", "Список ключевых слов, вызывающих событие запуска, разделенных запятыми."); LaunchForceLowerBound = config.Bind<float>("Event.Launch", "ForceLowerBound", 1500f, "Минимально возможная сила, применяемая к игроку при запуске."); LaunchForceHigherBound = config.Bind<float>("Event.Launch", "ForceHigherBound", 3000f, "Максимально возможная сила, применяемая к игроку при запуске."); LaunchStunDuration = config.Bind<float>("Event.Launch", "StunDuration", 3f, "Длительность в секундах, на которую игрок будет оглушен/сбит с ног после запуска."); AfflictionEnabled = config.Bind<bool>("Event.Affliction", "Enabled", true, "Включить событие 'Недуг'."); AfflictionMinPercent = config.Bind<float>("Event.Affliction", "MinPercent", 0.2f, "Минимальный процент (от 0.0 до 1.0) заполнения шкалы состояния при срабатывании."); AfflictionMaxPercent = config.Bind<float>("Event.Affliction", "MaxPercent", 0.6f, "Максимальный процент (от 0.0 до 1.0) заполнения шкалы состояния при срабатывании."); AfflictionTemperatureSwapEnabled = config.Bind<bool>("Event.Affliction", "TemperatureSwapEnabled", true, "Если включено, попытка избавиться от жары или холода, сказав противоположное, просто заменит текущий эффект на новый и добавит его сверху, чтобы предотвратить злоупотребление механикой."); AfflictionKeywordsInjury = config.Bind<string>("Event.Affliction", "KeywordsInjury", "урон, ударился, травма, ранил, поранил, боль, вред, ранка, рана, удар, кровь, синяк, порез, оранж, язва, разрез, соскреб, слеза, рвать, лом, растяжение, калеч, калек, больно, минус хп, дамаг, покоцал, шотнул, ваншот, ранение, кровотечение, ударили, ушиб, перелом, бо-бо", "Ключевые слова, вызывающие физическую травму."); AfflictionKeywordsHunger = config.Bind<string>("Event.Affliction", "KeywordsHunger", "голод, голоден, еда, кушать, жрать, пища, аппетит, желтый, перекус, обед, ужин, жратва, голодаю, проголодался, хавать, питание, продукты, перекусить, ням, вкусно, живот урчит, хавчик, сухпай, консерва, завтрак, полдник, хочу есть, заморить червячка, столовая, бургер, пицца, снек", "Ключевые слова, вызывающие голод."); AfflictionKeywordsCold = config.Bind<string>("Event.Affliction", "KeywordsCold", "холод, мороз, лед, зима, синий, иней, метель, стужа, замерз, озноб, льдина, онемел, холодрыга, ледяной, снег, вьюга, арктика, полярный, дубак, замерзаю, фриз, колотун, дрожу, сосулька, прохладно, сквозняк, свежо, минус градус, окоченел, мерзляк, айсберг, снеговик", "Ключевые слова, вызывающие статус холода."); AfflictionKeywordsHot = config.Bind<string>("Event.Affliction", "KeywordsHot", "жара, огонь, пламя, лето, красный, пожар, печка, кипит, жарко, горю, пекло, поджог, костер, солнце, духота, варить, запекать, сгораю, искры, плавить, обжегся, ожог, негр, нигер, уголек, черный, шалава, пидор, пидрас, пидорас, гей, гомик, петух, черт, демон, лава, духовка, кипяток, прожарка, гриль, факел, спички, зажигалка", "Ключевые слова, вызывающие статус жары."); AfflictionKeywordsPoison = config.Bind<string>("Event.Affliction", "KeywordsPoison", "тошнота, рвота, токсин, фиолетовый, болезнь, болен, зараза, отрава, мутит, тошнит, инфекция, болячка, недуг, токсичный, отравился, блевать, рыгать, укачало, химия, радиация, газ, воняет, дурно, плохо мне, живот болит, диарея, понос, вирус", "Ключевые слова, вызывающие статус отравления."); AfflictionKeywordsSpores = config.Bind<string>("Event.Affliction", "KeywordsSpores", "споры, розовый, гриб, плесень, грибок, грибочек, мухомор, поганка, мицелий, сырость, заплесневел, аллергия", "Ключевые слова, вызывающие статус спор."); TransmuteEnabled = config.Bind<bool>("Event.Transmute", "Enabled", true, "Включить событие 'Превращение'."); TransmuteDeathEnabled = config.Bind<bool>("Event.Transmute", "EnableDeath", true, "Включить мгновенную смерть при срабатывании превращения (используя вашу плоть как материал). Если отключено, вы просто получите урон (ваша плоть частично превратится)."); TransmuteBackpackEnabled = config.Bind<bool>("Event.Transmute", "EnableBackpack", false, "Включить превращение рюкзака в предметы"); TransmuteMilkEnabled = config.Bind<bool>("Event.Transmute", "EnableMilk", true, "Включить превращение 'молоко/кальций' -> Обогащенное молоко"); TransmuteCactusEnabled = config.Bind<bool>("Event.Transmute", "EnableCactus", true, "Включить превращение 'кактус' -> Кактус"); TransmuteCoconutEnabled = config.Bind<bool>("Event.Transmute", "EnableCoconut", true, "Включить превращение 'кокос' -> Кокос"); TransmuteAppleEnabled = config.Bind<bool>("Event.Transmute", "EnableApple", true, "Включить превращение 'яблоко/ягода' -> Хрустягоды"); TransmuteBananaEnabled = config.Bind<bool>("Event.Transmute", "EnableBanana", true, "Включить превращение 'банан' -> Кожура"); TransmuteEggEnabled = config.Bind<bool>("Event.Transmute", "EnableEgg", true, "Включить превращение 'яйцо' -> Яйцо"); TransmuteFruitEnabled = config.Bind<bool>("Event.Transmute", "EnableFruit", true, "Включить превращение 'фрукт' -> Случайный фрукт"); TransmuteMushroomEnabled = config.Bind<bool>("Event.Transmute", "EnableMushroom", true, "Включить превращение 'гриб' -> Гриб"); TransmuteBallEnabled = config.Bind<bool>("Event.Transmute", "EnableBall", true, "Включить превращение 'мяч' -> Баскетбольный мяч"); DeathEnabled = config.Bind<bool>("Event.Death", "Enabled", true, "Включить событие 'Смерть'."); DeathKeywords = config.Bind<string>("Event.Death", "Keywords", "смерть, умер, умри, труп, конец, сдохни, гроб, могила, череп, скелет, убить, гибель, мертв, финиш, хана, крышка, покойник, кости, фаталити, прикончи, убит, костлявая, суицид, скелетон, тлен, сдох, погиб, скончался, жмур, мертвец, на небеса, откинулся, преставился, ласты склеил", "Список ключевых слов, вызывающих событие смерти, разделенных запятыми."); HealEnabled = config.Bind<bool>("Event.Heal", "Enabled", true, "Включить событие 'Лечение'."); HealKeywords = config.Bind<string>("Event.Heal", "Keywords", "здоровье, хп, жизнь, жиза, лечи, хиль, хил, аптечка, медик, доктор, врач, бинт, таблетка, шприц, укол, реген, восстанови, вылечил, жив, здорово, полечи, медпункт, пластырь, стимулятор", "Список ключевых слов, вызывающих событие лечения, разделенных запятыми."); HealCooldown = config.Bind<float>("Event.Heal", "Cooldown", 120f, "Перезарядка в секундах для события лечения."); HealAmount = config.Bind<float>("Event.Heal", "Amount", 0.4f, "Процент (от 0.0 до 1.0) заполнения шкалы состояния при срабатывании."); ZombifyEnabled = config.Bind<bool>("Event.Zombify", "Enabled", true, "Включить событие 'Зомбификация'."); ZombifyKeywords = config.Bind<string>("Event.Zombify", "Keywords", "зомби, укус, мозг, гниль, зараза, вирус, нежить, мертвец, апокалипсис, мозги, ходячий, плоть, мясо, заражен, гниет, зомбак, людоед, трупоед, живой труп, кусь, вурдалак, укусил, монстр, чужой, паразит, мутант, рейк, слендер, бессмертный", "Список ключевых слов, вызывающих событие зомбификации, разделенных запятыми."); SleepEnabled = config.Bind<bool>("Event.Sleep", "Enabled", true, "Включить событие 'Сон'."); SleepKeywords = config.Bind<string>("Event.Sleep", "Keywords", "спать, сон, устал, кровать, вырубился, отдых, дремота, зевнул, бай, храп, отрубился, выдохся, спатки, сонный, подушка, поспать, дрыхнуть, соня, тихий час, спокойной ночи, боковая, баиньки, сновидение, кошмар, вздремнуть, койка, диван, матрас", "Список ключевых слов, вызывающих событие сна, разделенных запятыми."); DropEnabled = config.Bind<bool>("Event.Drop", "Enabled", true, "Включить событие 'Выброс предмета'."); DropKeywords = config.Bind<string>("Event.Drop", "Keywords", "уронил, выбросил, выронил, брось, потерял, выкинь, упс, потеря, отдай, бросил, отпусти, скинул, криворукий, растяпа, избавься, выбрось, выпало, руки дырявые, скользкие руки, не удержал, лови, кидай, дроп, дропни, выложи, положи, убери из рук", "Список ключевых слов, вызывающих событие выброса предмета, разделенных запятыми."); ExplodeEnabled = config.Bind<bool>("Event.Explode", "Enabled", true, "Включить событие 'Взрыв'."); ExplodeKeywords = config.Bind<string>("Event.Explode", "Keywords", "взрыв, бум, бомба, бабах, бах, рвануло, динамит, граната, ядерка, детонация, бабахнуло, рванет, взрывчатка, хлопок, взрывай, кабум, рвануть, мина, крипер, пластид, аллах акбар, бам, тыдыщ, петарда, салют, фейерверк, подрыв, запал, фитиль, тротил", "Список ключевых слов, вызывающих событие взрыва, разделенных запятыми."); ExplodeRadius = config.Bind<float>("Event.Explode", "Radius", 6f, "Радиус эффекта взрыва и урона."); ExplodeDamage = config.Bind<float>("Event.Explode", "DamagePercent", 0.4f, "Процент травмы (от 0.0 до 1.0), наносимый игроку."); ExplodeStunDuration = config.Bind<float>("Event.Explode", "StunDuration", 3f, "Длительность в секундах, на которую игрок будет оглушен/сбит с ног после взрыва."); ExplodeForceLowerBound = config.Bind<float>("Event.Explode", "ForceLowerBound", 2000f, "Минимально возможная сила взрыва."); ExplodeForceHigherBound = config.Bind<float>("Event.Explode", "ForceHigherBound", 3000f, "Максимально возможная сила взрыва."); SlipEnabled = config.Bind<bool>("Event.Slip", "Enabled", true, "Включить событие 'Поскальзывание'."); SlipKeywords = config.Bind<string>("Event.Slip", "Keywords", "упал, придурок, скользко, споткнулся, падение, качусь, блин, лед, скольжу, грохнулся, пиздец, блять, блядь, сука, хуйня, говно, ебать, ебаный, гад, скотина, урод, жопа, херня, проклятье, залупа, бля, ебать-копать, мразь, нахуй, ебанешься, ахуеть, охуеть, я хуею, выебу, выебать, манда, пидарас, гондон, шлюха, чмо, лох, дебил, даун, запнулся, равновесие, занесло, дрифт", "Список ключевых слов, вызывающих событие поскальзывания, разделенных запятыми."); SlipStunDuration = config.Bind<float>("Event.Slip", "StunDuration", 2f, "Длительность в секундах, на которую игрок будет оглушен/сбит с ног после поскальзывания."); BananaBombEnabled = config.Bind<bool>("Event.Slip", "BananaBombEnabled", true, "Включить редкую пасхалку 'Банановая бомба' при поскальзывании."); BananaBombChance = config.Bind<float>("Event.Slip", "BananaBombChance", 0.05f, "Шанс (0.0 - 1.0), что поскальзывание активирует 'Банановую бомбу'."); BananaBombAmount = config.Bind<int>("Event.Slip", "BananaBombAmount", 30, "Количество бананов, появляющихся во время 'Банановой бомбы'."); SacrificeEnabled = config.Bind<bool>("Event.Sacrifice", "Enabled", true, "Включить событие 'Жертвоприношение'."); SacrificeKeywords = config.Bind<string>("Event.Sacrifice", "Keywords", "жертва, обмен, душа, дар, оживи, воскреси, алтарь, дух, отдать, ритуал, приношение, воскрешение, пентаграмма, сатана, дьявол, сделка, кровь за кровь, жизнь за жизнь, верни, рес, ресни, подними", "Список ключевых слов, вызывающих событие жертвоприношения."); SacrificeCooldown = config.Bind<float>("Event.Sacrifice", "Cooldown", 300f, "Перезарядка в секундах для события жертвоприношения."); BlindEnabled = config.Bind<bool>("Event.Blind", "Enabled", true, "Включить событие 'Ослепление'."); BlindKeywords = config.Bind<string>("Event.Blind", "Keywords", "слепой, вспышка, глаза, зрение, не вижу, темно, ослеп, свет, ослепило, блик, фонарик, очи, темнота, ночь, мрак, выколи глаз, ничего не видно, черный экран, кто выключил свет, лампочка, прожектор, ярко, крот, повязка, туман войны", "Список ключевых слов, вызывающих событие ослепления."); BlindDuration = config.Bind<float>("Event.Blind", "Duration", 15f, "Длительность ослепления игрока в секундах."); } } [BepInPlugin("VoiceCurse", "VoiceCurse", "1.1.0")] public class Plugin : BaseUnityPlugin { private Config? _config; private VoiceHandler? _voiceHandler; private Harmony? _harmony; public const string Id = "VoiceCurse"; private static ManualLogSource Log { get; set; } public static string Name => "VoiceCurse"; public static string Version => "1.1.0"; private void Awake() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)("Плагин " + Name + " загружается...")); _config = new Config(((BaseUnityPlugin)this).Config); _harmony = new Harmony("VoiceCurse"); _harmony.PatchAll(); Log.LogInfo((object)"Harmony Patches применен."); string text = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); if (string.IsNullOrEmpty(text)) { text = Paths.PluginPath; } _voiceHandler = new VoiceHandler(Log, _config, text); Log.LogInfo((object)("Плагин " + Name + " успешно загрузился.")); } private void Update() { _voiceHandler?.Update(); } private void OnDestroy() { _voiceHandler?.Dispose(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace VoiceCurse.Voice { public class VoiceHook : MonoBehaviour { private VoiceHandler? _manager; private Recorder? _recorder; private bool _hasInjected; public void Initialize(VoiceHandler manager, Recorder recorder) { _manager = manager; _recorder = recorder; CheckIfReady(); } private void Update() { if (!_hasInjected) { CheckIfReady(); } } private void CheckIfReady() { if (!Object.op_Implicit((Object)(object)_recorder) || _manager == null || !_recorder.IsCurrentlyTransmitting) { return; } FieldInfo field = typeof(Recorder).GetField("voice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object? value = field.GetValue(_recorder); LocalVoice val = (LocalVoice)((value is LocalVoice) ? value : null); if (val != null) { _manager.OnPhotonVoiceReady(_recorder, val); _hasInjected = true; } } } private void PhotonVoiceCreated(PhotonVoiceCreatedParams p) { if (!_hasInjected && !((Object)(object)_recorder == (Object)null)) { _manager?.OnPhotonVoiceReady(_recorder, p.Voice); _hasInjected = true; } } } public class VoiceProcessor : IProcessor<float>, IDisposable { [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private IVoiceRecognizer <recognizer>P; [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int <inputSampleRate>P; private const int TargetSampleRate = 16000; public VoiceProcessor(IVoiceRecognizer recognizer, int inputSampleRate) { <recognizer>P = recognizer; <inputSampleRate>P = inputSampleRate; base..ctor(); } public float[]? Process(float[]? buf) { if (buf == null || buf.Length == 0) { return buf; } if (Math.Abs(<inputSampleRate>P - 16000) < 100) { ProcessDirect(buf); return buf; } float num = (float)<inputSampleRate>P / 16000f; int num2 = (int)((float)buf.Length / num); if (num2 == 0) { return buf; } short[] array = new short[num2]; for (int i = 0; i < num2; i++) { float num3 = (float)i * num; int num4 = (int)num3; float num5 = num3 - (float)num4; if (num4 >= buf.Length - 1) { array[i] = FloatToShort(buf[^1]); continue; } float num6 = buf[num4]; float num7 = buf[num4 + 1]; float sample = num6 + (num7 - num6) * num5; array[i] = FloatToShort(sample); } <recognizer>P.FeedAudio(array, array.Length); return buf; } private void ProcessDirect(float[] buf) { short[] array = new short[buf.Length]; for (int i = 0; i < buf.Length; i++) { array[i] = FloatToShort(buf[i]); } <recognizer>P.FeedAudio(array, array.Length); } private static short FloatToShort(float sample) { if (1 == 0) { } float num = ((sample > 1f) ? 1f : ((!(sample < -1f)) ? sample : (-1f))); if (1 == 0) { } sample = num; return (short)(sample * 32767f); } public void Dispose() { } } public class VoiceRecognizer : IVoiceRecognizer, IDisposable { private readonly VoskRecognizer _recognizer; private readonly ConcurrentQueue<short[]> _audioQueue = new ConcurrentQueue<short[]>(); private Thread? _workerThread; private volatile bool _isRunning; private const int MaxQueueSize = 50; public event Action<string>? OnPhraseRecognized; public event Action<string>? OnPartialResult; public VoiceRecognizer(Model model, float sampleRate) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown try { _recognizer = new VoskRecognizer(model, sampleRate); _recognizer.SetMaxAlternatives(0); _recognizer.SetWords(true); Debug.Log((object)$"[VoiceCurse] Инициализация VoskRecognizer с частотой: {sampleRate} Hz"); } catch (Exception ex) { Debug.LogError((object)("Ошибка создания VoskRecognizer: " + ex.Message)); throw; } } public void Start() { if (!_isRunning) { _isRunning = true; _workerThread = new Thread(ProcessAudioLoop) { IsBackground = true, Name = "VoiceCurse Worker" }; _workerThread.Start(); } } public void Stop() { _isRunning = false; Thread workerThread = _workerThread; if (workerThread != null && workerThread.IsAlive) { _workerThread.Join(500); } } public void FeedAudio(short[] pcmData, int length) { if (!_isRunning) { return; } if (_audioQueue.Count >= 50) { short[] result; while (_audioQueue.TryDequeue(out result)) { } } _audioQueue.Enqueue(pcmData); } private void ProcessAudioLoop() { while (_isRunning) { if (_audioQueue.TryDequeue(out short[] result)) { try { if (_recognizer.AcceptWaveform(result, result.Length)) { string json = _recognizer.Result(); ExtractAndFire(json, isPartial: false); } else { string json2 = _recognizer.PartialResult(); ExtractAndFire(json2, isPartial: true); } } catch (Exception ex) { Debug.LogError((object)("[VoiceCurse] Vosk ошибка: " + ex.Message)); } } else { Thread.Sleep(10); } } } private void ExtractAndFire(string json, bool isPartial) { if (string.IsNullOrEmpty(json)) { return; } string text = (isPartial ? "\"partial\"" : "\"text\""); int num = json.IndexOf(text + " :", StringComparison.Ordinal); if (num == -1) { num = json.IndexOf(text + ":", StringComparison.Ordinal); } if (num == -1) { return; } int num2 = json.IndexOf("\"", num + text.Length + 1, StringComparison.Ordinal) + 1; int num3 = json.LastIndexOf("\"", StringComparison.Ordinal); if (num3 <= num2) { return; } string text2 = json.Substring(num2, num3 - num2); if (!string.IsNullOrWhiteSpace(text2)) { if (isPartial) { this.OnPartialResult?.Invoke(text2); } else { this.OnPhraseRecognized?.Invoke(text2); } } } public void Dispose() { Stop(); _recognizer.Dispose(); } } } namespace VoiceCurse.Interfaces { public interface IVoiceEvent { bool TryExecute(string spokenWord, string fullSentence); void PlayEffects(Vector3 position); void PlayEffects(Character origin, Vector3 position, string detail); } public interface IVoiceRecognizer : IDisposable { event Action<string> OnPhraseRecognized; event Action<string> OnPartialResult; void FeedAudio(short[] pcmData, int length); void Start(); void Stop(); } } namespace VoiceCurse.Handlers { public class EventHandler { public static readonly Dictionary<string, IVoiceEvent> Events = new Dictionary<string, IVoiceEvent>(); private readonly Dictionary<string, int> _previousWordCounts = new Dictionary<string, int>(); public EventHandler(Config config) { Events.Clear(); RegisterEvents(config); } private static void RegisterEvents(Config config) { IEnumerable<Type> enumerable = from t in Assembly.GetExecutingAssembly().GetTypes() where typeof(VoiceEventBase).IsAssignableFrom(t) && !t.IsAbstract && t.IsClass select t; foreach (Type item in enumerable) { try { if (Activator.CreateInstance(item, config) is IVoiceEvent value) { string text = item.Name.Replace("Event", ""); Events[text] = value; if (config.EnableDebugLogs.Value) { Debug.Log((object)("[VoiceCurseRu] Ивент зарегистрирован: " + text)); } } } catch (Exception ex) { Debug.LogError((object)("[VoiceCurse] Ошибка регистрации ивента " + item.Name + ": " + ex.Message)); } } } public void HandleSpeech(string text, bool isFinal) { if (string.IsNullOrWhiteSpace(text)) { return; } string text2 = text.ToLowerInvariant(); string[] array = text2.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Dictionary<string, int> dictionary = new Dictionary<string, int>(); string[] array2 = array; string key; int value; foreach (string text3 in array2) { dictionary.TryAdd(text3, 0); key = text3; value = dictionary[key]++; } foreach (KeyValuePair<string, int> item in dictionary) { item.Deconstruct(out key, out value); string text4 = key; int num = value; int num2 = 0; if (_previousWordCounts.TryGetValue(text4, out var value2)) { num2 = value2; } int num3 = num - num2; if (num3 <= 0) { continue; } for (int j = 0; j < num3; j++) { foreach (IVoiceEvent value3 in Events.Values) { value3.TryExecute(text4, text2); } } } _previousWordCounts.Clear(); foreach (KeyValuePair<string, int> item2 in dictionary) { _previousWordCounts[item2.Key] = item2.Value; } if (isFinal) { _previousWordCounts.Clear(); } } } public class NetworkHandler : IOnEventCallback { private const byte VoiceCurseEventCode = 187; private static MonoBehaviour? _connectionLog; private static MethodInfo? _addMessageMethod; private static Dictionary<string, string> engToRuWords = new Dictionary<string, string> { { "Slip", "Скольжение" }, { "Heal", "Лечение" }, { "Affliction", "Бедствие" }, { "Sleep", "Сон" }, { "Launch", "Полёт" }, { "Zombify", "Зомбифицирование" }, { "Trasmute", "Превращение" }, { "Sacrifice", "Жертвоприношение" }, { "Explode", "Взрыв" }, { "Death", "Смерть" }, { "Blind", "Слепота" }, { "Drop", "Уронить" }, { "Forward", "Вперёд" }, { "Back", "Назад" }, { "Right", "Вправо" }, { "Left", "Влево" }, { "Up", "Вверх" }, { "Cold", "Холод" }, { "Hot", "Жара" }, { "Injury", "Урон" }, { "Hunger", "Голод" }, { "Poison", "Яд" }, { "Spores", "Споры" } }; public static void SendCurseEvent(string spokenWord, string matchedKeyword, string eventName, string? detail, string? payload, Vector3 position) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0058: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_0072: Unknown result type (might be due to invalid IL or missing references) object[] array = new object[7] { PhotonNetwork.LocalPlayer.ActorNumber, spokenWord, matchedKeyword, eventName, detail ?? string.Empty, position, payload ?? string.Empty }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)1 }; SendOptions val2 = default(SendOptions); ((SendOptions)(ref val2)).Reliability = true; SendOptions val3 = val2; PhotonNetwork.RaiseEvent((byte)187, (object)array, val, val3); } public void OnEvent(EventData photonEvent) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) if (photonEvent.Code != 187) { return; } object[] array = (object[])photonEvent.CustomData; int num = (int)array[0]; string fullWord = (string)array[1]; string keyword = (string)array[2]; string text = (string)array[3]; string text2 = (string)array[4]; Vector3 position = (Vector3)array[5]; string text3 = ((array.Length > 6) ? ((string)array[6]) : string.Empty); string playerName = "Unknown"; Color color = Color.white; Player player = PhotonNetwork.CurrentRoom.GetPlayer(num, false); if (player != null) { playerName = player.NickName; } Character val = FindCharacterByActorNumber(num); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.refs?.customization)) { color = val.refs.customization.PlayerColor; } DisplayNotification(playerName, color, fullWord, keyword, text, text2); if (EventHandler.Events.TryGetValue(text, out IVoiceEvent value)) { if (Object.op_Implicit((Object)(object)val)) { string detail = ((!string.IsNullOrEmpty(text3)) ? text3 : text2); value.PlayEffects(val, position, detail); } else { value.PlayEffects(position); } } } private static Character? FindCharacterByActorNumber(int actorNumber) { return ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character c) => ((MonoBehaviourPun)c).photonView.OwnerActorNr == actorNumber)); } private static void DisplayNotification(string playerName, Color color, string fullWord, string keyword, string eventName, string detail) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_connectionLog)) { Object obj = Object.FindFirstObjectByType(Type.GetType("PlayerConnectionLog, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")); _connectionLog = (MonoBehaviour?)(((object)((obj is MonoBehaviour) ? obj : null)) ?? ((object)((IEnumerable<MonoBehaviour>)Object.FindObjectsByType<MonoBehaviour>((FindObjectsSortMode)0)).FirstOrDefault((Func<MonoBehaviour, bool>)((MonoBehaviour m) => ((object)m).GetType().Name == "PlayerConnectionLog")))); _addMessageMethod = null; } if (!Object.op_Implicit((Object)(object)_connectionLog)) { return; } if (_addMessageMethod == null) { _addMessageMethod = ((object)_connectionLog).GetType().GetMethod("AddMessage", BindingFlags.Instance | BindingFlags.NonPublic); } if (_addMessageMethod == null) { return; } string text = "#" + ColorUtility.ToHtmlStringRGB(color); string text2 = fullWord; int num = fullWord.IndexOf(keyword, StringComparison.OrdinalIgnoreCase); if (num >= 0) { string text3 = fullWord.Substring(0, num); string text4 = fullWord.Substring(num, keyword.Length); int num2 = num + keyword.Length; string text5 = fullWord.Substring(num2, fullWord.Length - num2); text2 = text3 + "<color=#8B0000>" + text4 + "</color>" + text5; } string text6 = "<color=" + text + ">" + playerName + " сказал \"" + text2 + "\" что запустило </color><color=#FFA500>" + (engToRuWords.ContainsKey(eventName) ? engToRuWords[eventName] : eventName) + "</color><color=#FAFA33>" + (string.IsNullOrEmpty(detail) ? "" : (" (" + (engToRuWords.ContainsKey(detail) ? engToRuWords[detail] : detail) + ")")) + "</color>"; try { _addMessageMethod.Invoke(_connectionLog, new object[1] { text6 }); } catch { _connectionLog = null; } } } public class VoiceHandler : IDisposable { private readonly ManualLogSource _log; private readonly Config _config; private IVoiceRecognizer? _recognizer; private EventHandler? _eventHandler; private NetworkHandler? _networker; private Model? _voskModel; private VoiceHook? _activeHook; private readonly ConcurrentQueue<Action> _mainThreadActions = new ConcurrentQueue<Action>(); private volatile string _lastPartialText = ""; [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool SetDllDirectory(string lpPathName); public VoiceHandler(ManualLogSource logger, Config config, string pluginDir) { _log = logger; _config = config; Initialize(pluginDir); } private void Initialize(string pluginDir) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown _log.LogInfo((object)"Инициализация менеджера VoiceCurseRu..."); if (Directory.Exists(pluginDir)) { SetDllDirectory(pluginDir); } _eventHandler = new EventHandler(_config); _networker = new NetworkHandler(); PhotonNetwork.AddCallbackTarget((object)_networker); string text = Path.Combine(pluginDir, "model-ru-ru"); if (Directory.Exists(text)) { try { _voskModel = new Model(text); _log.LogInfo((object)"Vosk Model loaded successfully."); return; } catch (Exception ex) { _log.LogError((object)("Ошибка запуска Vosk Model: " + ex.Message)); return; } } _log.LogError((object)("Vosk model не найден: " + text)); } public void Update() { Action result; while (_mainThreadActions.TryDequeue(out result)) { result(); } if (!Object.op_Implicit((Object)(object)_activeHook) && Object.op_Implicit((Object)(object)Character.localCharacter)) { TryHookIntoPhotonVoice(); } } private void TryHookIntoPhotonVoice() { PhotonVoiceView component = ((Component)Character.localCharacter).GetComponent<PhotonVoiceView>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.RecorderInUse)) { Recorder recorderInUse = component.RecorderInUse; VoiceHook voiceHook = ((Component)recorderInUse).gameObject.AddComponent<VoiceHook>(); voiceHook.Initialize(this, recorderInUse); _activeHook = voiceHook; _log.LogInfo((object)("[VoiceCurseRu] Hooked into Recorder on: " + ((Object)((Component)recorderInUse).gameObject).name)); } } public void OnPhotonVoiceReady(Recorder recorder, LocalVoice voice) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0023: Unknown result type (might be due to invalid IL or missing references) int num = 48000; VoiceInfo info = voice.Info; if (((VoiceInfo)(ref info)).SamplingRate > 0) { info = voice.Info; num = ((VoiceInfo)(ref info)).SamplingRate; } _log.LogInfo((object)$"[VoiceCurseRu] Photon Input Rate: {num} Hz. Initializing Vosk at 16000 Hz."); SetupVoiceRecognition(); if (_recognizer is VoiceRecognizer && voice is LocalVoiceAudio<float> val) { ((LocalVoiceFramed<float>)(object)val).AddPostProcessor(new IProcessor<float>[1] { new VoiceProcessor(_recognizer, num) }); _log.LogInfo((object)$"[VoiceCurseRu] Audio Processor attached. Resampling {num} -> 16000 Hz."); } else { _log.LogWarning((object)("[VoiceCurseRu] Could not attach processor. Voice type: " + ((object)voice).GetType().Name)); } } private void SetupVoiceRecognition() { if (_recognizer != null || _voskModel == null) { return; } try { _recognizer = new VoiceRecognizer(_voskModel, 16000f); _recognizer.OnPhraseRecognized += delegate(string text) { string text2 = text; _lastPartialText = ""; _mainThreadActions.Enqueue(delegate { _log.LogInfo((object)("[Recognized]: " + text2)); _eventHandler?.HandleSpeech(text2, isFinal: true); }); }; _recognizer.OnPartialResult += delegate(string text) { if (!string.IsNullOrWhiteSpace(text) && text.Length >= 2 && !(_lastPartialText == text)) { _lastPartialText = text; string captured = text; _mainThreadActions.Enqueue(delegate { _log.LogInfo((object)("[Partial]: " + captured)); _eventHandler?.HandleSpeech(captured, isFinal: false); }); } }; _recognizer.Start(); _log.LogInfo((object)"[VoiceCurse] Vosk Recognizer запустился."); } catch (Exception ex) { _log.LogError((object)("Ошибка запуска Vosk Recognizer: " + ex.Message)); } } public void Dispose() { if (_networker != null) { PhotonNetwork.RemoveCallbackTarget((object)_networker); } _recognizer?.Stop(); _recognizer?.Dispose(); Model? voskModel = _voskModel; if (voskModel != null) { voskModel.Dispose(); } _log.LogInfo((object)"VoiceCurse Manager отключился."); } } } namespace VoiceCurse.Events { public class AfflictionEvent : VoiceEventBase { private readonly Dictionary<string, STATUSTYPE> _wordToType; public AfflictionEvent(Config config) : base(config) { _wordToType = new Dictionary<string, STATUSTYPE>(); LoadKeywordsForType(config.AfflictionKeywordsInjury.Value, (STATUSTYPE)0); LoadKeywordsForType(config.AfflictionKeywordsHunger.Value, (STATUSTYPE)1); LoadKeywordsForType(config.AfflictionKeywordsCold.Value, (STATUSTYPE)2); LoadKeywordsForType(config.AfflictionKeywordsHot.Value, (STATUSTYPE)8); LoadKeywordsForType(config.AfflictionKeywordsPoison.Value, (STATUSTYPE)3); LoadKeywordsForType(config.AfflictionKeywordsSpores.Value, (STATUSTYPE)10); } private void LoadKeywordsForType(string configLine, STATUSTYPE type) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) IEnumerable<string> enumerable = from w in configLine.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select w.Trim().ToLowerInvariant() into w where !string.IsNullOrWhiteSpace(w) select w; foreach (string item in enumerable) { _wordToType[item] = type; } } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.AfflictionEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> keys = _wordToType.Keys; result = keys; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Invalid comparison between Unknown and I4 //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 if (!Config.AfflictionEnabled.Value) { return false; } if (player.refs?.afflictions == null) { return false; } if (player.data.dead || player.data.fullyPassedOut) { return false; } if (!_wordToType.TryGetValue(matchedKeyword, out var value)) { return false; } base.ExecutionDetail = ((object)(STATUSTYPE)(ref value)).ToString(); bool value2 = Config.AfflictionTemperatureSwapEnabled.Value; bool flag = value2; if (flag) { bool flag2 = (((int)value == 2 || (int)value == 8) ? true : false); flag = flag2; } if (flag) { HandleTemperatureExchange(player, value); } float num = Random.Range(Config.AfflictionMinPercent.Value, Config.AfflictionMaxPercent.Value); if (Config.EnableDebugLogs.Value) { Debug.Log((object)$"[VoiceCurse] Affliction Specifics: {value} ({num:P0})"); } player.refs.afflictions.AddStatus(value, num, false, true); return true; } private void HandleTemperatureExchange(Character player, STATUSTYPE incomingType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0009: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) STATUSTYPE val = (STATUSTYPE)(((int)incomingType == 8) ? 2 : 8); float currentStatus = player.refs.afflictions.GetCurrentStatus(val); if (!(currentStatus <= 0.01f)) { if (Config.EnableDebugLogs.Value) { Debug.Log((object)$"[VoiceCurse] Swapping {val} ({currentStatus:P0}) to {incomingType}"); } player.refs.afflictions.SubtractStatus(val, currentStatus, false, false); player.refs.afflictions.AddStatus(incomingType, currentStatus, false, true); } } } public class BlindEvent : VoiceEventBase { [CompilerGenerated] private sealed class <BlindnessRoutine>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Character player; public BlindEvent <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <BlindnessRoutine>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (Time.time < <>4__this._blindEndTime && Object.op_Implicit((Object)(object)player) && !player.data.dead) { <>2__current = null; <>1__state = 1; return true; } if (Object.op_Implicit((Object)(object)player)) { ToggleBlindness(player, enable: false); } <>4__this._blindRoutine = null; 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(); } } private readonly HashSet<string> _keywords = VoiceEventBase.ParseKeywords(config.BlindKeywords.Value); private float _blindEndTime; private Coroutine? _blindRoutine; public BlindEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.BlindEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> keywords = _keywords; result = keywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { if (!Config.BlindEnabled.Value) { return false; } if (player.data.dead) { return false; } float value = Config.BlindDuration.Value; _blindEndTime = Time.time + value; if (_blindRoutine == null) { ToggleBlindness(player, enable: true); _blindRoutine = ((MonoBehaviour)player).StartCoroutine(BlindnessRoutine(player)); } player.AddIllegalStatus("BLIND", value); return true; } [IteratorStateMachine(typeof(<BlindnessRoutine>d__6))] private IEnumerator BlindnessRoutine(Character player) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <BlindnessRoutine>d__6(0) { <>4__this = this, player = player }; } private static void ToggleBlindness(Character player, bool enable) { if (Object.op_Implicit((Object)(object)player) && player.refs != null && Object.op_Implicit((Object)(object)player.refs.customization) && Object.op_Implicit((Object)(object)player.refs.customization.refs)) { Renderer blindRenderer = player.refs.customization.refs.blindRenderer; if (Object.op_Implicit((Object)(object)blindRenderer)) { ((Component)blindRenderer).gameObject.SetActive(enable); } } } } public class DeathEvent : VoiceEventBase { private readonly HashSet<string> _deathKeywords = VoiceEventBase.ParseKeywords(config.DeathKeywords.Value); public DeathEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.DeathEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> deathKeywords = _deathKeywords; result = deathKeywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { if (!Config.DeathEnabled.Value) { return false; } if (player.data.dead) { return false; } player.DieInstantly(); return true; } } public class DropEvent : VoiceEventBase { private readonly HashSet<string> _keywords = VoiceEventBase.ParseKeywords(config.DropKeywords.Value); public DropEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.DropEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> keywords = _keywords; result = keywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { return Config.DropEnabled.Value && !player.data.dead; } public override void PlayEffects(Character origin, Vector3 position) { //IL_0048: 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) //IL_004e: 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_006e: 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) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient || !Object.op_Implicit((Object)(object)origin) || origin.data.dead) { return; } ScatterBackpackContents(origin); Transform transform = ((Component)origin.GetBodypart((BodypartType)0)).transform; Vector3 val = transform.forward; if (Vector3.Dot(val, Vector3.up) < 0f) { val = -val; } Vector3 val2 = origin.Center + val * 0.6f + Vector3.up * 0.5f; for (byte b = 0; b < 4; b++) { if (!origin.player.GetItemSlot(b).IsEmpty()) { origin.refs.items.photonView.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2] { b, val2 }); val2 += Vector3.up * 0.3f; } } origin.refs.items.photonView.RPC("EquipSlotRpc", (RpcTarget)0, new object[2] { -1, -1 }); } private static void ScatterBackpackContents(Character player) { //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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) ItemSlot itemSlot = player.player.GetItemSlot((byte)3); BackpackData val = default(BackpackData); if (itemSlot.IsEmpty() || !itemSlot.data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val)) { return; } Vector3 center = player.Center; ItemSlot[] itemSlots = val.itemSlots; PhotonView val5 = default(PhotonView); foreach (ItemSlot val2 in itemSlots) { if (val2.IsEmpty()) { continue; } string prefabName = val2.GetPrefabName(); if (!string.IsNullOrEmpty(prefabName)) { Vector3 val3 = center + Random.insideUnitSphere * 0.5f; val3.y = center.y + 0.5f; GameObject val4 = PhotonNetwork.Instantiate("0_Items/" + prefabName, val3, Quaternion.identity, (byte)0, (object[])null); if (val4.TryGetComponent<PhotonView>(ref val5)) { val5.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { val2.data }); val5.RPC("SetKinematicRPC", (RpcTarget)0, new object[3] { false, val3, Quaternion.identity }); } val2.EmptyOut(); } } } } public class ExplodeEvent : VoiceEventBase { private readonly HashSet<string> _keywords = VoiceEventBase.ParseKeywords(config.ExplodeKeywords.Value); private static GameObject? _cachedExplosionPrefab; public ExplodeEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.ExplodeEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> keywords = _keywords; result = keywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { if (!Config.ExplodeEnabled.Value) { return false; } return !player.data.dead; } public override void PlayEffects(Vector3 position) { //IL_0030: 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_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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_cachedExplosionPrefab)) { FindExplosionPrefab(); } if (Object.op_Implicit((Object)(object)_cachedExplosionPrefab)) { Object.Instantiate<GameObject>(_cachedExplosionPrefab, position, Quaternion.identity); } Character localCharacter = Character.localCharacter; if (!Object.op_Implicit((Object)(object)localCharacter) || localCharacter.data.dead) { return; } float num = Vector3.Distance(localCharacter.Center, position); if (num <= Config.ExplodeRadius.Value) { if (Object.op_Implicit((Object)(object)localCharacter.refs.afflictions)) { localCharacter.refs.afflictions.AddStatus((STATUSTYPE)0, Config.ExplodeDamage.Value, false, true); } localCharacter.Fall(Config.ExplodeStunDuration.Value, 0f); Vector3 val = localCharacter.Center - position; Vector3 val2 = ((Vector3)(ref val)).normalized; val2 += Vector3.up * 0.6f; ((Vector3)(ref val2)).Normalize(); float num2 = Random.Range(Config.ExplodeForceLowerBound.Value, Config.ExplodeForceHigherBound.Value); localCharacter.AddForce(val2 * num2, 1f, 1f); } } private static void FindExplosionPrefab() { Dynamite val = Resources.FindObjectsOfTypeAll<Dynamite>().FirstOrDefault(); if (Object.op_Implicit((Object)(object)val)) { _cachedExplosionPrefab = val.explosionPrefab; } } } public class HealEvent : VoiceEventBase { private readonly HashSet<string> _keywords = VoiceEventBase.ParseKeywords(config.HealKeywords.Value); private float _lastHealTime = -999f; public HealEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.HealEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> keywords = _keywords; result = keywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { if (!Config.HealEnabled.Value) { return false; } if (player.data.dead || player.data.fullyPassedOut) { return false; } if (Time.time < _lastHealTime + Config.HealCooldown.Value) { Debug.Log((object)"[VoiceCurse] Cooldown active, cannot heal now."); return false; } _lastHealTime = Time.time; player.refs.afflictions.SubtractStatus((STATUSTYPE)0, Config.HealAmount.Value, false, false); player.refs.afflictions.SubtractStatus((STATUSTYPE)10, Config.HealAmount.Value, false, false); player.refs.afflictions.SubtractStatus((STATUSTYPE)2, Config.HealAmount.Value, false, false); player.refs.afflictions.SubtractStatus((STATUSTYPE)6, Config.HealAmount.Value, false, false); player.refs.afflictions.SubtractStatus((STATUSTYPE)8, Config.HealAmount.Value, false, false); player.refs.afflictions.SubtractStatus((STATUSTYPE)3, Config.HealAmount.Value, false, false); player.refs.afflictions.SubtractStatus((STATUSTYPE)9, Config.HealAmount.Value, false, false); return true; } } public class LaunchEvent : VoiceEventBase { private readonly HashSet<string> _keywords = VoiceEventBase.ParseKeywords(config.LaunchKeywords.Value); private static GameObject? _cachedLaunchSFX; public LaunchEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.LaunchEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> keywords = _keywords; result = keywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) if (!Config.LaunchEnabled.Value) { return false; } if (player.data.dead || player.data.fullyPassedOut) { return false; } if (_cachedLaunchSFX == null) { FindLaunchSFX(); } player.Fall(Config.LaunchStunDuration.Value, 0f); Vector3 normalized = ((Vector3)(ref player.data.lookDirection_Flat)).normalized; Vector3 val = Vector3.Cross(Vector3.up, normalized); string executionDetail; Vector3 val2; if (fullSentence.Contains("влево") || fullSentence.Contains("налево")) { executionDetail = "Left"; val2 = -val + Vector3.up * 0.2f; } else if (fullSentence.Contains("вправо") || fullSentence.Contains("направо")) { executionDetail = "Right"; val2 = val + Vector3.up * 0.2f; } else if (fullSentence.Contains("взад") || fullSentence.Contains("назад") || fullSentence.Contains("сзади")) { executionDetail = "Back"; val2 = -normalized + Vector3.up * 0.2f; } else if (fullSentence.Contains("вперёд") || fullSentence.Contains("вперед") || fullSentence.Contains("впереди")) { executionDetail = "Forward"; val2 = normalized + Vector3.up * 0.2f; } else if (fullSentence.Contains("вверх") || fullSentence.Contains("наверх")) { executionDetail = "Up"; val2 = Vector3.up; } else { executionDetail = "Random"; val2 = GetRandomUpwardDirection(); } base.ExecutionDetail = executionDetail; ((Vector3)(ref val2)).Normalize(); float num = Random.Range(Config.LaunchForceLowerBound.Value, Config.LaunchForceHigherBound.Value); Vector3 val3 = val2 * num; player.AddForce(val3, 1f, 1f); return true; } private static Vector3 GetRandomUpwardDirection() { //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_0009: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) Vector3 onUnitSphere = Random.onUnitSphere; onUnitSphere.y = Mathf.Abs(onUnitSphere.y); if (onUnitSphere.y < 0.5f) { onUnitSphere.y = 0.5f; } return onUnitSphere; } public override void PlayEffects(Vector3 position) { //IL_0030: 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 (!Object.op_Implicit((Object)(object)_cachedLaunchSFX)) { FindLaunchSFX(); } if (Object.op_Implicit((Object)(object)_cachedLaunchSFX)) { GameObject val = Object.Instantiate<GameObject>(_cachedLaunchSFX, position, Quaternion.identity); val.SetActive(true); Object.Destroy((Object)(object)val, 5f); } } private static void FindLaunchSFX() { ScoutCannon val = Resources.FindObjectsOfTypeAll<ScoutCannon>().FirstOrDefault(); if (val != null) { _cachedLaunchSFX = val.fireSFX; } } } public class SacrificeEvent : VoiceEventBase { private readonly HashSet<string> _sacrificeKeywords = VoiceEventBase.ParseKeywords(config.SacrificeKeywords.Value); private float _lastSacrificeTime = -999f; public SacrificeEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.SacrificeEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> sacrificeKeywords = _sacrificeKeywords; result = sacrificeKeywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if (!Config.SacrificeEnabled.Value) { return false; } if (player.data.dead) { return false; } if (Time.time < _lastSacrificeTime + Config.SacrificeCooldown.Value) { Debug.Log((object)"[VoiceCurse] Cooldown active, cannot sacrifice now."); return false; } Vector3 deathPos; Character closestDeadPlayer = DeathTracker.GetClosestDeadPlayer(player.Center, out deathPos); if (!Object.op_Implicit((Object)(object)closestDeadPlayer)) { return false; } _lastSacrificeTime = Time.time; Vector3 val = deathPos + Vector3.up * 1f; base.ExecutionDetail = "Reviving " + closestDeadPlayer.characterName; closestDeadPlayer.view.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[2] { val, true }); DeathTracker.RemoveDeath(closestDeadPlayer); player.DieInstantly(); return true; } } [HarmonyPatch(typeof(Character))] public static class DeathTracker { private static readonly Dictionary<int, Vector3> DeathLocations = new Dictionary<int, Vector3>(); [HarmonyPatch("RPCA_Die")] [HarmonyPrefix] private static void OnDiePrefix(Character __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)__instance)) { DeathLocations[((MonoBehaviourPun)__instance).photonView.ViewID] = __instance.Center; } } [HarmonyPatch("RPCA_Revive")] [HarmonyPostfix] private static void OnRevivePostfix(Character __instance) { RemoveDeath(__instance); } [HarmonyPatch("RPCA_ReviveAtPosition")] [HarmonyPostfix] private static void OnReviveAtPosPostfix(Character __instance) { RemoveDeath(__instance); } public static void RemoveDeath(Character c) { if (Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((MonoBehaviourPun)c).photonView)) { DeathLocations.Remove(((MonoBehaviourPun)c).photonView.ViewID); } } public static Character? GetClosestDeadPlayer(Vector3 origin, out Vector3 deathPos) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) Character result = null; float num = float.MaxValue; deathPos = Vector3.zero; foreach (Character item in Character.AllCharacters.Where((Character c) => c.data.dead)) { Vector3 val; if (DeathLocations.TryGetValue(((MonoBehaviourPun)item).photonView.ViewID, out var value)) { val = value; } else { if (!Object.op_Implicit((Object)(object)item.Ghost)) { continue; } val = ((Component)item.Ghost).transform.position; } float num2 = Vector3.Distance(origin, val); if (num2 < num) { num = num2; result = item; deathPos = val; } } return result; } } public class SleepEvent : VoiceEventBase { private readonly HashSet<string> _sleepKeywords = VoiceEventBase.ParseKeywords(config.SleepKeywords.Value); public SleepEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.SleepEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> sleepKeywords = _sleepKeywords; result = sleepKeywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { if (!Config.SleepEnabled.Value) { return false; } if (player.data.passedOut || player.data.dead) { return false; } player.PassOutInstantly(); return true; } } public class SlipEvent : VoiceEventBase { private readonly HashSet<string> _keywords = VoiceEventBase.ParseKeywords(config.SlipKeywords.Value); private static AudioClip? _cachedTripSound; private Item? _cachedBananaItem; private static readonly Regex NameCleaner = new Regex("\\s*\\((\\d+|Clone)\\)", RegexOptions.Compiled); public SlipEvent(Config config) : base(config) { } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.SlipEnabled.Value) { result = Enumerable.Empty<string>(); } else { IEnumerable<string> keywords = _keywords; result = keywords; } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (!Config.SlipEnabled.Value) { return false; } if (player.data.dead || player.data.fullyPassedOut) { return false; } if (Config.BananaBombEnabled.Value && Random.value <= Config.BananaBombChance.Value) { base.ExecutionDetail = "BananaBomb"; } player.Fall(Config.SlipStunDuration.Value, 0f); Vector3 lookDirection_Flat = player.data.lookDirection_Flat; ApplyForceToPart(player, (BodypartType)16, (lookDirection_Flat + Vector3.up) * 200f); ApplyForceToPart(player, (BodypartType)13, (lookDirection_Flat + Vector3.up) * 200f); ApplyForceToPart(player, (BodypartType)0, Vector3.up * 1500f); ApplyForceToPart(player, (BodypartType)4, lookDirection_Flat * -300f); return true; } private static void ApplyForceToPart(Character player, BodypartType partType, Vector3 force) { //IL_0002: 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) Rigidbody bodypartRig = player.GetBodypartRig(partType); if (Object.op_Implicit((Object)(object)bodypartRig)) { bodypartRig.AddForce(force, (ForceMode)1); } } public override void PlayEffects(Character origin, Vector3 position, string detail) { //IL_0003: 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) base.PlayEffects(origin, position, detail); if (detail == "BananaBomb") { SpawnBananaBomb(position); } } public override void PlayEffects(Vector3 position) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) AudioClip tripSound = GetTripSound(); if (Object.op_Implicit((Object)(object)tripSound)) { AudioSource.PlayClipAtPoint(tripSound, position); } } private void SpawnBananaBomb(Vector3 origin) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } Item bananaItem = GetBananaItem(); if (!Object.op_Implicit((Object)(object)bananaItem)) { if (Config.EnableDebugLogs.Value) { Debug.LogWarning((object)"[VoiceCurseRu] 'Банановая желтая кожура' не найдена для Банановой бомбы."); } return; } string text = NameCleaner.Replace(((Object)bananaItem).name, "").Trim(); string text2 = "0_Items/" + text; int value = Config.BananaBombAmount.Value; PhotonView val3 = default(PhotonView); Rigidbody val4 = default(Rigidbody); for (int i = 0; i < value; i++) { Vector3 val = origin + Random.insideUnitSphere * 3f; val.y = origin.y + 1.5f; GameObject val2 = PhotonNetwork.Instantiate(text2, val, Quaternion.identity, (byte)0, (object[])null); if (Object.op_Implicit((Object)(object)val2) && val2.TryGetComponent<PhotonView>(ref val3)) { val3.RPC("SetKinematicRPC", (RpcTarget)0, new object[3] { false, val, Quaternion.identity }); Vector3 randomUpwardDirection = GetRandomUpwardDirection(); float num = Random.Range(25f, 200f); if (val2.TryGetComponent<Rigidbody>(ref val4)) { val4.isKinematic = false; val4.AddForce(randomUpwardDirection * num, (ForceMode)1); } } } } private static Vector3 GetRandomUpwardDirection() { //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_0009: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) Vector3 onUnitSphere = Random.onUnitSphere; onUnitSphere.y = Mathf.Abs(onUnitSphere.y); if (onUnitSphere.y < 0.2f) { onUnitSphere.y = 0.5f; } return ((Vector3)(ref onUnitSphere)).normalized; } private Item? GetBananaItem() { if (Object.op_Implicit((Object)(object)_cachedBananaItem)) { return _cachedBananaItem; } _cachedBananaItem = ((IEnumerable<Item>)Resources.FindObjectsOfTypeAll<Item>()).FirstOrDefault((Func<Item, bool>)((Item i) => ((Object)i).name.Contains("Berrynana Peel Yellow"))); return _cachedBananaItem; } private static AudioClip? GetTripSound() { if (!Object.op_Implicit((Object)(object)_cachedTripSound)) { _cachedTripSound = ((IEnumerable<AudioClip>)Resources.FindObjectsOfTypeAll<AudioClip>()).FirstOrDefault((Func<AudioClip, bool>)((AudioClip c) => ((Object)c).name == "Au_Slip1")); } return _cachedTripSound; } } [Serializable] public class TransmutePayload { public string? ruleName; public bool isDeath; public int spawnCount; public Vector3 deathPosition; } public class TransmuteEvent : VoiceEventBase { private readonly List<(string Name, string[] Triggers, string[] Targets, Func<bool> IsEnabled)> _definitions; private readonly Dictionary<string, (string Name, string[] Targets, Func<bool> IsEnabled)> _transmuteLookup = new Dictionary<string, (string, string[], Func<bool>)>(); private readonly Dictionary<string, Item?> _itemCache = new Dictionary<string, Item>(); private static readonly Regex NameCleaner = new Regex("\\s*\\((\\d+|Clone)\\)", RegexOptions.Compiled); public TransmuteEvent(Config config) { Config config2 = config; base..ctor(config2); _definitions = new List<(string, string[], string[], Func<bool>)>(9) { ("Milk", new string[2] { "молоко", "кальций" }, new string[1] { "Fortified Milk" }, () => config2.TransmuteMilkEnabled.Value), ("Cactus", new string[1] { "кактус" }, new string[1] { "Cactus" }, () => config2.TransmuteCactusEnabled.Value), ("Coconut", new string[1] { "кокос" }, new string[1] { "Coconut" }, () => config2.TransmuteCoconutEnabled.Value), ("Apple", new string[2] { "яблок", "ягод" }, new string[3] { "Red Crispberry", "Yellow Crispberry", "Green Crispberry" }, () => config2.TransmuteAppleEnabled.Value), ("Banana", new string[1] { "банан" }, new string[1] { "Berrynana Peel Yellow" }, () => config2.TransmuteBananaEnabled.Value), ("Egg", new string[1] { "яйц" }, new string[1] { "Egg" }, () => config2.TransmuteEggEnabled.Value), ("Fruit", new string[1] { "фрукт" }, new string[10] { "Red Crispberry", "Yellow Crispberry", "Green Crispberry", "Kingberry Purple", "Kingberry Yellow", "Kingberry Green", "Berrynana Brown", "Berrynana Yellow", "Berrynana Pink", "Berrynana Blue" }, () => config2.TransmuteFruitEnabled.Value), ("Mushroom", new string[1] { "гриб" }, new string[1] { "Mushroom Normie" }, () => config2.TransmuteMushroomEnabled.Value), ("Ball", new string[1] { "мяч" }, new string[1] { "Basketball" }, () => config2.TransmuteBallEnabled.Value) }; foreach (var definition in _definitions) { string[] item = definition.Triggers; foreach (string key in item) { _transmuteLookup[key] = (definition.Name, definition.Targets, definition.IsEnabled); } } } protected override IEnumerable<string> GetKeywords() { IEnumerable<string> result; if (!Config.TransmuteEnabled.Value) { IEnumerable<string> enumerable = Array.Empty<string>(); result = enumerable; } else { result = _definitions.Where<(string, string[], string[], Func<bool>)>(((string Name, string[] Triggers, string[] Targets, Func<bool> IsEnabled) d) => d.IsEnabled()).SelectMany<(string, string[], string[], Func<bool>), string>(((string Name, string[] Triggers, string[] Targets, Func<bool> IsEnabled) d) => d.Triggers); } return result; } protected override bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword) { //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) string fullSentence2 = fullSentence; if (!Config.TransmuteEnabled.Value) { return false; } if (player.data.dead) { return false; } string[] array = null; string text = null; if (_transmuteLookup.TryGetValue(matchedKeyword, out (string, string[], Func<bool>) value) && value.Item3()) { (text, array, _) = value; } if (array == null) { string text2 = _transmuteLookup.Keys.FirstOrDefault((string k) => fullSentence2.Contains(k) && _transmuteLookup[k].IsEnabled()); if (text2 != null) { (text, array, _) = _transmuteLookup[text2]; } } if (array == null || array.Length == 0) { return false; } bool value2 = Config.TransmuteDeathEnabled.Value; TransmutePayload transmutePayload = new TransmutePayload { ruleName = text, isDeath = value2, spawnCount = 0, deathPosition = player.Center }; if (value2) { int spawnCount = ClearInventoryForDeath(player); player.DieInstantly(); transmutePayload.spawnCount = spawnCount; } base.ExecutionDetail = text; base.ExecutionPayload = JsonUtility.ToJson((object)transmutePayload); return true; } public override void PlayEffects(Character origin, Vector3 position, string detail) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient || !Object.op_Implicit((Object)(object)origin) || string.IsNullOrEmpty(detail)) { return; } TransmutePayload payload; try { payload = JsonUtility.FromJson<TransmutePayload>(detail); } catch { return; } if (payload == null || string.IsNullOrEmpty(payload.ruleName)) { return; } (string, string[], string[], Func<bool>) tuple = _definitions.FirstOrDefault<(string, string[], string[], Func<bool>)>(((string Name, string[] Triggers, string[] Targets, Func<bool> IsEnabled) d) => d.Name == payload.ruleName); if (tuple.Item3 == null || tuple.Item3.Length == 0) { return; } string[] item = tuple.Item3; if (payload.isDeath) { Vector3 origin2 = ((payload.deathPosition != Vector3.zero) ? payload.deathPosition : origin.Center); SpawnTransmutedItems(origin2, payload.spawnCount, item); return; } TransmuteInventoryAlive(origin, item); float num = Random.Range(Config.AfflictionMinPercent.Value, Config.AfflictionMaxPercent.Value); if (Object.op_Implicit((Object)(object)origin.refs.afflictions)) { origin.refs.afflictions.AddStatus((STATUSTYPE)0, num, false, true); } } private static int ClearInventoryForDeath(Character player) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) int num = 1; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, -5000f, 0f); for (byte b = 0; b < 3; b++) { ItemSlot itemSlot = player.player.GetItemSlot(b); if (itemSlot != null && !itemSlot.IsEmpty()) { num++; player.refs.items.photonView.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2] { b, val }); } } ItemSlot itemSlot2 = player.player.GetItemSlot((byte)3); if (itemSlot2 != null && !itemSlot2.IsEmpty()) { BackpackData val2 = default(BackpackData); if (itemSlot2.data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val2)) { num += val2.FilledSlotCount(); } num++; player.refs.items.photonView.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2] { (byte)3, val }); } if (Object.op_Implicit((Object)(object)player.refs.afflictions)) { player.refs.afflictions.UpdateWeight(); } return num; } private void TransmuteInventoryAlive(Character player, string[] possibleTargets) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, -5000f, 0f); Vector3 center = player.Center; player.refs.items.photonView.RPC("EquipSlotRpc", (RpcTarget)0, new object[2] { -1, -1 }); for (byte b = 0; b < 3; b++) { ItemSlot itemSlot = player.player.GetItemSlot(b); if (itemSlot != null && !itemSlot.IsEmpty()) { player.refs.items.photonView.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2] { b, val }); SpawnTransmutedItems(center, 1, possibleTargets); } } if (Config.TransmuteBackpackEnabled.Value) { ItemSlot itemSlot2 = player.player.GetItemSlot((byte)3); if (itemSlot2 != null && !itemSlot2.IsEmpty()) { int num = 1; BackpackData val2 = default(BackpackData); if (itemSlot2.data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val2)) { num += val2.FilledSlotCount(); } player.refs.items.photonView.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2] { (byte)3, val }); SpawnTransmutedItems(center, num, possibleTargets); } } if (Object.op_Implicit((Object)(object)player.refs.afflictions)) { player.refs.afflictions.UpdateWeight(); } } private void SpawnTransmutedItems(Vector3 origin, int count, string[] targets) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < count; i++) { SpawnItem(origin, targets, autoPickup: false, null); } } private void SpawnItem(Vector3 origin, string[] targets, bool autoPickup, Character? picker) { //IL_0029: 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_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_003e: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) string searchName = targets[Random.Range(0, targets.Length)]; Item orFindItem = GetOrFindItem(searchName); if (!Object.op_Implicit((Object)(object)orFindItem)) { return; } Vector3 val = origin + Random.insideUnitSphere * 0.5f; val.y = origin.y + 0.5f; string text = NameCleaner.Replace(((Object)orFindItem).name, "").Trim(); string text2 = "0_Items/" + text; GameObject val2 = PhotonNetwork.Instantiate(text2, val, Quaternion.identity, (byte)0, (object[])null); PhotonView val3 = default(PhotonView); if (!Object.op_Implicit((Object)(object)val2) || !val2.TryGetComponent<PhotonView>(ref val3)) { return; } val3.RPC("SetKinematicRPC", (RpcTarget)0, new object[3] { false, val, Quaternion.identity }); Item val4 = default(Item); if (autoPickup && Object.op_Implicit((Object)(object)picker) && val2.TryGetComponent<Item>(ref val4)) { if (picker.refs != null && (Object)(object)picker.refs.items != (Object)null) { picker.refs.items.lastEquippedSlotTime = 0f; } val4.Interact(picker); } } private Item? GetOrFindItem(string searchName) { string searchName2 = searchName; if (_itemCache.TryGetValue(searchName2, out Item value)) { if (Object.op_Implicit((Object)(object)value)) { return value; } _itemCache.Remove(searchName2); } Item val = ((IEnumerable<Item>)Resources.FindObjectsOfTypeAll<Item>()).FirstOrDefault((Func<Item, bool>)((Item i) => ((Object)i).name.Contains(searchName2) || (i.UIData != null && i.UIData.itemName.Contains(searchName2)))); _itemCache[searchName2] = val; if (!Object.op_Implicit((Object)(object)val) && Config.EnableDebugLogs.Value) { Debug.LogWarning((object)("[VoiceCurseRu] Не найден подходящий предмет '" + searchName2 + "'")); } return val; } } public abstract class VoiceEventBase : IVoiceEvent { protected readonly Config Config; private float _lastExecutionTime; private float Cooldown => Config.GlobalCooldown.Value; protected string? ExecutionDetail { get; set; } protected string? ExecutionPayload { get; set; } protected VoiceEventBase(Config config) { Config = config; _lastExecutionTime = -999f; base..ctor(); } protected abstract IEnumerable<string> GetKeywords(); protected abstract bool OnExecute(Character player, string spokenWord, string fullSentence, string matchedKeyword); protected static HashSet<string> ParseKeywords(string configLine) { return (from k in configLine.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select k.Trim().ToLowerInvariant() into k where !string.IsNullOrWhiteSpace(k) select k).ToHashSet(); } public bool TryExecute(string spokenWord, string fullSentence) { //IL_0232: Unknown result type (might be due to invalid I
plugins/Vosk.dll
Decompiled a day agousing System; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace Vosk; public class Model : IDisposable { private HandleRef handle; internal Model(IntPtr cPtr) { handle = new HandleRef(this, cPtr); } public Model(string model_path) : this(VoskPINVOKE.new_Model(model_path)) { } internal static HandleRef getCPtr(Model obj) { return obj?.handle ?? new HandleRef(null, IntPtr.Zero); } ~Model() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { lock (this) { if (handle.Handle != IntPtr.Zero) { VoskPINVOKE.delete_Model(handle); handle = new HandleRef(null, IntPtr.Zero); } } } public int FindWord(string word) { return VoskPINVOKE.Model_vosk_model_find_word(handle, word); } } public class SpkModel : IDisposable { private HandleRef handle; internal SpkModel(IntPtr cPtr) { handle = new HandleRef(this, cPtr); } public SpkModel(string model_path) : this(VoskPINVOKE.new_SpkModel(model_path)) { } internal static HandleRef getCPtr(SpkModel obj) { return obj?.handle ?? new HandleRef(null, IntPtr.Zero); } ~SpkModel() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { lock (this) { if (handle.Handle != IntPtr.Zero) { VoskPINVOKE.delete_SpkModel(handle); handle = new HandleRef(null, IntPtr.Zero); } } } } public class Vosk { public static void SetLogLevel(int level) { VoskPINVOKE.SetLogLevel(level); } public static void GpuInit() { VoskPINVOKE.GpuInit(); } public static void GpuThreadInit() { VoskPINVOKE.GpuThreadInit(); } } internal class VoskPINVOKE { static VoskPINVOKE() { } [DllImport("libvosk", EntryPoint = "vosk_model_new")] public static extern IntPtr new_Model(string jarg1); [DllImport("libvosk", EntryPoint = "vosk_model_free")] public static extern void delete_Model(HandleRef jarg1); [DllImport("libvosk", EntryPoint = "vosk_model_find_word")] public static extern int Model_vosk_model_find_word(HandleRef jarg1, string jarg2); [DllImport("libvosk", EntryPoint = "vosk_spk_model_new")] public static extern IntPtr new_SpkModel(string jarg1); [DllImport("libvosk", EntryPoint = "vosk_spk_model_free")] public static extern void delete_SpkModel(HandleRef jarg1); [DllImport("libvosk", EntryPoint = "vosk_recognizer_new")] public static extern IntPtr new_VoskRecognizer(HandleRef jarg1, float jarg2); [DllImport("libvosk", EntryPoint = "vosk_recognizer_new_spk")] public static extern IntPtr new_VoskRecognizerSpk(HandleRef jarg1, float jarg2, HandleRef jarg3); [DllImport("libvosk", EntryPoint = "vosk_recognizer_new_grm")] public static extern IntPtr new_VoskRecognizerGrm(HandleRef jarg1, float jarg2, string jarg3); [DllImport("libvosk", EntryPoint = "vosk_recognizer_free")] public static extern void delete_VoskRecognizer(HandleRef jarg1); [DllImport("libvosk", EntryPoint = "vosk_recognizer_set_max_alternatives")] public static extern void VoskRecognizer_SetMaxAlternatives(HandleRef jarg1, int jarg2); [DllImport("libvosk", EntryPoint = "vosk_recognizer_set_words")] public static extern void VoskRecognizer_SetWords(HandleRef jarg1, int jarg2); [DllImport("libvosk", EntryPoint = "vosk_recognizer_set_partial_words")] public static extern void VoskRecognizer_SetPartialWords(HandleRef jarg1, int jarg2); [DllImport("libvosk", EntryPoint = "vosk_recognizer_set_spk_model")] public static extern void VoskRecognizer_SetSpkModel(HandleRef jarg1, HandleRef jarg2); [DllImport("libvosk", EntryPoint = "vosk_recognizer_accept_waveform")] public static extern bool VoskRecognizer_AcceptWaveform(HandleRef jarg1, [In][MarshalAs(UnmanagedType.LPArray)] byte[] jarg2, int jarg3); [DllImport("libvosk", EntryPoint = "vosk_recognizer_accept_waveform_s")] public static extern bool VoskRecognizer_AcceptWaveformShort(HandleRef jarg1, [In][MarshalAs(UnmanagedType.LPArray)] short[] jarg2, int jarg3); [DllImport("libvosk", EntryPoint = "vosk_recognizer_accept_waveform_f")] public static extern bool VoskRecognizer_AcceptWaveformFloat(HandleRef jarg1, [In][MarshalAs(UnmanagedType.LPArray)] float[] jarg2, int jarg3); [DllImport("libvosk", EntryPoint = "vosk_recognizer_result")] public static extern IntPtr VoskRecognizer_Result(HandleRef jarg1); [DllImport("libvosk", EntryPoint = "vosk_recognizer_partial_result")] public static extern IntPtr VoskRecognizer_PartialResult(HandleRef jarg1); [DllImport("libvosk", EntryPoint = "vosk_recognizer_final_result")] public static extern IntPtr VoskRecognizer_FinalResult(HandleRef jarg1); [DllImport("libvosk", EntryPoint = "vosk_recognizer_reset")] public static extern void VoskRecognizer_Reset(HandleRef jarg1); [DllImport("libvosk", EntryPoint = "vosk_set_log_level")] public static extern void SetLogLevel(int jarg1); [DllImport("libvosk", EntryPoint = "vosk_gpu_init")] public static extern void GpuInit(); [DllImport("libvosk", EntryPoint = "vosk_gpu_thread_init")] public static extern void GpuThreadInit(); } public class VoskRecognizer : IDisposable { private HandleRef handle; internal VoskRecognizer(IntPtr cPtr) { handle = new HandleRef(this, cPtr); } public VoskRecognizer(Model model, float sample_rate) : this(VoskPINVOKE.new_VoskRecognizer(Model.getCPtr(model), sample_rate)) { } public VoskRecognizer(Model model, float sample_rate, SpkModel spk_model) : this(VoskPINVOKE.new_VoskRecognizerSpk(Model.getCPtr(model), sample_rate, SpkModel.getCPtr(spk_model))) { } public VoskRecognizer(Model model, float sample_rate, string grammar) : this(VoskPINVOKE.new_VoskRecognizerGrm(Model.getCPtr(model), sample_rate, grammar)) { } internal static HandleRef getCPtr(VoskRecognizer obj) { return obj?.handle ?? new HandleRef(null, IntPtr.Zero); } ~VoskRecognizer() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { lock (this) { if (handle.Handle != IntPtr.Zero) { VoskPINVOKE.delete_VoskRecognizer(handle); handle = new HandleRef(null, IntPtr.Zero); } } } public void SetMaxAlternatives(int max_alternatives) { VoskPINVOKE.VoskRecognizer_SetMaxAlternatives(handle, max_alternatives); } public void SetWords(bool words) { VoskPINVOKE.VoskRecognizer_SetWords(handle, words ? 1 : 0); } public void SetPartialWords(bool partial_words) { VoskPINVOKE.VoskRecognizer_SetPartialWords(handle, partial_words ? 1 : 0); } public void SetSpkModel(SpkModel spk_model) { VoskPINVOKE.VoskRecognizer_SetSpkModel(handle, SpkModel.getCPtr(spk_model)); } public bool AcceptWaveform(byte[] data, int len) { return VoskPINVOKE.VoskRecognizer_AcceptWaveform(handle, data, len); } public bool AcceptWaveform(short[] sdata, int len) { return VoskPINVOKE.VoskRecognizer_AcceptWaveformShort(handle, sdata, len); } public bool AcceptWaveform(float[] fdata, int len) { return VoskPINVOKE.VoskRecognizer_AcceptWaveformFloat(handle, fdata, len); } private static string PtrToStringUTF8(IntPtr ptr) { int i; for (i = 0; Marshal.ReadByte(ptr, i) != 0; i++) { } byte[] array = new byte[i]; Marshal.Copy(ptr, array, 0, i); return Encoding.UTF8.GetString(array); } public string Result() { return PtrToStringUTF8(VoskPINVOKE.VoskRecognizer_Result(handle)); } public string PartialResult() { return PtrToStringUTF8(VoskPINVOKE.VoskRecognizer_PartialResult(handle)); } public string FinalResult() { return PtrToStringUTF8(VoskPINVOKE.VoskRecognizer_FinalResult(handle)); } public void Reset() { VoskPINVOKE.VoskRecognizer_Reset(handle); } }