Decompiled source of MorePlayers v1.0.0

plugins/GoblinCleanupMorePlayers.dll

Decompiled 11 hours ago
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 GoblinCleanupMorePlayers.Patches;
using HarmonyLib;
using I2.Loc;
using Microsoft.CodeAnalysis;
using Steamworks;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GoblinCleanupMorePlayers")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+229564aa9c628763782faed15a74d94314182eaf")]
[assembly: AssemblyProduct("More Players")]
[assembly: AssemblyTitle("More Players")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace GoblinCleanupMorePlayers
{
	[BepInPlugin("GoblinCleanupMorePlayers", "More Players", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		internal static ConfigEntry<int> ConfigMaxPlayers;

		internal static Harmony HarmonyInstance;

		public const int VanillaMaxPlayers = 4;

		public const string Id = "GoblinCleanupMorePlayers";

		public static string Name => "More Players";

		public static string Version => "1.0.0";

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			HarmonyInstance = new Harmony("GoblinCleanupMorePlayers");
			ConfigMaxPlayers = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxPlayers", 8, "Maximum number of players (including yourself). Steam lobbies support up to 250. Range: 1-250.");
			if (ConfigMaxPlayers.Value < 1)
			{
				ConfigMaxPlayers.Value = 1;
			}
			if (ConfigMaxPlayers.Value > 250)
			{
				ConfigMaxPlayers.Value = 250;
			}
			Logger.LogInfo((object)string.Format("Plugin {0} loaded! Max players set to {1}", "GoblinCleanupMorePlayers", ConfigMaxPlayers.Value));
			HarmonyInstance.PatchAll(typeof(SteamLobbyPatches));
			HarmonyInstance.PatchAll(typeof(MenuManagerPatches));
			HarmonyInstance.PatchAll(typeof(DungeonManagerPatches));
			HarmonyInstance.PatchAll(typeof(DungeonPlayersPatches));
			HarmonyInstance.PatchAll(typeof(LobbiesListManagerPatches));
			HarmonyInstance.PatchAll(typeof(RewardsManagerPatches));
			Logger.LogInfo((object)"All patches applied");
		}

		private void OnDestroy()
		{
			Harmony harmonyInstance = HarmonyInstance;
			if (harmonyInstance != null)
			{
				harmonyInstance.UnpatchSelf();
			}
			Logger.LogInfo((object)"Plugin unloaded");
		}
	}
}
namespace GoblinCleanupMorePlayers.Patches
{
	public static class DungeonManagerPatches
	{
		[HarmonyPatch(typeof(DungeonManager), "UpdatePlayerKickout")]
		[HarmonyPrefix]
		private static bool FixKickoutBounds(DungeonManager __instance)
		{
			for (int i = 0; i < __instance.kickoutPlayer.Count; i++)
			{
				__instance.kickoutPlayer[i].SetActive(false);
			}
			List<GoblinCharacterController> list = new List<GoblinCharacterController>();
			foreach (GoblinCharacterController player in DungeonPlayers.instance.players)
			{
				if (Object.op_Implicit((Object)(object)player) && (Object)(object)player != (Object)(object)GoblinCharacterController.localPlayer)
				{
					list.Add(player);
				}
			}
			for (int j = 0; j < list.Count; j++)
			{
				if (j < __instance.kickoutPlayer.Count)
				{
					__instance.kickoutPlayer[j].SetActive(true);
				}
				if (j < __instance.txtkickoutNames.Count)
				{
					((TMP_Text)__instance.txtkickoutNames[j]).text = ((TMP_Text)list[j].playerName).text;
				}
			}
			return false;
		}
	}
	[HarmonyPatch]
	public static class DungeonPlayersPatches
	{
		[HarmonyPatch(typeof(DungeonPlayers), "GetPlayerDefaultSpawnPoint")]
		[HarmonyPrefix]
		private static bool AllSpawnAtHostRoom(ref Transform __result)
		{
			DungeonPlayers instance = DungeonPlayers.instance;
			if (instance.RoomsspawnPoints.Length == 0)
			{
				__result = instance.staffRoomSpawnPoint;
			}
			else
			{
				__result = instance.RoomsspawnPoints[0];
			}
			return false;
		}

		[HarmonyPatch(typeof(DungeonPlayers), "OnStartClient")]
		[HarmonyPostfix]
		private static void InitSharedRoomState(DungeonPlayers __instance)
		{
			for (int i = 0; i < __instance.restoreColliders.Length; i++)
			{
				if ((Object)(object)__instance.restoreColliders[i] != (Object)null)
				{
					((Component)__instance.restoreColliders[i]).gameObject.SetActive(false);
				}
			}
			for (int j = 1; j < __instance.RoomDoorObject.Length; j++)
			{
				if ((Object)(object)__instance.RoomDoorObject[j] != (Object)null)
				{
					__instance.RoomDoorObject[j].SetActive(true);
				}
			}
			if (__instance.RoomDoorObject.Length != 0 && (Object)(object)__instance.RoomDoorObject[0] != (Object)null)
			{
				__instance.RoomDoorObject[0].SetActive(false);
			}
			if (__instance.playerFrames.Length != 0 && (Object)(object)__instance.playerFrames[0] != (Object)null)
			{
				__instance.playerFrames[0].SetDisconnectData("Shared Room", __instance.noAvatarImage);
			}
			for (int k = 1; k < __instance.playerFrames.Length; k++)
			{
				if ((Object)(object)__instance.playerFrames[k] != (Object)null)
				{
					__instance.playerFrames[k].SetDisconnectData("Out of Order", __instance.noAvatarImage);
				}
			}
		}

		[HarmonyPatch(typeof(DungeonPlayers), "SetRoomData")]
		[HarmonyPrefix]
		private static bool SuppressSetRoomData()
		{
			return false;
		}

		[HarmonyPatch(typeof(DungeonPlayers), "EnableRoomDoor")]
		[HarmonyPrefix]
		private static bool SkipNonHostRoomManagement(int playerIndex)
		{
			return playerIndex == 0;
		}
	}
	public static class LobbiesListManagerPatches
	{
		[HarmonyPatch(typeof(LobbiesListManager), "UpdateLobbyEntry")]
		[HarmonyPostfix]
		private static void FixPlayerCountDisplay(LobbyDataEntry lobbyData, CSteamID lobbyID)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			string text = SteamMatchmaking.GetNumLobbyMembers(lobbyID) + "/" + SteamMatchmaking.GetLobbyMemberLimit(lobbyID);
			lobbyData.SetLobbyData(SteamMatchmaking.GetLobbyData(lobbyID, "isFull") == "False", SteamMatchmaking.GetLobbyData(lobbyID, "password"), text, SteamMatchmaking.GetLobbyData(lobbyID, "Level"), SteamMatchmaking.GetLobbyData(lobbyID, "GameVersion") == Application.version);
		}
	}
	public static class MenuManagerPatches
	{
		[HarmonyPatch(typeof(MenuManager), "OnClick_Host_Steam")]
		[HarmonyPrefix]
		private static void LogHostClick(MenuManager __instance)
		{
			Plugin.Logger.LogInfo((object)$"OnClick_Host_Steam: will use maxPlayers={Plugin.ConfigMaxPlayers.Value}");
		}
	}
	public static class RewardsManagerPatches
	{
		private static T Field<T>(object obj, string name)
		{
			return (T)AccessTools.Field(obj.GetType(), name).GetValue(obj);
		}

		private static void SetField(object obj, string name, object value)
		{
			AccessTools.Field(obj.GetType(), name).SetValue(obj, value);
		}

		[HarmonyPatch(typeof(RewardsManager), "ShowStats")]
		[HarmonyPrefix]
		private static bool FixShowStats(RewardsManager __instance, ref Dictionary<CSteamID, PlayerStats> stats, float extraExpMultiplier, float extraTicketsMultiplier)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Field<GameObject>(__instance, "panelHolder");
			TextMeshProUGUI val = Field<TextMeshProUGUI>(__instance, "txtTime");
			List<PlayerStatsCard> list = Field<List<PlayerStatsCard>>(__instance, "playerCards");
			TextMeshProUGUI val2 = Field<TextMeshProUGUI>(__instance, "ticketsReward");
			TextMeshProUGUI val3 = Field<TextMeshProUGUI>(__instance, "expReward");
			obj.SetActive(true);
			if (DungeonManager.dungeonInstance.GetTime() <= 30f)
			{
				__instance.taskCount = 0;
				((TMP_Text)val).color = Color.red;
			}
			else
			{
				((TMP_Text)val).color = Color.white;
			}
			int num = Mathf.RoundToInt((float)__instance.taskCount * __instance.expMultiplier * extraExpMultiplier);
			int num2 = Mathf.RoundToInt((float)__instance.taskCount * __instance.ticketsMultiplier * extraTicketsMultiplier);
			SetField(__instance, "expRewardAmount", num);
			SetField(__instance, "ticketsRewardAmount", num2);
			ProgressionController.AddStackedTickets(num2);
			ProgressionController.Instance.AddExpToClaim(num);
			((TMP_Text)val2).text = ProgressionController.Instance.GetTicketsToClaim().ToString();
			((TMP_Text)val3).text = ProgressionController.Instance.GetExpToClaim().ToString();
			foreach (PlayerStatsCard item in list)
			{
				item.holder.SetActive(false);
			}
			List<CSteamID> list2 = new List<CSteamID>();
			int num3 = -1;
			int num4 = 0;
			int num5 = 9999;
			int num6 = -1;
			int num7 = 0;
			int num8 = -1;
			int num9 = -1;
			int num10 = 0;
			foreach (KeyValuePair<CSteamID, PlayerStats> stat in stats)
			{
				if (DungeonPlayers.instance.IsPlayerInLobby(stat.Key))
				{
					if (num10 >= list.Count)
					{
						break;
					}
					PlayerStatsCard val4 = list[num10];
					val4.holder.SetActive(true);
					((TMP_Text)val4.txtName).text = SteamFriends.GetFriendPersonaName(stat.Key);
					((TMP_Text)val4.txtDeaths).text = stat.Value.deads.ToString();
					((TMP_Text)val4.txtRestorables).text = stat.Value.restorableObjects.ToString();
					((TMP_Text)val4.txtBlood).text = stat.Value.bloodstains.ToString();
					((TMP_Text)val4.txtOrganic).text = stat.Value.organicRemains.ToString();
					((TMP_Text)val4.txtTraps).text = stat.Value.traps.ToString();
					((TMP_Text)val4.txtMana).text = stat.Value.manaObjects.ToString();
					((TMP_Text)val4.txtGoldenChests).text = stat.Value.chestsFilled.ToString();
					((TMP_Text)val4.txtMonsters).text = stat.Value.monsters.ToString();
					int num11 = stat.Value.bloodstains + stat.Value.organicRemains * 2 + stat.Value.restorableObjects * 3 + stat.Value.traps * 4 + stat.Value.manaObjects * 3 + stat.Value.chestsFilled * 5 + stat.Value.monsters * 10 - stat.Value.deads;
					if (num11 > num4)
					{
						num4 = num11;
						num3 = num10;
					}
					else if (num11 < num5)
					{
						num5 = num11;
						num6 = num10;
					}
					else if (stat.Value.deads > num7)
					{
						num7 = stat.Value.deads;
						num8 = num10;
					}
					else
					{
						num9 = num10;
					}
					list2.Add(stat.Key);
					SetNomination(__instance, "lazy", val4.txtTitle);
					num10++;
				}
			}
			if (num10 <= 1)
			{
				SetNomination(__instance, "single", list[0].txtTitle);
				return false;
			}
			if (num3 != -1)
			{
				SetNomination(__instance, "MVP", list[num3].txtTitle);
			}
			if (num6 != -1)
			{
				SetNomination(__instance, "lazy", list[num6].txtTitle);
			}
			if (num8 != -1)
			{
				SetNomination(__instance, "death", list[num8].txtTitle);
			}
			if (num9 != -1 && stats.Count >= 4)
			{
				PlayerStats val5 = stats[list2[num9]];
				int restorableObjects = val5.restorableObjects;
				int num12 = 0;
				if (val5.bloodstains > restorableObjects)
				{
					restorableObjects = val5.bloodstains;
					num12 = 1;
				}
				else if (val5.organicRemains > restorableObjects)
				{
					restorableObjects = val5.organicRemains;
					num12 = 2;
				}
				else if (val5.traps > restorableObjects)
				{
					restorableObjects = val5.traps;
					num12 = 3;
				}
				else if (val5.manaObjects > restorableObjects)
				{
					restorableObjects = val5.manaObjects;
					num12 = 4;
				}
				else if (val5.chestsFilled > restorableObjects)
				{
					restorableObjects = val5.chestsFilled;
					num12 = 5;
				}
				else if (val5.monsters > restorableObjects)
				{
					restorableObjects = val5.monsters;
					num12 = 6;
				}
				SetNomination(__instance, num12 switch
				{
					0 => "objects", 
					1 => "blood", 
					2 => "organic", 
					3 => "traps", 
					4 => "mana", 
					5 => "chests", 
					6 => "monsters", 
					_ => "objects", 
				}, list[num9].txtTitle);
			}
			return false;
		}

		private static void SetNomination(RewardsManager instance, string find, TextMeshProUGUI txtTitle)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			foreach (Nominations item in Field<List<Nominations>>(instance, "nominations"))
			{
				if (item.id.ToUpper().Trim() == find.ToUpper().Trim())
				{
					((TMP_Text)txtTitle).text = LocalizedString.op_Implicit(item.localizatedTitle);
					break;
				}
			}
		}
	}
	public static class SteamLobbyPatches
	{
		[HarmonyPatch(typeof(SteamLobby), "HostLobby")]
		[HarmonyPrefix]
		private static void OverrideMaxPlayers(ref int maxPlayers, ref ELobbyType lobbyType)
		{
			Plugin.Logger.LogInfo((object)$"HostLobby: overriding maxPlayers {maxPlayers} -> {Plugin.ConfigMaxPlayers.Value}");
			maxPlayers = Plugin.ConfigMaxPlayers.Value;
		}

		[HarmonyPatch(typeof(SteamLobby), "OnLobbyCreated")]
		[HarmonyPostfix]
		private static void FixLobbyCreatedMaxPlayers(SteamLobby __instance)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.CurrentLobbyID != 0L)
			{
				FieldInfo field = typeof(SteamLobby).GetField("maxPlayers", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null)
				{
					int num = (int)field.GetValue(__instance);
					field.SetValue(__instance, Plugin.ConfigMaxPlayers.Value);
					Plugin.Logger.LogInfo((object)$"OnLobbyCreated: fixed maxPlayers {num} -> {Plugin.ConfigMaxPlayers.Value}");
				}
				CSteamID val = new CSteamID(__instance.CurrentLobbyID);
				int value = Plugin.ConfigMaxPlayers.Value;
				SteamMatchmaking.SetLobbyMemberLimit(val, value);
				int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(val);
				SteamMatchmaking.SetLobbyData(val, "players", numLobbyMembers + " / " + value);
				SteamMatchmaking.SetLobbyData(val, "isFull", (numLobbyMembers >= value).ToString());
				Plugin.Logger.LogInfo((object)$"OnLobbyCreated: SetLobbyMemberLimit -> {value}, players={numLobbyMembers}/{value}");
			}
		}
	}
}