using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PiShockClassLibrary.Models;
using PiShockClassLibrary.Services;
using PiShockLibrary.Enums;
using PiShockLibrary.Models;
using PiShockLibrary.Utilities;
using Sirenix.Serialization.Utilities;
using Steamworks;
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: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Autodesk.Fbx")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")]
[assembly: IgnoresAccessChecksTo("Klattersynth")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: AssemblyCompany("mxpuffin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+43894436dbd289d7963110c7041a713eee6ece98")]
[assembly: AssemblyProduct("REPOShock")]
[assembly: AssemblyTitle("REPOShock")]
[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 REPOShock.src
{
internal class AsyncPiShockRequestQueue : 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 AsyncPiShockRequestQueue()
{
Start();
}
public void Enqueue<T>(Func<T, Task> task, T args)
{
Func<T, Task> task2 = task;
T args2 = args;
if (_disposed)
{
throw new ObjectDisposedException("AsyncPiShockRequestQueue");
}
_taskQueue.Enqueue(() => task2(args2));
_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)
{
REPOShock.Logger.LogError((object)ex.ToString());
}
}
}
}
public async Task StopAsync()
{
if (_disposed)
{
return;
}
_cts.Cancel();
_signal.Release();
try
{
await _worker;
}
catch (Exception ex)
{
REPOShock.Logger.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;
}
}
}
internal class ConfigHandler
{
internal static ConfigHandler Instance { get; private set; }
public static ConfigEntry<int>? ConfigMaxIntensity { get; private set; }
public static ConfigEntry<int>? ConfigDeathIntensity { get; private set; }
public static ConfigEntry<int>? ConfigDeathDuration { get; private set; }
public static ConfigEntry<float>? ConfigDamageInteravl { get; private set; }
public static ConfigEntry<bool>? ConfigEnableBreakShock { get; private set; }
public static ConfigEntry<bool>? ConfigBreakIgnoreEnemy { get; private set; }
public static ConfigEntry<bool>? ConfigMapValueToShock { get; private set; }
public static ConfigEntry<float>? ConfigBreakValueDmgMult { get; private set; }
public static ConfigEntry<int>? ConfigBreakShockWindow { get; private set; }
public static ConfigEntry<float>? ThrownOffensiveGracePeriod { get; private set; }
public static ConfigEntry<float>? HitOffensiveGracePeriod { get; private set; }
public static void InitConfig()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Expected O, but got Unknown
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Expected O, but got Unknown
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Expected O, but got Unknown
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Expected O, but got Unknown
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Expected O, but got Unknown
//IL_0205: Unknown result type (might be due to invalid IL or missing references)
//IL_020f: Expected O, but got Unknown
ConfigMaxIntensity = REPOShock.CFG.Bind<int>("Settings", "Max_Intensity", 100, new ConfigDescription("The maximum amount of an intensity a shock will ever be.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
ConfigDamageInteravl = REPOShock.CFG.Bind<float>("Settings", "Damage_Interval", 1f, new ConfigDescription("The intensity for each damage dealt to you. Shock will always be rounded up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
ConfigDeathIntensity = REPOShock.CFG.Bind<int>("Settings", "Death_Intensity", 50, new ConfigDescription("The intensity when you die. (1-100)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
ConfigDeathDuration = REPOShock.CFG.Bind<int>("Settings", "Max_Duration", 3, new ConfigDescription("The duration when you die. (1-15)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 15), Array.Empty<object>()));
ConfigEnableBreakShock = REPOShock.CFG.Bind<bool>("Settings_Items", "Enable_Breaking_Item_Shocks", true, "If enabled, will shock you whenever a valuable item you're holding takes damage.");
ConfigMapValueToShock = REPOShock.CFG.Bind<bool>("Settings_Items", "Map_Value_to_Shock", false, "If enabled, shock intensity will be mapped to valuable objects original value.\nIf you break lose 250 durability on an item that started with 500, you would get\nshocked for 50% of your max intensity.");
ConfigBreakValueDmgMult = REPOShock.CFG.Bind<float>("Settings_Items", "Value_Loss_Multiplier", 0.1f, new ConfigDescription("The intensity of the shock based on value lost. Damage an item for 200 value? at 0.1,\nthis will shock you for 20%. Caps at MaxIntensity", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
ConfigBreakShockWindow = REPOShock.CFG.Bind<int>("Settings_Items", "Break_Shock_Window", 15, new ConfigDescription("The amount of time a Valuable Object you have touched is tied to you.\nIf it gets damaged during this period, you will get shocked.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 120), Array.Empty<object>()));
ConfigBreakIgnoreEnemy = REPOShock.CFG.Bind<bool>("Settings_Items", "Ignore_Hitting_Enemies", true, "If enabled, hitting an enemy with an item won't shock you.");
ThrownOffensiveGracePeriod = REPOShock.CFG.Bind<float>("Settings_Items", "Thrown_Offensive_Grace_Period", 2f, new ConfigDescription("The amount of time an object you let go of has to hit an enemy before it shocks you.\nThis also starts the HitOffensiveGracePeriod, so you can keep using it as a weapon.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
HitOffensiveGracePeriod = REPOShock.CFG.Bind<float>("Settings_Items", "Hit_Offensive_Grace_Period", 3f, new ConfigDescription("The amount of time an object you use as a weapon has before it causes you to get\nshocked again. After this times up, if you don't hit an enemy again, the item goes\nback to shocking you if it takes damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
}
}
internal static class ModGlobals
{
private static float _lastLevelMessage = Time.time;
internal static GameObject? LastOffensiveObject = null;
internal static float LastOffensiveGracePeriodTime = 0f;
internal static Dictionary<GameObject, float> RecentlyHeldObjects = new Dictionary<GameObject, float>();
internal static string SteamID { get; set; } = string.Empty;
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))
{
REPOShock.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;
REPOShock.Logger.LogInfo((object)"Player has been revived.");
}
}
internal class PiShockController
{
private PiShockAPI _piShockAPI;
private PiShockUserInfo _userInfo;
private AsyncPiShockRequestQueue _queue = new AsyncPiShockRequestQueue();
public PiShockController(PiShockAPI piShockAPI, PiShockUserInfo piShockUserInfo)
{
_piShockAPI = piShockAPI;
_userInfo = piShockUserInfo;
}
public static int ClampShock(int intensity)
{
return Math.Clamp(intensity, 1, ConfigHandler.ConfigMaxIntensity.Value);
}
public void OperatePiShock(int intensity, int duration, PiShockOperations op)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
Task.Run(async delegate
{
List<Task<bool>> tasks = new List<Task<bool>>();
LinqExtensions.ForEach<PiShockDeviceInfo>((IEnumerable<PiShockDeviceInfo>)_userInfo.Devices, (Action<PiShockDeviceInfo>)delegate(PiShockDeviceInfo device)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
PiShockOperateRequestBody val = new PiShockOperateRequestBody(_userInfo, op, device.ShareCode, intensity, duration, "R.E.P.O Shock");
tasks.Add(_piShockAPI.SendOperationRequest(val));
});
if ((await Task.WhenAll(tasks)).Any((bool success) => !success))
{
REPOShock.Logger.LogError((object)"One or more PiShock requests failed to execute!");
}
});
}
}
[BepInPlugin("mxpuffin.REPOShock", "REPOShock", "1.0")]
public class REPOShock : BaseUnityPlugin
{
internal static REPOShock Instance { get; private set; }
internal static ConfigFile CFG { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; set; }
private HttpClient? httpClient { get; set; }
private PiShockAPI? PiShockAPI { get; set; }
private PiShockUserInfo? PiShockUserInfo { get; set; }
internal static PiShockController? PiShockController { get; set; }
private async void Awake()
{
Instance = this;
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
CFG = ((BaseUnityPlugin)this).Config;
httpClient = new HttpClient();
PiShockAPI = new PiShockAPI(httpClient);
PiShockLogger.LogInfoAction = Logger.LogInfo;
PiShockLogger.LogErrorAction = Logger.LogError;
await LoadConfigAndLogin();
SteamId steamId = SteamClient.SteamId;
ModGlobals.SteamID = ((object)(SteamId)(ref steamId)).ToString();
Logger.LogInfo((object)("Setting steam ID for the session: " + ModGlobals.SteamID));
Patch();
Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
}
internal void Patch()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
//IL_0025: Expected O, but got Unknown
if (Harmony == null)
{
Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
Harmony val2 = val;
Harmony = val;
}
Harmony.PatchAll();
}
internal void Unpatch()
{
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void Update()
{
}
private async Task LoadConfigAndLogin()
{
ConfigHandler.InitConfig();
ConfigEntry<string> val = CFG.Bind<string>("Auth_PiShock", "UserName", "", "Your PiShock username");
ConfigEntry<string> val2 = CFG.Bind<string>("Auth_PiShock", "APIKey", "", "Your PiShock API Key");
ConfigEntry<string> val3 = CFG.Bind<string>("Auth_PiShock", "ShareCodes", "", "Enter your sharecodes here! If you have multiple, you can separate them with commas like so \"abc123,def456\"");
try
{
if (string.IsNullOrEmpty(val.Value) || string.IsNullOrEmpty(val2.Value))
{
throw new ArgumentException("Username and APIKey cannot be empty! Please add your Username and APIKey to the config!");
}
if (string.IsNullOrEmpty(val3.Value))
{
throw new ArgumentException("You have to enter atleast 1 Share Code! If you have multiple, you can separate them with commas like so \"abc123,def456\".");
}
string[] array = val3.Value.Split(',');
List<PiShockDeviceInfo> devices = new List<PiShockDeviceInfo>();
for (int i = 0; i < array.Length; i++)
{
devices.Add(new PiShockDeviceInfo($"Shocker {i}", array[i]));
}
Logger.LogInfo((object)val2.Value);
PiShockUserInfo piShockUserInfo = (await PiShockAPI.GetUserInfoFromAPI(val.Value, val2.Value)).WithDevices(devices);
PiShockController piShockController = new PiShockController(PiShockAPI, piShockUserInfo);
PiShockUserInfo = piShockUserInfo;
PiShockController = piShockController;
}
catch (Exception ex)
{
Logger.LogError((object)ex.ToString());
}
}
}
}
namespace REPOShock.src.Patches
{
[HarmonyPatch(typeof(PhysGrabObjectImpactDetector))]
internal static class PhysGrabObjectImpactDetectorPatch
{
private static bool _lastHitEnemy;
[HarmonyPrefix]
[HarmonyPatch("OnCollisionStay")]
private static void OnCollisionStay(ref Collision collision)
{
if (ConfigHandler.ConfigBreakIgnoreEnemy.Value)
{
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 (ConfigHandler.ConfigEnableBreakShock.Value && _loseValue)
{
ItemBreakPostfix(valueLost, breakLevel, __instance);
}
}
private static void ItemBreakPostfix(float valueLost, int breakLevel, 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);
REPOShock.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;
REPOShock.Logger.LogInfo((object)"[Damage Item Event] Enemy hit, aborting shock");
}
else if (_lastHitEnemy && Time.time - num <= ConfigHandler.ThrownOffensiveGracePeriod.Value)
{
ModGlobals.LastOffensiveGracePeriodTime = Time.time;
ModGlobals.LastOffensiveObject = damagedObject;
REPOShock.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 <= ConfigHandler.HitOffensiveGracePeriod.Value)
{
REPOShock.Logger.LogInfo((object)"[Damage Item Event] Recently used 'weapon' took damage, aborting shock");
}
else if (Time.time - num <= (float)ConfigHandler.ConfigBreakShockWindow.Value)
{
ShockPlayer(valueLost, originalValue, ((Object)damagedObject).name);
}
}
}
private static void ShockPlayer(float valueLost, float originalValue, string objName)
{
int intensity = (ConfigHandler.ConfigMapValueToShock.Value ? MapValue(valueLost, 0f, originalValue, 0f, ConfigHandler.ConfigMaxIntensity.Value) : ((int)Math.Ceiling(valueLost * ConfigHandler.ConfigBreakValueDmgMult.Value)));
intensity = PiShockController.ClampShock(intensity);
REPOShock.PiShockController?.OperatePiShock(intensity, 1, (PiShockOperations)0);
REPOShock.Logger.LogInfo((object)$"[Damage Item Event] Played damaged {objName} for {valueLost} - Shocking for {intensity}%");
}
private static int MapValue(float value, float start1, float stop1, float start2, float stop2)
{
return (int)(start1 + (value - start1) * (stop2 - start2) / (stop1 - start1));
}
}
[HarmonyPatch(typeof(PhysGrabObject))]
public static class PhysGrabObjectPatch
{
[HarmonyPostfix]
[HarmonyPatch("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);
REPOShock.Logger.LogInfo((object)("Added " + ((Object)((Component)__instance).gameObject).name + " to recently held"));
}
else
{
ModGlobals.RecentlyHeldObjects[((Component)__instance).gameObject] = Time.time;
REPOShock.Logger.LogInfo((object)("Updated " + ((Object)((Component)__instance).gameObject).name + " in recently held"));
}
}
}
}
[HarmonyPatch(typeof(PlayerAvatar))]
internal static class PlayerAvatarPatch
{
[HarmonyPostfix]
[HarmonyPatch("PlayerDeathRPC")]
private static void PlayerDeathRPC(PlayerAvatar __instance)
{
if (!(SemiFunc.PlayerGetSteamID(__instance) != ModGlobals.SteamID))
{
PlayerDeath();
}
}
private static void PlayerDeath()
{
if (!ModGlobals.IsSafeLevel)
{
ModGlobals.IsAlive = false;
int value = ConfigHandler.ConfigDeathIntensity.Value;
int value2 = ConfigHandler.ConfigDeathDuration.Value;
REPOShock.PiShockController?.OperatePiShock(value, value2, (PiShockOperations)0);
REPOShock.Logger.LogInfo((object)$"Player died, shocking with {value}% for {value2}s");
}
}
[HarmonyPostfix]
[HarmonyPatch("Revive")]
private static void PlayerRevive()
{
ModGlobals.Revive();
}
[HarmonyPostfix]
[HarmonyPatch("ReviveRPC")]
private static void ReviveRPC()
{
ModGlobals.Revive();
}
}
[HarmonyPatch(typeof(PlayerHealth))]
internal static class PlayerHealthPatch
{
[HarmonyPrefix]
[HarmonyPatch("Hurt")]
private static void TakeDamage(ref int damage, PlayerHealth __instance)
{
REPOShock.Logger.LogInfo((object)SemiFunc.PlayerGetSteamID(__instance.playerAvatar));
REPOShock.Logger.LogInfo((object)ModGlobals.SteamID);
if (!(SemiFunc.PlayerGetSteamID(__instance.playerAvatar) != ModGlobals.SteamID))
{
REPOShock.Logger.LogInfo((object)$"[Health Event]: Took Damage: {damage}. Is Safe: {ModGlobals.IsSafeLevel}. Is Alive?: {ModGlobals.IsAlive}");
if (!ModGlobals.IsSafeLevel && ModGlobals.IsAlive && damage != 0)
{
int intensity = (int)Math.Ceiling((float)damage * ConfigHandler.ConfigDamageInteravl.Value);
intensity = PiShockController.ClampShock(intensity);
REPOShock.PiShockController?.OperatePiShock(intensity, 1, (PiShockOperations)0);
REPOShock.Logger.LogInfo((object)$"[Health Event] Took {damage} damage, shocking for {intensity}%");
}
}
}
}
[HarmonyPatch(typeof(RunManager))]
internal static class RunManagerPatch
{
[HarmonyPostfix]
[HarmonyPatch("ChangeLevel")]
public static void ChangeLevel(RunManager __instance)
{
UpdateLevelInfoAndResetState(((Object)__instance.levelCurrent).name);
}
[HarmonyPostfix]
[HarmonyPatch("UpdateLevel")]
public static void UpdateLevel(RunManager __instance, ref string _levelName, ref bool _gameOver)
{
UpdateLevelInfoAndResetState(_levelName);
}
private static void UpdateLevelInfoAndResetState(string level)
{
string text = level.Replace("Level - ", "");
ModGlobals.UpdateLevel(text.Trim());
ModGlobals.RecentlyHeldObjects.Clear();
if (!ModGlobals.IsAlive)
{
ModGlobals.Revive();
}
}
}
}