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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[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("sonodima")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.2.0")]
[assembly: AssemblyInformationalVersion("1.2.2")]
[assembly: AssemblyProduct("BetterLobby")]
[assembly: AssemblyTitle("BetterLobby")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 BetterLobby
{
internal static class LobbyHelpers
{
private static readonly int s_dNumPlayers = 1;
private static readonly int s_dMaxPlayers = 4;
internal static bool IsFull => (NumPlayers ?? s_dNumPlayers) >= (MaxPlayers ?? s_dMaxPlayers);
internal static int? NumPlayers => PlayerHandler.instance?.players.Count;
internal static int? MaxPlayers => Traverse.Create((object)MainMenuHandler.SteamLobbyHandler).Field("m_MaxPlayers").GetValue<int>();
internal static CSteamID? CurrentID => Traverse.Create((object)MainMenuHandler.SteamLobbyHandler).Field("m_CurrentLobby").GetValue<CSteamID>();
internal static bool SetPublic(bool value)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
if (!RunChecks(out var id) || !id.HasValue)
{
return false;
}
ManualLogSource curLogger = Plugin.CurLogger;
if (curLogger != null)
{
curLogger.LogInfo((object)("Changing Steam lobby type to " + (value ? "PUBLIC" : "FRIENDS ONLY")));
}
SteamMatchmaking.SetLobbyType(id.Value, (ELobbyType)((!value) ? 1 : 2));
return true;
}
internal static bool SetJoinable(bool value)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
if (!RunChecks(out var id) || !id.HasValue)
{
return false;
}
ManualLogSource curLogger = Plugin.CurLogger;
if (curLogger != null)
{
curLogger.LogInfo((object)("Changing the current lobby to " + (value ? "JOINABLE" : "NOT JOINABLE")));
}
SteamMatchmaking.SetLobbyJoinable(id.Value, value);
if (PhotonNetwork.CurrentRoom != null)
{
PhotonNetwork.CurrentRoom.IsOpen = value;
PhotonNetwork.CurrentRoom.IsVisible = value;
}
return true;
}
private static bool RunChecks(out CSteamID? id)
{
id = CurrentID;
if (!id.HasValue)
{
ManualLogSource curLogger = Plugin.CurLogger;
if (curLogger != null)
{
curLogger.LogWarning((object)"Failed to get the current lobby's CSteamID value.");
}
return false;
}
if (!PhotonNetwork.IsMasterClient)
{
ManualLogSource curLogger2 = Plugin.CurLogger;
if (curLogger2 != null)
{
curLogger2.LogWarning((object)"You can't perform this operation because you are not the master client!");
}
return false;
}
return true;
}
}
internal sealed class PauseMenu : MonoBehaviour
{
private static GameObject UIMenu
{
get
{
Transform? obj2 = ((IEnumerable<Transform>)Resources.FindObjectsOfTypeAll<Transform>()).FirstOrDefault((Func<Transform, bool>)((Transform obj) => ((Object)obj).name == "EscapeMenu"));
if (obj2 == null)
{
return null;
}
Transform obj3 = obj2.Find("MainPage");
if (obj3 == null)
{
return null;
}
return ((Component)obj3).gameObject;
}
}
private static GameObject UIButtonList
{
get
{
GameObject uIMenu = UIMenu;
if (uIMenu == null)
{
return null;
}
Transform obj = uIMenu.transform.Find("LIST");
if (obj == null)
{
return null;
}
return ((Component)obj).gameObject;
}
}
internal static bool AddButton(string name, string text, UnityAction action, int? index = null)
{
GameObject uIButtonList = UIButtonList;
if ((Object)(object)uIButtonList == (Object)null)
{
ManualLogSource curLogger = Plugin.CurLogger;
if (curLogger != null)
{
curLogger.LogError((object)"Failed to find the EscapeMenu control list!");
}
return false;
}
Transform obj = uIButtonList.transform.Find("RESUME");
GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
if ((Object)(object)val == (Object)null)
{
ManualLogSource curLogger2 = Plugin.CurLogger;
if (curLogger2 != null)
{
curLogger2.LogError((object)"Failed to find the 'RESUME' button to use as a template!");
}
return false;
}
GameObject val2 = Object.Instantiate<GameObject>(val, uIButtonList.transform);
((Object)val2).name = name;
if (index.HasValue)
{
val2.transform.SetSiblingIndex(index.Value);
}
Button componentInChildren = val2.GetComponentInChildren<Button>();
if ((Object)(object)componentInChildren == (Object)null)
{
ManualLogSource curLogger3 = Plugin.CurLogger;
if (curLogger3 != null)
{
curLogger3.LogError((object)"Failed to find the Button component!");
}
Object.Destroy((Object)(object)val2);
return false;
}
TextMeshProUGUI componentInChildren2 = val2.GetComponentInChildren<TextMeshProUGUI>();
if ((Object)(object)componentInChildren2 == (Object)null)
{
ManualLogSource curLogger4 = Plugin.CurLogger;
if (curLogger4 != null)
{
curLogger4.LogError((object)"Failed to find the TextMeshProUGUI component!");
}
Object.Destroy((Object)(object)val2);
return false;
}
((UnityEvent)componentInChildren.onClick).AddListener(action);
((TMP_Text)componentInChildren2).SetCharArray(text.ToCharArray());
((Graphic)componentInChildren2).SetAllDirty();
return true;
}
}
[ContentWarningPlugin("BetterLobby", "1.2.2", true)]
[BepInPlugin("BetterLobby", "BetterLobby", "1.2.2")]
public sealed class Plugin : BaseUnityPlugin
{
private ConfigEntry<bool> _incompatibleAck;
public static ManualLogSource CurLogger { get; private set; }
private void Awake()
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
_incompatibleAck = ((BaseUnityPlugin)this).Config.Bind<bool>("Never Show Again", "Vanilla Compatible", false, "Whether the warning dialog shown when non vanilla-compatible plugins are found is hidden");
CurLogger = ((BaseUnityPlugin)this).Logger;
new Harmony("sonodima.BetterLobby").PatchAll();
}
private void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
if (!PhotonGameLobbyHandler.IsSurface || !PhotonNetwork.IsMasterClient)
{
return;
}
if ((Object)(object)PlayerHandler.instance != (Object)null)
{
PlayerHandler instance = PlayerHandler.instance;
instance.OnPlayerJoined = (Action<Player>)Delegate.Combine(instance.OnPlayerJoined, (Action<Player>)delegate(Player player)
{
((MonoBehaviour)this).StartCoroutine(OnPlayerJoined(player));
});
}
PauseMenu.AddButton("FILL", "FILL LOBBY", new UnityAction(OnFillPress), 1);
}
private IEnumerator OnPlayerJoined(Player player)
{
if (LobbyHelpers.IsFull && SurfaceNetworkHandler.HasStarted)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Maximum number of players reached, closing lobby to the public...");
LobbyHelpers.SetPublic(value: false);
}
yield return (object)new WaitForSeconds(2f);
if (PhotonGameLobbyHandler.CurrentObjective != null)
{
PhotonGameLobbyHandler.Instance.SetCurrentObjective(PhotonGameLobbyHandler.CurrentObjective);
}
yield return (object)new WaitForSeconds(1f);
PhotonView view = player.refs.view;
Player val = ((view != null) ? view.Owner : null);
if (val != null && (Object)(object)SurfaceNetworkHandler.Instance != (Object)null && SurfaceNetworkHandler.HasStarted)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Game has already started, sending RPCA_OpenDoor to the late-joiner...");
((MonoBehaviourPun)SurfaceNetworkHandler.Instance).photonView.RPC("RPCA_OpenDoor", val, new object[0]);
}
}
private void OnFillPress()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Expected O, but got Unknown
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
if (GameHandler.GetPluginHash() != "none" && !_incompatibleAck.Value)
{
ModalOption[] array = (ModalOption[])(object)new ModalOption[2]
{
new ModalOption("Never Show Again", (Action)delegate
{
_incompatibleAck.Value = true;
}),
new ModalOption("Ok", (Action)null)
};
Modal.Show("NON-VANILLA PLUGINS", "You have installed plugins that are marked as non vanilla-compatible.\r\nThis restricts the matchmaking to people with those same exact\r\nplugins, and BetterLobby may not be able to fill the lobby!", array, (Action)null);
}
if (LobbyHelpers.IsFull)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Lobby is already full, will not make it public.");
Modal.ShowError("LOBBY IS FULL", "Wait for a player to disconnect before making it public again!");
}
else if (!PhotonGameLobbyHandler.IsSurface)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Attempted to make the lobby public while not on suface!");
Modal.ShowError("NOT READY", "You need to be on surface to make the lobby public!");
}
else
{
LobbyHelpers.SetPublic(value: true);
LobbyHelpers.SetJoinable(value: true);
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "BetterLobby";
public const string PLUGIN_NAME = "BetterLobby";
public const string PLUGIN_VERSION = "1.2.2";
}
}
namespace BetterLobby.Patches
{
[HarmonyPatch]
internal static class InviteFriends
{
[HarmonyPrefix]
[HarmonyPatch(typeof(SteamLobbyHandler), "InviteScreen")]
private static bool InviteScreenPatch()
{
if (LobbyHelpers.IsFull)
{
ManualLogSource curLogger = Plugin.CurLogger;
if (curLogger != null)
{
curLogger.LogWarning((object)"Lobby is already full, will not show the invite screen.");
}
return false;
}
LobbyHelpers.SetPublic(value: false);
LobbyHelpers.SetJoinable(value: true);
return true;
}
[HarmonyPrefix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static bool InviteTerminalPatch(ref bool __result)
{
__result = false;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(EscapeMenuMainPage), "Update")]
private static bool InviteButtonPatch(EscapeMenuMainPage __instance)
{
Button inviteButton = __instance.inviteButton;
if (inviteButton != null)
{
GameObject gameObject = ((Component)inviteButton).gameObject;
if (gameObject != null)
{
gameObject.SetActive(true);
}
}
return false;
}
}
[HarmonyPatch]
public static class LobbyHandler
{
private static bool? s_wasHostPrivate;
[HarmonyPrefix]
[HarmonyPatch(typeof(SteamLobbyHandler), "HostMatch")]
private static bool OnHostMatch(ref bool privateMatch)
{
ManualLogSource curLogger = Plugin.CurLogger;
if (curLogger != null)
{
curLogger.LogInfo((object)("Requested " + (privateMatch ? "PRIVATE" : "PUBLIC") + " match. Creating a PUBLIC lobby..."));
}
s_wasHostPrivate = privateMatch;
privateMatch = false;
return true;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(SteamLobbyHandler), "OpenLobby")]
private static void OpenLobby()
{
if (!s_wasHostPrivate.HasValue)
{
ManualLogSource curLogger = Plugin.CurLogger;
if (curLogger != null)
{
curLogger.LogWarning((object)"OpenLobby called, but we didn't store a lobby type target! Check this routine again!");
}
return;
}
ManualLogSource curLogger2 = Plugin.CurLogger;
if (curLogger2 != null)
{
curLogger2.LogInfo((object)("Making the created lobby " + (s_wasHostPrivate.Value ? "PRIVATE" : "PUBLIC") + " as specified in HostMatch..."));
}
LobbyHelpers.SetPublic(!s_wasHostPrivate.Value);
s_wasHostPrivate = null;
}
}
}