Decompiled source of WKShock v1.0.0

BepInEx/plugins/PiShockClassLibrary.dll

Decompiled 9 hours ago
using 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 ago
using 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);
				}
			}
		}
	}
}