|
|
|
public partial class MultiplayerMenu : MarginContainer
|
|
|
|
{
|
|
|
|
enum Status
|
|
|
|
{
|
|
|
|
Disconnected,
|
|
|
|
ConnectionFailed,
|
|
|
|
HostingFailed,
|
|
|
|
Connecting,
|
|
|
|
Connected,
|
|
|
|
Hosting,
|
|
|
|
}
|
|
|
|
|
|
|
|
Status _status = Status.Disconnected;
|
|
|
|
|
|
|
|
[Export] public Label StatusLabel { get; set; }
|
|
|
|
|
|
|
|
[ExportGroup("When Disconnected")]
|
|
|
|
[Export] public Container WhenDisconnected { get; set; }
|
|
|
|
[Export] public LineEdit AddressInput { get; set; }
|
|
|
|
[Export] public SpinBox PortInput { get; set; }
|
|
|
|
[Export] public Button ConnectButton { get; set; }
|
|
|
|
[Export] public Button HostButton { get; set; }
|
|
|
|
|
|
|
|
[ExportGroup("When Server")]
|
|
|
|
[Export] public Container WhenServer { get; set; }
|
|
|
|
[Export] public LineEdit PortDisplay { get; set; }
|
|
|
|
|
|
|
|
[ExportGroup("When Connected")]
|
|
|
|
[Export] public Container WhenConnected { get; set; }
|
|
|
|
[Export] public Label PlayersLabel { get; set; }
|
|
|
|
[Export] public Button DisconnectButton { get; set; }
|
|
|
|
|
|
|
|
public override void _Ready()
|
|
|
|
{
|
|
|
|
PortDisplay.AddThemeColorOverride("font_uneditable_color", PortDisplay.GetThemeColor("font_color"));
|
|
|
|
|
|
|
|
Multiplayer.ConnectedToServer += () => UpdateStatus(Status.Connected);
|
|
|
|
Multiplayer.ConnectionFailed += () => UpdateStatus(Status.ConnectionFailed);
|
|
|
|
Multiplayer.ServerDisconnected += () => UpdateStatus(Status.Disconnected);
|
|
|
|
|
|
|
|
Game.Instance.MultiplayerManager.PlayerJoined += _ => UpdatePlayerCount();
|
|
|
|
Game.Instance.MultiplayerManager.PlayerLeft += _ => UpdatePlayerCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateStatus(Status status)
|
|
|
|
{
|
|
|
|
_status = status;
|
|
|
|
|
|
|
|
StatusLabel.Text = status switch {
|
|
|
|
Status.Disconnected => "Disconnected",
|
|
|
|
Status.ConnectionFailed => "Connection failed!",
|
|
|
|
Status.HostingFailed => "Hosting failed!",
|
|
|
|
Status.Connecting => "Connecting ...",
|
|
|
|
Status.Connected => "Connected",
|
|
|
|
Status.Hosting => "Hosting",
|
|
|
|
_ => throw new InvalidOperationException(),
|
|
|
|
};
|
|
|
|
StatusLabel.LabelSettings.FontColor = (status switch {
|
|
|
|
Status.Disconnected => Colors.DarkGray,
|
|
|
|
Status.ConnectionFailed => Colors.Red,
|
|
|
|
Status.HostingFailed => Colors.Red,
|
|
|
|
Status.Connecting => Colors.Yellow,
|
|
|
|
Status.Connected => Colors.Green,
|
|
|
|
Status.Hosting => Colors.Green,
|
|
|
|
_ => throw new InvalidOperationException(),
|
|
|
|
}).Lerp(StatusLabel.GetThemeColor("font_color"), 0.5f);
|
|
|
|
|
|
|
|
WhenDisconnected.Visible = status < Status.Connecting;
|
|
|
|
WhenServer.Visible = status == Status.Hosting;
|
|
|
|
WhenConnected.Visible = status >= Status.Connecting;
|
|
|
|
DisconnectButton.Text = status == Status.Hosting ? "Close Server" : "Disconnect";
|
|
|
|
|
|
|
|
UpdatePlayerCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdatePlayerCount()
|
|
|
|
{
|
|
|
|
PlayersLabel.Text = _status switch {
|
|
|
|
< Status.Connecting => "Singleplayer",
|
|
|
|
Status.Connecting => "??? Players",
|
|
|
|
> Status.Connecting => ((Func<string>)(() => {
|
|
|
|
var players = Game.Instance.MultiplayerManager.Players.GetChildCount();
|
|
|
|
return $"{players} {(players != 1 ? "Players" : "Player")}";
|
|
|
|
}))(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OnShowAddressToggled(bool toggledOn)
|
|
|
|
{
|
|
|
|
AddressInput.Secret = !toggledOn;
|
|
|
|
AddressInput.VirtualKeyboardType = toggledOn
|
|
|
|
? LineEdit.VirtualKeyboardTypeEnum.Default
|
|
|
|
: LineEdit.VirtualKeyboardTypeEnum.Password;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OnConnectPressed()
|
|
|
|
{
|
|
|
|
var address = AddressInput.Text;
|
|
|
|
if (address == "") address = AddressInput.PlaceholderText;
|
|
|
|
|
|
|
|
ushort port;
|
|
|
|
var colonIndex = address.LastIndexOf(':');
|
|
|
|
if (colonIndex >= 0) {
|
|
|
|
if (!ushort.TryParse(address[(colonIndex+1)..], out port)) port = 0;
|
|
|
|
address = address[..colonIndex];
|
|
|
|
} else {
|
|
|
|
port = ushort.Parse(AddressInput.PlaceholderText.Split(':')[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
Game.Instance.MultiplayerManager.Connect(address, port);
|
|
|
|
UpdateStatus(Status.Connecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OnHostPressed()
|
|
|
|
{
|
|
|
|
var port = (ushort)RoundToInt(PortInput.Value);
|
|
|
|
if (Game.Instance.MultiplayerManager.CreateServer(port)) {
|
|
|
|
PortDisplay.Text = port.ToString();
|
|
|
|
UpdateStatus(Status.Hosting);
|
|
|
|
} else
|
|
|
|
UpdateStatus(Status.HostingFailed);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OnDisconnectPressed()
|
|
|
|
{
|
|
|
|
Game.Instance.MultiplayerManager.Disconnect();
|
|
|
|
UpdateStatus(Status.Disconnected);
|
|
|
|
}
|
|
|
|
}
|