Decompiled source of WKShock v1.0.0
BepInEx/plugins/PiShockClassLibrary.dll
Decompiled 9 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PiShockClassLibrary.Interfaces; using PiShockClassLibrary.Models; using PiShockLibrary.Enums; using PiShockLibrary.Exceptions; using PiShockLibrary.Extensions; using PiShockLibrary.Models; using PiShockLibrary.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PiShockLibrary_NetFramework4.7.2")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("mxpuffin")] [assembly: AssemblyProduct("PiShockLibrary_NetFramework4.7.2")] [assembly: AssemblyCopyright("Copyright ©mxpuffin 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8567ba7d-6e96-431a-8dc4-6b7d19c06e5c")] [assembly: AssemblyFileVersion("1.0.0.1")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.1")] namespace PiShockLibrary.Utilities { public static class PiShockLogger { public static Action<string> LogInfoAction { get; set; } public static Action<string> LogErrorAction { get; set; } public static void Log(string message) { LogInfoAction?.Invoke("[PiShock] " + message); } public static void LogError(string message) { LogErrorAction?.Invoke("[PiShock] " + message); } } } namespace PiShockLibrary.Models { public class PiShockOperateRequestBody { public string UserName { get; private set; } public string APIKey { get; private set; } [JsonProperty("op")] public PiShockOperations Operation { get; private set; } [JsonProperty("code")] public string ShareCode { get; private set; } public int Intensity { get; private set; } public int Duration { get; private set; } [JsonProperty("name")] public string LogName { get; private set; } = "PiShock C# Library"; public bool Random { get; private set; } public bool Scale { get; private set; } public PiShockOperateRequestBody(PiShockUserInfo userInfo, PiShockOperations operation, int shockerIndex, int intensity, int duration, string logName = null) { UserName = userInfo.Username; APIKey = userInfo.ApiKey; Operation = operation; ShareCode = userInfo.Devices[shockerIndex].ShareCode ?? throw new NullReferenceException("Share Code Index provided was null"); Intensity = intensity; Duration = duration; LogName = logName ?? LogName; } public PiShockOperateRequestBody(PiShockUserInfo userInfo, PiShockOperations operation, string shareCode, int intensity, int duration, string logName = null) { UserName = userInfo.Username; APIKey = userInfo.ApiKey; Operation = operation; ShareCode = shareCode; Intensity = intensity; Duration = duration; LogName = logName ?? LogName; } } } namespace PiShockLibrary.Exceptions { internal class PiShockAPIException : Exception { public PiShockAPIException(string message, Exception innerException = null) : base(message, innerException) { } } internal class PiShockDeviceNotFoundException : Exception { public PiShockDeviceNotFoundException(string message, Exception innerException = null) : base(message, innerException) { } } } namespace PiShockLibrary.Extensions { internal static class HttpResponseMessageExtensions { internal static async Task<string> EnsureSuccessAndReturnStringBody(this HttpResponseMessage response) { response.EnsureSuccessStatusCode(); string obj = await response.Content.ReadAsStringAsync(); if (string.IsNullOrEmpty(obj)) { throw new PiShockAPIException("Invalid API request. Response body returned empty."); } return obj; } } } namespace PiShockLibrary.Enums { public enum PiShockOperations { Shock, Vibrate, Beep } } namespace PiShockClassLibrary.Services { public class PiShockAPI : IPiShockAPI { private readonly HttpClient _httpClient; public PiShockAPI(HttpClient httpClient) { _httpClient = httpClient; } public async Task<PiShockUserInfo> GetUserInfoFromAPI(string username, string apiKey) { PiShockLogger.Log("Attempting to Login to the PiShock Network!"); try { PiShockUserInfo piShockUserInfo = JsonConvert.DeserializeObject<PiShockUserInfo>(await (await _httpClient.GetAsync("https://auth.pishock.com/Auth/GetUserIfAPIKeyValid/?apiKey=" + apiKey + "&username=" + username)).EnsureSuccessAndReturnStringBody()); if (piShockUserInfo == null) { throw new NullReferenceException("Failed to deserialize login information"); } PiShockLogger.Log("Login Successful!: " + piShockUserInfo.Username); return new PiShockUserInfo(piShockUserInfo.ClientID, username, apiKey); } catch (PiShockAPIException ex) { PiShockLogger.LogError(ex.Message); throw new PiShockAPIException("Error fetching PiShock user info. Potentially Invalid Credentials."); } catch (Exception ex2) { PiShockLogger.LogError(ex2.Message); throw; } } public async Task<int[]> GetShareIDsByOwner(PiShockUserInfo userInfo) { PiShockLogger.Log("Attempting to Fetch Share IDs!"); PiShockLogger.Log("GetShareIDsByOwner Username: " + userInfo.Username); JToken val = JToken.Parse(await (await _httpClient.GetAsync(string.Format("{0}?UserId={1}&Token={2}&api=true", "https://ps.pishock.com/PiShock/GetShareCodesByOwner", userInfo.ClientID, userInfo.ApiKey))).EnsureSuccessAndReturnStringBody()); if (val[(object)userInfo.Username] != null) { JToken obj = val[(object)userInfo.Username]; int[] result = ((obj != null) ? obj.ToObject<int[]>() : null); PiShockLogger.Log("Share ID's Fetched Successfully!"); return result; } throw new PiShockDeviceNotFoundException("Could not fetch Share IDs for '" + userInfo.Username + "'."); } public async Task<PiShockUserInfo> GetShockerShareCodesByID(PiShockUserInfo userInfo) { int[] array = await GetShareIDsByOwner(userInfo); string text = string.Join("", array.Select((int id) => $"&shareIds={id}")); PiShockLogger.Log(string.Format("Attempting to retrieve {0} ShareCode{1}!", array.Length, (array.Length > 1) ? "s" : "")); try { JToken obj = JToken.Parse(await (await _httpClient.GetAsync(string.Format("{0}?UserId={1}&Token={2}&api=true{3}", "https://ps.pishock.com/PiShock/GetShockersByShareIds", userInfo.ClientID, userInfo.ApiKey, text))).EnsureSuccessAndReturnStringBody())[(object)userInfo.Username]; List<PiShockDeviceInfo> list = ((obj != null) ? obj.ToObject<List<PiShockDeviceInfo>>() : null); if (list == null) { throw new PiShockDeviceNotFoundException("Failed to deserialize share codes from response"); } PiShockLogger.Log("Share Codes retrieved successfully!"); return userInfo.WithDevices(list); } catch (PiShockDeviceNotFoundException) { throw; } catch (Exception ex2) { PiShockLogger.LogError(ex2.Message); throw; } } public async Task<PiShockUserInfo> GetUserInfoAndShareCodes(string username, string apiKey) { return await GetShockerShareCodesByID(await GetUserInfoFromAPI(username, apiKey)); } public async Task<bool> SendOperationRequest(PiShockOperateRequestBody requestBody) { StringContent content = null; try { string text = JsonConvert.SerializeObject((object)requestBody); content = new StringContent(text, Encoding.UTF8, "application/json"); string text2 = await (await _httpClient.PostAsync("https://ps.pishock.com/PiShock/operate", (HttpContent)(object)content)).EnsureSuccessAndReturnStringBody(); if (text2 != "\"Operation Attempted.\"") { throw new PiShockAPIException("Invalid PiShock Request: " + text2); } return text2 != null; } catch (Exception ex) { PiShockLogger.LogError("Error in SendOperationRequest: " + ex.Message + "\n" + ex.StackTrace); return false; } finally { StringContent obj = content; if (obj != null) { ((HttpContent)obj).Dispose(); } } } } } namespace PiShockClassLibrary.Models { public class PiShockDeviceInfo { public string ShockerName { get; private set; } public string ShareCode { get; private set; } public int ShockerId { get; private set; } public bool IsEnabled { get; private set; } public PiShockDeviceInfo(string shockerName, string shareCode) { ShockerName = shockerName; ShareCode = shareCode; ShockerId = -1; IsEnabled = true; } } public class PiShockUserInfo { public int ClientID { get; set; } public string Username { get; set; } [JsonIgnore] public string ApiKey { get; set; } public IReadOnlyList<PiShockDeviceInfo> Devices { get; set; } public PiShockUserInfo(int clientId, string username, string apiKey = null, List<PiShockDeviceInfo> devices = null) { ClientID = clientId; Username = username ?? string.Empty; ApiKey = apiKey ?? string.Empty; Devices = devices?.AsReadOnly() ?? new List<PiShockDeviceInfo>().AsReadOnly(); } public PiShockUserInfo WithDevices(List<PiShockDeviceInfo> devices) { return new PiShockUserInfo(ClientID, Username, ApiKey, devices); } } } namespace PiShockClassLibrary.Interfaces { public interface IPiShockAPI { Task<PiShockUserInfo> GetUserInfoFromAPI(string username, string apiKey); Task<int[]> GetShareIDsByOwner(PiShockUserInfo userInfo); Task<PiShockUserInfo> GetShockerShareCodesByID(PiShockUserInfo userInfo); Task<PiShockUserInfo> GetUserInfoAndShareCodes(string username, string apiKey); Task<bool> SendOperationRequest(PiShockOperateRequestBody requestBody); } } namespace PiShockClassLibrary.Constants { internal class ApiEndpoints { public const string BaseUrl = "https://ps.pishock.com/PiShock/"; public const string AuthUrl = "https://auth.pishock.com/Auth/GetUserIfAPIKeyValid/"; public const string GetShareCodesByOwner = "https://ps.pishock.com/PiShock/GetShareCodesByOwner"; public const string GetShockersByShareIds = "https://ps.pishock.com/PiShock/GetShockersByShareIds"; public const string Operate = "https://ps.pishock.com/PiShock/operate"; } }
BepInEx/plugins/WKShock.dll
Decompiled 9 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using PiShockClassLibrary.Models; using PiShockClassLibrary.Services; using PiShockLibrary.Enums; using PiShockLibrary.Models; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("WKShock")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("WKShock")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("C2826ADF-39EB-463A-9FDD-F5A4A478A93A")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace WKShock { public class PiShockController { private PiShockAPI _piShockAPI; private PiShockUserInfo _userInfo; private ManualLogSource _logger; public PiShockController(PiShockAPI piShockAPI, PiShockUserInfo piShockUserInfo, ManualLogSource logger) { _piShockAPI = piShockAPI; _userInfo = piShockUserInfo; _logger = logger; } public void OperatePiShock(int intensity, int duration, PiShockOperations op) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Task.Run(async delegate { List<Task<bool>> list = new List<Task<bool>>(); foreach (PiShockDeviceInfo device in _userInfo.Devices) { PiShockOperateRequestBody val = new PiShockOperateRequestBody(_userInfo, op, device.ShareCode, intensity, duration, "White Knuckle"); list.Add(_piShockAPI.SendOperationRequest(val)); } if ((await Task.WhenAll(list)).Any((bool success) => !success)) { _logger.LogWarning((object)"One or more PiShock requests failed to execute!"); } }); } } public class PiShockLogin { private readonly ManualLogSource _logger; private readonly PiShockAPI _api; private ConfigEntry<string> _username; private ConfigEntry<string> _apiKey; private ConfigEntry<string> _shareCodes; public ConfigEntry<bool> ModEnabled { get; private set; } public ConfigEntry<bool> EnableShock { get; private set; } public ConfigEntry<int> ShockIntensity { get; private set; } public ConfigEntry<int> ShockDuration { get; private set; } public ConfigEntry<bool> EnableVibrate { get; private set; } public ConfigEntry<int> VibrateIntensity { get; private set; } public ConfigEntry<int> VibrateDuration { get; private set; } public ConfigEntry<bool> EnableDeathShock { get; private set; } public ConfigEntry<int> DeathShockIntensity { get; private set; } public ConfigEntry<int> DeathShockDuration { get; private set; } public PiShockController Controller { get; private set; } public PiShockLogin(ConfigFile config, ManualLogSource logger) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown _logger = logger; _api = new PiShockAPI(new HttpClient()); _username = config.Bind<string>("1. PiShock Credentials", "Username", "", "Your PiShock Username"); _apiKey = config.Bind<string>("1. PiShock Credentials", "APIKey", "", "Your PiShock API Key"); _shareCodes = config.Bind<string>("1. PiShock Credentials", "ShareCodes", "", "Comma separated share codes"); ModEnabled = config.Bind<bool>("2. Gameplay Settings", "Mod Enabled", true, "Master switch to enable or disable all mod triggers."); EnableShock = config.Bind<bool>("3. Shock Settings", "Enable Shock", true, "Send a shock when taking damage."); ShockIntensity = config.Bind<int>("3. Shock Settings", "Shock Intensity", 25, new ConfigDescription("Intensity of the shock (1-100).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); ShockDuration = config.Bind<int>("3. Shock Settings", "Shock Duration", 1, new ConfigDescription("Duration of the shock in seconds (1-10).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); EnableVibrate = config.Bind<bool>("4. Vibrate Settings", "Enable Vibrate", false, "Send a vibration when taking damage."); VibrateIntensity = config.Bind<int>("4. Vibrate Settings", "Vibrate Intensity", 50, new ConfigDescription("Intensity of the vibration (1-100).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); VibrateDuration = config.Bind<int>("4. Vibrate Settings", "Vibrate Duration", 1, new ConfigDescription("Duration of the vibration in seconds (1-10).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); EnableDeathShock = config.Bind<bool>("5. Death Settings", "Enable Death Shock", true, "Send a massive shock when dying."); DeathShockIntensity = config.Bind<int>("5. Death Settings", "Death Shock Intensity", 50, new ConfigDescription("Intensity of the death shock (1-100).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); DeathShockDuration = config.Bind<int>("5. Death Settings", "Death Shock Duration", 3, new ConfigDescription("Duration of the death shock in seconds (1-10).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); } public async Task InitializeAsync() { try { if (string.IsNullOrEmpty(_username.Value) || string.IsNullOrEmpty(_apiKey.Value)) { _logger.LogError((object)"PiShock: Username or APIKey missing in config file!"); return; } if (string.IsNullOrEmpty(_shareCodes.Value)) { _logger.LogError((object)"PiShock: ShareCode missing in config file!"); return; } string[] array = _shareCodes.Value.Split(new char[1] { ',' }); List<PiShockDeviceInfo> devices = new List<PiShockDeviceInfo>(); for (int i = 0; i < array.Length; i++) { devices.Add(new PiShockDeviceInfo($"Shocker {i}", array[i].Trim())); } PiShockUserInfo piShockUserInfo = (await _api.GetUserInfoFromAPI(_username.Value, _apiKey.Value)).WithDevices(devices); Controller = new PiShockController(_api, piShockUserInfo, _logger); _logger.LogInfo((object)"PiShock login successful."); } catch (Exception ex) { _logger.LogError((object)("PiShock login failed: " + ex.Message)); } } } [BepInPlugin("com.xironix.wkshock", "WKShock", "1.0.0")] public class WKShockPlugin : BaseUnityPlugin { public static PiShockLogin PiShock { get; private set; } private void Awake() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.LogInfo((object)"WKShock is waking up..."); PiShock = new PiShockLogin(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); PiShock.InitializeAsync(); new Harmony("com.xironix.wkshock").PatchAll(); } } } namespace WKShock.HarmonyPatches { [HarmonyPatch(typeof(ENT_Player))] public class PlayerDamagePatch { [HarmonyPatch("Damage")] [HarmonyPrefix] public static void BeforePlayerTakesDamage(ENT_Player __instance, DamageInfo info, bool ___godmode, float ___health) { if (WKShockPlugin.PiShock != null && WKShockPlugin.PiShock.Controller != null && WKShockPlugin.PiShock.ModEnabled.Value && !___godmode && !(info.amount <= 0f) && !(___health - info.amount <= 0f)) { Debug.Log((object)$"Player hit for {info.amount} damage."); if (WKShockPlugin.PiShock.EnableShock.Value) { WKShockPlugin.PiShock.Controller.OperatePiShock(WKShockPlugin.PiShock.ShockIntensity.Value, WKShockPlugin.PiShock.ShockDuration.Value, (PiShockOperations)0); } if (WKShockPlugin.PiShock.EnableVibrate.Value) { WKShockPlugin.PiShock.Controller.OperatePiShock(WKShockPlugin.PiShock.VibrateIntensity.Value, WKShockPlugin.PiShock.VibrateDuration.Value, (PiShockOperations)1); } } } } [HarmonyPatch(typeof(ENT_Player))] public class PlayerDeathPatch { [HarmonyPatch("Kill")] [HarmonyPrefix] public static void BeforePlayerDies(bool ___dead, bool ___godmode) { if (WKShockPlugin.PiShock != null && WKShockPlugin.PiShock.Controller != null && WKShockPlugin.PiShock.ModEnabled.Value && !(___dead || ___godmode)) { Debug.Log((object)"Player died."); if (WKShockPlugin.PiShock.EnableDeathShock.Value) { WKShockPlugin.PiShock.Controller.OperatePiShock(WKShockPlugin.PiShock.DeathShockIntensity.Value, WKShockPlugin.PiShock.DeathShockDuration.Value, (PiShockOperations)0); } } } } }