-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
Copy pathLobby.cs
145 lines (121 loc) · 4.5 KB
/
Lobby.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using Godot;
using System;
using Godot.Collections;
public partial class Lobby : Control
{
private const int DefaultPort = 8910; // An arbitrary number.
private const int MaxNumberOfPeers = 1; // How many people we want to have in a game
private LineEdit _address;
private Button _hostButton;
private Button _joinButton;
private Label _statusOk;
private Label _statusFail;
private ENetMultiplayerPeer _peer;
public override void _Ready()
{
// Get nodes - the generic is a class, argument is node path.
_address = GetNode<LineEdit>("Address");
_hostButton = GetNode<Button>("HostButton");
_joinButton = GetNode<Button>("JoinButton");
_statusOk = GetNode<Label>("StatusOk");
_statusFail = GetNode<Label>("StatusFail");
// Connect all callbacks related to networking.
// Note: Use snake_case when talking to engine API.
GetTree().GetMultiplayer().Connect("peer_connected", new Callable(this, nameof(PlayerConnected)));
GetTree().GetMultiplayer().Connect("peer_disconnected", new Callable(this, nameof(PlayerDisconnected)));
GetTree().GetMultiplayer().Connect("connected_to_server", new Callable(this, nameof(ConnectedOk)));
GetTree().GetMultiplayer().Connect("connection_failed", new Callable(this, nameof(ConnectedFail)));
GetTree().GetMultiplayer().Connect("server_disconnected", new Callable(this, nameof(ServerDisconnected)));
}
// Network callbacks from SceneTree
// Callback from SceneTree.
private void PlayerConnected(int id)
{
// Someone connected, start the game!
var pong = ResourceLoader.Load<PackedScene>("res://pong.tscn").Instantiate();
// Connect deferred so we can safely erase it from the callback.
pong.Connect("GameFinished", new Callable(this, nameof(EndGame)), (int) ConnectFlags.Deferred);
GetTree().Root.AddChild(pong);
Hide();
}
private void PlayerDisconnected(int id)
{
EndGame(GetTree().GetMultiplayer().IsServer() ? "Client disconnected" : "Server disconnected");
}
// Callback from SceneTree, only for clients (not server).
private void ConnectedOk()
{
// This function is not needed for this project.
}
// Callback from SceneTree, only for clients (not server).
private void ConnectedFail()
{
SetStatus("Couldn't connect", false);
GetTree().GetMultiplayer().MultiplayerPeer = null; // Remove peer.
_hostButton.Disabled = false;
_joinButton.Disabled = false;
}
private void ServerDisconnected()
{
EndGame("Server disconnected");
}
// Game creation functions
private void EndGame(string withError = "")
{
if (HasNode("/root/Pong"))
{
// Erase immediately, otherwise network might show
// errors (this is why we connected deferred above).
GetNode("/root/Pong").Free();
Show();
}
GetTree().GetMultiplayer().MultiplayerPeer = null; // Remove peer.
_hostButton.Disabled = false;
_joinButton.Disabled = false;
SetStatus(withError, false);
}
private void SetStatus(string text, bool isOk)
{
// Simple way to show status.
if (isOk)
{
_statusOk.Text = text;
_statusFail.Text = "";
}
else
{
_statusOk.Text = "";
_statusFail.Text = text;
}
}
private void OnHostPressed()
{
_peer = new ENetMultiplayerPeer();
Error err = _peer.CreateServer(DefaultPort, MaxNumberOfPeers);
if (err != Error.Ok)
{
// Is another server running?
SetStatus("Can't host, address in use.", false);
return;
}
_peer.Host.Compress(ENetConnection.CompressionMode.RangeCoder);
GetTree().GetMultiplayer().MultiplayerPeer = _peer;
_hostButton.Disabled = true;
_joinButton.Disabled = true;
SetStatus("Waiting for player...", true);
}
private void OnJoinPressed()
{
string ip = _address.Text;
if (!ip.IsValidIPAddress())
{
SetStatus("IP address is invalid", false);
return;
}
_peer = new ENetMultiplayerPeer();
_peer.CreateClient(ip, DefaultPort);
_peer.Host.Compress(ENetConnection.CompressionMode.RangeCoder);
GetTree().GetMultiplayer().MultiplayerPeer = _peer;
SetStatus("Connecting...", true);
}
}