using System;
using System.Diagnostics;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using On;
using ShockingContent.Attributes;
using ShockingContent.Util;
using UnityEngine;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("ShockingContent")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShockingContent")]
[assembly: AssemblyTitle("ShockingContent")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ShockingContent
{
internal static class Config
{
internal static class Player
{
internal static class Damage
{
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<int> Duration;
internal static ConfigEntry<bool> VibrateOnly;
internal static ConfigEntry<bool> WarningVibration;
internal static ConfigEntry<bool> BasedOnRemainingHealth;
internal static ConfigEntry<int> MaxIntensity;
internal static ConfigEntry<int> MinIntensity;
internal static ConfigEntry<ShockingContentPlugin.ShockModes> ShockMode;
internal static ConfigEntry<int> Interval;
}
internal static class Death
{
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<int> Duration;
internal static ConfigEntry<int> Intensity;
internal static ConfigEntry<bool> VibrateOnly;
internal static ConfigEntry<bool> WarningVibration;
internal static ConfigEntry<ShockingContentPlugin.ShockModes> ShockMode;
internal static ConfigEntry<bool> Beep;
}
internal static class Heal
{
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<int> Duration;
internal static ConfigEntry<int> Intensity;
internal static ConfigEntry<ShockingContentPlugin.ShockModes> ShockMode;
internal static ConfigEntry<bool> Shock;
}
internal static class Revive
{
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<int> Duration;
internal static ConfigEntry<int> Intensity;
internal static ConfigEntry<bool> WarningVibration;
internal static ConfigEntry<bool> VibrateOnly;
internal static ConfigEntry<ShockingContentPlugin.ShockModes> ShockMode;
internal static ConfigEntry<bool> Beep;
}
}
internal static class ShockStick
{
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<int> Duration;
internal static ConfigEntry<int> Intensity;
internal static ConfigEntry<bool> WarningVibration;
internal static ConfigEntry<bool> VibrateOnly;
internal static ConfigEntry<ShockingContentPlugin.ShockModes> ShockMode;
internal static ConfigEntry<bool> Beep;
}
internal static ConfigEntry<string> PishockUsername;
internal static ConfigEntry<string> PishockApiKey;
internal static ConfigEntry<string> PishockCodes;
private static ConfigFile file { get; set; }
static Config()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
ShockingContentPlugin.logger.LogInfo((object)"Initializing config");
file = new ConfigFile(Paths.ConfigPath + "\\ShockingContentPlugin.cfg", true);
PishockApiKey = file.Bind<string>("PiShock", "ApiKey", "APIKEY", "PiShock API key");
PishockUsername = file.Bind<string>("PiShock", "Username", "USERNAME", "PiShock username.");
PishockCodes = file.Bind<string>("PiShock", "Codes", "CODES", "codes for PiShock seperated by a comma.");
Player.Damage.Enabled = file.Bind<bool>("Player.Damage", "Enabled", true, "Enable or disable damage effects.");
Player.Damage.Duration = file.Bind<int>("Player.Damage", "Duration", 1, "Duration of the damage effect in seconds.");
Player.Damage.VibrateOnly = file.Bind<bool>("Player.Damage", "VibrateOnly", false, "If true, only vibrate instead of using shocks.");
Player.Damage.WarningVibration = file.Bind<bool>("Player.Damage", "WarningVibration", false, "If true, provides a warning vibration before actual effect.");
Player.Damage.BasedOnRemainingHealth = file.Bind<bool>("Player.Damage", "BasedOnRemainingHealth", false, "If true, effects are based on the remaining health.");
Player.Damage.MaxIntensity = file.Bind<int>("Player.Damage", "MaxIntensity", 80, "Maximum intensity of the shock.");
Player.Damage.MinIntensity = file.Bind<int>("Player.Damage", "MinIntensity", 0, "Minimum intensity of the shock.");
Player.Damage.ShockMode = file.Bind<ShockingContentPlugin.ShockModes>("Player.Damage", "ShockMode", ShockingContentPlugin.ShockModes.ALL, "Mode of shock to be used.");
Player.Damage.Interval = file.Bind<int>("Player.Damage", "Interval", 0, "Interval between shocks.");
Player.Death.Enabled = file.Bind<bool>("Player.Death", "Enabled", true, "Enable or disable death effects.");
Player.Death.Duration = file.Bind<int>("Player.Death", "Duration", 5, "Duration of the death effect in seconds.");
Player.Death.Intensity = file.Bind<int>("Player.Death", "Intensity", 100, "Intensity of the death effect.");
Player.Death.VibrateOnly = file.Bind<bool>("Player.Death", "VibrateOnly", false, "If true, only vibrate instead of using shocks.");
Player.Death.WarningVibration = file.Bind<bool>("Player.Death", "WarningVibration", true, "If true, provides a warning vibration before actual effect.");
Player.Death.ShockMode = file.Bind<ShockingContentPlugin.ShockModes>("Player.Death", "ShockMode", ShockingContentPlugin.ShockModes.ALL, "Mode of shock to be used.");
Player.Death.Beep = file.Bind<bool>("Player.Death", "Beep", false, "If true, emits a beep sound on death.");
Player.Heal.Enabled = file.Bind<bool>("Player.Heal", "Enabled", false, "Enable or disable heal effects.");
Player.Heal.Duration = file.Bind<int>("Player.Heal", "Duration", 0, "Duration of the heal effect in seconds.");
Player.Heal.Intensity = file.Bind<int>("Player.Heal", "Intensity", 0, "Intensity of the heal effect.");
Player.Heal.ShockMode = file.Bind<ShockingContentPlugin.ShockModes>("Player.Heal", "ShockMode", ShockingContentPlugin.ShockModes.ALL, "Mode of shock to be used.");
Player.Heal.Shock = file.Bind<bool>("Player.Heal", "Shock", false, "If true, uses shock along with healing.");
Player.Revive.Enabled = file.Bind<bool>("Player.Revive", "Enabled", true, "Enable or disable revive effects.");
Player.Revive.Duration = file.Bind<int>("Player.Revive", "Duration", 2, "Duration of the revive effect in seconds.");
Player.Revive.Intensity = file.Bind<int>("Player.Revive", "Intensity", 30, "Intensity of the revive effect.");
Player.Revive.WarningVibration = file.Bind<bool>("Player.Revive", "WarningVibration", false, "If true, provides a warning vibration before actual effect.");
Player.Revive.VibrateOnly = file.Bind<bool>("Player.Revive", "VibrateOnly", false, "If true, only vibrate instead of using shocks.");
Player.Revive.ShockMode = file.Bind<ShockingContentPlugin.ShockModes>("Player.Revive", "ShockMode", ShockingContentPlugin.ShockModes.ALL, "Mode of shock to be used.");
Player.Revive.Beep = file.Bind<bool>("Player.Revive", "Beep", true, "If true, emits a beep sound on revive.");
ShockStick.Enabled = file.Bind<bool>("ShockStick", "Enabled", false, "Enable or disable the ShockStick.");
ShockStick.Duration = file.Bind<int>("ShockStick", "Duration", 0, "Duration of the ShockStick effect in seconds.");
ShockStick.Intensity = file.Bind<int>("ShockStick", "Intensity", 0, "Intensity of the ShockStick effect.");
ShockStick.WarningVibration = file.Bind<bool>("ShockStick", "WarningVibration", false, "If true, provides a warning vibration before actual effect.");
ShockStick.VibrateOnly = file.Bind<bool>("ShockStick", "VibrateOnly", false, "If true, only vibrate instead of using shocks.");
ShockStick.ShockMode = file.Bind<ShockingContentPlugin.ShockModes>("ShockStick", "ShockMode", ShockingContentPlugin.ShockModes.ALL, "Mode of shock to be used.");
ShockStick.Beep = file.Bind<bool>("ShockStick", "Beep", false, "If true, emits a beep sound with the effect.");
file.Save();
ShockingContentPlugin.logger.LogDebug((object)"Config saved");
}
}
public class PiShockApi
{
private string apiEndpoint = "https://do.pishock.com/api/apioperate/";
public string username { private get; set; }
public string apiKey { private get; set; }
public string code { private get; set; }
public string senderName { private get; set; }
public async Task Shock(int intensity, int duration)
{
using HttpClient client = new HttpClient();
var requestData = new
{
Username = username,
Name = senderName,
Code = code,
Intensity = intensity,
Duration = duration,
Apikey = apiKey,
Op = 0
};
string jsonBody = JsonConvert.SerializeObject((object)requestData);
using HttpContent content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(apiEndpoint, content);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Request sent successfully.");
return;
}
Console.WriteLine($"Error: {response.StatusCode} - {response.ReasonPhrase}");
Console.WriteLine("Response Content: " + await response.Content.ReadAsStringAsync());
}
public async Task Vibrate(int intensity, int duration)
{
using HttpClient client = new HttpClient();
var requestData = new
{
Username = username,
Name = senderName,
Code = code,
Intensity = intensity,
Duration = duration,
Apikey = apiKey,
Op = 1
};
string jsonBody = JsonConvert.SerializeObject((object)requestData);
using HttpContent content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(apiEndpoint, content);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Request sent successfully.");
return;
}
Console.WriteLine($"Error: {response.StatusCode} - {response.ReasonPhrase}");
Console.WriteLine("Response Content: " + await response.Content.ReadAsStringAsync());
}
public async Task Beep(int duration)
{
using HttpClient client = new HttpClient();
var requestData = new
{
Username = username,
Name = senderName,
Code = code,
Duration = duration,
Apikey = apiKey,
Op = 2
};
string jsonBody = JsonConvert.SerializeObject((object)requestData);
using HttpContent content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(apiEndpoint, content);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Request sent successfully.");
return;
}
Console.WriteLine($"Error: {response.StatusCode} - {response.ReasonPhrase}");
Console.WriteLine("Response Content: " + await response.Content.ReadAsStringAsync());
}
}
[BepInPlugin("ShockingContent", "ShockingContent", "1.0.0")]
public class ShockingContentPlugin : BaseUnityPlugin
{
internal enum ShockModes
{
FIRST,
LAST,
RANDOM,
ROUND_ROBIN,
RANDOM_ALL,
ALL
}
public static ManualLogSource logger;
public static ShockingContentPlugin Instance { get; private set; }
private void Awake()
{
logger = ((BaseUnityPlugin)this).Logger;
Instance = this;
Hook();
((BaseUnityPlugin)this).Logger.LogInfo((object)("API KEY IS: " + Config.PishockApiKey.Value));
((BaseUnityPlugin)this).Logger.LogInfo((object)"ShockingContentPlugin ShockingContent is loaded!");
}
private void Hook()
{
(MethodInfo, Attribute)[] methodsWithAttribute = ReflectionUtility.GetMethodsWithAttribute<Patch>();
(MethodInfo, Attribute)[] array = methodsWithAttribute;
for (int i = 0; i < array.Length; i++)
{
var (methodInfo, _) = array[i];
methodInfo.Invoke(null, Array.Empty<object>());
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"Patching complete");
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "ShockingContent";
public const string PLUGIN_NAME = "ShockingContent";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace ShockingContent.Util
{
internal static class Operations
{
internal static readonly string pishockLogId = "ShockingContentPlugin (Content warning)";
private static readonly Random rnd = new Random();
private static DateTime lastShock;
private static int roundRobin = 0;
private static bool DidDeath = false;
internal static async void DoOperation(int intensity, int duration, ShockingContentPlugin.ShockModes mode, bool warning = false, bool vibrateOnly = false, bool beep = false)
{
string[] codes = Config.PishockCodes.Value.Split(',');
bool[] picked = PickShockers(mode, codes.Length);
for (int i = 0; i < codes.Length; i++)
{
ShockingContentPlugin.logger.LogDebug((object)("Running DoOperation for shocker coded " + codes[i]));
if (!picked[i])
{
continue;
}
PiShockApi user = new PiShockApi
{
username = Config.PishockUsername.Value,
apiKey = Config.PishockApiKey.Value,
code = codes[i],
senderName = pishockLogId
};
if (beep)
{
await user.Beep(3000);
}
if (vibrateOnly || warning)
{
await user.Vibrate(intensity, duration);
if (!vibrateOnly)
{
ShockingContentPlugin.logger.LogDebug((object)"Vibrating with delay");
await Task.Delay(duration + 1000);
ShockingContentPlugin.logger.LogDebug((object)"Shocking after delay");
await user.Shock(intensity, duration);
}
}
else
{
await user.Shock(intensity, duration);
}
}
}
public static bool NextBoolean(Random random)
{
return random.Next() > 1073741823;
}
private static bool[] PickShockers(ShockingContentPlugin.ShockModes mode, int length)
{
bool[] array = new bool[length];
int num = rnd.Next(0, length);
if (roundRobin >= length)
{
roundRobin = 0;
}
for (int i = 0; i < length; i++)
{
switch (mode)
{
case ShockingContentPlugin.ShockModes.ALL:
array[i] = true;
break;
case ShockingContentPlugin.ShockModes.RANDOM_ALL:
array[i] = NextBoolean(rnd);
break;
case ShockingContentPlugin.ShockModes.RANDOM:
array[i] = i == num;
break;
case ShockingContentPlugin.ShockModes.FIRST:
array[i] = i == 0;
break;
case ShockingContentPlugin.ShockModes.LAST:
array[i] = i == length - 1;
break;
case ShockingContentPlugin.ShockModes.ROUND_ROBIN:
array[i] = i == roundRobin;
break;
}
}
roundRobin++;
if (mode == ShockingContentPlugin.ShockModes.RANDOM_ALL)
{
bool flag = false;
bool[] array2 = array;
for (int j = 0; j < array2.Length; j++)
{
if (array2[j])
{
flag = true;
break;
}
}
if (!flag)
{
array[num] = true;
}
}
return array;
}
internal static void DoDamage(int dmg, int health)
{
TimeSpan timeSpan = DateTime.Now - lastShock;
if (timeSpan < TimeSpan.FromSeconds(Config.Player.Damage.Interval.Value))
{
ShockingContentPlugin.logger.LogDebug((object)("Didn't shock due to interval. LastShock: " + lastShock.ToLongTimeString()));
return;
}
int intensity = Mathf.Clamp(dmg, Config.Player.Damage.MinIntensity.Value, Config.Player.Damage.MaxIntensity.Value);
int num = 100 - health;
int intensity2 = Mathf.Clamp(num, Config.Player.Damage.MinIntensity.Value, Config.Player.Damage.MaxIntensity.Value);
if (Config.Player.Damage.BasedOnRemainingHealth.Value)
{
ShockingContentPlugin.logger.LogInfo((object)("Shocking based on health for " + intensity2));
DoOperation(intensity2, Config.Player.Damage.Duration.Value, Config.Player.Damage.ShockMode.Value, Config.Player.Damage.WarningVibration.Value, Config.Player.Damage.VibrateOnly.Value);
}
else if (Config.Player.Damage.Enabled.Value)
{
ShockingContentPlugin.logger.LogInfo((object)("Shocking based on damage for " + intensity));
DoOperation(intensity, Config.Player.Damage.Duration.Value, Config.Player.Damage.ShockMode.Value, Config.Player.Damage.WarningVibration.Value, Config.Player.Damage.VibrateOnly.Value);
}
lastShock = DateTime.Now;
}
internal static void DoDeath()
{
if (!DidDeath && Config.Player.Death.Enabled.Value)
{
ShockingContentPlugin.logger.LogInfo((object)"Death shock");
if (Config.Player.Death.Beep.Value)
{
}
DoOperation(Config.Player.Death.Intensity.Value, Config.Player.Death.Duration.Value, Config.Player.Death.ShockMode.Value, Config.Player.Death.WarningVibration.Value, Config.Player.Death.VibrateOnly.Value, Config.Player.Death.Beep.Value);
DidDeath = true;
Task.Run(async delegate
{
await Task.Delay(20000);
DidDeath = false;
});
}
}
}
}
namespace ShockingContent.Patches
{
public static class PlayerPatches
{
[CompilerGenerated]
private static class <>O
{
public static hook_TakeDamage <0>__Player_TakeDamage;
public static hook_Die <1>__Player_Die;
public static hook_CallRevive <2>__Player_CallRevive;
public static hook_Heal <3>__Player_Heal;
}
private static DateTime lastHugged;
[Patch]
public static void Init()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Expected O, but got Unknown
ShockingContentPlugin.logger.LogInfo((object)"Patching player");
object obj = <>O.<0>__Player_TakeDamage;
if (obj == null)
{
hook_TakeDamage val = Player_TakeDamage;
<>O.<0>__Player_TakeDamage = val;
obj = (object)val;
}
Player.TakeDamage += (hook_TakeDamage)obj;
object obj2 = <>O.<1>__Player_Die;
if (obj2 == null)
{
hook_Die val2 = Player_Die;
<>O.<1>__Player_Die = val2;
obj2 = (object)val2;
}
Player.Die += (hook_Die)obj2;
object obj3 = <>O.<2>__Player_CallRevive;
if (obj3 == null)
{
hook_CallRevive val3 = Player_CallRevive;
<>O.<2>__Player_CallRevive = val3;
obj3 = (object)val3;
}
Player.CallRevive += (hook_CallRevive)obj3;
object obj4 = <>O.<3>__Player_Heal;
if (obj4 == null)
{
hook_Heal val4 = Player_Heal;
<>O.<3>__Player_Heal = val4;
obj4 = (object)val4;
}
Player.Heal += (hook_Heal)obj4;
}
private static bool Player_Heal(orig_Heal orig, Player self, float healAmount)
{
TimeSpan timeSpan = DateTime.Now - lastHugged;
bool result = orig.Invoke(self, healAmount);
if (!self.IsLocal || !Config.Player.Heal.Enabled.Value || timeSpan < TimeSpan.FromSeconds(1.0))
{
return result;
}
Operations.DoOperation(Config.Player.Heal.Intensity.Value, Config.Player.Heal.Duration.Value, Config.Player.Heal.ShockMode.Value, warning: false, !Config.Player.Heal.Shock.Value);
lastHugged = DateTime.Now;
return result;
}
private static void Player_CallRevive(orig_CallRevive orig, Player self)
{
orig.Invoke(self);
if (self.IsLocal && Config.Player.Revive.Enabled.Value)
{
Operations.DoOperation(Config.Player.Revive.Intensity.Value, Config.Player.Revive.Duration.Value, Config.Player.Revive.ShockMode.Value, Config.Player.Revive.WarningVibration.Value, Config.Player.Revive.VibrateOnly.Value, Config.Player.Revive.Beep.Value);
}
}
private static void Player_Die(orig_Die orig, Player self)
{
orig.Invoke(self);
if (self.IsLocal && Config.Player.Death.Enabled.Value)
{
Operations.DoDeath();
}
}
private static void Player_TakeDamage(orig_TakeDamage orig, Player self, float damage)
{
orig.Invoke(self, damage);
if (self.IsLocal && Config.Player.Damage.Enabled.Value)
{
Operations.DoDamage((int)Math.Round(damage), (int)Math.Round(self.data.health));
}
}
}
public static class ShockStickPatches
{
[CompilerGenerated]
private static class <>O
{
public static hook_OnShock <0>__ShockStick_OnShock;
}
[Patch]
public static void Init()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
ShockingContentPlugin.logger.LogInfo((object)"Patching shockstick");
object obj = <>O.<0>__ShockStick_OnShock;
if (obj == null)
{
hook_OnShock val = ShockStick_OnShock;
<>O.<0>__ShockStick_OnShock = val;
obj = (object)val;
}
ShockStick.OnShock += (hook_OnShock)obj;
}
private static void ShockStick_OnShock(orig_OnShock orig, ShockStick self, Player playerToShock)
{
orig.Invoke(self, playerToShock);
ShockingContentPlugin.logger.LogDebug((object)"Checking if enabled");
if (playerToShock.IsLocal && Config.ShockStick.Enabled.Value)
{
ShockingContentPlugin.logger.LogDebug((object)"Doing operation");
Operations.DoOperation(Config.ShockStick.Intensity.Value, Config.ShockStick.Duration.Value, Config.ShockStick.ShockMode.Value, Config.ShockStick.WarningVibration.Value, Config.ShockStick.VibrateOnly.Value, Config.ShockStick.Beep.Value);
}
}
}
}
namespace ShockingContent.Attributes
{
[AttributeUsage(AttributeTargets.Method)]
internal class Patch : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}