You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.9 KiB
129 lines
3.9 KiB
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.Multiplayer.PlayerJoined += _ => UpdatePlayerCount(); |
|
Game.Multiplayer.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 count = Game.Players.Count; |
|
return $"{count} {(count != 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.Multiplayer.Connect(address, port); |
|
UpdateStatus(Status.Connecting); |
|
} |
|
|
|
public void OnHostPressed() |
|
{ |
|
var port = (ushort)RoundToInt(PortInput.Value); |
|
if (Game.Multiplayer.CreateServer(port)) { |
|
PortDisplay.Text = port.ToString(); |
|
UpdateStatus(Status.Hosting); |
|
} else |
|
UpdateStatus(Status.HostingFailed); |
|
} |
|
|
|
public void OnDisconnectPressed() |
|
{ |
|
Game.Multiplayer.Disconnect(); |
|
UpdateStatus(Status.Disconnected); |
|
} |
|
}
|
|
|