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;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Igor_Does_Nothing")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SprintSpeedCap")]
[assembly: AssemblyTitle("SprintSpeedCap")]
[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;
}
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}
namespace Repo.SprintCap
{
[BepInPlugin("com.yourname.repo.sprintcap", "R.E.P.O Sprint Cap", "1.6.1")]
public class SprintCapPlugin : BaseUnityPlugin
{
public const string PluginGuid = "com.yourname.repo.sprintcap";
public const string PluginName = "R.E.P.O Sprint Cap";
public const string PluginVersion = "1.6.1";
internal static volatile bool Enabled = true;
internal static volatile float MaxUpgradeAdd = 2f;
internal static volatile float AbsMaxSprint = 0f;
private ConfigEntry<bool> _enabledCfg;
private ConfigEntry<float> _maxUpgradeAddCfg;
private ConfigEntry<float> _absMaxSprintCfg;
private ConfigEntry<bool> _attachToGameDirector;
private ManualLogSource _log;
private Harmony _harmony;
private void Awake()
{
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Expected O, but got Unknown
_log = ((BaseUnityPlugin)this).Logger;
_enabledCfg = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turn the cap on/off.");
_maxUpgradeAddCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxSprintUpgradeAdditive", 2f, "Maximum additive sprint-speed upgrade allowed.");
_absMaxSprintCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "AbsoluteMaxSprintSpeed", 0f, "Optional absolute cap for SprintSpeed (0 disables).");
_attachToGameDirector = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "AttachToGameDirector", false, "If true, parent the host under GameDirector when present.");
ApplyConfigToStatics();
_enabledCfg.SettingChanged += delegate
{
ApplyConfigToStatics();
};
_maxUpgradeAddCfg.SettingChanged += delegate
{
ApplyConfigToStatics();
};
_absMaxSprintCfg.SettingChanged += delegate
{
ApplyConfigToStatics();
};
BuildOrAttachHost();
_harmony = new Harmony("com.yourname.repo.sprintcap");
_harmony.PatchAll();
_log.LogInfo((object)string.Format("{0} {1} loaded. Enabled={2}, MaxUpAdd={3}, AbsMax={4}", "R.E.P.O Sprint Cap", "1.6.1", Enabled, MaxUpgradeAdd, AbsMaxSprint));
SceneManager.activeSceneChanged += OnActiveSceneChanged;
}
private void OnDestroy()
{
SceneManager.activeSceneChanged -= OnActiveSceneChanged;
_log.LogWarning((object)"R.E.P.O Sprint Cap OnDestroy() — patches left active, host persists.");
}
private void ApplyConfigToStatics()
{
Enabled = _enabledCfg.Value;
MaxUpgradeAdd = Mathf.Max(0f, _maxUpgradeAddCfg.Value);
AbsMaxSprint = _absMaxSprintCfg.Value;
}
private void OnActiveSceneChanged(Scene from, Scene to)
{
BuildOrAttachHost();
}
private void BuildOrAttachHost()
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected O, but got Unknown
GameObject val = null;
if (_attachToGameDirector.Value && (Object)(object)GameDirector.instance != (Object)null)
{
val = ((Component)GameDirector.instance).gameObject;
}
if ((Object)(object)val == (Object)null)
{
val = GameObject.Find("SprintCapHost (BepInEx)");
if ((Object)(object)val == (Object)null)
{
val = new GameObject("SprintCapHost (BepInEx)")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)(object)val);
}
}
if ((Object)(object)val.GetComponent<SprintCapHost>() == (Object)null)
{
val.AddComponent<SprintCapHost>();
}
}
}
public sealed class SprintCapHost : MonoBehaviour
{
}
internal static class SprintCapState
{
internal sealed class Data
{
public bool Initialized;
public float BaseNoUpgrade;
}
internal static readonly Dictionary<PlayerController, Data> Cache = new Dictionary<PlayerController, Data>(16);
internal static readonly FieldInfo FiOriginalSprint = AccessTools.Field(typeof(PlayerController), "playerOriginalSprintSpeed");
internal static Data Get(PlayerController pc)
{
if (!Cache.TryGetValue(pc, out Data value))
{
value = new Data();
Cache[pc] = value;
}
return value;
}
}
[HarmonyPatch(typeof(PlayerController), "FixedUpdate")]
internal static class PlayerController_FixedUpdate_Prefix
{
private static void Prefix(PlayerController __instance)
{
if (!SprintCapPlugin.Enabled || (Object)(object)__instance == (Object)null)
{
return;
}
SprintCapState.Data data = SprintCapState.Get(__instance);
if (!data.Initialized)
{
try
{
float num = (float)SprintCapState.FiOriginalSprint.GetValue(__instance);
float sprintSpeedUpgrades = __instance.SprintSpeedUpgrades;
data.BaseNoUpgrade = num - sprintSpeedUpgrades;
}
catch
{
data.BaseNoUpgrade = __instance.SprintSpeed - __instance.SprintSpeedUpgrades;
}
data.Initialized = true;
}
float num2 = (__instance.SprintSpeedUpgrades = Mathf.Min(__instance.SprintSpeedUpgrades, SprintCapPlugin.MaxUpgradeAdd));
float num3 = data.BaseNoUpgrade + num2;
if (SprintCapPlugin.AbsMaxSprint > 0f)
{
num3 = Mathf.Min(num3, SprintCapPlugin.AbsMaxSprint);
}
if (__instance.SprintSpeed > num3)
{
__instance.SprintSpeed = num3;
}
}
}
internal static class LocalPlayerKey
{
private static readonly FieldInfo FiPlayerSteamID = AccessTools.Field(typeof(PlayerController), "playerSteamID");
private static readonly MethodInfo MiPlayerGetSteamID = AccessTools.Method(typeof(SemiFunc), "PlayerGetSteamID", new Type[1] { typeof(PlayerAvatar) }, (Type[])null);
internal static bool TryGet(out string steamID)
{
steamID = null;
PlayerController instance = PlayerController.instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
try
{
if (MiPlayerGetSteamID != null && (Object)(object)instance.playerAvatarScript != (Object)null)
{
object obj = MiPlayerGetSteamID.Invoke(null, new object[1] { instance.playerAvatarScript });
if (obj is string text && !string.IsNullOrEmpty(text))
{
steamID = text;
return true;
}
}
}
catch
{
}
try
{
if (FiPlayerSteamID != null)
{
string text2 = FiPlayerSteamID.GetValue(instance) as string;
if (!string.IsNullOrEmpty(text2))
{
steamID = text2;
return true;
}
}
}
catch
{
}
return false;
}
internal static int ClampIntUpgrade(int original)
{
int num = Mathf.FloorToInt(SprintCapPlugin.MaxUpgradeAdd);
if (original <= num)
{
return original;
}
return num;
}
}
internal static class UpgradeClampHelper
{
internal struct State
{
public string key;
public int previous;
public bool changed;
}
internal static State ClampForLocalIfNeeded()
{
State state = default(State);
state.key = null;
state.previous = 0;
state.changed = false;
State result = state;
if (!LocalPlayerKey.TryGet(out string steamID))
{
return result;
}
StatsManager instance = StatsManager.instance;
if ((Object)(object)instance == (Object)null || instance.playerUpgradeSpeed == null)
{
return result;
}
if (instance.playerUpgradeSpeed.TryGetValue(steamID, out var value))
{
int num = value;
int num2 = num;
int num3 = LocalPlayerKey.ClampIntUpgrade(num2);
if (num3 != num2)
{
result.key = steamID;
result.previous = num2;
result.changed = true;
instance.playerUpgradeSpeed[steamID] = num3;
}
}
return result;
}
internal static void Restore(in State st)
{
if (st.changed && !string.IsNullOrEmpty(st.key))
{
StatsManager instance = StatsManager.instance;
if (!((Object)(object)instance == (Object)null) && instance.playerUpgradeSpeed != null)
{
instance.playerUpgradeSpeed[st.key] = st.previous;
}
}
}
}
[HarmonyPatch(typeof(CameraBob), "Update")]
internal static class CameraBob_Update_PrefixPostfix
{
private static void Prefix(out UpgradeClampHelper.State __state)
{
__state = UpgradeClampHelper.ClampForLocalIfNeeded();
}
private static void Postfix(in UpgradeClampHelper.State __state)
{
UpgradeClampHelper.Restore(in __state);
}
}
[HarmonyPatch(typeof(CameraZoom), "Update")]
internal static class CameraZoom_Update_PrefixPostfix
{
private static void Prefix(out UpgradeClampHelper.State __state)
{
__state = UpgradeClampHelper.ClampForLocalIfNeeded();
}
private static void Postfix(in UpgradeClampHelper.State __state)
{
UpgradeClampHelper.Restore(in __state);
}
}
[HarmonyPatch(typeof(PlayerAvatarVisuals), "Update")]
internal static class PlayerAvatarVisuals_Update_PrefixPostfix
{
private static void Prefix(out UpgradeClampHelper.State __state)
{
__state = UpgradeClampHelper.ClampForLocalIfNeeded();
}
private static void Postfix(in UpgradeClampHelper.State __state)
{
UpgradeClampHelper.Restore(in __state);
}
}
}