Decompiled source of BetterTeamUpgrades v2.2.0

BetterTeamUpgrades.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterTeamUpgrades.Config;
using BetterTeamUpgrades.Patches;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BetterTeamUpgrades")]
[assembly: AssemblyDescription("DLL for REPO mod.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("MrBytesized")]
[assembly: AssemblyProduct("BetterTeamUpgrades")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ef74d5e5-8fe6-4b6a-86ed-0e29e12695bb")]
[assembly: AssemblyFileVersion("2.2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("2.2.0.0")]
namespace BetterTeamUpgrades
{
	[BepInPlugin("MrBytesized.REPO.BetterTeamUpgrades", "Better Team Upgrades", "2.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		private const string mod_guid = "MrBytesized.REPO.BetterTeamUpgrades";

		private const string mod_name = "Better Team Upgrades";

		private const string mod_version = "2.2.0";

		private readonly Harmony harmony = new Harmony("MrBytesized.REPO.BetterTeamUpgrades");

		private static Plugin instance;

		internal static ManualLogSource Log;

		private (ConfigEntry<bool> configEntry, Action enablePatch, Action disablePatch, string description)[] _patchArray;

		public static ConfigFile PlguinConfig;

		internal static readonly object RandomLock = new object();

		internal static readonly Random Random = new Random();

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			Log = Logger.CreateLogSource("MrBytesized.REPO.BetterTeamUpgrades");
			PlguinConfig = ((BaseUnityPlugin)this).Config;
			harmony.PatchAll(typeof(StatsManagerInitPatch));
			Configuration.Init(PlguinConfig);
			_patchArray = new(ConfigEntry<bool>, Action, Action, string)[2]
			{
				(Configuration.EnableSharedUpgradesPatch, delegate
				{
					harmony.PatchAll(typeof(SharedUpgradesPatch));
				}, delegate
				{
					harmony.UnpatchSelf(typeof(SharedUpgradesPatch));
				}, "Shared Upgrades"),
				(Configuration.EnableLateJoinPlayerUpdateSyncPatch, delegate
				{
					harmony.PatchAll(typeof(LateJoinPlayerUpgradeSyncPatch));
				}, delegate
				{
					harmony.UnpatchSelf(typeof(LateJoinPlayerUpgradeSyncPatch));
				}, "Late Join Player Upgrade Sync")
			};
			(ConfigEntry<bool>, Action, Action, string)[] patchArray = _patchArray;
			for (int i = 0; i < patchArray.Length; i++)
			{
				var (configEntry, enablePatch, disablePatch, description) = patchArray[i];
				UpdatePatchFromConfig(configEntry, enablePatch, disablePatch, description);
				configEntry.SettingChanged += delegate
				{
					UpdatePatchFromConfig(configEntry, enablePatch, disablePatch, description);
				};
			}
			Log.LogInfo((object)"Better Team Upgrades mod has been activated");
		}

		private void UpdatePatchFromConfig(ConfigEntry<bool> configEntry, Action enablePatch, Action disablePatch, string description)
		{
			if (configEntry.Value)
			{
				try
				{
					enablePatch();
					Log.LogInfo((object)(description + " patch enabled."));
					return;
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Failed to enable " + description + ": " + ex.Message));
					return;
				}
			}
			try
			{
				disablePatch();
				Log.LogInfo((object)(description + " patch disabled."));
			}
			catch (Exception ex2)
			{
				Log.LogError((object)("Failed to disable " + description + ": " + ex2.Message));
			}
		}

		internal static int Roll(int min, int max)
		{
			lock (RandomLock)
			{
				return Random.Next(min, max);
			}
		}
	}
	public static class HarmonyExtensions
	{
		public static void UnpatchSelf(this Harmony harmony, Type patchClass)
		{
			HarmonyPatch[] array = patchClass.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).OfType<HarmonyPatch>().ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				HarmonyMethod info = ((HarmonyAttribute)array[i]).info;
				if (info == null)
				{
					Plugin.Log.LogWarning((object)("Invalid HarmonyPatch method info on class: " + patchClass.FullName));
					continue;
				}
				MethodInfo methodInfo = ResolveOriginal(info);
				if (methodInfo == null)
				{
					Plugin.Log.LogWarning((object)("Original method not found for class patch: " + FormatInfo(info)));
				}
				else
				{
					harmony.Unpatch((MethodBase)methodInfo, (HarmonyPatchType)0, harmony.Id);
				}
			}
			MethodInfo[] methods = patchClass.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo2 in methods)
			{
				HarmonyPatch[] array2 = methodInfo2.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).OfType<HarmonyPatch>().ToArray();
				if (array2.Length == 0)
				{
					continue;
				}
				array = array2;
				for (int j = 0; j < array.Length; j++)
				{
					HarmonyMethod info2 = ((HarmonyAttribute)array[j]).info;
					if (info2 == null)
					{
						Plugin.Log.LogWarning((object)("Invalid HarmonyPatch info on method: " + methodInfo2.DeclaringType.FullName + "." + methodInfo2.Name));
						continue;
					}
					MethodInfo methodInfo3 = ResolveOriginal(info2);
					if (methodInfo3 == null)
					{
						Plugin.Log.LogWarning((object)("Original method not found for method-level patch: " + FormatInfo(info2)));
					}
					else
					{
						harmony.Unpatch((MethodBase)methodInfo3, (HarmonyPatchType)0, harmony.Id);
					}
				}
			}
		}

		private static MethodInfo ResolveOriginal(HarmonyMethod info)
		{
			if (info.method != null)
			{
				return info.method;
			}
			if (info.declaringType == null || string.IsNullOrEmpty(info.methodName))
			{
				return null;
			}
			return AccessTools.Method(info.declaringType, info.methodName, info.argumentTypes, (Type[])null);
		}

		private static string FormatInfo(HarmonyMethod info)
		{
			string obj = ((info.declaringType != null) ? info.declaringType.FullName : "<null>");
			string text = ((!string.IsNullOrEmpty(info.methodName)) ? info.methodName : "<null>");
			return obj + "." + text;
		}
	}
}
namespace BetterTeamUpgrades.Patches
{
	[HarmonyPatch(typeof(PlayerAvatar), "Start")]
	public class LateJoinPlayerUpgradeSyncPatch
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass1_0
		{
			public string id;

			public Func<PlayerAvatar, bool> <>9__2;

			internal bool <SyncWithDelay>b__2(PlayerAvatar p)
			{
				return SemiFunc.PlayerGetSteamID(p) == id;
			}
		}

		[CompilerGenerated]
		private sealed class <SyncWithDelay>d__1 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public PlayerAvatar newPlayer;

			private float <timeWaited>5__2;

			private float <timeout>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SyncWithDelay>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Expected O, but got Unknown
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<timeWaited>5__2 = 0f;
					<timeout>5__3 = 10f;
					goto IL_006c;
				case 1:
					<>1__state = -1;
					<timeWaited>5__2 += 0.5f;
					goto IL_006c;
				case 2:
					{
						<>1__state = -1;
						if ((Object)(object)StatsManager.instance == (Object)null || (Object)(object)PunManager.instance == (Object)null)
						{
							return false;
						}
						PhotonView component = ((Component)PunManager.instance).GetComponent<PhotonView>();
						if ((Object)(object)component == (Object)null)
						{
							Plugin.Log.LogWarning((object)"Late Join: PunManager PhotonView not found.");
							return false;
						}
						string text = SemiFunc.PlayerGetSteamID(newPlayer);
						if (string.IsNullOrEmpty(text))
						{
							Plugin.Log.LogWarning((object)$"Late Join: Timed out waiting for SteamID for player {newPlayer.photonView.ViewID}. Skipping sync.");
							return false;
						}
						string text2 = (string)AccessTools.Field(typeof(PlayerAvatar), "playerName").GetValue(newPlayer);
						Plugin.Log.LogInfo((object)("Late Join: Player " + text2 + " (" + text + ") is ready. Starting sync..."));
						List<PlayerAvatar> source = SemiFunc.PlayerGetAll();
						List<string> list = (from p in source
							select SemiFunc.PlayerGetSteamID(p) into id
							where !string.IsNullOrEmpty(id)
							select id).ToList();
						foreach (KeyValuePair<string, Dictionary<string, int>> dictionaryOfDictionary in StatsManager.instance.dictionaryOfDictionaries)
						{
							if (!dictionaryOfDictionary.Key.StartsWith("playerUpgrade"))
							{
								continue;
							}
							string key = dictionaryOfDictionary.Key;
							Dictionary<string, int> value = dictionaryOfDictionary.Value;
							bool flag = SharedUpgradesPatch.VanillaKeys.Contains(key);
							string text3 = (flag ? "Vanilla Upgrade Settings" : "Modded Upgrade Settings");
							string text4 = key.Replace("player", "");
							if (!Plugin.PlguinConfig.Bind<bool>(text3, text4, true, "Enable upgrade syncing for " + key).Value)
							{
								Plugin.Log.LogInfo((object)("Late Join: Skipping " + key + " because config toggle '" + text3 + ":" + text4 + "' is disabled."));
								continue;
							}
							if (!flag && !Configuration.EnableCustomUpgradeSyncing.Value)
							{
								Plugin.Log.LogInfo((object)("Late Join: Custom Upgrade Syncing is disabled. Skipping: " + key));
								continue;
							}
							int num = 0;
							foreach (string item in list)
							{
								if (value.TryGetValue(item, out var value2) && value2 > num)
								{
									num = value2;
								}
							}
							if (num <= 0)
							{
								continue;
							}
							using List<string>.Enumerator enumerator2 = list.GetEnumerator();
							while (enumerator2.MoveNext())
							{
								<>c__DisplayClass1_0 CS$<>8__locals0 = new <>c__DisplayClass1_0
								{
									id = enumerator2.Current
								};
								int num2 = (value.ContainsKey(CS$<>8__locals0.id) ? value[CS$<>8__locals0.id] : 0);
								int num3 = num - num2;
								if (num3 <= 0)
								{
									continue;
								}
								for (int i = 0; i < num3; i++)
								{
									Plugin.Log.LogInfo((object)("Late Join: Considering sync " + key + " for " + CS$<>8__locals0.id + " (+1)"));
									int num4 = Plugin.Roll(0, 100);
									if (num4 >= Configuration.LateJoinUpgradeSyncChance.Value)
									{
										Plugin.Log.LogInfo((object)$"Late Join: Skipped syncing {key} for {CS$<>8__locals0.id} due to chance roll ({num4} >= {Configuration.LateJoinUpgradeSyncChance.Value})");
										continue;
									}
									if (flag)
									{
										string text5 = key.Substring("playerUpgrade".Length);
										component.RPC("TesterUpgradeCommandRPC", (RpcTarget)1, new object[3] { CS$<>8__locals0.id, text5, 1 });
										if (value.ContainsKey(CS$<>8__locals0.id))
										{
											value[CS$<>8__locals0.id]++;
										}
										else
										{
											value[CS$<>8__locals0.id] = 1;
										}
									}
									else
									{
										component.RPC("UpdateStatRPC", (RpcTarget)1, new object[3]
										{
											key,
											CS$<>8__locals0.id,
											num2 + 1
										});
										value[CS$<>8__locals0.id] = num2 + 1;
									}
									string text6 = "Unknown";
									PlayerAvatar val = ((IEnumerable<PlayerAvatar>)source).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => SemiFunc.PlayerGetSteamID(p) == CS$<>8__locals0.id));
									if ((Object)(object)val != (Object)null)
									{
										text6 = (string)AccessTools.Field(typeof(PlayerAvatar), "playerName").GetValue(val);
									}
									Plugin.Log.LogInfo((object)("Late Join: Synced " + key + " for " + text6 + " (+1)"));
									num2++;
								}
							}
						}
						Plugin.Log.LogInfo((object)("Late Join: Sync complete for " + text2 + "."));
						return false;
					}
					IL_006c:
					if (string.IsNullOrEmpty(SemiFunc.PlayerGetSteamID(newPlayer)) && <timeWaited>5__2 < <timeout>5__3)
					{
						<>2__current = (object)new WaitForSeconds(0.5f);
						<>1__state = 1;
						return true;
					}
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 2;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[HarmonyPostfix]
		private static void Postfix(PlayerAvatar __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelMainMenu) && !((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelLobbyMenu) && !((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelRecording) && !((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelSplashScreen))
			{
				((MonoBehaviour)__instance).StartCoroutine(SyncWithDelay(__instance));
			}
		}

		[IteratorStateMachine(typeof(<SyncWithDelay>d__1))]
		private static IEnumerator SyncWithDelay(PlayerAvatar newPlayer)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SyncWithDelay>d__1(0)
			{
				newPlayer = newPlayer
			};
		}
	}
	[HarmonyPatch(typeof(ItemUpgrade), "PlayerUpgrade")]
	public class SharedUpgradesPatch
	{
		public struct UpgradeContext
		{
			public string SteamID;

			public int ViewID;

			public string PlayerName;

			public Dictionary<string, int> PreUpgradeStats;
		}

		public static HashSet<string> VanillaKeys = new HashSet<string>();

		public static HashSet<string> ModdedKeys = new HashSet<string>();

		[HarmonyPrefix]
		public static void Prefix(ItemUpgrade __instance, out UpgradeContext __state)
		{
			__state = default(UpgradeContext);
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			object? value = AccessTools.Field(typeof(ItemUpgrade), "itemToggle").GetValue(__instance);
			ItemToggle val = (ItemToggle)((value is ItemToggle) ? value : null);
			if ((Object)(object)val == (Object)null || !val.toggleState)
			{
				return;
			}
			int num = (int)AccessTools.Field(typeof(ItemToggle), "playerTogglePhotonID").GetValue(val);
			PlayerAvatar val2 = SemiFunc.PlayerAvatarGetFromPhotonID(num);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			string playerName = (string)AccessTools.Field(typeof(PlayerAvatar), "playerName").GetValue(val2);
			string text = (string)AccessTools.Field(typeof(PlayerAvatar), "steamID").GetValue(val2);
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			if ((Object)(object)StatsManager.instance != (Object)null)
			{
				foreach (KeyValuePair<string, Dictionary<string, int>> dictionaryOfDictionary in StatsManager.instance.dictionaryOfDictionaries)
				{
					if (dictionaryOfDictionary.Key.StartsWith("playerUpgrade"))
					{
						if (dictionaryOfDictionary.Value.TryGetValue(text, out var value2))
						{
							dictionary[dictionaryOfDictionary.Key] = value2;
						}
						else
						{
							dictionary[dictionaryOfDictionary.Key] = 0;
						}
					}
				}
			}
			__state = new UpgradeContext
			{
				SteamID = text,
				ViewID = num,
				PlayerName = playerName,
				PreUpgradeStats = dictionary
			};
		}

		[HarmonyPostfix]
		public static void Postfix(ItemUpgrade __instance, UpgradeContext __state)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || string.IsNullOrEmpty(__state.SteamID) || (Object)(object)PunManager.instance == (Object)null)
			{
				return;
			}
			PhotonView component = ((Component)PunManager.instance).GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogError((object)"SharedUpgrades: PunManager PhotonView not found!");
				return;
			}
			foreach (KeyValuePair<string, Dictionary<string, int>> dictionaryOfDictionary in StatsManager.instance.dictionaryOfDictionaries)
			{
				if (!dictionaryOfDictionary.Key.StartsWith("playerUpgrade"))
				{
					continue;
				}
				bool flag = VanillaKeys.Contains(dictionaryOfDictionary.Key);
				string text = (flag ? "Vanilla Upgrade Settings" : "Modded Upgrade Settings");
				string text2 = dictionaryOfDictionary.Key.Replace("player", "");
				if (!Plugin.PlguinConfig.Bind<bool>(text, text2, true, "Enable shared upgrade syncing for " + dictionaryOfDictionary.Key).Value)
				{
					Plugin.Log.LogInfo((object)("SharedUpgrades: Skipping " + dictionaryOfDictionary.Key + " because config toggle '" + text + ":" + text2 + "' is disabled."));
					continue;
				}
				int num = (dictionaryOfDictionary.Value.ContainsKey(__state.SteamID) ? dictionaryOfDictionary.Value[__state.SteamID] : 0);
				int num2 = (__state.PreUpgradeStats.ContainsKey(dictionaryOfDictionary.Key) ? __state.PreUpgradeStats[dictionaryOfDictionary.Key] : 0);
				if (num > num2)
				{
					int num3 = num - num2;
					string key = dictionaryOfDictionary.Key;
					Plugin.Log.LogInfo((object)$"Detected upgrade: {key} (+{num3}) for {__state.PlayerName}({__state.SteamID})");
					int num4 = Plugin.Roll(0, 100);
					if (num4 >= Configuration.SharedUpgradeChance.Value)
					{
						Plugin.Log.LogInfo((object)$"Skipped syncing {key} due to chance roll ({num4} >= {Configuration.SharedUpgradeChance.Value})");
					}
					else if (flag)
					{
						string command = key.Substring("playerUpgrade".Length);
						DistributeVanillaUpgrade(component, command, num3, __state);
					}
					else if (!Configuration.EnableCustomUpgradeSyncing.Value)
					{
						Plugin.Log.LogInfo((object)("Custom Upgrade Syncing is disabled. Skipping: " + key));
					}
					else
					{
						DistributeCustomUpgrade(component, key, num, __state);
					}
				}
			}
		}

		private static void DistributeVanillaUpgrade(PhotonView punView, string command, int amount, UpgradeContext context)
		{
			foreach (PlayerAvatar item in SemiFunc.PlayerGetAll())
			{
				if ((Object)(object)item == (Object)null || (Object)(object)item.photonView == (Object)null)
				{
					continue;
				}
				if (item.photonView.ViewID == context.ViewID)
				{
					Plugin.Log.LogInfo((object)("Skipping original upgrader: " + command + " for " + context.PlayerName + "(" + context.SteamID + ")"));
					continue;
				}
				string text = (string)AccessTools.Field(typeof(PlayerAvatar), "playerName").GetValue(item);
				if (string.IsNullOrEmpty(text))
				{
					text = "Unknown";
				}
				string text2 = (string)AccessTools.Field(typeof(PlayerAvatar), "steamID").GetValue(item);
				if (!string.IsNullOrEmpty(text2))
				{
					punView.RPC("TesterUpgradeCommandRPC", (RpcTarget)0, new object[3] { text2, command, amount });
					Plugin.Log.LogInfo((object)("Synced Vanilla: " + command + " for " + text + "(" + text2 + ")"));
				}
			}
		}

		private static void DistributeCustomUpgrade(PhotonView punView, string dictionaryKey, int totalValue, UpgradeContext context)
		{
			foreach (PlayerAvatar item in SemiFunc.PlayerGetAll())
			{
				if ((Object)(object)item == (Object)null || (Object)(object)item.photonView == (Object)null)
				{
					continue;
				}
				if (item.photonView.ViewID == context.ViewID)
				{
					Plugin.Log.LogInfo((object)("Skipping original upgrader: " + dictionaryKey + " for " + context.PlayerName + "(" + context.SteamID + ")"));
					continue;
				}
				string text = (string)AccessTools.Field(typeof(PlayerAvatar), "playerName").GetValue(item);
				if (string.IsNullOrEmpty(text))
				{
					text = "Unknown";
				}
				string text2 = (string)AccessTools.Field(typeof(PlayerAvatar), "steamID").GetValue(item);
				if (!string.IsNullOrEmpty(text2))
				{
					punView.RPC("UpdateStatRPC", (RpcTarget)0, new object[3] { dictionaryKey, text2, totalValue });
					Plugin.Log.LogInfo((object)("Synced Custom: " + dictionaryKey + " for " + text + "(" + text2 + ")"));
				}
			}
		}
	}
	[HarmonyPatch(typeof(StatsManager), "Start")]
	public class StatsManagerInitPatch
	{
		[HarmonyPostfix]
		public static void Postfix(StatsManager __instance)
		{
			SharedUpgradesPatch.VanillaKeys.Clear();
			SharedUpgradesPatch.ModdedKeys.Clear();
			HashSet<string> hashSet = (from f in typeof(StatsManager).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
				select f.Name).ToHashSet();
			foreach (string key in __instance.dictionaryOfDictionaries.Keys)
			{
				if (key.StartsWith("playerUpgrade"))
				{
					string text = key.Replace("player", "");
					if (hashSet.Contains(key))
					{
						SharedUpgradesPatch.VanillaKeys.Add(key);
						Plugin.PlguinConfig.Bind<bool>("Vanilla Upgrade Settings", text, true, "Enable shared upgrade syncing for " + key);
					}
					else
					{
						SharedUpgradesPatch.ModdedKeys.Add(key);
						Plugin.PlguinConfig.Bind<bool>("Modded Upgrade Settings", text, true, "Enable shared upgrade syncing for modded upgrade " + key);
					}
				}
			}
			Plugin.Log.LogInfo((object)$"Auto-discovered {SharedUpgradesPatch.VanillaKeys.Count} vanilla upgrade keys and {SharedUpgradesPatch.ModdedKeys.Count} modded upgrade keys.");
		}
	}
}
namespace BetterTeamUpgrades.Config
{
	internal class Configuration
	{
		public static ConfigEntry<bool> EnableSharedUpgradesPatch;

		public static ConfigEntry<int> SharedUpgradeChance;

		public static ConfigEntry<bool> EnableLateJoinPlayerUpdateSyncPatch;

		public static ConfigEntry<int> LateJoinUpgradeSyncChance;

		public static ConfigEntry<bool> EnableCustomUpgradeSyncing;

		public static void Init(ConfigFile config)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0049: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0097: Expected O, but got Unknown
			EnableSharedUpgradesPatch = config.Bind<bool>("Shared Upgrade Settings", "EnableSharedUpgrades", true, "Enables Shared Upgrades for all supported Upgrades");
			SharedUpgradeChance = config.Bind<int>(new ConfigDefinition("Shared Upgrade Settings", "SharedUpgradeChance"), 100, new ConfigDescription("The percentage chance (0-100) that an upgrade will be shared with team members when purchased.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			EnableLateJoinPlayerUpdateSyncPatch = config.Bind<bool>("Late Join Settings", "EnableLateJoinPlayerUpgradeSync", false, "Enables Upgrade Sync for Late Joining Players");
			LateJoinUpgradeSyncChance = config.Bind<int>(new ConfigDefinition("Late Join Settings", "LateJoinUpgradeSyncChance"), 100, new ConfigDescription("The percentage chance (0-100) that a late joining player will receive each upgrade their team members have.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			EnableCustomUpgradeSyncing = config.Bind<bool>("Extra Sync Settings", "EnableCustomUpgradeSyncing", true, "Enables Custom Upgrade Syncing for Modded Upgrades (may cause issues with some mods)");
		}
	}
}