using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("dotoo_antilag_photon_disc")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("dotoo_antilag_photon_disc")]
[assembly: AssemblyTitle("dotoo_antilag_photon_disc")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace AntiLagPhotonDisc
{
[BepInPlugin("dotoo.antilagphotondisc", "Anti-lag Photon Disc", "0.1.0")]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
internal static ConfigEntry<bool> DevMode;
internal static ConfigEntry<int> MaxChunks;
internal static ConfigEntry<float> PullSpeedMultiplier;
private void Awake()
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
DevMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DevMode", false, "Enable verbose debug logging. Leave this off for normal play.");
MaxChunks = ((BaseUnityPlugin)this).Config.Bind<int>("Limit", "MaxChunks", 100, new ConfigDescription("Maximum number of Photon Disc health chunks that can exist at once. When this is exceeded, the oldest chunks are removed first. Set to 0 to disable the limit. Only chunks spawned by the Photon Disc upgrade are counted.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>()));
PullSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Pull", "PullSpeedMultiplier", 1f, new ConfigDescription("Multiplier for how fast Photon Disc health chunks fly toward you. 1 = vanilla speed. Only affects chunks spawned by the Photon Disc upgrade.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
Harmony harmony = new Harmony("dotoo.antilagphotondisc");
TryPatch(harmony, typeof(PhotonDiscSpawnPatch));
TryPatch(harmony, typeof(CollectableSpawnPatch));
TryPatch(harmony, typeof(HealingDeactivatedPatch));
}
private static void TryPatch(Harmony harmony, Type patchType)
{
try
{
harmony.CreateClassProcessor(patchType).Patch();
if (DevMode.Value)
{
Log.LogInfo((object)("[DevMode] Patched " + patchType.Name));
}
}
catch (Exception ex)
{
Log.LogError((object)("Failed to patch " + patchType.Name + ": " + ex));
}
}
}
internal static class ChunkTracker
{
internal static bool InPhotonSpawn;
internal static int RemovedThisCall;
private static readonly LinkedList<HealingCollectable> list = new LinkedList<HealingCollectable>();
private static readonly Dictionary<HealingCollectable, LinkedListNode<HealingCollectable>> nodes = new Dictionary<HealingCollectable, LinkedListNode<HealingCollectable>>();
private static readonly FieldInfo prefabField = AccessTools.Field(typeof(ClientCollectable), "prefab");
private static readonly FieldInfo speedField = AccessTools.Field(typeof(ClientCollectable), "magnetizeSpeed");
internal static int Count => nodes.Count;
internal static void Add(HealingCollectable heal)
{
Remove(heal);
nodes[heal] = list.AddLast(heal);
int value = Plugin.MaxChunks.Value;
if (value <= 0)
{
return;
}
while (nodes.Count > value && list.First != null)
{
HealingCollectable value2 = list.First.Value;
Remove(value2);
RemovedThisCall++;
if ((Object)(object)value2 != (Object)null && ((Component)value2).gameObject.activeSelf)
{
((ClientCollectable)value2).DespawnTrackedObject();
}
}
}
internal static void Remove(HealingCollectable heal)
{
if (heal != null && nodes.TryGetValue(heal, out var value))
{
list.Remove(value);
nodes.Remove(heal);
}
}
internal static void SetSpeed(HealingCollectable heal, float multiplier)
{
if (prefabField == null || speedField == null)
{
return;
}
object? value = prefabField.GetValue(heal);
ClientCollectable val = (ClientCollectable)((value is ClientCollectable) ? value : null);
if (!((Object)(object)val == (Object)null))
{
float num = (float)speedField.GetValue(val) * multiplier;
float num2 = (float)speedField.GetValue(heal);
if (!Mathf.Approximately(num2, num))
{
speedField.SetValue(heal, num);
}
}
}
}
[HarmonyPatch]
internal static class PhotonDiscSpawnPatch
{
private static int callCount;
internal static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(PhotonDiscBullet), "SpawnHealthChunks", new Type[2]
{
typeof(int),
typeof(float)
}, (Type[])null);
}
internal static void Prefix(int count)
{
ChunkTracker.InPhotonSpawn = true;
ChunkTracker.RemovedThisCall = 0;
callCount = count;
}
internal static void Finalizer()
{
ChunkTracker.InPhotonSpawn = false;
if (Plugin.DevMode.Value)
{
Plugin.Log.LogInfo((object)("[DevMode] SpawnHealthChunks count=" + callCount + " alive=" + ChunkTracker.Count + " removed=" + ChunkTracker.RemovedThisCall + " max=" + Plugin.MaxChunks.Value));
}
}
}
[HarmonyPatch]
internal static class CollectableSpawnPatch
{
internal static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(ClientCollectable), "SpawnCollectable", new Type[3]
{
typeof(ClientCollectable),
typeof(Vector3),
typeof(float)
}, (Type[])null);
}
internal static void Postfix(ClientCollectable __result)
{
HealingCollectable val = (HealingCollectable)(object)((__result is HealingCollectable) ? __result : null);
if (!((Object)(object)val == (Object)null))
{
if (ChunkTracker.InPhotonSpawn)
{
ChunkTracker.Add(val);
ChunkTracker.SetSpeed(val, Plugin.PullSpeedMultiplier.Value);
}
else
{
ChunkTracker.Remove(val);
ChunkTracker.SetSpeed(val, 1f);
}
}
}
}
[HarmonyPatch]
internal static class HealingDeactivatedPatch
{
internal static MethodBase TargetMethod()
{
return AccessTools.DeclaredMethod(typeof(HealingCollectable), "OnDeactivated", (Type[])null, (Type[])null);
}
internal static void Postfix(HealingCollectable __instance)
{
ChunkTracker.Remove(__instance);
}
}
}