Decompiled source of CrashoutCrewExtraTime v1.0.1

CrashoutCrewExtraTime.dll

Decompiled 16 hours ago
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);
					}
				}
			}
		}
	}
}