using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using HarmonyLib;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace CrashoutCrewExtraTime;
[BepInPlugin("com.strazer.extratime", "Crashout Crew Extra Time", "1.0.0")]
public sealed class CrashoutCrewExtraTimePlugin : BaseUnityPlugin
{
public const string GUID = "com.strazer.extratime";
public const string NAME = "Crashout Crew Extra Time";
public const string VERSION = "1.0.0";
private Harmony _harmony;
private int _patchCount;
private void Awake()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
_harmony = new Harmony("com.strazer.extratime");
((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format(" {0} v{1}", "Crashout Crew Extra Time", "1.0.0"));
((BaseUnityPlugin)this).Logger.LogInfo((object)"========================================");
float mult = Bind("ShiftStartMultiplier", 1f);
float mult2 = Bind("ShiftDurationMultiplier", 1f);
float mult3 = Bind("TruckPatienceMultiplier", 1f);
float mult4 = Bind("TruckArrivalMultiplier", 1f);
float mult5 = Bind("TruckDepartureMultiplier", 1f);
float mult6 = Bind("PauseMultiplier", 1f);
float mult7 = Bind("LockInMultiplier", 1f);
float mult8 = Bind("RespawnMultiplier", 1f);
float mult9 = Bind("BoxSpawnMultiplier", 1f);
float mult10 = Bind("WarehouseMultiplier", 1f);
PatchFieldPostfix("ShiftManager", "organizationalDuration", "OnStartServer", mult);
PatchNamedPostfix("ShiftManager", "ServerPrepareShift", "_serverStrikeOutDuration", mult2);
PatchFieldPostfix("ContractShift", "truckPatienceDuration", "OnEntityCreated", mult3);
PatchFieldPostfix("OutboundBay", "animationDuration", "OnEntityCreated", mult5);
PatchFieldPostfix("ButtonLockIn", "lockInDuration", "OnEntityCreated", mult7);
PatchFieldPostfix("ButtonPauseShiftTimers", "pauseDuration", "OnEntityCreated", mult6);
PatchFieldPostfix("PlayerStress", "stressCrashOutDuration", "OnEntityCreated", mult8);
PatchFieldPostfix("BoxHeldSpawner", "spawnEveryInSeconds", "OnEntityCreated", mult9);
PatchFieldPrefix("WarehouseManager", "timerParam", "ServerUpdateInbound", mult4);
PatchFieldPrefix("WarehouseManager", "timerParam", "ServerUpdateOutbound", mult10);
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Applied {_patchCount} timer patches.");
((BaseUnityPlugin)this).Logger.LogInfo((object)"========================================");
}
private float Bind(string key, float def)
{
return ((BaseUnityPlugin)this).Config.Bind<float>("Timers", key, def, "Timer multiplier. 0.5 = fast, 1.0 = vanilla, 2.0 = long.").Value;
}
private Type ResolveType(string name)
{
Type type = AccessTools.TypeByName(name);
if (type == null)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
try
{
Type[] types = assembly.GetTypes();
foreach (Type type2 in types)
{
if (type2.Name == name)
{
return type2;
}
}
}
catch
{
}
}
}
return type;
}
private void PatchFieldPostfix(string className, string fieldName, string methodName, float mult)
{
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Expected O, but got Unknown
if (mult > 0.9999f && mult < 1.0001f)
{
return;
}
Type type = ResolveType(className);
if (type == null)
{
Warn(className);
return;
}
FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field == null)
{
Warn(className + "." + fieldName);
return;
}
MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method == null)
{
Warn(className + "." + methodName);
return;
}
PatchStore.Add(field, mult);
_harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(PatchStore), "FieldPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
_patchCount++;
((BaseUnityPlugin)this).Logger.LogInfo((object)$" + {className}.{fieldName} x{mult:F2}");
}
private void PatchNamedPostfix(string className, string methodName, string fieldName, float mult)
{
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
if (mult > 0.9999f && mult < 1.0001f)
{
return;
}
Type type = ResolveType(className);
if (type == null)
{
Warn(className);
return;
}
MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method == null)
{
Warn(className + "." + methodName);
return;
}
PatchStore.AddNamed(fieldName, mult);
_harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(PatchStore), "NamedFieldPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
_patchCount++;
((BaseUnityPlugin)this).Logger.LogInfo((object)$" + {className}.{methodName} -> {fieldName} x{mult:F2}");
}
private void PatchFieldPrefix(string className, string fieldName, string methodName, float mult)
{
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Expected O, but got Unknown
if (mult > 0.9999f && mult < 1.0001f)
{
return;
}
Type type = ResolveType(className);
if (type == null)
{
Warn(className);
return;
}
FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field == null)
{
Warn(className + "." + fieldName);
return;
}
MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method == null)
{
Warn(className + "." + methodName);
return;
}
PatchStore.Add(field, mult);
_harmony.Patch((MethodBase)method, new HarmonyMethod(typeof(PatchStore), "FieldPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
_patchCount++;
((BaseUnityPlugin)this).Logger.LogInfo((object)$" + {className}.{fieldName} x{mult:F2}");
}
private void Warn(string msg)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)(" ? " + msg));
}
}
internal static class PatchStore
{
private static readonly Dictionary<string, float> _namedFields = new Dictionary<string, float>();
private static readonly Dictionary<FieldInfo, float> _fields = new Dictionary<FieldInfo, float>();
[ThreadStatic]
private static float _mult;
public static void Add(FieldInfo field, float mult)
{
lock (_fields)
{
_fields[field] = mult;
}
}
public static void AddNamed(string name, float mult)
{
lock (_namedFields)
{
_namedFields[name] = mult;
}
}
public static void FieldPostfix(object __instance)
{
if (__instance == null)
{
return;
}
lock (_fields)
{
foreach (KeyValuePair<FieldInfo, float> field in _fields)
{
if (field.Key.DeclaringType.IsAssignableFrom(__instance.GetType()))
{
object value = field.Key.GetValue(__instance);
if (value is float)
{
field.Key.SetValue(__instance, (float)value * field.Value);
}
}
}
}
}
public static void NamedFieldPostfix(object __instance)
{
if (__instance == null)
{
return;
}
lock (_namedFields)
{
foreach (KeyValuePair<string, float> namedField in _namedFields)
{
FieldInfo field = __instance.GetType().GetField(namedField.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
object value = field.GetValue(__instance);
if (value is float)
{
field.SetValue(__instance, (float)value * namedField.Value);
}
}
}
}
}
public static void FieldPrefix(object __instance)
{
if (__instance == null)
{
return;
}
lock (_fields)
{
foreach (KeyValuePair<FieldInfo, float> field in _fields)
{
if (field.Key.DeclaringType.IsAssignableFrom(__instance.GetType()))
{
object value = field.Key.GetValue(__instance);
if (value is float)
{
field.Key.SetValue(__instance, (float)value * field.Value);
}
}
}
}
}
}