using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
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 BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RoundsShock.Server;
using UnityEngine;
using UnityEngine.Networking;
[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.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("RoundsShock")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ce793567f712328b16a8a899c7f4462a0204027f")]
[assembly: AssemblyProduct("RoundsShock")]
[assembly: AssemblyTitle("RoundsShock")]
[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.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]
[Microsoft.CodeAnalysis.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]
[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 RoundsShock
{
public struct ModConfig
{
public string username;
public string apiKey;
public string code;
public int hitIntensity;
public int hitDuration;
public int deathIntensity;
public int deathDuration;
public bool ConfigPlausable()
{
return !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(apiKey) && !string.IsNullOrEmpty(code);
}
public void SaveToPlayerPrefs()
{
PlayerPrefs.SetString("shocker_pishock_username", username);
PlayerPrefs.SetString("shocker_pishock_apikey", apiKey);
PlayerPrefs.SetString("shocker_pishock_code", code);
PlayerPrefs.SetInt("shocker_hit_intensity", hitIntensity);
PlayerPrefs.SetInt("shocker_hit_duration", hitDuration);
PlayerPrefs.SetInt("shocker_death_intensity", deathIntensity);
PlayerPrefs.SetInt("shocker_death_duration", deathDuration);
PlayerPrefs.Save();
}
public static ModConfig LoadFromPlayerPrefs()
{
ModConfig result = default(ModConfig);
result.username = PlayerPrefs.GetString("shocker_pishock_username");
result.apiKey = PlayerPrefs.GetString("shocker_pishock_apikey");
result.code = PlayerPrefs.GetString("shocker_pishock_code");
result.hitIntensity = PlayerPrefs.GetInt("shocker_hit_intensity", 20);
result.hitDuration = PlayerPrefs.GetInt("shocker_hit_duration", 1);
result.deathIntensity = PlayerPrefs.GetInt("shocker_death_intensity", 30);
result.deathDuration = PlayerPrefs.GetInt("shocker_death_duration", 1);
return result;
}
}
public sealed class PiShock
{
public static readonly PiShock Self = new PiShock();
private const string API_URL = "https://do.pishock.com/api/apioperate/";
public void Hit(float delay = 0f)
{
ExecuteWithDelay(delay, delegate
{
SendOperation(0, Plugin.ModConfig.hitIntensity, Plugin.ModConfig.hitDuration);
});
}
public void Death(float delay = 0f)
{
ExecuteWithDelay(delay, delegate
{
SendOperation(0, Plugin.ModConfig.deathIntensity, Plugin.ModConfig.deathDuration);
});
}
public void Defuse(float delay = 0f)
{
ExecuteWithDelay(delay, delegate
{
SendOperation(1, 100, 500);
});
}
public void Test(float delay = 0f)
{
ExecuteWithDelay(delay, delegate
{
SendOperation(1, 20, 1);
SendOperation(2, 50, 1);
});
}
public void SendOperation(int op, int intensity, int duration)
{
if (!Plugin.ModConfig.ConfigPlausable())
{
Plugin.Logger.LogWarning((object)"Shock requested, but the config is not plausable");
}
else
{
((MonoBehaviour)Plugin.Instance).StartCoroutine(Coroutine());
}
IEnumerator Coroutine()
{
string jsonBody = null;
try
{
jsonBody = $" {{\r\n \"Username\": \"{Plugin.ModConfig.username}\",\r\n \"Apikey\": \"{Plugin.ModConfig.apiKey}\",\r\n \"Code\": \"{Plugin.ModConfig.code}\",\r\n \"Name\": \"RoundsShock\",\r\n \"Op\": \"{op}\",\r\n \"Intensity\": \"{intensity}\",\r\n \"Duration\": \"{duration}\"\r\n}}\r\n";
}
catch (Exception ex2)
{
Exception ex = ex2;
Plugin.Logger.LogError((object)$"Failed to convert dictionary into json, {ex}");
}
if (jsonBody == null)
{
yield return 0;
}
UnityWebRequest request = new UnityWebRequest("https://do.pishock.com/api/apioperate/", "POST");
byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonBody);
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
Plugin.Logger.LogFatal((object)$"Sending PiShock operation: {op} {intensity} {duration}");
yield return request.SendWebRequest();
Plugin.Logger.LogFatal((object)(request.responseCode + " " + request.downloadHandler.text));
}
}
private static void ExecuteWithDelay(float delay, Action action)
{
Action action2 = action;
((MonoBehaviour)Plugin.Instance).StartCoroutine(Coroutine());
IEnumerator Coroutine()
{
yield return (object)new WaitForSeconds(delay);
action2();
}
}
}
[HarmonyPatch]
public static class PlayerDamageHandler
{
private static readonly FieldInfo? _playerField;
private static FieldInfo? GetField(string name, Type type)
{
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo fieldInfo = typeof(HealthHandler).GetField(name, bindingAttr);
if (fieldInfo == null)
{
Plugin.Logger.LogError((object)("Failed to find field \"" + name + "\" on HealthHandler"));
return null;
}
if (fieldInfo.FieldType != type)
{
Plugin.Logger.LogError((object)$"Field \"{name}\" on HealthHandler was not of type \"{type}\"");
fieldInfo = null;
}
return fieldInfo;
}
static PlayerDamageHandler()
{
_playerField = GetField("player", typeof(Player));
PrintAll();
}
private static void PrintAll()
{
Type typeFromHandle = typeof(HealthHandler);
Plugin.Logger.LogInfo((object)$"Printing everything on {typeFromHandle}");
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo[] fields = typeFromHandle.GetFields(bindingAttr);
foreach (FieldInfo fieldInfo in fields)
{
Plugin.Logger.LogInfo((object)$"{fieldInfo.Name}, {fieldInfo.FieldType}");
}
PropertyInfo[] properties = typeFromHandle.GetProperties(bindingAttr);
foreach (PropertyInfo propertyInfo in properties)
{
Plugin.Logger.LogInfo((object)$"{propertyInfo.Name}, {propertyInfo.PropertyType}");
}
}
[HarmonyPatch(typeof(HealthHandler), "DoDamage")]
[HarmonyPrefix]
private static void OnDamage(HealthHandler __instance, Vector2 damage)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
if (!(_playerField == null))
{
Plugin.Logger.LogError((object)"Damage detected");
Player val = (Player)_playerField.GetValue(__instance);
if ((Object)(object)val == (Object)null)
{
Plugin.Logger.LogError((object)"Player field returned null when doing damage handling");
}
else if (val.data.view.IsMine)
{
PiShock.Self.Hit();
}
}
}
}
[HarmonyPatch]
public static class PlayerDeathHandler
{
[HarmonyPatch(typeof(PlayerManager), "PlayerDied")]
[HarmonyPrefix]
private static void OnDeath(PlayerManager __instance, Player player)
{
bool isMine = player.data.view.IsMine;
Plugin.Logger.LogInfo((object)$"Death detected. Me: {isMine}");
if (isMine)
{
PiShock.Self.Death();
}
}
}
[BepInPlugin("RoundsShock-guid", "RoundsShock", "1.0.0")]
[HarmonyPatch]
public sealed class Plugin : BaseUnityPlugin
{
public static Plugin Instance { get; private set; }
public static ManualLogSource Logger { get; } = Logger.CreateLogSource("RoundsShock");
public static ModConfig ModConfig { get; set; }
private void Awake()
{
Instance = this;
((Component)this).gameObject.AddComponent<ConfigServer>();
ModConfig = ModConfig.LoadFromPlayerPrefs();
Logger.LogError((object)"Rounds shock loaded");
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
}
}
}
namespace RoundsShock.Server
{
public static class BodyParser
{
public static Dictionary<string, string> ParseUrlEncoded(HttpListenerRequest request)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
string text = new StreamReader(request.InputStream).ReadToEnd();
Plugin.Logger.LogMessage((object)text);
string[] array = text.Split(new char[1] { '&' });
string[] array2 = array;
foreach (string text2 in array2)
{
string[] array3 = text2.Split(new char[1] { '=' });
dictionary.Add(array3[0], array3[1]);
}
return dictionary;
}
}
public sealed class ConfigServer : MonoBehaviour
{
private readonly string? _configHtml;
private readonly string? _testHtml;
private Thread? _thread;
private bool CanRun => _configHtml != null && _testHtml != null;
private string? LoadString(string path)
{
try
{
Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
if (manifestResourceStream == null)
{
Plugin.Logger.LogFatal((object)("Resource stream not found for path " + path));
return null;
}
StreamReader streamReader = new StreamReader(manifestResourceStream);
return streamReader.ReadToEnd();
}
catch (Exception ex)
{
Plugin.Logger.LogFatal((object)("Server Failed to Load stream " + path + ": " + ex.Message));
return null;
}
}
private ConfigServer()
{
_configHtml = LoadString("RoundsShock.Server.Resources.config.html");
_testHtml = LoadString("RoundsShock.Server.Resources.test.html");
}
private void Awake()
{
if (CanRun)
{
_thread = new Thread(RunWebServer);
_thread.Start();
}
else
{
Plugin.Logger.LogFatal((object)"Due to a failure loading HTML the config server will not start");
}
}
private void OnDestroy()
{
if (CanRun)
{
_thread.Abort();
}
}
private void RunWebServer()
{
string text = "http://localhost:6969/";
HttpListener httpListener = new HttpListener();
httpListener.Prefixes.Add(text);
httpListener.Start();
Application.OpenURL(text);
while (true)
{
HttpListenerContext context = httpListener.GetContext();
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
try
{
Plugin.Logger.LogWarning((object)(request.HttpMethod + " " + request.Url.AbsolutePath));
if (request.Url.AbsolutePath.Contains("simpletest") && request.HttpMethod == "GET")
{
PiShock.Self.Test();
response.Redirect("/");
}
else if (request.Url.AbsolutePath.Contains("testpls") && request.HttpMethod == "POST")
{
Dictionary<string, string> dictionary = BodyParser.ParseUrlEncoded(request);
PiShock.Self.SendOperation(int.Parse(dictionary["operation"]), int.Parse(dictionary["intensity"]), int.Parse(dictionary["duration"]));
response.StatusCode = 200;
}
else if (request.Url.AbsolutePath.Contains("test") && request.HttpMethod == "GET")
{
response.StatusCode = 200;
response.ContentType = "text/html";
response.ContentEncoding = Encoding.UTF8;
byte[] bytes = Encoding.UTF8.GetBytes(_testHtml);
response.ContentLength64 = bytes.Length;
response.OutputStream.Write(bytes, 0, bytes.Length);
response.OutputStream.Close();
}
else if (request.Url.AbsolutePath.Contains("save") && request.HttpMethod == "POST")
{
Dictionary<string, string> dictionary2 = BodyParser.ParseUrlEncoded(request);
ModConfig modConfig = default(ModConfig);
modConfig.username = dictionary2["username"];
modConfig.apiKey = dictionary2["apiKey"];
modConfig.code = dictionary2["code"];
modConfig.hitIntensity = int.Parse(dictionary2["hitIntensity"]);
modConfig.hitDuration = int.Parse(dictionary2["hitDuration"]);
modConfig.deathIntensity = int.Parse(dictionary2["deathIntensity"]);
modConfig.deathDuration = int.Parse(dictionary2["deathDuration"]);
ModConfig modConfig2 = modConfig;
modConfig2.SaveToPlayerPrefs();
Plugin.ModConfig = modConfig2;
response.Redirect("/");
}
else if (request.Url.AbsolutePath == "/" && request.HttpMethod == "GET")
{
ModConfig modConfig3 = Plugin.ModConfig;
string s = _configHtml.Replace("{{username}}", modConfig3.username).Replace("{{apiKey}}", modConfig3.apiKey).Replace("{{code}}", modConfig3.code)
.Replace("{{hitIntensity}}", modConfig3.hitIntensity.ToString())
.Replace("{{hitDuration}}", modConfig3.hitDuration.ToString())
.Replace("{{deathIntensity}}", modConfig3.deathIntensity.ToString())
.Replace("{{deathDuration}}", modConfig3.deathDuration.ToString());
response.StatusCode = 200;
response.ContentType = "text/html";
response.ContentEncoding = Encoding.UTF8;
byte[] bytes2 = Encoding.UTF8.GetBytes(s);
response.ContentLength64 = bytes2.Length;
response.OutputStream.Write(bytes2, 0, bytes2.Length);
response.OutputStream.Close();
}
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)ex);
response.StatusCode = 500;
}
response.Close();
}
}
}
}