mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-04 23:10:08 +01:00
This leads to code that is easier to understand and runs faster thanks to GDScript's typed instructions. The untyped declaration warning is now enabled on all projects where type hints were added. All projects currently run without any untyped declration warnings. Dodge the Creeps and Squash the Creeps demos intentionally don't use type hints to match the documentation, where type hints haven't been adopted yet (given its beginner focus).
131 lines
3.3 KiB
GDScript
131 lines
3.3 KiB
GDScript
extends Node
|
|
|
|
enum Message {
|
|
JOIN,
|
|
ID,
|
|
PEER_CONNECT,
|
|
PEER_DISCONNECT,
|
|
OFFER,
|
|
ANSWER,
|
|
CANDIDATE,
|
|
SEAL,
|
|
}
|
|
|
|
@export var autojoin := true
|
|
@export var lobby := "" # Will create a new lobby if empty.
|
|
@export var mesh := true # Will use the lobby host as relay otherwise.
|
|
|
|
var ws := WebSocketPeer.new()
|
|
var code := 1000
|
|
var reason := "Unknown"
|
|
var old_state := WebSocketPeer.STATE_CLOSED
|
|
|
|
signal lobby_joined(lobby: String)
|
|
signal connected(id: int, use_mesh: bool)
|
|
signal disconnected()
|
|
signal peer_connected(id: int)
|
|
signal peer_disconnected(id: int)
|
|
signal offer_received(id: int, offer: int)
|
|
signal answer_received(id: int, answer: int)
|
|
signal candidate_received(id: int, mid: String, index: int, sdp: String)
|
|
signal lobby_sealed()
|
|
|
|
|
|
func connect_to_url(url: String) -> void:
|
|
close()
|
|
code = 1000
|
|
reason = "Unknown"
|
|
ws.connect_to_url(url)
|
|
|
|
|
|
func close() -> void:
|
|
ws.close()
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
ws.poll()
|
|
var state := ws.get_ready_state()
|
|
if state != old_state and state == WebSocketPeer.STATE_OPEN and autojoin:
|
|
join_lobby(lobby)
|
|
while state == WebSocketPeer.STATE_OPEN and ws.get_available_packet_count():
|
|
if not _parse_msg():
|
|
print("Error parsing message from server.")
|
|
if state != old_state and state == WebSocketPeer.STATE_CLOSED:
|
|
code = ws.get_close_code()
|
|
reason = ws.get_close_reason()
|
|
disconnected.emit()
|
|
old_state = state
|
|
|
|
|
|
func _parse_msg() -> bool:
|
|
var parsed: Dictionary = JSON.parse_string(ws.get_packet().get_string_from_utf8())
|
|
if typeof(parsed) != TYPE_DICTIONARY or not parsed.has("type") or not parsed.has("id") or \
|
|
typeof(parsed.get("data")) != TYPE_STRING:
|
|
return false
|
|
|
|
var msg := parsed as Dictionary
|
|
if not str(msg.type).is_valid_int() or not str(msg.id).is_valid_int():
|
|
return false
|
|
|
|
var type := str(msg.type).to_int()
|
|
var src_id := str(msg.id).to_int()
|
|
|
|
if type == Message.ID:
|
|
connected.emit(src_id, msg.data == "true")
|
|
elif type == Message.JOIN:
|
|
lobby_joined.emit(msg.data)
|
|
elif type == Message.SEAL:
|
|
lobby_sealed.emit()
|
|
elif type == Message.PEER_CONNECT:
|
|
# Client connected.
|
|
peer_connected.emit(src_id)
|
|
elif type == Message.PEER_DISCONNECT:
|
|
# Client connected.
|
|
peer_disconnected.emit(src_id)
|
|
elif type == Message.OFFER:
|
|
# Offer received.
|
|
offer_received.emit(src_id, msg.data)
|
|
elif type == Message.ANSWER:
|
|
# Answer received.
|
|
answer_received.emit(src_id, msg.data)
|
|
elif type == Message.CANDIDATE:
|
|
# Candidate received.
|
|
var candidate: PackedStringArray = msg.data.split("\n", false)
|
|
if candidate.size() != 3:
|
|
return false
|
|
if not candidate[1].is_valid_int():
|
|
return false
|
|
candidate_received.emit(src_id, candidate[0], candidate[1].to_int(), candidate[2])
|
|
else:
|
|
return false
|
|
|
|
return true # Parsed.
|
|
|
|
|
|
func join_lobby(lobby: String) -> Error:
|
|
return _send_msg(Message.JOIN, 0 if mesh else 1, lobby)
|
|
|
|
|
|
func seal_lobby() -> Error:
|
|
return _send_msg(Message.SEAL, 0)
|
|
|
|
|
|
func send_candidate(id: int, mid: String, index: int, sdp: String) -> Error:
|
|
return _send_msg(Message.CANDIDATE, id, "\n%s\n%d\n%s" % [mid, index, sdp])
|
|
|
|
|
|
func send_offer(id: int, offer: String) -> Error:
|
|
return _send_msg(Message.OFFER, id, offer)
|
|
|
|
|
|
func send_answer(id: int, answer: String) -> Error:
|
|
return _send_msg(Message.ANSWER, id, answer)
|
|
|
|
|
|
func _send_msg(type: int, id: int, data: String = "") -> Error:
|
|
return ws.send_text(JSON.stringify({
|
|
"type": type,
|
|
"id": id,
|
|
"data": data,
|
|
}))
|