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}");
}
}
}
}