2020-04-04 15:11:28 +02:00
|
|
|
using System.Text.RegularExpressions;
|
2021-09-19 19:34:46 +02:00
|
|
|
using Content.Client.MainMenu.UI;
|
2022-09-14 14:34:48 -07:00
|
|
|
using Content.Client.UserInterface.Systems.EscapeMenu;
|
2020-04-04 15:11:28 +02:00
|
|
|
using Robust.Client;
|
|
|
|
|
using Robust.Client.ResourceManagement;
|
|
|
|
|
using Robust.Client.UserInterface;
|
|
|
|
|
using Robust.Client.UserInterface.Controls;
|
2020-11-07 01:15:56 +01:00
|
|
|
using Robust.Shared;
|
2021-02-11 01:13:03 -08:00
|
|
|
using Robust.Shared.Configuration;
|
2020-04-04 15:11:28 +02:00
|
|
|
using Robust.Shared.Network;
|
|
|
|
|
using Robust.Shared.Utility;
|
2020-06-18 02:40:47 +02:00
|
|
|
using UsernameHelpers = Robust.Shared.AuthLib.UsernameHelpers;
|
2020-04-04 15:11:28 +02:00
|
|
|
|
2021-06-09 22:19:39 +02:00
|
|
|
namespace Content.Client.MainMenu
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Main menu screen that is the first screen to be displayed when the game starts.
|
|
|
|
|
/// </summary>
|
|
|
|
|
// Instantiated dynamically through the StateManager, Dependencies will be resolved.
|
2022-02-16 00:23:23 -07:00
|
|
|
public sealed class MainScreen : Robust.Client.State.State
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
2020-08-24 14:10:28 +02:00
|
|
|
[Dependency] private readonly IBaseClient _client = default!;
|
|
|
|
|
[Dependency] private readonly IClientNetManager _netManager = default!;
|
|
|
|
|
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
|
|
|
|
[Dependency] private readonly IGameController _controllerProxy = default!;
|
|
|
|
|
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
|
|
|
|
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
2020-04-04 15:11:28 +02:00
|
|
|
|
2021-03-10 14:48:29 +01:00
|
|
|
private MainMenuControl _mainMenuControl = default!;
|
2020-04-04 15:11:28 +02:00
|
|
|
private bool _isConnecting;
|
|
|
|
|
|
|
|
|
|
// ReSharper disable once InconsistentNaming
|
2020-11-27 11:00:49 +01:00
|
|
|
private static readonly Regex IPv6Regex = new(@"\[(.*:.*:.*)](?::(\d+))?");
|
2020-04-04 15:11:28 +02:00
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
2022-09-04 16:17:05 -07:00
|
|
|
protected override void Startup()
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
|
|
|
|
_mainMenuControl = new MainMenuControl(_resourceCache, _configurationManager);
|
2020-08-24 14:10:28 +02:00
|
|
|
_userInterfaceManager.StateRoot.AddChild(_mainMenuControl);
|
2020-04-04 15:11:28 +02:00
|
|
|
|
|
|
|
|
_mainMenuControl.QuitButton.OnPressed += QuitButtonPressed;
|
|
|
|
|
_mainMenuControl.OptionsButton.OnPressed += OptionsButtonPressed;
|
|
|
|
|
_mainMenuControl.DirectConnectButton.OnPressed += DirectConnectButtonPressed;
|
|
|
|
|
_mainMenuControl.AddressBox.OnTextEntered += AddressBoxEntered;
|
2022-10-12 01:16:23 -07:00
|
|
|
_mainMenuControl.ChangelogButton.OnPressed += ChangelogButtonPressed;
|
2020-04-04 15:11:28 +02:00
|
|
|
|
|
|
|
|
_client.RunLevelChanged += RunLevelChanged;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
2022-09-04 16:17:05 -07:00
|
|
|
protected override void Shutdown()
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
|
|
|
|
_client.RunLevelChanged -= RunLevelChanged;
|
|
|
|
|
_netManager.ConnectFailed -= _onConnectFailed;
|
|
|
|
|
|
|
|
|
|
_mainMenuControl.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-12 01:16:23 -07:00
|
|
|
private void ChangelogButtonPressed(BaseButton.ButtonEventArgs args)
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
2022-10-12 01:16:23 -07:00
|
|
|
_userInterfaceManager.GetUIController<ChangelogUIController>().ToggleWindow();
|
2020-04-04 15:11:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OptionsButtonPressed(BaseButton.ButtonEventArgs args)
|
|
|
|
|
{
|
2022-10-12 01:16:23 -07:00
|
|
|
_userInterfaceManager.GetUIController<OptionsUIController>().ToggleWindow();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void QuitButtonPressed(BaseButton.ButtonEventArgs args)
|
|
|
|
|
{
|
|
|
|
|
_controllerProxy.Shutdown();
|
2020-04-04 15:11:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DirectConnectButtonPressed(BaseButton.ButtonEventArgs args)
|
|
|
|
|
{
|
|
|
|
|
var input = _mainMenuControl.AddressBox;
|
|
|
|
|
TryConnect(input.Text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddressBoxEntered(LineEdit.LineEditEventArgs args)
|
|
|
|
|
{
|
|
|
|
|
if (_isConnecting)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TryConnect(args.Text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void TryConnect(string address)
|
|
|
|
|
{
|
2021-10-28 14:23:17 +02:00
|
|
|
var inputName = _mainMenuControl.UsernameBox.Text.Trim();
|
2020-06-18 02:40:47 +02:00
|
|
|
if (!UsernameHelpers.IsNameValid(inputName, out var reason))
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
2020-09-17 09:55:50 +12:00
|
|
|
var invalidReason = Loc.GetString(reason.ToText());
|
2020-08-24 14:10:28 +02:00
|
|
|
_userInterfaceManager.Popup(
|
2021-06-21 02:13:54 +02:00
|
|
|
Loc.GetString("main-menu-invalid-username-with-reason", ("invalidReason", invalidReason)),
|
|
|
|
|
Loc.GetString("main-menu-invalid-username"));
|
2020-04-04 15:11:28 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-07 01:15:56 +01:00
|
|
|
var configName = _configurationManager.GetCVar(CVars.PlayerName);
|
2021-10-28 14:23:17 +02:00
|
|
|
if (_mainMenuControl.UsernameBox.Text != configName)
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
2020-11-07 01:15:56 +01:00
|
|
|
_configurationManager.SetCVar(CVars.PlayerName, inputName);
|
2020-04-04 15:11:28 +02:00
|
|
|
_configurationManager.SaveToFile();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_setConnectingState(true);
|
|
|
|
|
_netManager.ConnectFailed += _onConnectFailed;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ParseAddress(address, out var ip, out var port);
|
|
|
|
|
_client.ConnectToServer(ip, port);
|
|
|
|
|
}
|
|
|
|
|
catch (ArgumentException e)
|
|
|
|
|
{
|
2020-08-24 14:10:28 +02:00
|
|
|
_userInterfaceManager.Popup($"Unable to connect: {e.Message}", "Connection error.");
|
2020-04-04 15:11:28 +02:00
|
|
|
Logger.Warning(e.ToString());
|
|
|
|
|
_netManager.ConnectFailed -= _onConnectFailed;
|
2020-09-10 12:41:04 +02:00
|
|
|
_setConnectingState(false);
|
2020-04-04 15:11:28 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-10 14:48:29 +01:00
|
|
|
private void RunLevelChanged(object? obj, RunLevelChangedEventArgs args)
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
2022-04-16 08:57:19 +10:00
|
|
|
switch (args.NewLevel)
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
2022-04-16 08:57:19 +10:00
|
|
|
case ClientRunLevel.Connecting:
|
|
|
|
|
_setConnectingState(true);
|
|
|
|
|
break;
|
|
|
|
|
case ClientRunLevel.Initialize:
|
|
|
|
|
_setConnectingState(false);
|
|
|
|
|
_netManager.ConnectFailed -= _onConnectFailed;
|
|
|
|
|
break;
|
2020-04-04 15:11:28 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ParseAddress(string address, out string ip, out ushort port)
|
|
|
|
|
{
|
|
|
|
|
var match6 = IPv6Regex.Match(address);
|
|
|
|
|
if (match6 != Match.Empty)
|
|
|
|
|
{
|
|
|
|
|
ip = match6.Groups[1].Value;
|
|
|
|
|
if (!match6.Groups[2].Success)
|
|
|
|
|
{
|
|
|
|
|
port = _client.DefaultPort;
|
|
|
|
|
}
|
|
|
|
|
else if (!ushort.TryParse(match6.Groups[2].Value, out port))
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("Not a valid port.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// See if the IP includes a port.
|
|
|
|
|
var split = address.Split(':');
|
|
|
|
|
ip = address;
|
|
|
|
|
port = _client.DefaultPort;
|
|
|
|
|
if (split.Length > 2)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("Not a valid Address.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IP:port format.
|
|
|
|
|
if (split.Length == 2)
|
|
|
|
|
{
|
|
|
|
|
ip = split[0];
|
|
|
|
|
if (!ushort.TryParse(split[1], out port))
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("Not a valid port.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-10 14:48:29 +01:00
|
|
|
private void _onConnectFailed(object? _, NetConnectFailArgs args)
|
2020-04-04 15:11:28 +02:00
|
|
|
{
|
2021-06-21 02:13:54 +02:00
|
|
|
_userInterfaceManager.Popup(Loc.GetString("main-menu-failed-to-connect",("reason", args.Reason)));
|
2020-04-04 15:11:28 +02:00
|
|
|
_netManager.ConnectFailed -= _onConnectFailed;
|
|
|
|
|
_setConnectingState(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void _setConnectingState(bool state)
|
|
|
|
|
{
|
|
|
|
|
_isConnecting = state;
|
|
|
|
|
_mainMenuControl.DirectConnectButton.Disabled = state;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|