Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ReOpenShock v1.0.5
ReOpenShock.dll
Decompiled a year agousing System; using System.Collections.Generic; 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 HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using ReOpenShock.Patches; using Sirenix.Serialization.Utilities; using Sirenix.Utilities; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ReOpenShock")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5+b1f49121efd3625308aaa2fa11c6630d1abfc48c")] [assembly: AssemblyProduct("Shocks you in R.E.P.O")] [assembly: AssemblyTitle("ReOpenShock")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.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 ReOpenShock { public static class ModConfig { private static class ConfigGroups { public static readonly string Connection = "Connection"; public static readonly string General = "General"; public static readonly string ShockEvents = "Shock Events"; public static readonly string Misc = "Misc"; } public static ConfigEntry<string> OpenShockAPIDomain; public static ConfigEntry<string> OpenShockAPIKey; public static ConfigEntry<bool> DeveloperMode; public static ConfigEntry<int> ShockStrength; public static ConfigEntry<float> ShockDuration; public static ConfigEntry<bool> ShockOnDeath; public static ConfigEntry<bool> ShockOnDamage; public static ConfigEntry<bool> ShockOnItemBreak; private static readonly ImmutableList<ConfigEntry<string>> RegenOsClientOnChange = new ImmutableList<ConfigEntry<string>>((IList<ConfigEntry<string>>)new List<ConfigEntry<string>>(2) { OpenShockAPIDomain, OpenShockAPIKey }); public static void Init(ConfigFile config) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown OpenShockAPIDomain = config.Bind<string>(ConfigGroups.Connection, "OpenShock API", "https://api.openshock.app", "The OpenShock instance's API"); OpenShockAPIKey = config.Bind<string>(ConfigGroups.Connection, "OpenShock API Key", "GO TO YOUR CONFIG FILE TO EDIT", "Go to your config file to edit!"); DeveloperMode = config.Bind<bool>(ConfigGroups.Misc, "Developer Mode", false, new ConfigDescription("Beeps Only", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); ShockStrength = config.Bind<int>(ConfigGroups.General, "Shock Strength", 20, new ConfigDescription("", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); ShockDuration = config.Bind<float>(ConfigGroups.General, "Shock Duration", 0.3f, new ConfigDescription("", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 30f), Array.Empty<object>())); ShockOnDeath = config.Bind<bool>(ConfigGroups.ShockEvents, "Shock On Death", true, "Do you want to be shocked on death?"); ShockOnDamage = config.Bind<bool>(ConfigGroups.ShockEvents, "Shock On Damage", true, "Shock on damage proportionate to how low you are"); ShockOnItemBreak = config.Bind<bool>(ConfigGroups.ShockEvents, "Shock On Item Break", true, "Shocks you when an item breaks, proportionate to how much health the item had"); } } internal static class ModGlobals { private static float _lastLevelMessage = Time.time; internal static GameObject? LastOffensiveObject = null; internal static float LastOffensiveGracePeriodTime = 0f; internal static readonly Dictionary<GameObject, float> RecentlyHeldObjects = new Dictionary<GameObject, float>(); internal static bool IsAlive { get; set; } = true; internal static string CurrentLevel { get; set; } = ""; internal static bool IsSafeLevel { get; set; } = true; internal static float LastHeldItemPickupTime { get; set; } = Time.time; internal static void UpdateLevel(string level) { CurrentLevel = level; EvaluateIsSafeLevel(); if (!(_lastLevelMessage < 3f)) { ReOpenShock.Instance.Logger.LogInfo((object)("Updating Level to " + level + " - Resetting Mod Global Variables")); _lastLevelMessage = Time.time; } } private static void EvaluateIsSafeLevel() { bool flag = false; if (!SemiFunc.IsMultiplayer()) { flag = CurrentLevel == "Arena"; } IsSafeLevel = CurrentLevel == "Shop" || CurrentLevel == "Lobby" || CurrentLevel == "Lobby Menu" || CurrentLevel == "" || flag; } internal static void Revive() { IsAlive = true; ReOpenShock.Instance.Logger.LogInfo((object)"Player has been revived."); } } public enum ControlType { Stop, Shock, Vibrate, Sound } public class ControlRequest { public IEnumerable<Control> Shocks { get; set; } = null; public string CustomName { get; set; } } public class Control { public string Id { get; set; } public ControlType Type { get; set; } public int Intensity { get; set; } public int Duration { get; set; } } public class DevicesRes { public string message { get; set; } public List<Hub> data { get; set; } } public class Hub { public string id { get; set; } public string name { get; set; } public DateTime createdOn { get; set; } public List<Shocker> shockers { get; set; } } public class Shocker { public string name { get; set; } public bool isPaused { get; set; } public DateTime createdOn { get; set; } public string id { get; set; } public int rfId { get; set; } public string model { get; set; } } public class OpenShockApi { private static readonly ManualLogSource Logger = Logger.CreateLogSource("OpenShockApi"); private readonly HttpClient _httpClient; public ImmutableList<string> devices = new ImmutableList<string>((IList<string>)new List<string>()); public OpenShockApi(string apiToken, Uri server) { HttpClientHandler handler = new HttpClientHandler(); _httpClient = new HttpClient(handler) { BaseAddress = server }; _httpClient.DefaultRequestHeaders.Add("User-Agent", "ReOpenShock/1.0.5"); _httpClient.DefaultRequestHeaders.Add("OpenShockToken", apiToken); } public async Task Control(List<Control> shocks) { if (shocks.Count != 0) { Logger.LogInfo((object)"Sending control request to OpenShock API"); HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, "/2/shockers/control") { Content = new StringContent(JsonConvert.SerializeObject((object)new ControlRequest { Shocks = shocks, CustomName = "Integrations.ReOpenShock" }), Encoding.UTF8, "application/json") }; HttpResponseMessage response = await _httpClient.SendAsync(requestMessage); if (!response.IsSuccessStatusCode) { Logger.LogError((object)$"Failed to send control request to OpenShock API [{response.StatusCode}]"); } else { Logger.LogInfo((object)"Successfully sent control request"); } } } public async Task GetDevices() { if (ModConfig.OpenShockAPIKey.Value == (string)((ConfigEntryBase)ModConfig.OpenShockAPIKey).DefaultValue) { devices = new ImmutableList<string>((IList<string>)new List<string>()); return; } Logger.LogInfo((object)"Sending get devices request to OpenShock API"); HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "/1/shockers/own"); HttpResponseMessage response = await _httpClient.SendAsync(requestMessage); if (!response.IsSuccessStatusCode) { Logger.LogError((object)$"Failed to send get devices request to OpenShock API [{response.StatusCode}]"); return; } DevicesRes resCl = JsonConvert.DeserializeObject<DevicesRes>(await response.Content.ReadAsStringAsync()); List<string> shockerIds = new List<string>(); foreach (Hub hub in resCl.data) { foreach (Shocker shocker in hub.shockers) { shockerIds.Add(shocker.id); } } devices = LinqExtensions.ToImmutableList<string>((IEnumerable<string>)shockerIds); Logger.LogInfo((object)$"Got {devices.Count} shockers"); } } [BepInPlugin("gay.lilyy.ReOpenShock", "ReOpenShock", "1.0.5")] public class ReOpenShock : BaseUnityPlugin { public const string PluginGuid = "gay.lilyy.ReOpenShock"; public const string PluginName = "ReOpenShock"; public const string PluginVersion = "1.0.5"; public static ReOpenShock Instance; private Harmony _harmony; internal OpenShockApi client; public ManualLogSource Logger; public async void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; ModConfig.Init(((BaseUnityPlugin)this).Config); Patch(); Logger.LogInfo((object)"ReOpenShock patched!"); await MakeClient(); } public async Task MakeClient() { client = new OpenShockApi(ModConfig.OpenShockAPIKey.Value, new Uri(ModConfig.OpenShockAPIDomain.Value)); await client.GetDevices(); } private void Patch() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown if (_harmony == null) { _harmony = new Harmony("gay.lilyy.ReOpenShock"); } _harmony.PatchAll(typeof(PlayerPatches)); _harmony.PatchAll(typeof(ValuablePatches)); _harmony.PatchAll(typeof(ValuablePatches.PhysGrabObjectImpactDetectorPatch)); } public async void ActionShockers(ControlType action, int strength) { List<Control> actions = new List<Control>(); foreach (string device in Instance.client.devices) { actions.Add(new Control { Id = device, Duration = (int)(ModConfig.ShockDuration.Value * 1000f), Intensity = strength, Type = (ModConfig.DeveloperMode.Value ? ControlType.Sound : action) }); } Logger.LogInfo((object)$"Actioning shockers at mode {action} at {strength}% for {ModConfig.ShockDuration}s"); await Instance.client.Control(actions); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ReOpenShock"; public const string PLUGIN_NAME = "Shocks you in R.E.P.O"; public const string PLUGIN_VERSION = "1.0.5"; } } namespace ReOpenShock.Patches { public static class PlayerPatches { private static int _lastHealth; [HarmonyPostfix] [HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathDone")] public static void PlayerDeathDone_PostFix(PlayerAvatar __instance) { ReOpenShock.Instance.Logger.LogInfo((object)(__instance.playerName + " died")); if (__instance.isLocal) { ReOpenShock.Instance.Logger.LogInfo((object)"Shocking!"); Task.Run(delegate { ReOpenShock.Instance.ActionShockers(ModConfig.ShockOnDeath.Value ? ControlType.Shock : ControlType.Vibrate, ModConfig.ShockStrength.Value); }); } } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerHealth), "Hurt")] public static void PlayerHurt_Prefix(PlayerHealth __instance) { if (!((Component)__instance).GetComponent<PlayerAvatar>().isLocal || !ModConfig.ShockOnDamage.Value) { return; } if (_lastHealth < 0) { _lastHealth = __instance.health; } if (__instance.health < _lastHealth) { float num = (1f - (float)__instance.health / (float)__instance.maxHealth) * 100f; ReOpenShock.Instance.Logger.LogInfo((object)num); int shockValue = Mathf.RoundToInt(num); ReOpenShock.Instance.Logger.LogInfo((object)$"Health decreased: {_lastHealth} -> {__instance.health}, sending shock {shockValue}"); Task.Run(delegate { ReOpenShock.Instance.ActionShockers(ControlType.Shock, shockValue); }); } _lastHealth = __instance.health; } } public static class ValuablePatches { [HarmonyPatch(typeof(PhysGrabObjectImpactDetector))] public static class PhysGrabObjectImpactDetectorPatch { private static bool _lastHitEnemy; [HarmonyPrefix] [HarmonyPatch("OnCollisionStay")] private static void OnCollisionStay(ref Collision collision) { if (((Component)collision.transform).CompareTag("Enemy")) { _lastHitEnemy = true; } else { _lastHitEnemy = false; } } [HarmonyPostfix] [HarmonyPatch("BreakRPC")] private static void ItemImpactBreakRPC(float valueLost, ref bool _loseValue, int breakLevel, PhysGrabObjectImpactDetector __instance) { if (ModConfig.ShockOnItemBreak.Value && _loseValue) { ItemBreakPostfix(valueLost, __instance); } } private static void ItemBreakPostfix(float valueLost, PhysGrabObjectImpactDetector __instance) { if (!ModGlobals.IsAlive || ModGlobals.CurrentLevel == "Arena" || !__instance.isValuable) { return; } bool heldByLocalPlayer = __instance.physGrabObject.heldByLocalPlayer; if (heldByLocalPlayer) { if (!ModGlobals.RecentlyHeldObjects.ContainsKey(((Component)__instance).gameObject)) { ModGlobals.RecentlyHeldObjects.Add(((Component)__instance).gameObject, Time.time); ReOpenShock.Instance.Logger.LogInfo((object)("Object " + ((Object)((Component)__instance).gameObject).name + " added to held objects.")); } else { ModGlobals.RecentlyHeldObjects[((Component)__instance).gameObject] = Time.time; } } float dollarValueOriginal = __instance.valuableObject.dollarValueOriginal; ShockPlayerIfNecessary(((Component)__instance).gameObject, valueLost, dollarValueOriginal, heldByLocalPlayer); } private static void ShockPlayerIfNecessary(GameObject damagedObject, float valueLost, float originalValue, bool isHeldByLocalPlayer) { if (ModGlobals.RecentlyHeldObjects.ContainsKey(damagedObject)) { float num = ModGlobals.RecentlyHeldObjects[damagedObject]; if (isHeldByLocalPlayer && _lastHitEnemy) { ModGlobals.LastOffensiveGracePeriodTime = Time.time; ModGlobals.LastOffensiveObject = damagedObject; ReOpenShock.Instance.Logger.LogInfo((object)"[Damage Item Event] Enemy hit, aborting shock"); } else if (_lastHitEnemy && Time.time - num <= 2f) { ModGlobals.LastOffensiveGracePeriodTime = Time.time; ModGlobals.LastOffensiveObject = damagedObject; ReOpenShock.Instance.Logger.LogInfo((object)"[Damage Item Event] Enemy hit in thrown grace period, aborting shock"); } else if ((Object)(object)ModGlobals.LastOffensiveObject == (Object)(object)damagedObject && Time.time - ModGlobals.LastOffensiveGracePeriodTime <= 3f) { ReOpenShock.Instance.Logger.LogInfo((object)"[Damage Item Event] Recently used 'weapon' took damage, aborting shock"); } else if (Time.time - num <= 4f) { ShockPlayer(valueLost, originalValue, ((Object)damagedObject).name); } } } private static void ShockPlayer(float valueLost, float originalValue, string objName) { int num = MapValue(valueLost, 0f, originalValue, 0f, ModConfig.ShockStrength.Value); ReOpenShock.Instance.Logger.LogInfo((object)$"[Damage Item Event] Played damaged {objName} for {valueLost} - Shocking for {num}%"); ReOpenShock.Instance.ActionShockers(ControlType.Shock, num); } private static int MapValue(float value, float start1, float stop1, float start2, float stop2) { return (int)(start1 + (value - start1) * (stop2 - start2) / (stop1 - start1)); } } [HarmonyPostfix] [HarmonyPatch(typeof(PhysGrabObject), "GrabEnded")] private static void GrabEndedPostFix(PhysGrabObject __instance) { if (__instance.isValuable && __instance.heldByLocalPlayer) { ModGlobals.LastHeldItemPickupTime = Time.time; ModGlobals.LastOffensiveGracePeriodTime = 0f; if (!ModGlobals.RecentlyHeldObjects.ContainsKey(((Component)__instance).gameObject)) { ModGlobals.RecentlyHeldObjects.Add(((Component)__instance).gameObject, Time.time); ReOpenShock.Instance.Logger.LogInfo((object)("Added " + ((Object)((Component)__instance).gameObject).name + " to recently held")); } else { ModGlobals.RecentlyHeldObjects[((Component)__instance).gameObject] = Time.time; ReOpenShock.Instance.Logger.LogInfo((object)("Updated " + ((Object)((Component)__instance).gameObject).name + " in recently held")); } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }