using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("addzeey.PeakShock")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.0.0")]
[assembly: AssemblyInformationalVersion("0.4.0+879aaaa4fbb2a8c92c75128c80f227247491bdaa")]
[assembly: AssemblyProduct("addzeey.PeakShock")]
[assembly: AssemblyTitle("PeakShock")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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]
[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]
[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;
}
}
}
public interface IShockController
{
void EnqueueShock(int intensity, int duration, string? code = null, bool isDeath = false);
}
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 PeakShock
{
internal class ShockRequestQueue : IDisposable
{
private ConcurrentQueue<Func<Task>> _taskQueue;
private SemaphoreSlim _signal;
private CancellationTokenSource _cts;
private Task _worker;
private readonly object _lock = new object();
private bool _disposed;
public ShockRequestQueue()
{
Start();
}
public void Enqueue(Func<Task> task)
{
if (_disposed)
{
throw new ObjectDisposedException("ShockRequestQueue");
}
_taskQueue.Enqueue(task);
_signal.Release();
}
public void Enqueue<T>(Func<T, Task> task, T args)
{
if (_disposed)
{
throw new ObjectDisposedException("ShockRequestQueue");
}
_taskQueue.Enqueue(() => task(args));
_signal.Release();
}
public void Start()
{
_taskQueue = new ConcurrentQueue<Func<Task>>();
_signal = new SemaphoreSlim(0);
_cts = new CancellationTokenSource();
_worker = Task.Run((Func<Task?>)ProcessQueueAsync);
}
private async Task ProcessQueueAsync()
{
while (!_cts.Token.IsCancellationRequested)
{
await _signal.WaitAsync(_cts.Token);
if (_taskQueue.TryDequeue(out Func<Task> result))
{
try
{
await result();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)ex.ToString());
}
}
}
}
public async Task StopAsync()
{
if (_disposed)
{
return;
}
_cts.Cancel();
_signal.Release();
try
{
await _worker;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)ex.ToString());
}
}
public async Task ResetAsync()
{
lock (_lock)
{
if (!_worker.IsCompleted)
{
StopAsync().Wait();
}
Start();
}
}
public void Dispose()
{
if (!_disposed)
{
StopAsync().Wait();
_cts.Dispose();
_signal.Dispose();
_disposed = true;
}
}
}
public class OpenShockController : IShockController
{
private readonly ShockRequestQueue _queue = new ShockRequestQueue();
private readonly string _apiUrl;
private readonly string _deviceId;
private readonly string _apiKey;
private readonly HttpClient _client = new HttpClient();
private DateTime _lastShockTime = DateTime.MinValue;
private DateTime _lastDeathShockTime = DateTime.MinValue;
private static readonly TimeSpan DeathShockCooldown = TimeSpan.FromSeconds(11.0);
private TimeSpan ShockCooldown => TimeSpan.FromSeconds(1.0 + (double)Math.Max(0f, Plugin.ShockCooldownSeconds.Value));
public OpenShockController()
{
_apiUrl = Plugin.OpenShockApiUrl.Value;
_deviceId = Plugin.OpenShockDeviceId.Value;
_apiKey = Plugin.OpenShockApiKey.Value;
}
public void EnqueueShock(int intensity, int duration, string? code = null, bool isDeath = false)
{
DateTime utcNow = DateTime.UtcNow;
if (isDeath)
{
if (utcNow - _lastDeathShockTime < DeathShockCooldown)
{
Plugin.Log.LogInfo((object)"[PeakShock] OpenShock death shock skipped due to death cooldown.");
return;
}
_lastDeathShockTime = utcNow;
}
else if (utcNow - _lastShockTime < ShockCooldown)
{
Plugin.Log.LogInfo((object)"[PeakShock] OpenShock shock skipped due to cooldown.");
return;
}
if (!isDeath)
{
_lastShockTime = utcNow;
}
_queue.Enqueue(() => TriggerShockInternal(intensity, duration, code));
}
private async Task TriggerShockInternal(int intensity, int duration, string? code)
{
int num = Math.Clamp(duration * 1000, 300, 65535);
if (string.IsNullOrEmpty(_apiUrl) || string.IsNullOrEmpty(_apiKey))
{
Plugin.Log.LogWarning((object)$"[PeakShock] Would send OpenShock (intensity={intensity}, duration={num}), but OpenShock credentials are not set.");
return;
}
string text = ((!string.IsNullOrEmpty(code)) ? code : _deviceId);
if (string.IsNullOrEmpty(text))
{
Plugin.Log.LogWarning((object)"[PeakShock] No deviceId or share code provided for OpenShock.");
return;
}
Plugin.Log.LogInfo((object)$"[PeakShock] Sending OpenShock: id={text}, intensity={intensity}, duration={num}");
var anon = new
{
Shocks = new[]
{
new
{
Id = text,
Type = 1,
Intensity = intensity,
Duration = num
}
},
CustomName = "Integrations.PeakShock"
};
string content = JsonConvert.SerializeObject((object)anon);
StringContent content2 = new StringContent(content, Encoding.UTF8, "application/json");
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, _apiUrl + "/2/shockers/control")
{
Content = content2
};
httpRequestMessage.Headers.Add("OpenShockToken", _apiKey);
httpRequestMessage.Headers.Add("User-Agent", "PeakShock/" + Plugin.Version);
try
{
HttpResponseMessage response = await _client.SendAsync(httpRequestMessage);
if (!response.IsSuccessStatusCode)
{
string arg = await response.Content.ReadAsStringAsync();
Plugin.Log.LogError((object)$"OpenShock API error: {response.StatusCode} {arg}");
}
}
catch (Exception arg2)
{
Plugin.Log.LogError((object)$"OpenShock API exception: {arg2}");
}
}
}
public class PiShockController : IShockController
{
private const string PiShockIdLookupUrl = "https://pishock-lookup.addzeey.com/";
private const string PiShockV3DocsUrl = "https://docs.pishock.com/pishock/pishock-v3-documentation.html";
private readonly HttpClient _client = new HttpClient();
private readonly ShockRequestQueue _queue = new ShockRequestQueue();
private DateTime _lastShockTime = DateTime.MinValue;
private DateTime _lastDeathShockTime = DateTime.MinValue;
private static readonly TimeSpan DeathShockCooldown = TimeSpan.FromSeconds(11.0);
private TimeSpan ShockCooldown => TimeSpan.FromSeconds(1f + Math.Max(0f, Plugin.ShockCooldownSeconds.Value));
public void TriggerShock(int intensity, int duration = 1, string? shockerIdOverride = null, bool isDeath = false)
{
DateTime utcNow = DateTime.UtcNow;
if (isDeath)
{
if (utcNow - _lastDeathShockTime < DeathShockCooldown)
{
Plugin.Log.LogInfo((object)"[PeakShock] Death shock skipped due to death cooldown.");
return;
}
_lastDeathShockTime = utcNow;
}
else if (utcNow - _lastShockTime < ShockCooldown)
{
Plugin.Log.LogInfo((object)"[PeakShock] Shock skipped due to cooldown.");
return;
}
if (!isDeath)
{
_lastShockTime = utcNow;
}
string shockerId = (string.IsNullOrWhiteSpace(shockerIdOverride) ? Plugin.PiShockShockerId.Value : shockerIdOverride);
Plugin.Log.LogInfo((object)$"[PeakShock] Enqueue shock: intensity={intensity}, duration={duration}s, shockerId={shockerId}");
_queue.Enqueue(() => TriggerShockInternal(intensity, duration, shockerId));
}
public void EnqueueShock(int intensity, int duration, string? code = null, bool isDeath = false)
{
TriggerShock(intensity, duration, code, isDeath);
}
private async Task TriggerShockInternal(int intensity, int duration, string shockerId)
{
string value = Plugin.PiShockAPIKey.Value;
if (string.IsNullOrWhiteSpace(value) || string.IsNullOrWhiteSpace(shockerId))
{
Plugin.Log.LogWarning((object)("[PeakShock] PiShock shock skipped because configuration is incomplete. Required values: APIKey and ShockerId. Current values present: " + $"APIKey={!string.IsNullOrWhiteSpace(value)}, ShockerId={!string.IsNullOrWhiteSpace(shockerId)}. " + "Use the shocker id lookup tool: https://pishock-lookup.addzeey.com/"));
return;
}
int num = duration * 1000;
Plugin.Log.LogInfo((object)$"[PeakShock] Sending shock: intensity={intensity}, duration={num}ms, shockerId={shockerId}");
string content = JsonConvert.SerializeObject((object)new
{
AgentName = "PeakShock Mod",
Intensity = intensity,
Duration = num,
Operation = 0
});
StringContent content2 = new StringContent(content, Encoding.UTF8, "application/json");
try
{
string text = Plugin.PiShockApiUrl.Value.TrimEnd('/');
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, text + "/Shockers/" + Uri.EscapeDataString(shockerId))
{
Content = content2
};
httpRequestMessage.Headers.Add("X-PiShock-Api-Key", value);
httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Plugin.Log.LogInfo((object)$"[PeakShock] Sending request to PiShock API ({httpRequestMessage.RequestUri}): Intensity={intensity}, Duration={num}ms, ShockerId={shockerId}");
HttpResponseMessage response = await _client.SendAsync(httpRequestMessage);
if (!response.IsSuccessStatusCode)
{
string responseBody = await response.Content.ReadAsStringAsync();
Plugin.Log.LogError((object)$"[PeakShock] PiShock API error: {(int)response.StatusCode} {response.StatusCode}. {GetStatusExplanation(response.StatusCode, shockerId)} Response body: {FormatResponseBody(responseBody)}");
}
else
{
Plugin.Log.LogInfo((object)("[PeakShock] PiShock API accepted the shock command for shockerId=" + shockerId + "."));
}
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"[PeakShock] PiShock API exception while sending shock to shockerId={shockerId}: {arg}");
}
}
private static string GetStatusExplanation(HttpStatusCode statusCode, string shockerId)
{
return statusCode switch
{
HttpStatusCode.Unauthorized => "Authentication failed. Verify the PiShock APIKey is configured correctly.",
HttpStatusCode.Forbidden => "PiShock rejected this request for the authenticated account.",
HttpStatusCode.NotFound => "PiShock could not find an accessible share for shockerId=" + shockerId + ". Verify the configured ShockerId by using the lookup tool: https://pishock-lookup.addzeey.com/",
HttpStatusCode.MethodNotAllowed => "The configured share does not allow shock operations for this device.",
HttpStatusCode.NotAcceptable => "The PiShock device is not V3. Ask the user to flash V3 firmware and use PiShock Discord support if needed: https://docs.pishock.com/pishock/pishock-v3-documentation.html",
HttpStatusCode.Gone => "The PiShock share is locked.",
HttpStatusCode.PreconditionFailed => "The requested intensity is out of bounds for this device or share.",
HttpStatusCode.RequestedRangeNotSatisfiable => "The requested duration exceeds PiShock limits. The current integration sends duration in milliseconds.",
HttpStatusCode.ServiceUnavailable => "The PiShock share or shocker is paused.",
_ => "Unexpected PiShock response. Check the response body and current PiShock API docs.",
};
}
private static string FormatResponseBody(string responseBody)
{
if (!string.IsNullOrWhiteSpace(responseBody))
{
return responseBody;
}
return "<empty>";
}
}
[BepInPlugin("addzeey.PeakShock", "PeakShock", "0.4.0")]
public class Plugin : BaseUnityPlugin
{
public enum ShockProvider
{
PiShock,
OpenShock
}
public const string PluginVersion = "0.4.0";
private Harmony? _harmony;
public const string Id = "addzeey.PeakShock";
internal static ManualLogSource Log { get; private set; }
internal static ConfigFile CFG { get; private set; }
internal static PiShockController PiShockController { get; private set; }
internal static ConfigEntry<string> PiShockApiUrl { get; private set; }
internal static ConfigEntry<string> PiShockAPIKey { get; private set; }
internal static ConfigEntry<string> PiShockShockerId { get; private set; }
internal static ConfigEntry<int> MinShock { get; private set; }
internal static ConfigEntry<int> MaxShock { get; private set; }
internal static ConfigEntry<int> DeathShock { get; private set; }
internal static ConfigEntry<int> DeathDuration { get; private set; }
internal static ConfigEntry<bool> EnableInjuryShock { get; private set; }
internal static ConfigEntry<bool> EnablePoisonShock { get; private set; }
internal static ConfigEntry<bool> EnableColdShock { get; private set; }
internal static ConfigEntry<bool> EnableHotShock { get; private set; }
internal static ConfigEntry<bool> EnableSporesShock { get; private set; }
internal static ConfigEntry<bool> EnableThornsShock { get; private set; }
internal static ConfigEntry<bool> EnableWebShock { get; private set; }
internal static ConfigEntry<bool> EnableArrowShock { get; private set; }
internal static ConfigEntry<bool> EnablePetrifyShock { get; private set; }
internal static ConfigEntry<bool> EnableFlyTrapShock { get; private set; }
internal static ConfigEntry<bool> ShockWhilePassedOut { get; private set; }
internal static ConfigEntry<float> ShockCooldownSeconds { get; private set; }
internal static ConfigEntry<ShockProvider> ShockProviderType { get; private set; }
internal static ConfigEntry<string> OpenShockApiUrl { get; private set; }
internal static ConfigEntry<string> OpenShockDeviceId { get; private set; }
internal static ConfigEntry<string> OpenShockApiKey { get; private set; }
internal static IShockController ShockController { get; private set; }
public static string Name => "PeakShock";
public static string Version => "0.4.0";
private void Awake()
{
//IL_0486: Unknown result type (might be due to invalid IL or missing references)
//IL_0490: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
CFG = ((BaseUnityPlugin)this).Config;
PiShockApiUrl = CFG.Bind<string>("PiShock", "ApiUrl", "https://api.pishock.com", "PiShock API URL");
PiShockAPIKey = CFG.Bind<string>("PiShock", "APIKey", "", "Your PiShock API Key");
PiShockShockerId = CFG.Bind<string>("PiShock", "ShockerId", "", "Your PiShock shocker id. Use the lookup tool if you do not know it yet.");
MinShock = CFG.Bind<int>("Shock", "MinShock", 10, "Minimum shock intensity (1-100)");
MaxShock = CFG.Bind<int>("Shock", "MaxShock", 100, "Maximum shock intensity (1-100)");
DeathShock = CFG.Bind<int>("Shock", "DeathShock", 80, "Shock intensity on death (1-100)");
DeathDuration = CFG.Bind<int>("Shock", "DeathDuration", 2, "Shock duration on death (seconds)");
EnableInjuryShock = CFG.Bind<bool>("ShockTypes", "EnableInjuryShock", true, "Enable shock for Injury damage");
EnablePoisonShock = CFG.Bind<bool>("ShockTypes", "EnablePoisonShock", false, "Enable shock for Poison damage");
EnableColdShock = CFG.Bind<bool>("ShockTypes", "EnableColdShock", false, "Enable shock for Cold damage");
EnableHotShock = CFG.Bind<bool>("ShockTypes", "EnableHotShock", false, "Enable shock for Hot/Fire damage");
EnableSporesShock = CFG.Bind<bool>("ShockTypes", "EnableSporesShock", false, "Enable shock when spore infection increases");
EnableThornsShock = CFG.Bind<bool>("ShockTypes", "EnableThornsShock", false, "Enable shock for Thorns damage");
EnableWebShock = CFG.Bind<bool>("ShockTypes", "EnableWebShock", false, "Enable shock for Web/Spider web");
EnableArrowShock = CFG.Bind<bool>("ShockTypes", "EnableArrowShock", false, "Enable shock when an arrow becomes lodged in the player");
EnablePetrifyShock = CFG.Bind<bool>("ShockTypes", "EnablePetrifyShock", false, "Enable shock when petrification increases");
EnableFlyTrapShock = CFG.Bind<bool>("ShockTypes", "EnableFlyTrapShock", false, "Enable shock when caught by a Venus fly trap");
ShockCooldownSeconds = CFG.Bind<float>("Shock", "ShockCooldownSeconds", 2f, "Minimum seconds between shocks (prevents shock spam)");
ShockWhilePassedOut = CFG.Bind<bool>("Shock", "ShockWhilePassedOut", false, "Allow status shocks while the player is passed out");
ShockProviderType = CFG.Bind<ShockProvider>("Shock", "Provider", ShockProvider.PiShock, "Choose PiShock or OpenShock");
OpenShockApiUrl = CFG.Bind<string>("OpenShock", "ApiUrl", "https://api.openshock.app", "OpenShock API URL");
OpenShockDeviceId = CFG.Bind<string>("OpenShock", "DeviceId", "", "OpenShock Device ID");
OpenShockApiKey = CFG.Bind<string>("OpenShock", "ApiKey", "", "OpenShock API Key");
Log.LogInfo((object)$"[PeakShock] Config:\nMinShock={MinShock.Value}\nMaxShock={MaxShock.Value}\nDeathShock={DeathShock.Value}\nDeathDuration={DeathDuration.Value}\nEnableInjuryShock={EnableInjuryShock.Value}\nEnablePoisonShock={EnablePoisonShock.Value}\nEnableColdShock={EnableColdShock.Value}\nEnableHotShock={EnableHotShock.Value}\nEnableSporesShock={EnableSporesShock.Value}\nEnableThornsShock={EnableThornsShock.Value}\nEnableWebShock={EnableWebShock.Value}\nEnableArrowShock={EnableArrowShock.Value}\nEnablePetrifyShock={EnablePetrifyShock.Value}\nEnableFlyTrapShock={EnableFlyTrapShock.Value}\nShockWhilePassedOut={ShockWhilePassedOut.Value}\nShockCooldownSeconds={ShockCooldownSeconds.Value}");
if (ShockProviderType.Value == ShockProvider.PiShock)
{
ShockController = new PiShockController();
Log.LogInfo((object)"[PeakShock] Initialized PiShockController");
}
else
{
ShockController = new OpenShockController();
Log.LogInfo((object)"[PeakShock] Initialized OpenShockController");
}
_harmony = new Harmony("com.yourname.PeakShock");
_harmony.PatchAll(Assembly.GetExecutingAssembly());
Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
}
}
}
namespace PeakShock.PeakShock.Patches
{
internal static class StatusShockHandler
{
private const float DamageThreshold = 0.01f;
private static readonly Dictionary<STATUSTYPE, float> PendingDamage = new Dictionary<STATUSTYPE, float>();
internal static void HandleIncrease(CharacterAfflictions afflictions, STATUSTYPE statusType, float amount)
{
//IL_007f: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: 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_00d8: 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_010b: Unknown result type (might be due to invalid IL or missing references)
if (!afflictions.character.IsLocal || (Object)(object)afflictions.character != (Object)(object)Character.localCharacter || amount <= 0f)
{
return;
}
bool flag = afflictions.character.data.fullyPassedOut || afflictions.character.data.passedOut;
if (afflictions.character.data.dead || (flag && !Plugin.ShockWhilePassedOut.Value))
{
Plugin.Log.LogInfo((object)$"[PeakShock] Ignored status effect shock ({statusType}) because player is dead or passed out.");
}
else
{
if (!TryGetEnabled(statusType, out var isEnabled))
{
return;
}
if (!isEnabled)
{
Plugin.Log.LogInfo((object)$"[PeakShock] Ignored {statusType} shock (disabled in config).");
return;
}
if (amount < 0.01f)
{
PendingDamage.TryGetValue(statusType, out var value);
value += amount;
PendingDamage[statusType] = value;
if (value < 0.01f)
{
return;
}
amount = value;
PendingDamage[statusType] = 0f;
Plugin.Log.LogInfo((object)$"[PeakShock] Accumulated damage {amount} from {statusType} exceeds threshold, triggering shock.");
}
int intensity = Mathf.Clamp(Mathf.RoundToInt(amount * (float)Plugin.MaxShock.Value), Plugin.MinShock.Value, Plugin.MaxShock.Value);
Plugin.Log.LogInfo((object)$"[PeakShock] Status effect {statusType} damage: {amount}, shock: {intensity}%");
Task.Run(delegate
{
Plugin.ShockController.EnqueueShock(intensity, 1);
});
}
}
private static bool TryGetEnabled(STATUSTYPE statusType, out bool isEnabled)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected I4, but got Unknown
switch ((int)statusType)
{
case 0:
isEnabled = Plugin.EnableInjuryShock.Value;
return true;
case 3:
isEnabled = Plugin.EnablePoisonShock.Value;
return true;
case 2:
isEnabled = Plugin.EnableColdShock.Value;
return true;
case 8:
isEnabled = Plugin.EnableHotShock.Value;
return true;
case 10:
isEnabled = Plugin.EnableSporesShock.Value;
return true;
case 9:
isEnabled = Plugin.EnableThornsShock.Value;
return true;
case 11:
isEnabled = Plugin.EnableWebShock.Value;
return true;
case 12:
isEnabled = Plugin.EnableArrowShock.Value;
return true;
case 13:
isEnabled = Plugin.EnablePetrifyShock.Value;
return true;
case 14:
isEnabled = Plugin.EnableFlyTrapShock.Value;
return true;
default:
isEnabled = false;
return false;
}
}
}
[HarmonyPatch(typeof(Character), "RPCA_Die")]
public class CharacterDeathPatch
{
[HarmonyPostfix]
public static void Postfix(Character __instance)
{
if (__instance.IsLocal)
{
int intensity = Plugin.DeathShock.Value;
int duration = Plugin.DeathDuration.Value;
Plugin.Log.LogInfo((object)$"[PeakShock] Player died. Triggering death shock: {intensity}% for {duration}s");
Task.Run(delegate
{
Plugin.ShockController.EnqueueShock(intensity, duration, null, isDeath: true);
});
}
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
public class CharacterAfflictions_AddStatus_Patch
{
[HarmonyPostfix]
public static void Postfix(CharacterAfflictions __instance, bool __result, STATUSTYPE statusType, float amount, bool fromRPC, bool playEffects, bool notify)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Invalid comparison between Unknown and I4
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Invalid comparison between Unknown and I4
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if (__result && (int)statusType != 9 && (int)statusType != 12 && (int)statusType != 13)
{
StatusShockHandler.HandleIncrease(__instance, statusType, amount);
}
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "AddThorn", new Type[]
{
typeof(int),
typeof(ushort),
typeof(bool)
})]
public class CharacterAfflictions_AddThorn_Patch
{
public sealed class StatusBefore
{
public float Thorns;
public float Arrows;
}
[HarmonyPrefix]
public static void Prefix(CharacterAfflictions __instance, out StatusBefore __state)
{
__state = new StatusBefore
{
Thorns = __instance.GetCurrentStatus((STATUSTYPE)9),
Arrows = __instance.GetCurrentStatus((STATUSTYPE)12)
};
}
[HarmonyPostfix]
public static void Postfix(CharacterAfflictions __instance, StatusBefore __state)
{
float amount = __instance.GetCurrentStatus((STATUSTYPE)9) - __state.Thorns;
float amount2 = __instance.GetCurrentStatus((STATUSTYPE)12) - __state.Arrows;
StatusShockHandler.HandleIncrease(__instance, (STATUSTYPE)9, amount);
StatusShockHandler.HandleIncrease(__instance, (STATUSTYPE)12, amount2);
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "AddPetrify", new Type[] { typeof(int) })]
public class CharacterAfflictions_AddPetrify_Patch
{
[HarmonyPrefix]
public static void Prefix(CharacterAfflictions __instance, out int __state)
{
__state = __instance.character.data.petrifyAmount;
}
[HarmonyPostfix]
public static void Postfix(CharacterAfflictions __instance, int __state)
{
int num = __instance.character.data.petrifyAmount - __state;
StatusShockHandler.HandleIncrease(__instance, (STATUSTYPE)13, (float)num / 100f);
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}