Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LethalHaptics v0.0.6
BepInEx/plugins/LethalVibrations.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Buttplug.Client; using Buttplug.Client.Connectors.WebsocketConnector; using Buttplug.Core; using Costura; using GameNetcodeStuff; using HarmonyLib; using LethalVibrations.Buttplug; using LethalVibrations.Patches; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7", FrameworkDisplayName = ".NET Framework 4.7")] [assembly: AssemblyCompany("LethalVibrations")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Lethal Company mod that makes your sex toys vibrate.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LethalVibrations")] [assembly: AssemblyTitle("LethalVibrations")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { AssemblyLoader.Attach(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LethalVibrations { [BepInPlugin("LethalVibrations", "LethalVibrations", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static DeviceManager DeviceManager { get; private set; } internal static ManualLogSource Mls { get; private set; } private void Awake() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_008e: 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) Mls = ((BaseUnityPlugin)this).Logger; DeviceManager = new DeviceManager("LethalVibrations"); DeviceManager.ConnectDevices(); Harmony val = new Harmony("LethalVibrations"); val.PatchAll(typeof(PlayerControllerBPatches)); val.PatchAll(typeof(ItemChargerPatches)); val.PatchAll(typeof(EnemyAIPatches)); val.PatchAll(typeof(HUDManagerPatches)); val.PatchAll(typeof(GrabbableObjectPatches)); val.PatchAll(typeof(RoundManagerPatches)); val.PatchAll(typeof(NoisemakerPropPatches)); val.PatchAll(typeof(ShipAlarmCordPatches)); val.PatchAll(typeof(StunGrenadeItemPatches)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin LethalVibrations (1.0.0) is loaded!"); } } public static class PluginInfo { public const string PLUGIN_GUID = "LethalVibrations"; public const string PLUGIN_NAME = "LethalVibrations"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace LethalVibrations.Patches { internal class EnemyAIPatches { [HarmonyPatch(typeof(EnemyAI), "HitEnemy")] [HarmonyPostfix] private static void HitEnemyPatch(int force, PlayerControllerB playerWhoHit) { if (playerWhoHit.playerClientId == GameNetworkManager.Instance.localPlayerController.playerClientId) { Plugin.Mls.LogDebug((object)"HitEnemy got called"); if (Plugin.DeviceManager.IsConnected() && Config.VibrateDamageDealtEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.VibrateDamageDealtStrength.Value, Config.VibrateDamageDealtDuration.Value); } } } } internal class GrabbableObjectPatches { [HarmonyPatch(typeof(GrabbableObject), "GrabItemOnClient")] [HarmonyPostfix] private static void GrabItemOnClientPatch(GrabbableObject __instance) { if (__instance.itemProperties.isScrap && !__instance.isInShipRoom) { Plugin.Mls.LogDebug((object)"GrabItemOnClient called"); if (Plugin.DeviceManager.IsConnected() && Config.Rewarding.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.VibrateKilledStrength.Value, Config.VibrateKilledDuration.Value); } } } } internal class HUDManagerPatches { [HarmonyPatch(typeof(HUDManager), "ShakeCamera")] [HarmonyPostfix] private static void ShakeCameraPatch(ScreenShakeType shakeType) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected I4, but got Unknown Plugin.Mls.LogDebug((object)$"ShakeCamera {shakeType} got called"); if (Plugin.DeviceManager.IsConnected() && Config.VibrateScreenShakeEnabled.Value) { switch ((int)shakeType) { case 0: Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(0.3f + Config.VibrateScreenShakeAmplifier.Value, Config.VibrateScreenShakeDuration.Value); break; case 1: Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(0.6f + Config.VibrateScreenShakeAmplifier.Value, Config.VibrateScreenShakeDuration.Value); break; case 2: Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(0.5f + Config.VibrateScreenShakeAmplifier.Value, Config.VibrateScreenShakeDuration.Value + 0.6f); break; case 3: Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(0.9f + Config.VibrateScreenShakeAmplifier.Value, Config.VibrateScreenShakeDuration.Value + 0.3f); break; } } } [HarmonyPatch(typeof(HUDManager), "DisplayNewDeadline")] [HarmonyPostfix] private static void DisplayNewDeadlinePatch() { Plugin.Mls.LogDebug((object)"DisplayNewDeadline got called"); if (Plugin.DeviceManager.IsConnected() && Config.QuotaReachedEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.QuotaReachedStrength.Value, Config.QuotaReachedDuration.Value); } } [HarmonyPatch(typeof(HUDManager), "PingScan_performed")] [HarmonyPostfix] private static void PingScan_performedPatch() { Plugin.Mls.LogDebug((object)"PingScan_performed got called"); if (Plugin.DeviceManager.IsConnected() && Config.PingScanEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.PingScanStrength.Value, Config.PingScanDuration.Value); } } } internal class ItemChargerPatches { [HarmonyPatch(typeof(ItemCharger), "ChargeItem")] [HarmonyPostfix] private static void ChargeItemPatch() { Plugin.Mls.LogDebug((object)"ChargeItem got called"); if (Plugin.DeviceManager.IsConnected() && Config.VibrateItemChargerChargeEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.VibrateItemChargerChargeStrength.Value, Config.VibrateItemChargerChargeDuration.Value); } } } internal class NoisemakerPropPatches { [HarmonyPatch(typeof(NoisemakerProp), "ItemActivate")] [HarmonyPostfix] private static void ItemActivatePatch(NoisemakerProp __instance) { Plugin.Mls.LogDebug((object)("NoisemakerProp.ItemActivate got called: " + ((GrabbableObject)__instance).itemProperties.itemName)); if (!(((GrabbableObject)__instance).itemProperties.itemName != "Airhorn") && Plugin.DeviceManager.IsConnected() && Config.AirhornEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.AirhornStrength.Value, Config.AirhornDuration.Value); } } } internal class PlayerControllerBPatches { [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")] [HarmonyPostfix] private static void DamagePlayerPatch(PlayerControllerB __instance, int damageNumber) { if (((NetworkBehaviour)__instance).IsOwner) { float num = damageNumber; Plugin.Mls.LogDebug((object)$"DamagePlayer got called: {num} ({num / 100f})"); if (Plugin.DeviceManager.IsConnected() && Config.VibrateDamageReceivedEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(num / 100f + Config.VibrateDamageReceivedAmplifier.Value, Config.VibrateDamageReceivedDuration.Value); } } } [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] [HarmonyPostfix] private static void KillPlayerPatch(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { Plugin.Mls.LogDebug((object)"KillPlayer got called"); if (Plugin.DeviceManager.IsConnected() && Config.VibrateKilledEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.VibrateKilledStrength.Value, Config.VibrateKilledDuration.Value); } } } } public class RoundManagerPatches { [HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")] [HarmonyPostfix] private static void GrabItemOnClientPatch(RoundManager __instance) { Plugin.Mls.LogDebug((object)"DespawnPropsAtEndOfRound called"); if (Plugin.DeviceManager.IsConnected() && Config.RoundSurvivalEnabled.Value && !GameNetworkManager.Instance.localPlayerController.isPlayerDead) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.RoundSurvivalStrength.Value, Config.RoundSurvivalDuration.Value); } } } public class ShipAlarmCordPatches { [HarmonyPatch(typeof(ShipAlarmCord), "PullCordClientRpc")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> PullCordClientRpcTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); int index = list.FindLastIndex((CodeInstruction i) => i.opcode == OpCodes.Nop) + 1; list.InsertRange(index, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ShipAlarmCordPatches), "StartVibrating", (Type[])null, (Type[])null)) }); foreach (CodeInstruction item in list) { yield return item; } } [HarmonyPatch(typeof(ShipAlarmCord), "StopPullingCordClientRpc")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> StopPullingCordClientRpcTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); int index = list.FindLastIndex((CodeInstruction i) => i.opcode == OpCodes.Nop) + 1; list.InsertRange(index, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ShipAlarmCordPatches), "StopVibrating", (Type[])null, (Type[])null)) }); foreach (CodeInstruction item in list) { yield return item; } } [HarmonyPatch(typeof(ShipAlarmCord), "HoldCordDown")] [HarmonyPostfix] private static void HoldCordDownPatch() { Plugin.Mls.LogDebug((object)"ShipAlarmCord.HoldCordDown got called"); StartVibrating(); } [HarmonyPatch(typeof(ShipAlarmCord), "StopHorn")] [HarmonyPostfix] private static void StopHornPatch() { Plugin.Mls.LogDebug((object)"ShipAlarmCord.StopHorn got called"); StopVibrating(); } private static void StartVibrating() { if (Plugin.DeviceManager.IsConnected() && Config.ShipHornEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevices(Config.ShipHornStrength.Value); } } private static void StopVibrating() { if (Plugin.DeviceManager.IsConnected() && Config.ShipHornEnabled.Value) { Plugin.DeviceManager.StopConnectedDevices(); } } } public class StunGrenadeItemPatches { [HarmonyPatch(typeof(StunGrenadeItem), "StunExplosion")] [HarmonyPostfix] private static void StunExplosionPatch(StunGrenadeItem __instance) { Plugin.Mls.LogDebug((object)"StunExplosion got called"); if (Plugin.DeviceManager.IsConnected() && Config.FlashbangEnabled.Value) { Plugin.DeviceManager.VibrateConnectedDevicesWithDuration(Config.FlashbangStrength.Value, 0.3f); } } } } namespace LethalVibrations.Buttplug { internal class Config { private static ConfigFile ConfigFile { get; set; } internal static ConfigEntry<string> ServerUri { get; set; } internal static ConfigEntry<float> VibrateAmplifier { get; set; } internal static ConfigEntry<bool> Rewarding { get; set; } internal static ConfigEntry<bool> VibrateDamageReceivedEnabled { get; set; } internal static ConfigEntry<float> VibrateDamageReceivedDuration { get; set; } internal static ConfigEntry<float> VibrateDamageReceivedAmplifier { get; set; } internal static ConfigEntry<bool> VibrateDamageDealtEnabled { get; set; } internal static ConfigEntry<float> VibrateDamageDealtDuration { get; set; } internal static ConfigEntry<float> VibrateDamageDealtStrength { get; set; } internal static ConfigEntry<bool> VibrateKilledEnabled { get; set; } internal static ConfigEntry<float> VibrateKilledDuration { get; set; } internal static ConfigEntry<float> VibrateKilledStrength { get; set; } internal static ConfigEntry<bool> VibrateItemChargerChargeEnabled { get; set; } internal static ConfigEntry<float> VibrateItemChargerChargeDuration { get; set; } internal static ConfigEntry<float> VibrateItemChargerChargeStrength { get; set; } internal static ConfigEntry<bool> VibrateScreenShakeEnabled { get; set; } internal static ConfigEntry<float> VibrateScreenShakeDuration { get; set; } internal static ConfigEntry<float> VibrateScreenShakeAmplifier { get; set; } internal static ConfigEntry<bool> PingScanEnabled { get; set; } internal static ConfigEntry<float> PingScanDuration { get; set; } internal static ConfigEntry<float> PingScanStrength { get; set; } internal static ConfigEntry<bool> QuotaReachedEnabled { get; set; } internal static ConfigEntry<float> QuotaReachedDuration { get; set; } internal static ConfigEntry<float> QuotaReachedStrength { get; set; } internal static ConfigEntry<bool> RoundSurvivalEnabled { get; set; } internal static ConfigEntry<float> RoundSurvivalDuration { get; set; } internal static ConfigEntry<float> RoundSurvivalStrength { get; set; } internal static ConfigEntry<bool> AirhornEnabled { get; set; } internal static ConfigEntry<float> AirhornDuration { get; set; } internal static ConfigEntry<float> AirhornStrength { get; set; } internal static ConfigEntry<bool> ShipHornEnabled { get; set; } internal static ConfigEntry<float> ShipHornStrength { get; set; } internal static ConfigEntry<bool> FlashbangEnabled { get; set; } internal static ConfigEntry<float> FlashbangStrength { get; set; } static Config() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown ConfigFile = new ConfigFile(Paths.ConfigPath + "\\LethalVibrations.cfg", true); ServerUri = ConfigFile.Bind<string>("Devices", "Server Uri", "ws://localhost:12345", "URI of the Intiface server."); VibrateAmplifier = ConfigFile.Bind<float>("Vibrations", "Amplifier", 0f, "Change the amplification of vibration"); Rewarding = ConfigFile.Bind<bool>("Vibrations", "Rewarding", true, "Enable rewarding"); VibrateDamageDealtEnabled = ConfigFile.Bind<bool>("Vibrations.DamageDealt", "Enabled", true, "Vibrate when you deal damage"); VibrateDamageDealtDuration = ConfigFile.Bind<float>("Vibrations.DamageDealt", "Duration", 1f, "Length of time to vibrate for"); VibrateDamageDealtStrength = ConfigFile.Bind<float>("Vibrations.DamageDealt", "Strength", 0.5f, "Change the strength of vibration"); QuotaReachedEnabled = ConfigFile.Bind<bool>("Vibrations.QuotaReached", "Enabled", true, "Vibrate when you reach the quota"); QuotaReachedDuration = ConfigFile.Bind<float>("Vibrations.QuotaReached", "Duration", 1f, "Length of time to vibrate for"); QuotaReachedStrength = ConfigFile.Bind<float>("Vibrations.QuotaReached", "Strength", 0.5f, "Change the strength of vibration"); RoundSurvivalEnabled = ConfigFile.Bind<bool>("Vibrations.RoundSurvival", "Enabled", true, "Vibrate when you survive the round"); RoundSurvivalDuration = ConfigFile.Bind<float>("Vibrations.RoundSurvival", "Duration", 1f, "Length of time to vibrate for"); RoundSurvivalStrength = ConfigFile.Bind<float>("Vibrations.RoundSurvival", "Strength", 0.3f, "Change the strength of vibration"); VibrateDamageReceivedEnabled = ConfigFile.Bind<bool>("Vibrations.DamageReceived", "Enabled", true, "Vibrate when you receive damage"); VibrateDamageReceivedDuration = ConfigFile.Bind<float>("Vibrations.DamageReceived", "Duration", 1f, "Length of time to vibrate for"); VibrateDamageReceivedAmplifier = ConfigFile.Bind<float>("Vibrations.DamageReceived", "Amplifier", 0f, "Change the amplification of vibration"); VibrateKilledEnabled = ConfigFile.Bind<bool>("Vibrations.PlayerKilled", "Enabled", false, "Vibrate when you die"); VibrateKilledDuration = ConfigFile.Bind<float>("Vibrations.PlayerKilled", "Duration", 1f, "Length of time to vibrate for"); VibrateKilledStrength = ConfigFile.Bind<float>("Vibrations.PlayerKilled", "Strength", 1f, "Change the strength of vibration"); PingScanEnabled = ConfigFile.Bind<bool>("Vibrations.PingScan", "Enabled", false, "Vibrate when you press right click"); PingScanDuration = ConfigFile.Bind<float>("Vibrations.PingScan", "Duration", 0.3f, "Length of time to vibrate for"); PingScanStrength = ConfigFile.Bind<float>("Vibrations.PingScan", "Strength", 0.3f, "Change the strength of vibration"); VibrateItemChargerChargeEnabled = ConfigFile.Bind<bool>("Vibrations.ItemCharge", "Enabled", true, "Vibrate when you charge an item"); VibrateItemChargerChargeDuration = ConfigFile.Bind<float>("Vibrations.ItemCharge", "Duration", 1f, "Length of time to vibrate for"); VibrateItemChargerChargeStrength = ConfigFile.Bind<float>("Vibrations.ItemCharge", "Strength", 0.4f, "Change the strength of vibration"); VibrateScreenShakeEnabled = ConfigFile.Bind<bool>("Vibrations.ShakeScreen", "Enabled", true, "Vibrate when your screen shakes"); VibrateScreenShakeDuration = ConfigFile.Bind<float>("Vibrations.ShakeScreen", "Duration", 1f, "Length of time to vibrate for"); VibrateScreenShakeAmplifier = ConfigFile.Bind<float>("Vibrations.ShakeScreen", "Amplifier", 0f, "Change the amplification of vibration"); AirhornEnabled = ConfigFile.Bind<bool>("Vibrations.Airhorn", "Enabled", false, "Vibrate when someone uses the airhorn"); AirhornDuration = ConfigFile.Bind<float>("Vibrations.Airhorn", "Duration", 1f, "Length of time to vibrate for"); AirhornStrength = ConfigFile.Bind<float>("Vibrations.Airhorn", "Strength", 0.1f, "Change the intensity of vibration"); ShipHornEnabled = ConfigFile.Bind<bool>("Vibrations.ShipHorn", "Enabled", true, "Vibrate when someone airs the ships horn"); ShipHornStrength = ConfigFile.Bind<float>("Vibrations.ShipHorn", "Strength", 0.5f, "Change the intensity of vibration"); FlashbangEnabled = ConfigFile.Bind<bool>("Vibrations.Flashbang", "Enabled", true, "Vibrate when a flashbang goes off"); FlashbangStrength = ConfigFile.Bind<float>("Vibrations.Flashbang", "Strength", 0.5f, "Change the intensity of vibration"); } } public class DeviceManager { private List<ButtplugClientDevice> ConnectedDevices { get; set; } private ButtplugClient ButtplugClient { get; set; } public DeviceManager(string clientName) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown ConnectedDevices = new List<ButtplugClientDevice>(); ButtplugClient = new ButtplugClient(clientName); Plugin.Mls.LogInfo((object)("BP client created for " + clientName)); ButtplugClient.DeviceAdded += HandleDeviceAdded; ButtplugClient.DeviceRemoved += HandleDeviceRemoved; } public bool IsConnected() { return ButtplugClient.Connected; } public async void ConnectDevices() { if (ButtplugClient.Connected) { return; } try { Plugin.Mls.LogInfo((object)("Attempting to connect to Intiface server at " + Config.ServerUri.Value)); await ButtplugClient.ConnectAsync((IButtplugClientConnector)new ButtplugWebsocketConnector(new Uri(Config.ServerUri.Value)), default(CancellationToken)); Plugin.Mls.LogInfo((object)"Connection successful. Beginning scan for devices"); await ButtplugClient.StartScanningAsync(default(CancellationToken)); } catch (ButtplugException val) { ButtplugException arg = val; Plugin.Mls.LogError((object)"Attempt to connect to devices failed. Ensure Intiface is running and attempt to reconnect from the 'Devices' section in the mod's in-game settings."); Plugin.Mls.LogDebug((object)$"ButtplugIO error occured while connecting devices: {arg}"); } } public void VibrateConnectedDevicesWithDuration(double intensity, float time) { intensity += Config.VibrateAmplifier.Value; ConnectedDevices.ForEach(Action); async void Action(ButtplugClientDevice device) { await device.VibrateAsync((double)Mathf.Clamp((float)intensity, 0f, 1f)); await Task.Delay((int)(time * 1000f)); await device.VibrateAsync(0.0); } } public void VibrateConnectedDevices(double intensity) { intensity += Config.VibrateAmplifier.Value; ConnectedDevices.ForEach(Action); async void Action(ButtplugClientDevice device) { await device.VibrateAsync((double)Mathf.Clamp((float)intensity, 0f, 1f)); } } public void StopConnectedDevices() { ConnectedDevices.ForEach(async delegate(ButtplugClientDevice device) { await device.Stop(); }); } internal void CleanUp() { StopConnectedDevices(); } private void HandleDeviceAdded(object sender, DeviceAddedEventArgs args) { if (!IsVibratableDevice(args.Device)) { Plugin.Mls.LogInfo((object)(args.Device.Name + " was detected but ignored due to it not being vibratable.")); return; } Plugin.Mls.LogInfo((object)(args.Device.Name + " connected to client " + ButtplugClient.Name)); ConnectedDevices.Add(args.Device); } private void HandleDeviceRemoved(object sender, DeviceRemovedEventArgs args) { if (IsVibratableDevice(args.Device)) { Plugin.Mls.LogInfo((object)(args.Device.Name + " disconnected from client " + ButtplugClient.Name)); ConnectedDevices.Remove(args.Device); } } private bool IsVibratableDevice(ButtplugClientDevice device) { return device.VibrateAttributes.Count > 0; } } } namespace Costura { [CompilerGenerated] internal static class AssemblyLoader { private static object nullCacheLock = new object(); private static Dictionary<string, bool> nullCache = new Dictionary<string, bool>(); private static Dictionary<string, string> assemblyNames = new Dictionary<string, string>(); private static Dictionary<string, string> symbolNames = new Dictionary<string, string>(); private static int isAttached; private static string CultureToString(CultureInfo culture) { if (culture == null) { return ""; } return culture.Name; } private static Assembly ReadExistingAssembly(AssemblyName name) { AppDomain currentDomain = AppDomain.CurrentDomain; Assembly[] assemblies = currentDomain.GetAssemblies(); Assembly[] array = assemblies; foreach (Assembly assembly in array) { AssemblyName name2 = assembly.GetName(); if (string.Equals(name2.Name, name.Name, StringComparison.InvariantCultureIgnoreCase) && string.Equals(CultureToString(name2.CultureInfo), CultureToString(name.CultureInfo), StringComparison.InvariantCultureIgnoreCase)) { return assembly; } } return null; } private static void CopyTo(Stream source, Stream destination) { byte[] array = new byte[81920]; int count; while ((count = source.Read(array, 0, array.Length)) != 0) { destination.Write(array, 0, count); } } private static Stream LoadStream(string fullName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); if (fullName.EndsWith(".compressed")) { using (Stream stream = executingAssembly.GetManifestResourceStream(fullName)) { using DeflateStream source = new DeflateStream(stream, CompressionMode.Decompress); MemoryStream memoryStream = new MemoryStream(); CopyTo(source, memoryStream); memoryStream.Position = 0L; return memoryStream; } } return executingAssembly.GetManifestResourceStream(fullName); } private static Stream LoadStream(Dictionary<string, string> resourceNames, string name) { if (resourceNames.TryGetValue(name, out var value)) { return LoadStream(value); } return null; } private static byte[] ReadStream(Stream stream) { byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); return array; } private static Assembly ReadFromEmbeddedResources(Dictionary<string, string> assemblyNames, Dictionary<string, string> symbolNames, AssemblyName requestedAssemblyName) { string text = requestedAssemblyName.Name.ToLowerInvariant(); if (requestedAssemblyName.CultureInfo != null && !string.IsNullOrEmpty(requestedAssemblyName.CultureInfo.Name)) { text = requestedAssemblyName.CultureInfo.Name + "." + text; } byte[] rawAssembly; using (Stream stream = LoadStream(assemblyNames, text)) { if (stream == null) { return null; } rawAssembly = ReadStream(stream); } using (Stream stream2 = LoadStream(symbolNames, text)) { if (stream2 != null) { byte[] rawSymbolStore = ReadStream(stream2); return Assembly.Load(rawAssembly, rawSymbolStore); } } return Assembly.Load(rawAssembly); } public static Assembly ResolveAssembly(object sender, ResolveEventArgs e) { lock (nullCacheLock) { if (nullCache.ContainsKey(e.Name)) { return null; } } AssemblyName assemblyName = new AssemblyName(e.Name); Assembly assembly = ReadExistingAssembly(assemblyName); if ((object)assembly != null) { return assembly; } assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName); if ((object)assembly == null) { lock (nullCacheLock) { nullCache[e.Name] = true; } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assembly = Assembly.Load(assemblyName); } } return assembly; } static AssemblyLoader() { assemblyNames.Add("buttplug.client.connectors.websocketconnector", "costura.buttplug.client.connectors.websocketconnector.dll.compressed"); assemblyNames.Add("buttplug", "costura.buttplug.dll.compressed"); assemblyNames.Add("deniszykov.websocketlistener", "costura.deniszykov.websocketlistener.dll.compressed"); assemblyNames.Add("system.appcontext", "costura.system.appcontext.dll.compressed"); assemblyNames.Add("system.collections.concurrent", "costura.system.collections.concurrent.dll.compressed"); assemblyNames.Add("system.collections", "costura.system.collections.dll.compressed"); assemblyNames.Add("system.collections.nongeneric", "costura.system.collections.nongeneric.dll.compressed"); assemblyNames.Add("system.collections.specialized", "costura.system.collections.specialized.dll.compressed"); assemblyNames.Add("system.componentmodel.annotations", "costura.system.componentmodel.annotations.dll.compressed"); assemblyNames.Add("system.componentmodel.composition", "costura.system.componentmodel.composition.dll.compressed"); assemblyNames.Add("system.componentmodel", "costura.system.componentmodel.dll.compressed"); assemblyNames.Add("system.componentmodel.eventbasedasync", "costura.system.componentmodel.eventbasedasync.dll.compressed"); assemblyNames.Add("system.componentmodel.primitives", "costura.system.componentmodel.primitives.dll.compressed"); assemblyNames.Add("system.componentmodel.typeconverter", "costura.system.componentmodel.typeconverter.dll.compressed"); assemblyNames.Add("system.console", "costura.system.console.dll.compressed"); assemblyNames.Add("system.core", "costura.system.core.dll.compressed"); assemblyNames.Add("system.data.common", "costura.system.data.common.dll.compressed"); assemblyNames.Add("system.data", "costura.system.data.dll.compressed"); assemblyNames.Add("system.diagnostics.contracts", "costura.system.diagnostics.contracts.dll.compressed"); assemblyNames.Add("system.diagnostics.debug", "costura.system.diagnostics.debug.dll.compressed"); assemblyNames.Add("system.diagnostics.diagnosticsource", "costura.system.diagnostics.diagnosticsource.dll.compressed"); assemblyNames.Add("system.diagnostics.fileversioninfo", "costura.system.diagnostics.fileversioninfo.dll.compressed"); assemblyNames.Add("system.diagnostics.process", "costura.system.diagnostics.process.dll.compressed"); assemblyNames.Add("system.diagnostics.stacktrace", "costura.system.diagnostics.stacktrace.dll.compressed"); assemblyNames.Add("system.diagnostics.textwritertracelistener", "costura.system.diagnostics.textwritertracelistener.dll.compressed"); assemblyNames.Add("system.diagnostics.tools", "costura.system.diagnostics.tools.dll.compressed"); assemblyNames.Add("system.diagnostics.tracesource", "costura.system.diagnostics.tracesource.dll.compressed"); assemblyNames.Add("system.diagnostics.tracing", "costura.system.diagnostics.tracing.dll.compressed"); assemblyNames.Add("system.drawing", "costura.system.drawing.dll.compressed"); assemblyNames.Add("system.drawing.primitives", "costura.system.drawing.primitives.dll.compressed"); assemblyNames.Add("system.dynamic.runtime", "costura.system.dynamic.runtime.dll.compressed"); assemblyNames.Add("system.globalization.calendars", "costura.system.globalization.calendars.dll.compressed"); assemblyNames.Add("system.globalization", "costura.system.globalization.dll.compressed"); assemblyNames.Add("system.globalization.extensions", "costura.system.globalization.extensions.dll.compressed"); assemblyNames.Add("system.io.compression", "costura.system.io.compression.dll.compressed"); assemblyNames.Add("system.io.compression.filesystem", "costura.system.io.compression.filesystem.dll.compressed"); assemblyNames.Add("system.io.compression.zipfile", "costura.system.io.compression.zipfile.dll.compressed"); assemblyNames.Add("system.io", "costura.system.io.dll.compressed"); assemblyNames.Add("system.io.filesystem", "costura.system.io.filesystem.dll.compressed"); assemblyNames.Add("system.io.filesystem.driveinfo", "costura.system.io.filesystem.driveinfo.dll.compressed"); assemblyNames.Add("system.io.filesystem.primitives", "costura.system.io.filesystem.primitives.dll.compressed"); assemblyNames.Add("system.io.filesystem.watcher", "costura.system.io.filesystem.watcher.dll.compressed"); assemblyNames.Add("system.io.isolatedstorage", "costura.system.io.isolatedstorage.dll.compressed"); assemblyNames.Add("system.io.memorymappedfiles", "costura.system.io.memorymappedfiles.dll.compressed"); assemblyNames.Add("system.io.pipes", "costura.system.io.pipes.dll.compressed"); assemblyNames.Add("system.io.unmanagedmemorystream", "costura.system.io.unmanagedmemorystream.dll.compressed"); assemblyNames.Add("system.linq", "costura.system.linq.dll.compressed"); assemblyNames.Add("system.linq.expressions", "costura.system.linq.expressions.dll.compressed"); assemblyNames.Add("system.linq.parallel", "costura.system.linq.parallel.dll.compressed"); assemblyNames.Add("system.linq.queryable", "costura.system.linq.queryable.dll.compressed"); assemblyNames.Add("system.net.http", "costura.system.net.http.dll.compressed"); assemblyNames.Add("system.net.nameresolution", "costura.system.net.nameresolution.dll.compressed"); assemblyNames.Add("system.net.networkinformation", "costura.system.net.networkinformation.dll.compressed"); assemblyNames.Add("system.net.ping", "costura.system.net.ping.dll.compressed"); assemblyNames.Add("system.net.primitives", "costura.system.net.primitives.dll.compressed"); assemblyNames.Add("system.net.requests", "costura.system.net.requests.dll.compressed"); assemblyNames.Add("system.net.security", "costura.system.net.security.dll.compressed"); assemblyNames.Add("system.net.sockets", "costura.system.net.sockets.dll.compressed"); assemblyNames.Add("system.net.webheadercollection", "costura.system.net.webheadercollection.dll.compressed"); assemblyNames.Add("system.net.websockets.client", "costura.system.net.websockets.client.dll.compressed"); assemblyNames.Add("system.net.websockets", "costura.system.net.websockets.dll.compressed"); assemblyNames.Add("system.numerics", "costura.system.numerics.dll.compressed"); assemblyNames.Add("system.objectmodel", "costura.system.objectmodel.dll.compressed"); assemblyNames.Add("system.reflection", "costura.system.reflection.dll.compressed"); assemblyNames.Add("system.reflection.emit", "costura.system.reflection.emit.dll.compressed"); assemblyNames.Add("system.reflection.emit.ilgeneration", "costura.system.reflection.emit.ilgeneration.dll.compressed"); assemblyNames.Add("system.reflection.emit.lightweight", "costura.system.reflection.emit.lightweight.dll.compressed"); assemblyNames.Add("system.reflection.extensions", "costura.system.reflection.extensions.dll.compressed"); assemblyNames.Add("system.reflection.primitives", "costura.system.reflection.primitives.dll.compressed"); assemblyNames.Add("system.resources.reader", "costura.system.resources.reader.dll.compressed"); assemblyNames.Add("system.resources.resourcemanager", "costura.system.resources.resourcemanager.dll.compressed"); assemblyNames.Add("system.resources.writer", "costura.system.resources.writer.dll.compressed"); assemblyNames.Add("system.runtime.compilerservices.unsafe", "costura.system.runtime.compilerservices.unsafe.dll.compressed"); assemblyNames.Add("system.runtime.compilerservices.visualc", "costura.system.runtime.compilerservices.visualc.dll.compressed"); assemblyNames.Add("system.runtime", "costura.system.runtime.dll.compressed"); assemblyNames.Add("system.runtime.extensions", "costura.system.runtime.extensions.dll.compressed"); assemblyNames.Add("system.runtime.handles", "costura.system.runtime.handles.dll.compressed"); assemblyNames.Add("system.runtime.interopservices", "costura.system.runtime.interopservices.dll.compressed"); assemblyNames.Add("system.runtime.interopservices.runtimeinformation", "costura.system.runtime.interopservices.runtimeinformation.dll.compressed"); assemblyNames.Add("system.runtime.interopservices.windowsruntime", "costura.system.runtime.interopservices.windowsruntime.dll.compressed"); assemblyNames.Add("system.runtime.numerics", "costura.system.runtime.numerics.dll.compressed"); assemblyNames.Add("system.runtime.serialization", "costura.system.runtime.serialization.dll.compressed"); assemblyNames.Add("system.runtime.serialization.formatters", "costura.system.runtime.serialization.formatters.dll.compressed"); assemblyNames.Add("system.runtime.serialization.json", "costura.system.runtime.serialization.json.dll.compressed"); assemblyNames.Add("system.runtime.serialization.primitives", "costura.system.runtime.serialization.primitives.dll.compressed"); assemblyNames.Add("system.runtime.serialization.xml", "costura.system.runtime.serialization.xml.dll.compressed"); assemblyNames.Add("system.security.claims", "costura.system.security.claims.dll.compressed"); assemblyNames.Add("system.security.cryptography.algorithms", "costura.system.security.cryptography.algorithms.dll.compressed"); assemblyNames.Add("system.security.cryptography.csp", "costura.system.security.cryptography.csp.dll.compressed"); assemblyNames.Add("system.security.cryptography.encoding", "costura.system.security.cryptography.encoding.dll.compressed"); assemblyNames.Add("system.security.cryptography.primitives", "costura.system.security.cryptography.primitives.dll.compressed"); assemblyNames.Add("system.security.cryptography.x509certificates", "costura.system.security.cryptography.x509certificates.dll.compressed"); assemblyNames.Add("system.security.principal", "costura.system.security.principal.dll.compressed"); assemblyNames.Add("system.security.securestring", "costura.system.security.securestring.dll.compressed"); assemblyNames.Add("system.servicemodel.duplex", "costura.system.servicemodel.duplex.dll.compressed"); assemblyNames.Add("system.servicemodel.http", "costura.system.servicemodel.http.dll.compressed"); assemblyNames.Add("system.servicemodel.nettcp", "costura.system.servicemodel.nettcp.dll.compressed"); assemblyNames.Add("system.servicemodel.primitives", "costura.system.servicemodel.primitives.dll.compressed"); assemblyNames.Add("system.servicemodel.security", "costura.system.servicemodel.security.dll.compressed"); assemblyNames.Add("system.text.encoding", "costura.system.text.encoding.dll.compressed"); assemblyNames.Add("system.text.encoding.extensions", "costura.system.text.encoding.extensions.dll.compressed"); assemblyNames.Add("system.text.regularexpressions", "costura.system.text.regularexpressions.dll.compressed"); assemblyNames.Add("system.threading.channels", "costura.system.threading.channels.dll.compressed"); assemblyNames.Add("system.threading", "costura.system.threading.dll.compressed"); assemblyNames.Add("system.threading.overlapped", "costura.system.threading.overlapped.dll.compressed"); assemblyNames.Add("system.threading.tasks", "costura.system.threading.tasks.dll.compressed"); assemblyNames.Add("system.threading.tasks.extensions", "costura.system.threading.tasks.extensions.dll.compressed"); assemblyNames.Add("system.threading.tasks.parallel", "costura.system.threading.tasks.parallel.dll.compressed"); assemblyNames.Add("system.threading.thread", "costura.system.threading.thread.dll.compressed"); assemblyNames.Add("system.threading.threadpool", "costura.system.threading.threadpool.dll.compressed"); assemblyNames.Add("system.threading.timer", "costura.system.threading.timer.dll.compressed"); assemblyNames.Add("system.valuetuple", "costura.system.valuetuple.dll.compressed"); assemblyNames.Add("system.xml", "costura.system.xml.dll.compressed"); assemblyNames.Add("system.xml.linq", "costura.system.xml.linq.dll.compressed"); assemblyNames.Add("system.xml.readerwriter", "costura.system.xml.readerwriter.dll.compressed"); assemblyNames.Add("system.xml.xdocument", "costura.system.xml.xdocument.dll.compressed"); assemblyNames.Add("system.xml.xmldocument", "costura.system.xml.xmldocument.dll.compressed"); assemblyNames.Add("system.xml.xmlserializer", "costura.system.xml.xmlserializer.dll.compressed"); assemblyNames.Add("system.xml.xpath", "costura.system.xml.xpath.dll.compressed"); assemblyNames.Add("system.xml.xpath.xdocument", "costura.system.xml.xpath.xdocument.dll.compressed"); } public static void Attach() { if (Interlocked.Exchange(ref isAttached, 1) == 1) { return; } AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) { lock (nullCacheLock) { if (nullCache.ContainsKey(e.Name)) { return null; } } AssemblyName assemblyName = new AssemblyName(e.Name); Assembly assembly = ReadExistingAssembly(assemblyName); if ((object)assembly != null) { return assembly; } assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName); if ((object)assembly == null) { lock (nullCacheLock) { nullCache[e.Name] = true; } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assembly = Assembly.Load(assemblyName); } } return assembly; }; } } } internal class LethalVibrations_ProcessedByFody { internal const string FodyVersion = "6.8.0.0"; internal const string Costura = "5.7.0"; }