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.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using SpongePEAK.Core.Logging;
using SpongePEAK.Core.Patching;
using SpongePEAK.Lib.Features;
using SpongePEAK.Lib.Plugin;
using SpongePEAK.Lib.UI;
using SpongePEAK.Lobby.Features;
using SpongePEAK.Lobby.Matchmaking;
using SpongePEAK.Lobby.UI;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
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("sponge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) sponge")]
[assembly: AssemblyDescription("Public lobby browser with host-set lock codes.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ddcbf023fcb4c2065ad9b038910633cd4a3a93b0")]
[assembly: AssemblyProduct("SpongePEAKLobby")]
[assembly: AssemblyTitle("com.sponge.peaklobby")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[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 SpongePEAK.Lobby
{
[BepInPlugin("com.sponge.peaklobby", "SpongePEAKLobby", "1.0.0")]
public sealed class LobbyPlugin : SpongePlugin
{
public const string Guid = "com.sponge.peaklobby";
private FeatureRegistry _registry;
private LobbyBrowserFeature _browser;
private BrowserWindow _window;
private ConfigEntry<KeyCode> _key;
protected override string DisplayName => "SpongePEAKLobby";
protected override void OnLoad()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
_registry = new FeatureRegistry(((BaseUnityPlugin)this).Config, ((SpongePlugin)this).Log);
_key = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Lobby", "BrowserKey", (KeyCode)287, "Opens the lobby browser.");
_browser = new LobbyBrowserFeature();
_browser.Configure(((BaseUnityPlugin)this).Config);
_registry.Register((ModFeature)(object)_browser);
_registry.EnableAll(((SpongePlugin)this).Patches);
if (((ModFeature)_browser).IsActive)
{
_window = new BrowserWindow(_browser, ((SpongePlugin)this).Log);
MenuIntegration.AddMainMenuButton("LOBBY BROWSER", (Action)delegate
{
_window?.Toggle();
});
}
}
private void Update()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if (_browser != null && ((ModFeature)_browser).IsActive)
{
_browser.Tick();
ConfigEntry<KeyCode> key = _key;
if (Input.GetKeyDown((KeyCode)((key == null) ? 287 : ((int)key.Value))))
{
_window?.Toggle();
}
_window?.Tick();
}
}
protected override void OnUnload()
{
_browser?.Cleanup();
}
}
}
namespace SpongePEAK.Lobby.UI
{
public sealed class BrowserWindow
{
private readonly LobbyBrowserFeature _feature;
private readonly ModLog _log;
private GameObject _root;
private ModalCursorWindow _modal;
private TMP_InputField _searchField;
private TMP_InputField _hostField;
private RectTransform _results;
private ScrollRect _scroll;
private TextMeshProUGUI _searchHint;
private TextMeshProUGUI _status;
private TextMeshProUGUI _lockState;
private Toggle _listToggle;
private readonly List<GameObject> _rows = new List<GameObject>();
private int _lastResultCount = -1;
private bool _suppressCallbacks;
public bool IsOpen { get; private set; }
public BrowserWindow(LobbyBrowserFeature feature, ModLog log)
{
_feature = feature;
_log = log;
}
public void Toggle()
{
if (IsOpen)
{
Close();
}
else if (!((Object)(object)_root == (Object)null) || Build())
{
IsOpen = true;
_root.SetActive(true);
ModalCursorWindow modal = _modal;
if (modal != null)
{
modal.SetOpen(true);
}
_feature.Search.Search(((Object)(object)_searchField != (Object)null) ? _searchField.text : string.Empty);
Refresh(force: true);
}
}
public void Close()
{
if (IsOpen)
{
IsOpen = false;
ModalCursorWindow modal = _modal;
if (modal != null)
{
modal.SetOpen(false);
}
if ((Object)(object)_root != (Object)null)
{
_root.SetActive(false);
}
}
}
public void Tick()
{
if (IsOpen)
{
Refresh();
}
}
private bool Build()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Expected O, but got Unknown
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_023d: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
//IL_0278: Unknown result type (might be due to invalid IL or missing references)
//IL_028d: Unknown result type (might be due to invalid IL or missing references)
//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
try
{
_root = new GameObject("SpongeUI_LobbyBrowser", new Type[3]
{
typeof(Canvas),
typeof(CanvasScaler),
typeof(GraphicRaycaster)
});
Object.DontDestroyOnLoad((Object)(object)_root);
Canvas component = _root.GetComponent<Canvas>();
component.renderMode = (RenderMode)0;
component.sortingOrder = 510;
CanvasScaler component2 = _root.GetComponent<CanvasScaler>();
component2.uiScaleMode = (ScaleMode)1;
component2.referenceResolution = new Vector2(1920f, 1080f);
component2.matchWidthOrHeight = 0.5f;
RectTransform val = NewRect("Panel", _root.transform);
Vector2 anchorMin = (val.anchorMax = new Vector2(0.5f, 0.5f));
val.anchorMin = anchorMin;
val.pivot = new Vector2(0.5f, 0.5f);
val.sizeDelta = new Vector2(760f, 820f);
val.anchoredPosition = Vector2.zero;
((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0.13f, 0.1f, 0.07f, 0.96f);
Label(val, "PEAK LOBBIES", 26f, new Vector2(0f, -16f), new Color(0.98f, 0.86f, 0.55f));
_searchField = Field(val, "Search code (blank = public lobbies)", new Vector2(-220f, -60f), new Vector2(420f, 44f));
RectTransform val3 = NewRect("Find", (Transform)(object)val);
anchorMin = (val3.anchorMax = new Vector2(0.5f, 1f));
val3.anchorMin = anchorMin;
val3.pivot = new Vector2(0.5f, 1f);
val3.sizeDelta = new Vector2(140f, 44f);
val3.anchoredPosition = new Vector2(120f, -60f);
PeakStyle.CreateButton("SEARCH", (Transform)(object)val3, (Action)delegate
{
_feature.Search.Search(((Object)(object)_searchField != (Object)null) ? _searchField.text : string.Empty);
});
_searchHint = Label(val, "", 15f, new Vector2(0f, -110f), new Color(1f, 1f, 1f, 0.55f));
RectTransform val5 = NewRect("Results", (Transform)(object)val);
val5.anchorMin = new Vector2(0f, 0f);
val5.anchorMax = new Vector2(1f, 1f);
val5.offsetMin = new Vector2(24f, 240f);
val5.offsetMax = new Vector2(-24f, -140f);
_results = val5;
_scroll = ScrollableList.Ensure((Transform)(object)_results, _log, 3f);
_status = Label(val, "", 16f, new Vector2(0f, -150f), new Color(1f, 1f, 1f, 0.7f));
BuildHostControls(val);
_modal = _root.AddComponent<ModalCursorWindow>();
_modal.SetLogger(_log);
_modal.Closed = delegate
{
IsOpen = false;
if ((Object)(object)_root != (Object)null)
{
_root.SetActive(false);
}
};
_root.SetActive(false);
return true;
}
catch (Exception ex)
{
ModLog log = _log;
if (log != null)
{
log.Exception("Could not build the lobby browser", ex);
}
_root = null;
return false;
}
}
private void BuildHostControls(RectTransform panel)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
//IL_0278: Unknown result type (might be due to invalid IL or missing references)
//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0315: Unknown result type (might be due to invalid IL or missing references)
//IL_0371: Unknown result type (might be due to invalid IL or missing references)
//IL_0376: Unknown result type (might be due to invalid IL or missing references)
//IL_0399: Unknown result type (might be due to invalid IL or missing references)
//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
//IL_03db: 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_0415: Unknown result type (might be due to invalid IL or missing references)
//IL_0442: Unknown result type (might be due to invalid IL or missing references)
//IL_0449: Unknown result type (might be due to invalid IL or missing references)
//IL_045b: Unknown result type (might be due to invalid IL or missing references)
//IL_0470: Unknown result type (might be due to invalid IL or missing references)
//IL_0484: Unknown result type (might be due to invalid IL or missing references)
//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
//IL_04da: Unknown result type (might be due to invalid IL or missing references)
//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
//IL_0506: Unknown result type (might be due to invalid IL or missing references)
RectTransform rectTransform = ((TMP_Text)Label(panel, "YOUR LOBBY", 18f, Vector2.zero, new Color(0.98f, 0.86f, 0.55f, 0.9f))).rectTransform;
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(0.5f, 0f);
rectTransform.anchorMax = val;
rectTransform.anchorMin = val;
rectTransform.pivot = new Vector2(0.5f, 0f);
rectTransform.sizeDelta = new Vector2(400f, 28f);
rectTransform.anchoredPosition = new Vector2(0f, 196f);
_hostField = Field(panel, "Lock code (blank = unlocked)", Vector2.zero, new Vector2(360f, 44f));
RectTransform component = ((Component)_hostField).GetComponent<RectTransform>();
((Vector2)(ref val))..ctor(0.5f, 0f);
component.anchorMax = val;
component.anchorMin = val;
component.pivot = new Vector2(0.5f, 0f);
component.anchoredPosition = new Vector2(-120f, 144f);
RectTransform val2 = NewRect("SetCode", (Transform)(object)panel);
((Vector2)(ref val))..ctor(0.5f, 0f);
val2.anchorMax = val;
val2.anchorMin = val;
val2.pivot = new Vector2(0.5f, 0f);
val2.sizeDelta = new Vector2(110f, 44f);
val2.anchoredPosition = new Vector2(125f, 144f);
PeakStyle.CreateButton("LOCK", (Transform)(object)val2, (Action)delegate
{
if ((Object)(object)_hostField != (Object)null && LockCode.IsValid(_hostField.text))
{
_feature.SetCode(_hostField.text);
Refresh(force: true);
}
});
RectTransform val3 = NewRect("ClearCode", (Transform)(object)panel);
((Vector2)(ref val))..ctor(0.5f, 0f);
val3.anchorMax = val;
val3.anchorMin = val;
val3.pivot = new Vector2(0.5f, 0f);
val3.sizeDelta = new Vector2(110f, 44f);
val3.anchoredPosition = new Vector2(245f, 144f);
PeakStyle.CreateButton("UNLOCK", (Transform)(object)val3, (Action)delegate
{
if ((Object)(object)_hostField != (Object)null)
{
_hostField.text = string.Empty;
}
_feature.ClearCode();
Refresh(force: true);
});
RectTransform val4 = NewRect("ListToggle", (Transform)(object)panel);
((Vector2)(ref val))..ctor(0.5f, 0f);
val4.anchorMax = val;
val4.anchorMin = val;
val4.pivot = new Vector2(0.5f, 0f);
val4.sizeDelta = new Vector2(28f, 28f);
val4.anchoredPosition = new Vector2(-250f, 104f);
Image val5 = ((Component)val4).gameObject.AddComponent<Image>();
((Graphic)val5).color = new Color(0.05f, 0.04f, 0.03f, 0.95f);
RectTransform obj = NewRect("Check", (Transform)(object)val4);
obj.anchorMin = new Vector2(0.18f, 0.18f);
obj.anchorMax = new Vector2(0.82f, 0.82f);
obj.offsetMin = Vector2.zero;
obj.offsetMax = Vector2.zero;
Image val6 = ((Component)obj).gameObject.AddComponent<Image>();
((Graphic)val6).color = new Color(0.98f, 0.86f, 0.55f);
_listToggle = ((Component)val4).gameObject.AddComponent<Toggle>();
((Selectable)_listToggle).targetGraphic = (Graphic)(object)val5;
_listToggle.graphic = (Graphic)(object)val6;
((UnityEvent<bool>)(object)_listToggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool v)
{
if (!_suppressCallbacks)
{
_feature.SetListed(v);
Refresh(force: true);
}
});
TextMeshProUGUI obj2 = Label(panel, "List my lobby publicly", 15f, Vector2.zero, Color.white);
RectTransform rectTransform2 = ((TMP_Text)obj2).rectTransform;
((Vector2)(ref val))..ctor(0.5f, 0f);
rectTransform2.anchorMax = val;
rectTransform2.anchorMin = val;
rectTransform2.pivot = new Vector2(0f, 0f);
rectTransform2.sizeDelta = new Vector2(340f, 24f);
rectTransform2.anchoredPosition = new Vector2(-226f, 106f);
((TMP_Text)obj2).alignment = (TextAlignmentOptions)4097;
_lockState = Label(panel, "", 14f, Vector2.zero, new Color(1f, 1f, 1f, 0.6f));
RectTransform rectTransform3 = ((TMP_Text)_lockState).rectTransform;
((Vector2)(ref val))..ctor(0.5f, 0f);
rectTransform3.anchorMax = val;
rectTransform3.anchorMin = val;
rectTransform3.pivot = new Vector2(0.5f, 0f);
rectTransform3.sizeDelta = new Vector2(700f, 52f);
rectTransform3.anchoredPosition = new Vector2(0f, 46f);
((TMP_Text)_lockState).alignment = (TextAlignmentOptions)258;
RectTransform val7 = NewRect("Close", (Transform)(object)panel);
((Vector2)(ref val))..ctor(1f, 0f);
val7.anchorMax = val;
val7.anchorMin = val;
val7.pivot = new Vector2(1f, 0f);
val7.sizeDelta = new Vector2(130f, 34f);
val7.anchoredPosition = new Vector2(-24f, 8f);
PeakStyle.CreateButton("CLOSE", (Transform)(object)val7, (Action)Close);
}
private void Refresh(bool force = false)
{
LobbySearch search = _feature.Search;
string text = (((Object)(object)_searchField != (Object)null) ? _searchField.text.Trim() : string.Empty);
if ((Object)(object)_searchHint != (Object)null)
{
((TMP_Text)_searchHint).text = ((text.Length > 0) ? "Showing only lobbies using this exact code." : "Showing public lobbies. Type a code to find a locked one.");
}
if ((Object)(object)_status != (Object)null)
{
if (search.Searching)
{
((TMP_Text)_status).text = "Searching...";
}
else if (search.Error.Length > 0)
{
((TMP_Text)_status).text = search.Error;
}
else if (search.Results.Count == 0)
{
((TMP_Text)_status).text = ((text.Length > 0) ? "No lobby is using that code. Check it with whoever sent it." : "No public lobbies right now.");
}
else
{
((TMP_Text)_status).text = $"{search.Results.Count} lobby(s) found.";
}
}
if (force || search.Results.Count != _lastResultCount)
{
_lastResultCount = search.Results.Count;
BuildRows(search.Results);
}
LobbyPublisher publisher = _feature.Publisher;
_suppressCallbacks = true;
try
{
if ((Object)(object)_listToggle != (Object)null)
{
_listToggle.isOn = publisher.IsListed;
((Selectable)_listToggle).interactable = !publisher.IsLocked;
}
}
finally
{
_suppressCallbacks = false;
}
if ((Object)(object)_lockState != (Object)null)
{
((TMP_Text)_lockState).text = (publisher.IsLocked ? "Locked. Hidden from lobby browsers. Anyone with the code can find it, and your Steam friends can still join from their friends list as usual." : (publisher.IsListed ? "Visible to anyone browsing lobbies." : "Not listed. Friends can still join through Steam."));
}
}
private void BuildRows(IReadOnlyList<LobbyEntry> entries)
{
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Expected O, but got Unknown
for (int i = 0; i < entries.Count; i++)
{
GameObject val = ((i < _rows.Count) ? _rows[i] : CreateRow());
if ((Object)(object)val == (Object)null)
{
continue;
}
LobbyEntry entry = entries[i];
val.SetActive(true);
TextMeshProUGUI componentInChildren = val.GetComponentInChildren<TextMeshProUGUI>(true);
if ((Object)(object)componentInChildren != (Object)null)
{
string arg = ((entry.Name.Length > 0) ? entry.Name : "PEAK lobby");
((TMP_Text)componentInChildren).text = $"{arg} <color=#FFFFFF80>{entry.Players}/{entry.Capacity}" + ((entry.Scene.Length > 0) ? (" (" + entry.Scene + ")") : "") + "</color>";
((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)4097;
((TMP_Text)componentInChildren).fontSize = 17f;
}
Button componentInChildren2 = val.GetComponentInChildren<Button>(true);
if ((Object)(object)componentInChildren2 != (Object)null)
{
((UnityEventBase)componentInChildren2.onClick).RemoveAllListeners();
((UnityEvent)componentInChildren2.onClick).AddListener((UnityAction)delegate
{
Join(entry);
});
}
}
for (int num = entries.Count; num < _rows.Count; num++)
{
_rows[num].SetActive(false);
}
ScrollableList.Refresh(_scroll);
}
private GameObject CreateRow()
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: 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_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
try
{
RectTransform val = NewRect($"Row{_rows.Count}", (Transform)(object)_results);
val.sizeDelta = new Vector2(0f, 36f);
LayoutElement obj = ((Component)val).gameObject.AddComponent<LayoutElement>();
obj.preferredHeight = 36f;
obj.minHeight = 36f;
Button val2 = PeakStyle.CreateButton("lobby", (Transform)(object)val, (Action)null);
if ((Object)(object)val2 != (Object)null)
{
RectTransform component = ((Component)val2).GetComponent<RectTransform>();
if ((Object)(object)component != (Object)null)
{
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = Vector2.zero;
component.offsetMax = Vector2.zero;
}
}
_rows.Add(((Component)val).gameObject);
return ((Component)val).gameObject;
}
catch (Exception ex)
{
ModLog log = _log;
if (log != null)
{
log.Exception("Could not create a lobby row", ex);
}
return null;
}
}
private void Join(LobbyEntry entry)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
try
{
Close();
SteamMatchmaking.JoinLobby(entry.Id);
ModLog log = _log;
if (log != null)
{
log.Info((object)$"Joining lobby {entry.Id}.");
}
}
catch (Exception ex)
{
ModLog log2 = _log;
if (log2 != null)
{
log2.Exception("Could not join the lobby", ex);
}
}
}
private static RectTransform NewRect(string name, Transform parent)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
((Transform)component).SetParent(parent, false);
return component;
}
private TMP_InputField Field(RectTransform panel, string placeholderText, Vector2 position, Vector2 size)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = NewRect("Field", (Transform)(object)panel);
Vector2 val2 = default(Vector2);
((Vector2)(ref val2))..ctor(0.5f, 1f);
val.anchorMax = val2;
val.anchorMin = val2;
val.pivot = new Vector2(0.5f, 1f);
val.sizeDelta = size;
val.anchoredPosition = position;
((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0.05f, 0.04f, 0.03f, 0.95f);
RectTransform val3 = NewRect("TextArea", (Transform)(object)val);
val3.anchorMin = Vector2.zero;
val3.anchorMax = Vector2.one;
val3.offsetMin = new Vector2(10f, 4f);
val3.offsetMax = new Vector2(-10f, -4f);
((Component)val3).gameObject.AddComponent<RectMask2D>();
RectTransform obj = NewRect("Text", (Transform)(object)val3);
obj.anchorMin = Vector2.zero;
obj.anchorMax = Vector2.one;
obj.offsetMin = Vector2.zero;
obj.offsetMax = Vector2.zero;
TextMeshProUGUI val4 = ((Component)obj).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)val4).fontSize = 18f;
((TMP_Text)val4).alignment = (TextAlignmentOptions)4097;
((Graphic)val4).color = Color.white;
Inherit(val4);
RectTransform obj2 = NewRect("Placeholder", (Transform)(object)val3);
obj2.anchorMin = Vector2.zero;
obj2.anchorMax = Vector2.one;
obj2.offsetMin = Vector2.zero;
obj2.offsetMax = Vector2.zero;
TextMeshProUGUI val5 = ((Component)obj2).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)val5).text = placeholderText;
((TMP_Text)val5).fontSize = 18f;
((TMP_Text)val5).alignment = (TextAlignmentOptions)4097;
((Graphic)val5).color = new Color(1f, 1f, 1f, 0.35f);
Inherit(val5);
TMP_InputField obj3 = ((Component)val).gameObject.AddComponent<TMP_InputField>();
obj3.textViewport = val3;
obj3.textComponent = (TMP_Text)(object)val4;
obj3.placeholder = (Graphic)(object)val5;
obj3.caretColor = Color.white;
obj3.characterLimit = 32;
return obj3;
}
private TextMeshProUGUI Label(RectTransform panel, string text, float size, Vector2 position, Color color)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: 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)
RectTransform obj = NewRect("Label", (Transform)(object)panel);
obj.anchorMin = new Vector2(0f, 1f);
obj.anchorMax = new Vector2(1f, 1f);
obj.pivot = new Vector2(0.5f, 1f);
obj.sizeDelta = new Vector2(-48f, size + 10f);
obj.anchoredPosition = position;
TextMeshProUGUI obj2 = ((Component)obj).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)obj2).text = text;
((TMP_Text)obj2).fontSize = size;
((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
((Graphic)obj2).color = color;
Inherit(obj2);
return obj2;
}
private static void Inherit(TextMeshProUGUI text)
{
GameObject buttonTemplate = PeakStyle.ButtonTemplate;
TextMeshProUGUI val = ((buttonTemplate != null) ? buttonTemplate.GetComponentInChildren<TextMeshProUGUI>(true) : null);
if ((Object)(object)((val != null) ? ((TMP_Text)val).font : null) != (Object)null)
{
((TMP_Text)text).font = ((TMP_Text)val).font;
}
}
}
}
namespace SpongePEAK.Lobby.Matchmaking
{
internal sealed class LobbyPublisher
{
private readonly ModLog _log;
private string _hash = string.Empty;
private bool _listed;
private string _writtenHash;
private bool _writtenListed;
private CSteamID _writtenTo = CSteamID.Nil;
public string Hash => _hash;
public bool IsLocked => _hash.Length > 0;
public bool IsListed => _listed;
public LobbyPublisher(ModLog log)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
_log = log;
}
public void SetCode(string raw)
{
_hash = LockCode.Hash(raw);
if (_hash.Length > 0)
{
_listed = false;
}
Invalidate();
}
public void ClearCode()
{
_hash = string.Empty;
Invalidate();
}
public void SetListed(bool listed)
{
_listed = listed && !IsLocked;
Invalidate();
}
public void Invalidate()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
_writtenTo = CSteamID.Nil;
_writtenHash = null;
}
public bool Publish()
{
//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_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!PhotonNetwork.IsMasterClient || PhotonNetwork.OfflineMode)
{
return false;
}
CSteamID val = CurrentLobby();
if (val == CSteamID.Nil)
{
return false;
}
if (val == _writtenTo && _writtenHash == _hash && _writtenListed == _listed)
{
return false;
}
SteamMatchmaking.SetLobbyData(val, "sponge_lock", _hash);
string text = (_listed ? "true" : string.Empty);
SteamMatchmaking.SetLobbyData(val, "sponge_public", text);
SteamMatchmaking.SetLobbyData(val, "TopMidLeftRight", text);
_writtenTo = val;
_writtenHash = _hash;
_writtenListed = _listed;
ModLog log = _log;
if (log != null)
{
log.Info((object)(IsLocked ? "Lobby locked; hidden from browsers, still joinable by invite or code." : (_listed ? "Lobby published to public browsers." : "Lobby unlisted.")));
}
return true;
}
catch (Exception ex)
{
ModLog log2 = _log;
if (log2 != null)
{
log2.Exception("Could not publish lobby state", ex);
}
return false;
}
}
private static CSteamID CurrentLobby()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
SteamLobbyHandler service = GameHandler.GetService<SteamLobbyHandler>();
if (service == null || !service.InSteamLobby())
{
return CSteamID.Nil;
}
return service.LobbySteamId;
}
}
internal sealed class LobbyEntry
{
public CSteamID Id;
public string Name = "";
public int Players;
public int Capacity;
public string Scene = "";
public bool Locked;
}
internal sealed class LobbySearch
{
private readonly ModLog _log;
private CallResult<LobbyMatchList_t> _callResult;
public List<LobbyEntry> Results { get; } = new List<LobbyEntry>();
public bool Searching { get; private set; }
public string Error { get; private set; } = "";
public event Action Updated;
public LobbySearch(ModLog log)
{
_log = log;
}
public void Search(string code)
{
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
if (Searching)
{
return;
}
try
{
if (!SteamManager.Initialized)
{
Error = "Steam is not running.";
this.Updated?.Invoke();
return;
}
if (_callResult == null)
{
_callResult = CallResult<LobbyMatchList_t>.Create((APIDispatchDelegate<LobbyMatchList_t>)OnLobbyMatchList);
}
string text = LockCode.Hash(code);
if (text.Length > 0)
{
SteamMatchmaking.AddRequestLobbyListStringFilter("sponge_lock", text, (ELobbyComparison)0);
}
else
{
SteamMatchmaking.AddRequestLobbyListStringFilter("TopMidLeftRight", "true", (ELobbyComparison)0);
}
Searching = true;
Error = "";
_callResult.Set(SteamMatchmaking.RequestLobbyList(), (APIDispatchDelegate<LobbyMatchList_t>)null);
}
catch (Exception ex)
{
Searching = false;
Error = "Search failed; see the log.";
ModLog log = _log;
if (log != null)
{
log.Exception("Lobby search failed", ex);
}
this.Updated?.Invoke();
}
}
private void OnLobbyMatchList(LobbyMatchList_t result, bool failure)
{
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: 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_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
Searching = false;
Results.Clear();
if (failure)
{
Error = "Steam did not answer the lobby request.";
this.Updated?.Invoke();
return;
}
try
{
for (int i = 0; i < result.m_nLobbiesMatching; i++)
{
CSteamID lobbyByIndex = SteamMatchmaking.GetLobbyByIndex(i);
Results.Add(new LobbyEntry
{
Id = lobbyByIndex,
Name = SteamMatchmaking.GetLobbyData(lobbyByIndex, "name"),
Players = SteamMatchmaking.GetNumLobbyMembers(lobbyByIndex),
Capacity = SteamMatchmaking.GetLobbyMemberLimit(lobbyByIndex),
Scene = SteamMatchmaking.GetLobbyData(lobbyByIndex, "CurrentScene"),
Locked = (SteamMatchmaking.GetLobbyData(lobbyByIndex, "sponge_lock").Length > 0)
});
}
}
catch (Exception ex)
{
ModLog log = _log;
if (log != null)
{
log.Exception("Could not read lobby results", ex);
}
}
this.Updated?.Invoke();
}
}
internal static class LockCode
{
public const string DataKey = "sponge_lock";
public const string PublicKey = "sponge_public";
public const string InteropKey = "TopMidLeftRight";
public const int MaxLength = 32;
public static string Normalise(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
{
return string.Empty;
}
string text = raw.Trim();
if (text.Length > 32)
{
text = text.Substring(0, 32);
}
return text.ToUpperInvariant();
}
public static bool IsValid(string raw)
{
return Normalise(raw).Length > 0;
}
public static string Hash(string raw)
{
string text = Normalise(raw);
if (text.Length == 0)
{
return string.Empty;
}
using SHA256 sHA = SHA256.Create();
byte[] array = sHA.ComputeHash(Encoding.UTF8.GetBytes("sponge.peak.lobby.v1:" + text));
StringBuilder stringBuilder = new StringBuilder(16);
for (int i = 0; i < 8; i++)
{
stringBuilder.Append(array[i].ToString("x2"));
}
return stringBuilder.ToString();
}
}
}
namespace SpongePEAK.Lobby.Features
{
public sealed class LobbyBrowserFeature : ModFeature, IMatchmakingCallbacks, IInRoomCallbacks
{
private const float ReassertInterval = 100f;
private ConfigEntry<string> _savedCode;
private ConfigEntry<bool> _publishByDefault;
private LobbyPublisher _publisher;
private LobbySearch _search;
private ModLog _log;
private float _nextReassert;
private bool _registered;
public override string Name => "LobbyBrowser";
public override string Description => "Browse public lobbies, publish your own, or lock it with a code so only people who have the code can find it.";
public override string Replaces => "Isotope-PEAKLobbyBrowser";
public override string Section => "Lobby";
internal LobbySearch Search => _search;
internal LobbyPublisher Publisher => _publisher;
public void Configure(ConfigFile config)
{
_savedCode = config.Bind<string>("Lobby", "LockCode", "", "Your lobby's lock code. While set, your lobby is hidden from lobby browsers and can only be found by someone who types this exact code. Invites and the Steam friends list still work. Leave blank for no lock.");
_publishByDefault = config.Bind<bool>("Lobby", "PublishPublicly", false, "List your lobby in public browsers so strangers can join. Ignored while a lock code is set, since a locked lobby is by definition not publicly listed.");
}
protected override void OnEnable(PatchHost patches, ModLog log)
{
_log = log;
_publisher = new LobbyPublisher(log);
_search = new LobbySearch(log);
string text = _savedCode?.Value ?? "";
if (LockCode.IsValid(text))
{
_publisher.SetCode(text);
}
else
{
_publisher.SetListed(_publishByDefault?.Value ?? false);
}
if (!_registered)
{
PhotonNetwork.AddCallbackTarget((object)this);
_registered = true;
}
log.Info((object)"Lobby browser ready.");
}
public void SetCode(string raw)
{
_publisher.SetCode(raw);
if (_savedCode != null)
{
_savedCode.Value = LockCode.Normalise(raw);
}
_publisher.Publish();
}
public void ClearCode()
{
_publisher.ClearCode();
if (_savedCode != null)
{
_savedCode.Value = "";
}
_publisher.SetListed(_publishByDefault?.Value ?? false);
_publisher.Publish();
}
public void SetListed(bool listed)
{
_publisher.SetListed(listed);
if (_publishByDefault != null)
{
_publishByDefault.Value = listed;
}
_publisher.Publish();
}
public void Tick()
{
if (((ModFeature)this).IsActive && _publisher != null && !(Time.realtimeSinceStartup < _nextReassert))
{
_nextReassert = Time.realtimeSinceStartup + 100f;
_publisher.Publish();
}
}
public void OnJoinedRoom()
{
_publisher?.Invalidate();
_publisher?.Publish();
}
public void OnMasterClientSwitched(Player newMasterClient)
{
try
{
_publisher?.Invalidate();
_publisher?.Publish();
}
catch (Exception ex)
{
ModLog log = _log;
if (log != null)
{
log.Exception("Could not re-assert lobby state after host migration", ex);
}
}
}
public void Cleanup()
{
if (_registered)
{
PhotonNetwork.RemoveCallbackTarget((object)this);
_registered = false;
}
}
public void OnCreatedRoom()
{
}
public void OnCreateRoomFailed(short returnCode, string message)
{
}
public void OnJoinRoomFailed(short returnCode, string message)
{
}
public void OnJoinRandomFailed(short returnCode, string message)
{
}
public void OnLeftRoom()
{
}
public void OnFriendListUpdate(List<FriendInfo> friendList)
{
}
public void OnPlayerEnteredRoom(Player newPlayer)
{
}
public void OnPlayerLeftRoom(Player otherPlayer)
{
}
public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
{
}
public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
}
}
}