wth is happening
This commit is contained in:
parent
724a351d96
commit
9c5b376852
6 changed files with 147 additions and 122 deletions
|
@ -5,7 +5,9 @@ const MultiplayerClient = preload("multiplayer_client.gd")
|
|||
onready var client = MultiplayerClient.new()
|
||||
|
||||
func _ready():
|
||||
# client.signaller.connect("websocket_connected", self, "signaller_disconnected")
|
||||
add_child(client)
|
||||
client.signaller.connect("websocket_connected", self, "_signaller_connected")
|
||||
|
||||
func goto_scene(scene_resource_name):
|
||||
var _result = get_tree().change_scene("res://%s.tscn" % scene_resource_name)
|
||||
|
@ -18,9 +20,12 @@ func start_singleplayer_game():
|
|||
client.close()
|
||||
goto_scene("game")
|
||||
|
||||
func _signaller_connected():
|
||||
goto_scene("multiplayer")
|
||||
|
||||
func lobby_browser():
|
||||
client.close()
|
||||
goto_scene("multiplayer")
|
||||
Global.client.connect_to_signaller()
|
||||
|
||||
func lobby():
|
||||
goto_scene("lobby")
|
||||
|
|
6
lobby.gd
6
lobby.gd
|
@ -7,8 +7,12 @@ func _ready():
|
|||
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.connect("websocket_disconnected", self, "_signaller_disconnected")
|
||||
Global.client.signaller.request_peer_list()
|
||||
|
||||
func _signaller_disconnected():
|
||||
Global.main_menu()
|
||||
|
||||
func _draw():
|
||||
pass
|
||||
|
||||
|
@ -19,7 +23,7 @@ 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)
|
||||
print("New Lobby Peer ", id, name)
|
||||
peers.add_item("%s" % name)
|
||||
peers.set_item_metadata(peers.get_item_count() - 1, { "id": id })
|
||||
|
||||
|
|
|
@ -9,18 +9,18 @@ func _ready():
|
|||
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.signaller.connect("websocket_disconnected", self, "_signaller_disconnected")
|
||||
Global.client.signaller.request_lobby_list()
|
||||
|
||||
func _lobby_joined(id):
|
||||
func _signaller_disconnected():
|
||||
Global.main_menu()
|
||||
|
||||
func _lobby_joined(_id, _peerId):
|
||||
Global.lobby()
|
||||
|
||||
func _lobby_left(_id):
|
||||
Global.lobby_browser()
|
||||
|
||||
func _signaller_connected():
|
||||
Global.client.signaller.request_lobby_list()
|
||||
|
||||
func _on_back_pressed():
|
||||
Global.main_menu()
|
||||
|
||||
|
|
|
@ -15,16 +15,16 @@ onready var mp = WebRTCMultiplayer.new()
|
|||
onready var signaller = SignallerClient.new()
|
||||
|
||||
func _ready():
|
||||
# connect("connected", self, "connected")
|
||||
# connect("disconnected", self, "disconnected")
|
||||
# signaller.connect("websocket_connected", self, "connected")
|
||||
# signaller.connect("websocket_disconnected", self, "disconnected")
|
||||
|
||||
# connect("offer_received", self, "offer_received")
|
||||
# connect("answer_received", self, "answer_received")
|
||||
# connect("candidate_received", self, "candidate_received")
|
||||
signaller.connect("offer_received", self, "offer_received")
|
||||
signaller.connect("answer_received", self, "answer_received")
|
||||
signaller.connect("candidate_received", self, "candidate_received")
|
||||
|
||||
# connect("lobby_joined", self, "lobby_joined")
|
||||
signaller.connect("lobby_joined", self, "_lobby_joined")
|
||||
# connect("lobby_sealed", self, "lobby_sealed")
|
||||
# connect("peer_connected", self, "peer_connected")
|
||||
signaller.connect("peer_joined", self, "_peer_joined")
|
||||
# connect("peer_disconnected", self, "peer_disconnected")
|
||||
add_child(signaller)
|
||||
|
||||
|
@ -36,26 +36,30 @@ func connect_to_signaller():
|
|||
close()
|
||||
signaller.connect_to_websocket_signaller(multiplayer_url)
|
||||
|
||||
func _create_peer(id):
|
||||
func _create_peer(peer_id):
|
||||
var peer: WebRTCPeerConnection = WebRTCPeerConnection.new()
|
||||
peer.initialize({"iceServers": webrtc_ice_servers})
|
||||
peer.connect("session_description_created", self, "_offer_created", [id])
|
||||
peer.connect("ice_candidate_created", self, "_new_ice_candidate", [id])
|
||||
mp.add_peer(peer, id)
|
||||
if id > mp.get_unique_id():
|
||||
# TODO: peer.create_offer()
|
||||
pass
|
||||
print("New Net Peer %s with peer_id %d" % [peer, peer_id])
|
||||
var _peer_init_results = peer.initialize({"iceServers": webrtc_ice_servers})
|
||||
peer.connect("session_description_created", self, "_offer_created", [peer_id])
|
||||
peer.connect("ice_candidate_created", self, "_new_ice_candidate", [peer_id])
|
||||
mp.add_peer(peer, peer_id)
|
||||
var uid = mp.get_unique_id()
|
||||
if peer_id > uid:
|
||||
var offer_result = peer.create_offer()
|
||||
print("Create Offer Result: ", offer_result)
|
||||
else:
|
||||
print("Did not create offer: %d <= %d" % [peer_id, uid])
|
||||
return peer
|
||||
|
||||
func _new_ice_candidate(mid_name, index_name, sdp_name, id):
|
||||
print("New ICE Candidate: ", mid_name, index_name, sdp_name, id)
|
||||
# TODO: send_candidate(id, mid_name, index_name, sdp_name)
|
||||
func _new_ice_candidate(mid_name, index_name, sdp_name, peer_id):
|
||||
print("New ICE Candidate: ", mid_name, index_name, sdp_name, peer_id)
|
||||
signaller.send_candidate(peer_id, mid_name, index_name, sdp_name)
|
||||
|
||||
func _offer_created(type, data, id):
|
||||
if not mp.has_peer(id):
|
||||
func _offer_created(type, data, peer_id):
|
||||
print("Offer Created", type, data, peer_id)
|
||||
if not mp.has_peer(peer_id):
|
||||
return
|
||||
print("created", type)
|
||||
mp.get_peer(id).connection.set_local_description(type, data)
|
||||
mp.get_peer(peer_id).connection.set_local_description(type, data)
|
||||
if type == "offer":
|
||||
# TODO: send_offer(id, data)
|
||||
pass
|
||||
|
@ -63,28 +67,35 @@ func _offer_created(type, data, id):
|
|||
# TODO: send_answer(id, data)
|
||||
pass
|
||||
|
||||
func connected(id):
|
||||
print("Connected %d" % id)
|
||||
mp.initialize(id, true)
|
||||
func _lobby_joined(id, peer_id):
|
||||
print("Connected to lobby %s as peer %d" % [id, peer_id])
|
||||
mp.initialize(peer_id, true)
|
||||
|
||||
func peer_connected(id):
|
||||
print("Peer connected %d" % id)
|
||||
_create_peer(id)
|
||||
func _peer_joined(peers):
|
||||
for i in range(len(peers)):
|
||||
var peer_id = peers[i]["peerId"]
|
||||
if not mp.has_peer(peer_id):
|
||||
_create_peer(peer_id)
|
||||
|
||||
func peer_disconnected(id):
|
||||
print("Peer disconnected ", id)
|
||||
if mp.has_peer(id):
|
||||
mp.remove_peer(id)
|
||||
|
||||
func offer_received(id, offer):
|
||||
print("Got offer: %d" % id)
|
||||
func offer_received(data):
|
||||
print("Got offer: ", data)
|
||||
var id = data["peerId"]
|
||||
if mp.has_peer(id):
|
||||
mp.get_peer(id).connection.set_remote_description("offer", offer)
|
||||
mp.get_peer(id).connection.set_remote_description("offer", data["offer"])
|
||||
|
||||
func answer_received(id, answer):
|
||||
print("Got answer: %d" % id)
|
||||
func answer_received(data):
|
||||
print("Got answer: ", data)
|
||||
var id = data["peerId"]
|
||||
if mp.has_peer(id):
|
||||
mp.get_peer(id).connection.set_remote_description("answer", answer)
|
||||
mp.get_peer(id).connection.set_remote_description("answer", data["offer"])
|
||||
|
||||
func candidate_received(id, mid, index, sdp):
|
||||
func candidate_received(data):
|
||||
print("Candidate Received: ", data)
|
||||
var id = data["peerId"]
|
||||
if mp.has_peer(id):
|
||||
mp.get_peer(id).connection.add_ice_candidate(mid, index, sdp)
|
||||
mp.get_peer(id).connection.add_ice_candidate(data["mid"], data["index"], data["sdp"])
|
||||
|
|
54
server.ts
54
server.ts
|
@ -13,7 +13,8 @@ interface DataMessage {
|
|||
type: string;
|
||||
}
|
||||
|
||||
type ServerData = Record<string, string | number | symbol> | string;
|
||||
type ServerDataObject = Record<string, string | number | symbol | null>;
|
||||
type ServerData = ServerDataObject | string;
|
||||
type Message = string | DataMessage;
|
||||
|
||||
const broadcast = (message: Message) =>
|
||||
|
@ -32,6 +33,7 @@ const buildMessage = (
|
|||
|
||||
class Client {
|
||||
id: ID;
|
||||
peerId: number | null;
|
||||
name: string;
|
||||
socket: WebSocket;
|
||||
lobby: Lobby | null;
|
||||
|
@ -39,11 +41,10 @@ class Client {
|
|||
constructor(socket: WebSocket) {
|
||||
this.id = crypto.randomUUID();
|
||||
this.socket = socket;
|
||||
this.peerId = null;
|
||||
this.name = "Client";
|
||||
this.lobby = null;
|
||||
|
||||
this.send(buildMessage("your-id", this.id));
|
||||
|
||||
console.log(this);
|
||||
allClients.set(this.id, this);
|
||||
}
|
||||
|
@ -78,8 +79,10 @@ class Client {
|
|||
|
||||
clientList() {
|
||||
if (!this.lobby) return;
|
||||
const netClients: { id: ID; name: string }[] = [];
|
||||
this.lobby.clients.forEach(({ id, name }) => netClients.push({ id, name }));
|
||||
const netClients: { id: ID; name: string; peerId: number | null }[] = [];
|
||||
this.lobby.clients.forEach(({ id, name, peerId }) =>
|
||||
netClients.push({ id, name, peerId })
|
||||
);
|
||||
// TODO: chunk async?
|
||||
this.send(buildMessage("peer_list", netClients));
|
||||
}
|
||||
|
@ -118,8 +121,10 @@ class Client {
|
|||
return;
|
||||
}
|
||||
this.lobby = lobby;
|
||||
this.send(buildMessage("lobby_joined", { id: lobby.id }));
|
||||
lobby.addClient(this);
|
||||
this.send(
|
||||
buildMessage("lobby_joined", { id: lobby.id, peerId: this.peerId }),
|
||||
);
|
||||
}
|
||||
|
||||
lobbyLeave() {
|
||||
|
@ -128,6 +133,7 @@ class Client {
|
|||
this.send(`[info] cannot leave lobby (not in a lobby)`);
|
||||
return;
|
||||
}
|
||||
this.peerId = null;
|
||||
this.lobby = null;
|
||||
if (this.isConnected()) {
|
||||
this.send(buildMessage("lobby_left", { id: leavingLobby.id }));
|
||||
|
@ -149,6 +155,7 @@ class Lobby {
|
|||
this.name = name || this.id;
|
||||
|
||||
allLobbies.set(this.id, this);
|
||||
host.peerId = 1;
|
||||
host.lobbyJoin(this);
|
||||
allClients.forEach((client) => client.lobbyNew(this));
|
||||
}
|
||||
|
@ -166,10 +173,19 @@ class Lobby {
|
|||
}
|
||||
|
||||
addClient(client: Client) {
|
||||
this.clients.set(client.id, client);
|
||||
if (!client.peerId) {
|
||||
const arr = new Int32Array(1);
|
||||
crypto.getRandomValues(arr);
|
||||
client.peerId = Math.abs(arr[0]);
|
||||
}
|
||||
this.broadcast(
|
||||
buildMessage("peer_joined", { id: client.id, name: client.name }),
|
||||
buildMessage("peer_joined", {
|
||||
id: client.id,
|
||||
name: client.name,
|
||||
peerId: client.peerId,
|
||||
}),
|
||||
);
|
||||
this.clients.set(client.id, client);
|
||||
}
|
||||
|
||||
removeClient({ id }: Client) {
|
||||
|
@ -182,10 +198,16 @@ class Lobby {
|
|||
}
|
||||
}
|
||||
|
||||
interface ClientMessage {
|
||||
type: "candidate" | "offer" | "answer";
|
||||
data: ServerDataObject;
|
||||
}
|
||||
|
||||
// events
|
||||
function onMessage(client: Client, ev: MessageEvent) {
|
||||
// TODO: log who from?
|
||||
console.log("Client Message Received", ev.data);
|
||||
if (ev.data === "init") client.send(buildMessage("your_id", client.id));
|
||||
if (ev.data === "lobby_create") client.lobbyCreate();
|
||||
if (ev.data === "lobby_leave") client.lobbyLeave();
|
||||
if (ev.data === "request_lobby_list") client.lobbyList();
|
||||
|
@ -196,6 +218,22 @@ function onMessage(client: Client, ev: MessageEvent) {
|
|||
if (lobby) client.lobbyJoin(lobby);
|
||||
else client.send(`[info] could not find lobby ${id}`);
|
||||
}
|
||||
if (ev.data.startsWith("json:")) {
|
||||
const data: ClientMessage = JSON.parse(ev.data.substr(5));
|
||||
if (data.type in ["candidate", "answer", "offer"]) {
|
||||
if (typeof data.data === "object") {
|
||||
const subdata = data.data;
|
||||
if (typeof subdata["peerId"] === "number") {
|
||||
const peerId: number = subdata["peerId"];
|
||||
const payload = Object.assign({}, data);
|
||||
payload.data.peerId = client.peerId;
|
||||
for (const client of allClients.values()) {
|
||||
client.send(ev.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onSocketOpen(_client: Client, _ev: Event) {
|
||||
|
|
|
@ -8,16 +8,21 @@ expected to fully setup the peer connections.
|
|||
|
||||
signal lobby_new(lobbiesList)
|
||||
signal lobby_delete(id)
|
||||
signal lobby_joined(id)
|
||||
signal lobby_joined(id, peer_id)
|
||||
signal lobby_left(id)
|
||||
signal peer_joined(id)
|
||||
signal peer_left(id)
|
||||
signal candidate_received(data)
|
||||
signal offer_received(data)
|
||||
signal answer_received(data)
|
||||
signal websocket_connected
|
||||
signal websocket_disconnected
|
||||
|
||||
onready var ws: WebSocketClient = WebSocketClient.new()
|
||||
|
||||
onready var client_id = null
|
||||
onready var lobby_id = null
|
||||
onready var peer_id = null
|
||||
|
||||
func _ready():
|
||||
var _result = ws.connect("data_received", self, "_parse_msg")
|
||||
|
@ -45,6 +50,7 @@ func _connected(protocol = ""):
|
|||
print("WebSocket signaller connected via protocol ", protocol)
|
||||
ws.get_peer(1).set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)
|
||||
emit_signal("websocket_connected")
|
||||
_send("init")
|
||||
|
||||
func _process(_delta: float):
|
||||
var status: int = ws.get_connection_status()
|
||||
|
@ -78,89 +84,50 @@ func _parse_msg():
|
|||
|
||||
func handle_message(data: Dictionary):
|
||||
match data["type"]:
|
||||
"your_id": client_id = data["data"]
|
||||
"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"])
|
||||
peer_id = data["peerId"]
|
||||
emit_signal("lobby_joined", data["id"], data["peerId"])
|
||||
"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_joined": emit_signal("peer_joined", [{"id": data["id"], "name": data["name"], "peerId": data["peerId"]}])
|
||||
"peer_left": emit_signal("peer_left", data["id"])
|
||||
"candidate":
|
||||
print("Candidate received ", data["data"])
|
||||
emit_signal("candidate_received", data["data"])
|
||||
"offer":
|
||||
print("Offer received ", data["data"])
|
||||
emit_signal("offer_received", data["data"])
|
||||
"answer":
|
||||
print("Answer received ", data["data"])
|
||||
emit_signal("answer_received", data["data"])
|
||||
_: print("Unhandled Data Message: ", JSON.print(data))
|
||||
|
||||
func send_candidate(peerId, mid, index, sdp) -> int:
|
||||
return _send("json:%s" % JSON.print({
|
||||
"type": "candidate",
|
||||
"data": {
|
||||
"peerId": peerId,
|
||||
"mid": mid,
|
||||
"index": index,
|
||||
"sdp": sdp
|
||||
}
|
||||
}))
|
||||
|
||||
func send_offer(peerId, offer) -> int:
|
||||
return _send("json:%s" % JSON.print({ "type": "offer", "data": {"peerId": peerId, "offer": offer }}))
|
||||
|
||||
func send_answer(peerId, answer) -> int:
|
||||
return _send("json:%s" % JSON.print({ "type": "answer", "data": {"peerId": peerId, "answer": answer }}))
|
||||
|
||||
"""
|
||||
func _parse_msg():
|
||||
var pkt_str: String = ws.get_peer(1).get_packet().get_string_from_utf8()
|
||||
|
||||
var req: PoolStringArray = pkt_str.split("\n", true, 1)
|
||||
if req.size() != 2: # Invalid request size
|
||||
return
|
||||
|
||||
var type: String = req[0]
|
||||
if type.length() < 3: # Invalid type size
|
||||
return
|
||||
|
||||
if type.begins_with("J: "):
|
||||
print("Emitting lobby_joined")
|
||||
emit_signal("lobby_joined", type.substr(3, type.length() - 3))
|
||||
return
|
||||
elif type.begins_with("S: "):
|
||||
emit_signal("lobby_sealed")
|
||||
return
|
||||
|
||||
var src_str: String = type.substr(3, type.length() - 3)
|
||||
if not src_str.is_valid_integer(): # Source id is not an integer
|
||||
return
|
||||
|
||||
var src_id: int = int(src_str)
|
||||
|
||||
if type.begins_with("I: "):
|
||||
print("Emitting connected")
|
||||
emit_signal("connected", src_id)
|
||||
elif type.begins_with("N: "):
|
||||
# Client connected
|
||||
print("Emitting peer_connected")
|
||||
emit_signal("peer_connected", src_id)
|
||||
elif type.begins_with("D: "):
|
||||
# Client connected
|
||||
emit_signal("peer_disconnected", src_id)
|
||||
elif type.begins_with("O: "):
|
||||
# Offer received
|
||||
print("Emitting offer_received")
|
||||
emit_signal("offer_received", src_id, req[1])
|
||||
elif type.begins_with("A: "):
|
||||
# Answer received
|
||||
print("Emitting answer_received")
|
||||
emit_signal("answer_received", src_id, req[1])
|
||||
elif type.begins_with("C: "):
|
||||
# Candidate received
|
||||
var candidate: PoolStringArray = req[1].split("\n", false)
|
||||
if candidate.size() != 3:
|
||||
return
|
||||
if not candidate[1].is_valid_integer():
|
||||
return
|
||||
print("Emitting candidate_received")
|
||||
emit_signal("candidate_received", src_id, candidate[0], int(candidate[1]), candidate[2])
|
||||
|
||||
func join_lobby(joined_lobby):
|
||||
return ws.get_peer(1).put_packet(("J: %s\n" % joined_lobby).to_utf8())
|
||||
|
||||
func seal_lobby():
|
||||
return ws.get_peer(1).put_packet("S: \n".to_utf8())
|
||||
|
||||
func send_candidate(id, mid, index, sdp) -> int:
|
||||
return _send_msg("C", id, "\n%s\n%d\n%s" % [mid, index, sdp])
|
||||
|
||||
func send_offer(id, offer) -> int:
|
||||
return _send_msg("O", id, offer)
|
||||
|
||||
func send_answer(id, answer) -> int:
|
||||
return _send_msg("A", id, answer)
|
||||
|
||||
func _send_msg(type, id, data) -> int:
|
||||
return ws.get_peer(1).put_packet(("%s: %d\n%s" % [type, id, data]).to_utf8())
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue