basic lobbies
This commit is contained in:
parent
6d608b6f0e
commit
160d0dbebe
2
deps.ts
Normal file
2
deps.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export const randomInt = (low: number, high: number) =>
|
||||||
|
Math.floor(Math.random() * (high - low + 1) + low);
|
|
@ -11,13 +11,20 @@ func goto_scene(scene_resource_name):
|
||||||
var _result = get_tree().change_scene("res://%s.tscn" % scene_resource_name)
|
var _result = get_tree().change_scene("res://%s.tscn" % scene_resource_name)
|
||||||
|
|
||||||
func main_menu():
|
func main_menu():
|
||||||
|
client.close()
|
||||||
goto_scene("main")
|
goto_scene("main")
|
||||||
|
|
||||||
func start_singleplayer_game():
|
func start_singleplayer_game():
|
||||||
|
client.close()
|
||||||
goto_scene("game")
|
goto_scene("game")
|
||||||
|
|
||||||
func multiplayer():
|
func lobby_browser():
|
||||||
|
client.close()
|
||||||
goto_scene("multiplayer")
|
goto_scene("multiplayer")
|
||||||
|
|
||||||
|
func lobby():
|
||||||
|
goto_scene("lobby")
|
||||||
|
|
||||||
func quit():
|
func quit():
|
||||||
|
client.close()
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
27
lobby.gd
27
lobby.gd
|
@ -1,8 +1,13 @@
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
|
onready var peers = $MarginContainer/peers
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
$MarginContainer/Label.text = Global.client.lobby
|
Global.client.signaller.connect("peer_joined", self, "_peer_joined")
|
||||||
pass
|
Global.client.signaller.connect("peer_left", self, "_peer_left")
|
||||||
|
Global.client.signaller.connect("lobby_left", self, "_lobby_left")
|
||||||
|
$MarginContainer/Label.text = Global.client.signaller.lobby_id
|
||||||
|
Global.client.signaller.request_peer_list()
|
||||||
|
|
||||||
func _draw():
|
func _draw():
|
||||||
pass
|
pass
|
||||||
|
@ -10,6 +15,22 @@ func _draw():
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
func _peer_joined(joined_peers):
|
||||||
|
for i in range(len(joined_peers)):
|
||||||
|
var id = joined_peers[i]["id"]
|
||||||
|
var name = joined_peers[i]["name"]
|
||||||
|
print("New Peer ", id, name)
|
||||||
|
peers.add_item("%s" % name)
|
||||||
|
peers.set_item_metadata(peers.get_item_count() - 1, { "id": id })
|
||||||
|
|
||||||
|
func _peer_left(id):
|
||||||
|
for i in range(peers.get_item_count()):
|
||||||
|
if id == peers.get_item_metadata(i)["id"]:
|
||||||
|
peers.remove_item(i)
|
||||||
|
return
|
||||||
|
|
||||||
func _on_Button_pressed():
|
func _on_Button_pressed():
|
||||||
Global.leave_game()
|
Global.lobby_browser()
|
||||||
|
|
||||||
|
func _lobby_left(_id):
|
||||||
|
Global.lobby_browser()
|
||||||
|
|
13
lobby.tscn
13
lobby.tscn
|
@ -6,8 +6,13 @@
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
[node name="MarginContainer" type="VBoxContainer" parent="."]
|
[node name="MarginContainer" type="VBoxContainer" parent="."]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
margin_right = 669.0
|
margin_right = 669.0
|
||||||
margin_bottom = 366.0
|
margin_bottom = 366.0
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="MarginContainer"]
|
[node name="Label" type="Label" parent="MarginContainer"]
|
||||||
margin_right = 669.0
|
margin_right = 669.0
|
||||||
|
@ -21,6 +26,12 @@ __meta__ = {
|
||||||
margin_top = 18.0
|
margin_top = 18.0
|
||||||
margin_right = 669.0
|
margin_right = 669.0
|
||||||
margin_bottom = 38.0
|
margin_bottom = 38.0
|
||||||
text = "Close Lobby"
|
text = "Leave"
|
||||||
|
|
||||||
|
[node name="peers" type="ItemList" parent="MarginContainer"]
|
||||||
|
margin_top = 42.0
|
||||||
|
margin_right = 669.0
|
||||||
|
margin_bottom = 51.0
|
||||||
|
auto_height = true
|
||||||
|
|
||||||
[connection signal="pressed" from="MarginContainer/Button" to="." method="_on_Button_pressed"]
|
[connection signal="pressed" from="MarginContainer/Button" to="." method="_on_Button_pressed"]
|
||||||
|
|
4
main.gd
4
main.gd
|
@ -3,10 +3,8 @@ extends Node
|
||||||
func _on_Singleplayer_pressed():
|
func _on_Singleplayer_pressed():
|
||||||
Global.start_singleplayer_game()
|
Global.start_singleplayer_game()
|
||||||
|
|
||||||
|
|
||||||
func _on_CreateLobbyButton_pressed():
|
func _on_CreateLobbyButton_pressed():
|
||||||
Global.multiplayer()
|
Global.lobby_browser()
|
||||||
|
|
||||||
|
|
||||||
func _on_JoinLobbyButton_pressed():
|
func _on_JoinLobbyButton_pressed():
|
||||||
Global.quit()
|
Global.quit()
|
||||||
|
|
|
@ -1,9 +1,48 @@
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
|
# TODO: rename to server browser
|
||||||
|
|
||||||
onready var is_loaded = false
|
onready var is_loaded = false
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
Global.client.signaller.connect("lobby_new", self, "_lobby_new")
|
||||||
|
Global.client.signaller.connect("lobby_delete", self, "_lobby_delete")
|
||||||
|
Global.client.signaller.connect("lobby_joined", self, "_lobby_joined")
|
||||||
|
Global.client.signaller.connect("lobby_left", self, "_lobby_left")
|
||||||
|
Global.client.signaller.connect("websocket_connected", self, "_signaller_connected")
|
||||||
Global.client.connect_to_signaller()
|
Global.client.connect_to_signaller()
|
||||||
|
|
||||||
|
func _lobby_joined(id):
|
||||||
|
Global.lobby()
|
||||||
|
|
||||||
|
func _lobby_left(_id):
|
||||||
|
Global.lobby_browser()
|
||||||
|
|
||||||
|
func _signaller_connected():
|
||||||
|
Global.client.signaller.request_lobby_list()
|
||||||
|
|
||||||
func _on_back_pressed():
|
func _on_back_pressed():
|
||||||
pass
|
Global.main_menu()
|
||||||
|
|
||||||
|
func _on_create_lobby_pressed():
|
||||||
|
Global.client.signaller.create_lobby()
|
||||||
|
|
||||||
|
func _on_join_pressed():
|
||||||
|
var items = $lobbies.get_selected_items()
|
||||||
|
if len(items) > 0:
|
||||||
|
Global.client.signaller.join_lobby($lobbies.get_item_metadata(items[0])["id"])
|
||||||
|
|
||||||
|
func _lobby_new(lobbies):
|
||||||
|
for i in range(len(lobbies)):
|
||||||
|
var id = lobbies[i]["id"]
|
||||||
|
var name = lobbies[i]["name"]
|
||||||
|
print("New Lobby ", id, name)
|
||||||
|
# TODO: could keep an index of IDs and indexes
|
||||||
|
$lobbies.add_item("%s" % name)
|
||||||
|
$lobbies.set_item_metadata($lobbies.get_item_count() - 1, { "id": id })
|
||||||
|
|
||||||
|
func _lobby_delete(id):
|
||||||
|
for i in range($lobbies.get_item_count()):
|
||||||
|
if id == $lobbies.get_item_metadata(i)["id"]:
|
||||||
|
$lobbies.remove_item(i)
|
||||||
|
return
|
||||||
|
|
|
@ -11,30 +11,47 @@ __meta__ = {
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="back" type="Button" parent="."]
|
[node name="back" type="Button" parent="."]
|
||||||
margin_left = 27.0
|
margin_left = 565.0
|
||||||
margin_top = 357.0
|
margin_top = 214.0
|
||||||
margin_right = 286.0
|
margin_right = 824.0
|
||||||
margin_bottom = 432.0
|
margin_bottom = 289.0
|
||||||
text = "Back"
|
text = "Back"
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="create_lobby" type="Button" parent="."]
|
[node name="create_lobby" type="Button" parent="."]
|
||||||
margin_right = 259.0
|
margin_left = 12.0
|
||||||
margin_bottom = 75.0
|
margin_top = 11.0
|
||||||
|
margin_right = 550.0
|
||||||
|
margin_bottom = 86.0
|
||||||
text = "Create Lobby"
|
text = "Create Lobby"
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="lobbies" type="Label" parent="."]
|
[node name="join" type="Button" parent="."]
|
||||||
margin_left = 25.0
|
margin_left = 10.0
|
||||||
margin_top = 91.0
|
margin_top = 414.0
|
||||||
margin_right = 591.0
|
margin_right = 548.0
|
||||||
margin_bottom = 325.0
|
margin_bottom = 489.0
|
||||||
|
text = "Join"
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="lobbies" type="ItemList" parent="."]
|
||||||
|
anchor_right = 0.121
|
||||||
|
anchor_bottom = 0.217
|
||||||
|
margin_left = 18.0
|
||||||
|
margin_top = 105.0
|
||||||
|
margin_right = 416.096
|
||||||
|
margin_bottom = 267.8
|
||||||
|
same_column_width = true
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[connection signal="pressed" from="back" to="." method="_on_back_pressed"]
|
[connection signal="pressed" from="back" to="." method="_on_back_pressed"]
|
||||||
|
[connection signal="pressed" from="create_lobby" to="." method="_on_create_lobby_pressed"]
|
||||||
|
[connection signal="pressed" from="join" to="." method="_on_join_pressed"]
|
||||||
|
|
|
@ -12,7 +12,7 @@ var webrtc_ice_servers = [
|
||||||
const SignallerClient = preload("signaller_client.gd")
|
const SignallerClient = preload("signaller_client.gd")
|
||||||
|
|
||||||
onready var mp = WebRTCMultiplayer.new()
|
onready var mp = WebRTCMultiplayer.new()
|
||||||
onready var sc = SignallerClient.new()
|
onready var signaller = SignallerClient.new()
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
# connect("connected", self, "connected")
|
# connect("connected", self, "connected")
|
||||||
|
@ -26,15 +26,15 @@ func _ready():
|
||||||
# connect("lobby_sealed", self, "lobby_sealed")
|
# connect("lobby_sealed", self, "lobby_sealed")
|
||||||
# connect("peer_connected", self, "peer_connected")
|
# connect("peer_connected", self, "peer_connected")
|
||||||
# connect("peer_disconnected", self, "peer_disconnected")
|
# connect("peer_disconnected", self, "peer_disconnected")
|
||||||
add_child(sc)
|
add_child(signaller)
|
||||||
|
|
||||||
func close():
|
func close():
|
||||||
mp.close()
|
mp.close()
|
||||||
sc.close()
|
signaller.close()
|
||||||
|
|
||||||
func connect_to_signaller():
|
func connect_to_signaller():
|
||||||
close()
|
close()
|
||||||
sc.connect_to_websocket_signaller(multiplayer_url)
|
signaller.connect_to_websocket_signaller(multiplayer_url)
|
||||||
|
|
||||||
func _create_peer(id):
|
func _create_peer(id):
|
||||||
var peer: WebRTCPeerConnection = WebRTCPeerConnection.new()
|
var peer: WebRTCPeerConnection = WebRTCPeerConnection.new()
|
||||||
|
|
266
server.ts
266
server.ts
|
@ -1,67 +1,241 @@
|
||||||
const PORT = parseInt(Deno.env.get("PORT") || "80");
|
import { randomInt } from "./deps.ts";
|
||||||
|
|
||||||
const randomInt = (low: number, high: number) =>
|
|
||||||
Math.floor(Math.random() * (high - low + 1) + low);
|
|
||||||
|
|
||||||
const randomSecret = () => new Array(8).map(() => randomInt(0, 10)).join("");
|
|
||||||
|
|
||||||
interface Client {
|
|
||||||
socket: WebSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const SERVER_VERSION = "0.1.0";
|
||||||
// TODO: version comparison
|
// TODO: version comparison
|
||||||
|
|
||||||
interface Lobby {
|
type ID = string;
|
||||||
name: string;
|
|
||||||
clients: Client[];
|
// app state
|
||||||
// TODO: private vs public lobbies?
|
const allLobbies = new Map<ID, Lobby>();
|
||||||
|
const allClients = new Map<ID, Client>();
|
||||||
|
|
||||||
|
interface DataMessage {
|
||||||
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lobbies = new Set<Lobby>();
|
type ServerData = Record<string, string | number | symbol> | string;
|
||||||
const clients = new Set<Client>();
|
type Message = string | DataMessage;
|
||||||
|
|
||||||
|
const broadcast = (message: Message) =>
|
||||||
|
allClients.forEach((client) => client.send(message));
|
||||||
|
|
||||||
|
const buildMessage = (
|
||||||
|
type: string,
|
||||||
|
data: ServerData | ServerData[],
|
||||||
|
) =>
|
||||||
|
Object.assign(
|
||||||
|
{ type },
|
||||||
|
Array.isArray(data)
|
||||||
|
? { data }
|
||||||
|
: (typeof data === "object" ? data : { data }),
|
||||||
|
);
|
||||||
|
|
||||||
|
class Client {
|
||||||
|
id: ID;
|
||||||
|
name: string;
|
||||||
|
socket: WebSocket;
|
||||||
|
lobby: Lobby | null;
|
||||||
|
|
||||||
|
constructor(socket: WebSocket) {
|
||||||
|
this.id = crypto.randomUUID();
|
||||||
|
this.socket = socket;
|
||||||
|
this.name = "Client";
|
||||||
|
this.lobby = null;
|
||||||
|
|
||||||
|
this.send(buildMessage("your-id", this.id));
|
||||||
|
|
||||||
|
console.log(this);
|
||||||
|
allClients.set(this.id, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
isConnected() {
|
||||||
|
return this.socket.readyState == WebSocket.OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
this.lobbyLeave();
|
||||||
|
if (this.isConnected()) {
|
||||||
|
this.socket.close();
|
||||||
|
}
|
||||||
|
allClients.delete(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
send(message: Message) {
|
||||||
|
try {
|
||||||
|
this.socket.send(
|
||||||
|
typeof message === "object"
|
||||||
|
? ("json:" + JSON.stringify(message))
|
||||||
|
: message,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(
|
||||||
|
`Failed to send on socket ${this.socket} to client ${this.id}. Disconnecting and removing...`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clientList() {
|
||||||
|
if (!this.lobby) return;
|
||||||
|
const netClients: { id: ID; name: string }[] = [];
|
||||||
|
this.lobby.clients.forEach(({ id, name }) => netClients.push({ id, name }));
|
||||||
|
// TODO: chunk async?
|
||||||
|
this.send(buildMessage("peer_list", netClients));
|
||||||
|
}
|
||||||
|
|
||||||
|
lobbyList() {
|
||||||
|
const netLobbies: { id: ID; name: string }[] = [];
|
||||||
|
allLobbies.forEach(({ id, name }) => netLobbies.push({ id, name }));
|
||||||
|
// TODO: chunk async?
|
||||||
|
this.send(buildMessage("lobby_list", netLobbies));
|
||||||
|
}
|
||||||
|
|
||||||
|
lobbyNew({ id, name }: Lobby) {
|
||||||
|
// if the client is already in a lobby, we don't care about new lobbies
|
||||||
|
if (this.lobby) return;
|
||||||
|
this.send(buildMessage("lobby_new", { id, name }));
|
||||||
|
}
|
||||||
|
|
||||||
|
lobbyDelete({ id }: Lobby) {
|
||||||
|
if (this.lobby) return;
|
||||||
|
this.send(buildMessage("lobby_delete", { id }));
|
||||||
|
}
|
||||||
|
|
||||||
|
lobbyCreate() {
|
||||||
|
if (this.lobby) {
|
||||||
|
this.send(
|
||||||
|
`[info] cannot create lobby (already in lobby ${this.lobby.id})`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new Lobby(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
lobbyJoin(lobby: Lobby) {
|
||||||
|
if (this.lobby) {
|
||||||
|
this.send(`[info] cannot join lobby (already in lobby ${this.lobby.id})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.lobby = lobby;
|
||||||
|
this.send(buildMessage("lobby_joined", { id: lobby.id }));
|
||||||
|
lobby.addClient(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
lobbyLeave() {
|
||||||
|
const leavingLobby = this.lobby;
|
||||||
|
if (!leavingLobby) {
|
||||||
|
this.send(`[info] cannot leave lobby (not in a lobby)`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.lobby = null;
|
||||||
|
if (this.isConnected()) {
|
||||||
|
this.send(buildMessage("lobby_left", { id: leavingLobby.id }));
|
||||||
|
}
|
||||||
|
leavingLobby.removeClient(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Lobby {
|
||||||
|
id: ID;
|
||||||
|
name: string;
|
||||||
|
clients: Map<ID, Client>;
|
||||||
|
hostClientId: ID;
|
||||||
|
|
||||||
|
constructor(host: Client, name?: string) {
|
||||||
|
this.id = crypto.randomUUID();
|
||||||
|
this.hostClientId = host.id;
|
||||||
|
this.clients = new Map<ID, Client>();
|
||||||
|
this.name = name || this.id;
|
||||||
|
|
||||||
|
allLobbies.set(this.id, this);
|
||||||
|
host.lobbyJoin(this);
|
||||||
|
allClients.forEach((client) => client.lobbyNew(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
allClients.forEach((client) => client.lobbyDelete(this));
|
||||||
|
this.clients.forEach((client) => {
|
||||||
|
client.lobbyLeave();
|
||||||
|
});
|
||||||
|
allLobbies.delete(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcast(message: Message) {
|
||||||
|
this.clients.forEach((client) => client.send(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
addClient(client: Client) {
|
||||||
|
this.clients.set(client.id, client);
|
||||||
|
this.broadcast(
|
||||||
|
buildMessage("peer_joined", { id: client.id, name: client.name }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeClient({ id }: Client) {
|
||||||
|
this.clients.delete(id);
|
||||||
|
this.broadcast(buildMessage("peer_left", { id }));
|
||||||
|
if (id === this.hostClientId) {
|
||||||
|
console.warn("Host left!");
|
||||||
|
this.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// events
|
||||||
|
function onMessage(client: Client, ev: MessageEvent) {
|
||||||
|
// TODO: log who from?
|
||||||
|
console.log("Client Message Received", ev.data);
|
||||||
|
if (ev.data === "lobby_create") client.lobbyCreate();
|
||||||
|
if (ev.data === "lobby_leave") client.lobbyLeave();
|
||||||
|
if (ev.data === "request_lobby_list") client.lobbyList();
|
||||||
|
if (ev.data === "request_peer_list") client.clientList();
|
||||||
|
if (ev.data.startsWith("lobby_join:")) {
|
||||||
|
const id = ev.data.substr(11);
|
||||||
|
const lobby = allLobbies.get(id);
|
||||||
|
if (lobby) client.lobbyJoin(lobby);
|
||||||
|
else client.send(`[info] could not find lobby ${id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSocketOpen(_client: Client, _ev: Event) {
|
||||||
|
console.log("New Client");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClientLeave(client: Client) {
|
||||||
|
client.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSocketClose(client: Client, _ev: Event) {
|
||||||
|
console.log("Client Close");
|
||||||
|
onClientLeave(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSocketError(client: Client, _ev: Event) {
|
||||||
|
console.log("Client Error");
|
||||||
|
onClientLeave(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PORT = parseInt(Deno.env.get("PORT") || "80");
|
||||||
console.log("Listening on port", PORT);
|
console.log("Listening on port", PORT);
|
||||||
const listener = Deno.listen({ port: PORT });
|
const listener = Deno.listen({ port: PORT });
|
||||||
for await (const conn of listener) {
|
for await (const conn of listener) {
|
||||||
console.debug("Connection received:", conn);
|
// console.debug("Connection received:", conn);
|
||||||
(async () => {
|
(async () => {
|
||||||
const server = Deno.serveHttp(conn);
|
const server = Deno.serveHttp(conn);
|
||||||
for await (const { respondWith, request } of server) {
|
for await (const { respondWith, request } of server) {
|
||||||
console.debug("HTTP Request Received", request);
|
// console.debug("HTTP Request Received", request);
|
||||||
try {
|
try {
|
||||||
|
console.warn(JSON.stringify([allClients, allLobbies]));
|
||||||
const { socket, response } = Deno.upgradeWebSocket(request);
|
const { socket, response } = Deno.upgradeWebSocket(request);
|
||||||
const client: Client = { socket };
|
const client = new Client(socket);
|
||||||
socket.onmessage = (ev) => {
|
socket.onmessage = (ev) => onMessage(client, ev);
|
||||||
console.log("Client Message Received", ev);
|
socket.onopen = (ev) => onSocketOpen(client, ev);
|
||||||
};
|
socket.onclose = (ev) => onSocketClose(client, ev);
|
||||||
socket.onopen = (ev) => {
|
socket.onerror = (ev) => onSocketError(client, ev);
|
||||||
console.log("New Client:", ev);
|
|
||||||
if (!clients.has(client)) clients.add(client);
|
|
||||||
socket.send("lobbies_start");
|
|
||||||
lobbies.forEach(({ name, clients }) => {
|
|
||||||
socket.send(JSON.stringify({ name, numClients: clients.length }));
|
|
||||||
});
|
|
||||||
socket.send("lobbies_end");
|
|
||||||
};
|
|
||||||
socket.onclose = (ev) => {
|
|
||||||
console.log("Client Socket Close:", ev);
|
|
||||||
if (clients.has(client)) clients.delete(client);
|
|
||||||
};
|
|
||||||
socket.onerror = (ev) => {
|
|
||||||
console.log("Client Socket Error:", ev);
|
|
||||||
if (clients.has(client)) clients.delete(client);
|
|
||||||
};
|
|
||||||
respondWith(response);
|
respondWith(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
let body = "400 Bad Request";
|
|
||||||
if (e instanceof TypeError) {
|
|
||||||
body += " - Expected to be able to upgrade to WebSocket connection";
|
|
||||||
console.log("Could not add client:", e);
|
|
||||||
} else {
|
|
||||||
console.log("Could not add client for unhandled reason:", e);
|
console.log("Could not add client for unhandled reason:", e);
|
||||||
}
|
|
||||||
respondWith(
|
respondWith(
|
||||||
new Response(body, {
|
new Response("400 Bad Request", {
|
||||||
status: 400,
|
status: 400,
|
||||||
headers: { "content-type": "text/html" },
|
headers: { "content-type": "text/html" },
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -6,8 +6,19 @@ in order to enable establishish WebRTC P2P connections. Another module is
|
||||||
expected to fully setup the peer connections.
|
expected to fully setup the peer connections.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
signal lobby_new(lobbiesList)
|
||||||
|
signal lobby_delete(id)
|
||||||
|
signal lobby_joined(id)
|
||||||
|
signal lobby_left(id)
|
||||||
|
signal peer_joined(id)
|
||||||
|
signal peer_left(id)
|
||||||
|
signal websocket_connected
|
||||||
|
signal websocket_disconnected
|
||||||
|
|
||||||
onready var ws: WebSocketClient = WebSocketClient.new()
|
onready var ws: WebSocketClient = WebSocketClient.new()
|
||||||
|
|
||||||
|
onready var lobby_id = null
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var _result = ws.connect("data_received", self, "_parse_msg")
|
var _result = ws.connect("data_received", self, "_parse_msg")
|
||||||
_result = ws.connect("connection_established", self, "_connected")
|
_result = ws.connect("connection_established", self, "_connected")
|
||||||
|
@ -25,8 +36,7 @@ func connect_to_websocket_signaller(url: String):
|
||||||
var _result = ws.connect_to_url(url)
|
var _result = ws.connect_to_url(url)
|
||||||
|
|
||||||
func _closed():
|
func _closed():
|
||||||
# emit_signal("disconnected")
|
emit_signal("websocket_disconnected")
|
||||||
pass
|
|
||||||
|
|
||||||
func _close_request(code: int, reason: String):
|
func _close_request(code: int, reason: String):
|
||||||
print("Received WebSocket close request from signalling server ", code, reason)
|
print("Received WebSocket close request from signalling server ", code, reason)
|
||||||
|
@ -34,38 +44,53 @@ func _close_request(code: int, reason: String):
|
||||||
func _connected(protocol = ""):
|
func _connected(protocol = ""):
|
||||||
print("WebSocket signaller connected via protocol ", protocol)
|
print("WebSocket signaller connected via protocol ", protocol)
|
||||||
ws.get_peer(1).set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)
|
ws.get_peer(1).set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)
|
||||||
|
emit_signal("websocket_connected")
|
||||||
|
|
||||||
func _process(_delta: float):
|
func _process(_delta: float):
|
||||||
var status: int = ws.get_connection_status()
|
var status: int = ws.get_connection_status()
|
||||||
if status == WebSocketClient.CONNECTION_CONNECTING or status == WebSocketClient.CONNECTION_CONNECTED:
|
if status == WebSocketClient.CONNECTION_CONNECTING or status == WebSocketClient.CONNECTION_CONNECTED:
|
||||||
ws.poll()
|
ws.poll()
|
||||||
|
|
||||||
|
func join_lobby(id: String):
|
||||||
|
return _send("lobby_join:%s" % id)
|
||||||
|
|
||||||
|
func create_lobby():
|
||||||
|
return _send("lobby_create")
|
||||||
|
|
||||||
|
func request_lobby_list():
|
||||||
|
return _send("request_lobby_list")
|
||||||
|
|
||||||
|
func request_peer_list():
|
||||||
|
return _send("request_peer_list")
|
||||||
|
|
||||||
|
func _send(s: String):
|
||||||
|
return ws.get_peer(1).put_packet(s.to_utf8())
|
||||||
|
|
||||||
func _parse_msg():
|
func _parse_msg():
|
||||||
var pkt_str: String = ws.get_peer(1).get_packet().get_string_from_utf8()
|
var msg: String = ws.get_peer(1).get_packet().get_string_from_utf8()
|
||||||
print("Signaller sent: ", pkt_str)
|
print("Signaller sent: ", msg)
|
||||||
|
if msg.begins_with("json:"):
|
||||||
|
var data = JSON.parse(msg.substr(5))
|
||||||
|
if data.error == OK:
|
||||||
|
handle_message(data.result)
|
||||||
|
else:
|
||||||
|
print("Unhandled Message: ", msg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func handle_message(data: Dictionary):
|
||||||
|
match data["type"]:
|
||||||
|
"lobby_new": emit_signal("lobby_new", [{"id": data["id"], "name": data["name"]}])
|
||||||
|
"lobby_delete": emit_signal("lobby_delete", data["id"])
|
||||||
|
"lobby_joined":
|
||||||
|
lobby_id = data["id"]
|
||||||
|
emit_signal("lobby_joined", data["id"])
|
||||||
|
"lobby_left":
|
||||||
|
lobby_id = null
|
||||||
|
emit_signal("lobby_left", data["id"])
|
||||||
|
"lobby_list": emit_signal("lobby_new", data["data"])
|
||||||
|
"peer_list": emit_signal("peer_joined", data["data"])
|
||||||
|
"peer_joined": emit_signal("peer_joined", [{"id": data["id"], "name": data["name"]}])
|
||||||
|
"peer_left": emit_signal("peer_left", data["id"])
|
||||||
|
_: print("Unhandled Data Message: ", JSON.print(data))
|
||||||
|
|
||||||
"""
|
"""
|
||||||
func _parse_msg():
|
func _parse_msg():
|
||||||
|
|
Loading…
Reference in a new issue