Cleanup
This commit is contained in:
parent
595cef84f1
commit
08eb9534a3
BIN
assets/img/check.png
Normal file
BIN
assets/img/check.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
35
assets/img/check.png.import
Normal file
35
assets/img/check.png.import
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="StreamTexture"
|
||||||
|
path="res://.import/check.png-77d9c6c18a6e8ab3e8f9b0823b5b1f3f.stex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/img/check.png"
|
||||||
|
dest_files=[ "res://.import/check.png-77d9c6c18a6e8ab3e8f9b0823b5b1f3f.stex" ]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_mode=0
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
flags/repeat=0
|
||||||
|
flags/filter=true
|
||||||
|
flags/mipmaps=false
|
||||||
|
flags/anisotropic=false
|
||||||
|
flags/srgb=2
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/HDR_as_SRGB=false
|
||||||
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
stream=false
|
||||||
|
size_limit=0
|
||||||
|
detect_3d=true
|
||||||
|
svg/scale=1.0
|
BIN
assets/img/cross.png
Normal file
BIN
assets/img/cross.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
35
assets/img/cross.png.import
Normal file
35
assets/img/cross.png.import
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="StreamTexture"
|
||||||
|
path="res://.import/cross.png-5021b7dd515961663820ff8784177d02.stex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/img/cross.png"
|
||||||
|
dest_files=[ "res://.import/cross.png-5021b7dd515961663820ff8784177d02.stex" ]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_mode=0
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
flags/repeat=0
|
||||||
|
flags/filter=true
|
||||||
|
flags/mipmaps=false
|
||||||
|
flags/anisotropic=false
|
||||||
|
flags/srgb=2
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/HDR_as_SRGB=false
|
||||||
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
stream=false
|
||||||
|
size_limit=0
|
||||||
|
detect_3d=true
|
||||||
|
svg/scale=1.0
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
@ -2,15 +2,15 @@
|
||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="StreamTexture"
|
type="StreamTexture"
|
||||||
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
|
path="res://.import/icon.png-859001d62588b6d9cb01a8eba79b6466.stex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://icon.png"
|
source_file="res://assets/img/icon.png"
|
||||||
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
|
dest_files=[ "res://.import/icon.png-859001d62588b6d9cb01a8eba79b6466.stex" ]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ process/fix_alpha_border=true
|
||||||
process/premult_alpha=false
|
process/premult_alpha=false
|
||||||
process/HDR_as_SRGB=false
|
process/HDR_as_SRGB=false
|
||||||
process/invert_color=false
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
stream=false
|
stream=false
|
||||||
size_limit=0
|
size_limit=0
|
||||||
detect_3d=true
|
detect_3d=true
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_resource type="Theme" load_steps=2 format=2]
|
[gd_resource type="Theme" load_steps=2 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://iosevkalyte.tres" type="DynamicFont" id=1]
|
[ext_resource path="res://assets/fonts/iosevkalyte/iosevkalyte.tres" type="DynamicFont" id=1]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
default_font = ExtResource( 1 )
|
default_font = ExtResource( 1 )
|
|
@ -11,12 +11,12 @@ config_version=4
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="kdt"
|
config/name="kdt"
|
||||||
run/main_scene="res://main.tscn"
|
run/main_scene="res://screens/main.tscn"
|
||||||
config/icon="res://icon.png"
|
config/icon="res://assets/img/icon.png"
|
||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
Global="*res://global.gd"
|
Global="*res://scripts/global.gd"
|
||||||
|
|
||||||
[gdnative]
|
[gdnative]
|
||||||
|
|
||||||
|
@ -36,4 +36,4 @@ quality/driver/driver_name="GLES2"
|
||||||
vram_compression/import_etc=true
|
vram_compression/import_etc=true
|
||||||
vram_compression/import_etc2=false
|
vram_compression/import_etc2=false
|
||||||
environment/default_clear_color=Color( 0, 0, 0, 1 )
|
environment/default_clear_color=Color( 0, 0, 0, 1 )
|
||||||
environment/default_environment="res://default_env.tres"
|
environment/default_environment="res://assets/default_env.tres"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene load_steps=2 format=2]
|
[gd_scene load_steps=2 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://game.gd" type="Script" id=1]
|
[ext_resource path="res://scripts/game.gd" type="Script" id=1]
|
||||||
|
|
||||||
[node name="Node2D" type="Node2D"]
|
[node name="Node2D" type="Node2D"]
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
|
@ -1,7 +1,7 @@
|
||||||
[gd_scene load_steps=3 format=2]
|
[gd_scene load_steps=3 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://lobby.gd" type="Script" id=1]
|
[ext_resource path="res://scripts/lobby.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://theme.tres" type="Theme" id=2]
|
[ext_resource path="res://assets/theme.tres" type="Theme" id=2]
|
||||||
|
|
||||||
[node name="lobby" type="MarginContainer"]
|
[node name="lobby" type="MarginContainer"]
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
|
@ -34,14 +34,50 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="lobby_info" type="Label" parent="v/head"]
|
[node name="lobby_info" type="LineEdit" parent="v/head"]
|
||||||
margin_left = 154.0
|
margin_left = 154.0
|
||||||
|
margin_top = 9.0
|
||||||
|
margin_right = 356.0
|
||||||
|
margin_bottom = 40.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Lobby Info"
|
||||||
|
placeholder_text = "Lobby Name"
|
||||||
|
|
||||||
|
[node name="l1" type="Label" parent="v/head"]
|
||||||
|
margin_left = 360.0
|
||||||
|
margin_top = 14.0
|
||||||
|
margin_right = 464.0
|
||||||
|
margin_bottom = 35.0
|
||||||
|
text = " Max Players:"
|
||||||
|
|
||||||
|
[node name="max_players" type="LineEdit" parent="v/head"]
|
||||||
|
margin_left = 468.0
|
||||||
|
margin_top = 9.0
|
||||||
|
margin_right = 574.0
|
||||||
|
margin_bottom = 40.0
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "20"
|
||||||
|
|
||||||
|
[node name="lock" type="CheckButton" parent="v/head"]
|
||||||
|
margin_left = 578.0
|
||||||
|
margin_right = 706.0
|
||||||
|
margin_bottom = 50.0
|
||||||
|
hint_tooltip = "Prevent players from joining to minimize \"Ready Up\" trolling"
|
||||||
|
text = "Locked"
|
||||||
|
|
||||||
|
[node name="start" type="Button" parent="v/head"]
|
||||||
|
margin_left = 710.0
|
||||||
|
margin_right = 860.0
|
||||||
|
margin_bottom = 50.0
|
||||||
|
rect_min_size = Vector2( 150, 0 )
|
||||||
|
text = "Start Game"
|
||||||
|
|
||||||
|
[node name="ready_up" type="CheckButton" parent="v/head"]
|
||||||
|
margin_left = 864.0
|
||||||
margin_right = 984.0
|
margin_right = 984.0
|
||||||
margin_bottom = 50.0
|
margin_bottom = 50.0
|
||||||
size_flags_horizontal = 3
|
text = "Ready"
|
||||||
size_flags_vertical = 3
|
|
||||||
valign = 1
|
|
||||||
autowrap = true
|
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
@ -61,6 +97,7 @@ margin_bottom = 506.0
|
||||||
margin_right = 180.0
|
margin_right = 180.0
|
||||||
margin_bottom = 21.0
|
margin_bottom = 21.0
|
||||||
text = "Players: 1"
|
text = "Players: 1"
|
||||||
|
valign = 2
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
@ -73,6 +110,8 @@ rect_min_size = Vector2( 180, 0 )
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
auto_height = true
|
auto_height = true
|
||||||
|
icon_scale = 0.5
|
||||||
|
fixed_icon_size = Vector2( 32, 32 )
|
||||||
|
|
||||||
[node name="v" type="VBoxContainer" parent="v/body"]
|
[node name="v" type="VBoxContainer" parent="v/body"]
|
||||||
margin_left = 184.0
|
margin_left = 184.0
|
||||||
|
@ -83,28 +122,28 @@ size_flags_vertical = 3
|
||||||
|
|
||||||
[node name="chat_head" type="HBoxContainer" parent="v/body/v"]
|
[node name="chat_head" type="HBoxContainer" parent="v/body/v"]
|
||||||
margin_right = 800.0
|
margin_right = 800.0
|
||||||
margin_bottom = 29.0
|
margin_bottom = 40.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
[node name="label" type="Label" parent="v/body/v/chat_head"]
|
[node name="label" type="Label" parent="v/body/v/chat_head"]
|
||||||
margin_right = 680.0
|
margin_right = 628.0
|
||||||
margin_bottom = 29.0
|
margin_bottom = 40.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
text = "Chat"
|
text = "Chat"
|
||||||
valign = 1
|
valign = 2
|
||||||
|
|
||||||
[node name="auto_scroll" type="CheckBox" parent="v/body/v/chat_head"]
|
[node name="auto_scroll" type="CheckButton" parent="v/body/v/chat_head"]
|
||||||
margin_left = 684.0
|
margin_left = 632.0
|
||||||
margin_right = 800.0
|
margin_right = 800.0
|
||||||
margin_bottom = 29.0
|
margin_bottom = 40.0
|
||||||
size_flags_horizontal = 0
|
size_flags_horizontal = 0
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
pressed = true
|
pressed = true
|
||||||
text = "Auto Scroll"
|
text = "Auto Scroll"
|
||||||
|
|
||||||
[node name="messages" type="TextEdit" parent="v/body/v"]
|
[node name="messages" type="TextEdit" parent="v/body/v"]
|
||||||
margin_top = 33.0
|
margin_top = 44.0
|
||||||
margin_right = 800.0
|
margin_right = 800.0
|
||||||
margin_bottom = 471.0
|
margin_bottom = 471.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
@ -140,5 +179,7 @@ size_flags_vertical = 3
|
||||||
text = "Send Message"
|
text = "Send Message"
|
||||||
|
|
||||||
[connection signal="pressed" from="v/head/leave_button" to="." method="_on_leave_button_pressed"]
|
[connection signal="pressed" from="v/head/leave_button" to="." method="_on_leave_button_pressed"]
|
||||||
|
[connection signal="text_changed" from="v/head/lobby_info" to="." method="_on_lobby_info_text_changed"]
|
||||||
|
[connection signal="toggled" from="v/head/ready_up" to="." method="_on_ready_up_toggled"]
|
||||||
[connection signal="text_entered" from="v/body/v/h/chat" to="." method="_on_TextEdit_text_entered"]
|
[connection signal="text_entered" from="v/body/v/h/chat" to="." method="_on_TextEdit_text_entered"]
|
||||||
[connection signal="pressed" from="v/body/v/h/Button" to="." method="_on_Button_pressed"]
|
[connection signal="pressed" from="v/body/v/h/Button" to="." method="_on_Button_pressed"]
|
|
@ -1,8 +1,8 @@
|
||||||
[gd_scene load_steps=5 format=2]
|
[gd_scene load_steps=5 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://main.gd" type="Script" id=1]
|
[ext_resource path="res://scripts/main.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://assets/fonts/iosevkalyte/iosevkalyte-regular.ttf" type="DynamicFontData" id=2]
|
[ext_resource path="res://assets/fonts/iosevkalyte/iosevkalyte-regular.ttf" type="DynamicFontData" id=2]
|
||||||
[ext_resource path="res://theme.tres" type="Theme" id=3]
|
[ext_resource path="res://assets/theme.tres" type="Theme" id=3]
|
||||||
|
|
||||||
[sub_resource type="DynamicFont" id=1]
|
[sub_resource type="DynamicFont" id=1]
|
||||||
size = 70
|
size = 70
|
|
@ -1,7 +1,7 @@
|
||||||
[gd_scene load_steps=3 format=2]
|
[gd_scene load_steps=3 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://multiplayer.gd" type="Script" id=1]
|
[ext_resource path="res://scripts/multiplayer.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://theme.tres" type="Theme" id=2]
|
[ext_resource path="res://assets/theme.tres" type="Theme" id=2]
|
||||||
|
|
||||||
[node name="Control" type="MarginContainer"]
|
[node name="Control" type="MarginContainer"]
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
18
screens/test.tscn
Normal file
18
screens/test.tscn
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
[gd_scene format=2]
|
||||||
|
|
||||||
|
[node name="Control" type="GridContainer"]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
columns = 4
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||||
|
margin_bottom = 14.0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="."]
|
||||||
|
margin_left = 4.0
|
||||||
|
margin_right = 69.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
text = "some text"
|
|
@ -1,23 +1,42 @@
|
||||||
extends MarginContainer
|
extends MarginContainer
|
||||||
|
|
||||||
onready var peers = $v/body/peers/peers
|
onready var peers = $v/body/peers/peers
|
||||||
onready var lobby_info_label = $v/head/lobby_info
|
onready var lobby_name = $v/head/lobby_info
|
||||||
onready var peers_list_label = $v/body/peers/label
|
onready var peers_list_label = $v/body/peers/label
|
||||||
onready var cursors = {}
|
onready var cursors = {}
|
||||||
onready var chat = $v/body/v/messages
|
onready var chat = $v/body/v/messages
|
||||||
onready var chat_edit = $v/body/v/h/chat
|
onready var chat_edit = $v/body/v/h/chat
|
||||||
onready var auto_scroll_chk = $v/body/v/chat_head/auto_scroll
|
onready var auto_scroll_chk = $v/body/v/chat_head/auto_scroll
|
||||||
|
|
||||||
|
onready var max_players = $v/head/max_players
|
||||||
|
onready var ready_up = $v/head/ready_up
|
||||||
|
onready var lock = $v/head/lock
|
||||||
|
onready var start = $v/head/start
|
||||||
|
|
||||||
|
onready var ready_tex: Texture = load("res://assets/img/check.png")
|
||||||
|
onready var not_ready_tex: Texture = load("res://assets/img/cross.png")
|
||||||
|
onready var can_start = true
|
||||||
|
|
||||||
|
onready var peers_map = {}
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
Global.client.signaller.connect("peer_joined", self, "_peer_joined")
|
Global.client.signaller.connect("peer_joined", self, "_peer_joined")
|
||||||
Global.client.signaller.connect("peer_left", self, "_peer_left")
|
Global.client.signaller.connect("peer_left", self, "_peer_left")
|
||||||
# Global.client.connect("peer_disconnected", self, "_peer_left")
|
# Global.client.connect("peer_disconnected", self, "_peer_left")
|
||||||
Global.client.signaller.connect("lobby_left", self, "_lobby_left")
|
Global.client.signaller.connect("lobby_left", self, "_lobby_left")
|
||||||
lobby_info_label.text = "%s%s" % [Global.client.signaller.lobby_name, _host_suffix(get_tree().get_network_unique_id())]
|
lobby_name.text = "%s" % Global.client.signaller.lobby_name
|
||||||
Global.client.signaller.connect("websocket_disconnected", self, "_signaller_disconnected")
|
Global.client.signaller.connect("websocket_disconnected", self, "_signaller_disconnected")
|
||||||
Global.client.signaller.request_peer_list()
|
Global.client.signaller.request_peer_list()
|
||||||
call_deferred("add_chat", "# Connected to %s" % Global.client.signaller.lobby_name)
|
call_deferred("add_chat", "# Connected to %s" % Global.client.signaller.lobby_name)
|
||||||
|
|
||||||
|
var is_host = Global.client.signaller.peer_id == 1
|
||||||
|
if is_host:
|
||||||
|
ready_up.queue_free()
|
||||||
|
else:
|
||||||
|
max_players.editable = false
|
||||||
|
start.queue_free()
|
||||||
|
lock.queue_free()
|
||||||
|
|
||||||
func _host_suffix(id):
|
func _host_suffix(id):
|
||||||
if id == 1:
|
if id == 1:
|
||||||
return " (Host)"
|
return " (Host)"
|
||||||
|
@ -29,23 +48,27 @@ func _signaller_disconnected():
|
||||||
|
|
||||||
func _peer_joined(joined_peers):
|
func _peer_joined(joined_peers):
|
||||||
call_deferred("update_player_count")
|
call_deferred("update_player_count")
|
||||||
print("Joined Peers: %s" % [joined_peers])
|
for peer_index in range(len(joined_peers)):
|
||||||
for i in range(len(joined_peers)):
|
var peer = joined_peers[peer_index]
|
||||||
var id = joined_peers[i]["id"]
|
var id = peer["id"]
|
||||||
var exists = false
|
var peer_text = "%s%s" % [peer["name"], _host_suffix(peer["peerId"])]
|
||||||
for j in range(peers.get_item_count()):
|
if peers_map.has(id):
|
||||||
var md = peers.get_item_metadata(j)
|
var i = peers_map[id]
|
||||||
if md and md.has("id") and md["id"] == id:
|
var old_peer = peers.get_item_metadata(i)
|
||||||
print("Already have this one")
|
peers.set_item_metadata(i, peer)
|
||||||
exists = true
|
# announce changes?
|
||||||
break
|
else:
|
||||||
if not exists:
|
call_deferred("add_chat", "> %s joined the lobby" % peer["name"])
|
||||||
var peerId = joined_peers[i]["peerId"]
|
var ready = false
|
||||||
var name = joined_peers[i]["name"]
|
var tex = not_ready_tex
|
||||||
print("New Lobby Peer ID: %s, Name: %s, PeerID: %s" % [id, name, peerId])
|
if peerId == 1:
|
||||||
call_deferred("add_chat", "> %s joined the lobby" % name)
|
ready = true
|
||||||
peers.add_item("%s%s" % [name, _host_suffix(peerId)])
|
tex = ready_tex
|
||||||
peers.set_item_metadata(peers.get_item_count() - 1, { "id": id, "peerId": peerId, "name": name })
|
peers.add_item(peer_text, tex)
|
||||||
|
var i = peers.get_item_count() - 1
|
||||||
|
peers.set_item_metadata(i, peer)
|
||||||
|
peers_map[id] = i
|
||||||
|
if !ready: can_start = false
|
||||||
|
|
||||||
func _peer_left(ids):
|
func _peer_left(ids):
|
||||||
call_deferred("update_player_count")
|
call_deferred("update_player_count")
|
||||||
|
@ -64,7 +87,12 @@ func update_player_count():
|
||||||
peers_list_label.text = "Players: %d" % peers.get_item_count()
|
peers_list_label.text = "Players: %d" % peers.get_item_count()
|
||||||
|
|
||||||
func _on_Button_pressed():
|
func _on_Button_pressed():
|
||||||
send_chat_message()
|
send_chkkkkkkat_message()
|
||||||
|
|
||||||
|
func _on_ready_up_toggled(button_pressed: bool):
|
||||||
|
|
||||||
|
func _on_lobby_info_text_changed(new_text: String):
|
||||||
|
Global.client.signaller.set_lobby_name(new_text)
|
||||||
|
|
||||||
remotesync func add_chat(message):
|
remotesync func add_chat(message):
|
||||||
if auto_scroll_chk.pressed: call_deferred("scroll_chat_to_bottom")
|
if auto_scroll_chk.pressed: call_deferred("scroll_chat_to_bottom")
|
|
@ -9,6 +9,8 @@ onready var join_button = $v/head/join
|
||||||
onready var lobbies_label = $v/subhead/label
|
onready var lobbies_label = $v/subhead/label
|
||||||
onready var display_name_edit = $v/subhead/display_name
|
onready var display_name_edit = $v/subhead/display_name
|
||||||
|
|
||||||
|
onready var lobbies_map = {}
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
display_name_edit.text = Global.client.signaller.display_name
|
display_name_edit.text = Global.client.signaller.display_name
|
||||||
join_button.disabled = true
|
join_button.disabled = true
|
||||||
|
@ -44,13 +46,21 @@ func _on_join_pressed():
|
||||||
Global.client.signaller.join_lobby(lobbies.get_item_metadata(items[0])["id"])
|
Global.client.signaller.join_lobby(lobbies.get_item_metadata(items[0])["id"])
|
||||||
|
|
||||||
func _lobby_new(new_lobbies):
|
func _lobby_new(new_lobbies):
|
||||||
for i in range(len(new_lobbies)):
|
# TODO: handle scrolling so that the user is never too jarred (like chat)
|
||||||
var id = new_lobbies[i]["id"]
|
for lobby_index in range(len(new_lobbies)):
|
||||||
var name = new_lobbies[i]["name"]
|
var lobby = new_lobbies[lobby_index]
|
||||||
print("New Lobby ", id, name)
|
var id = lobby["id"]
|
||||||
# TODO: could keep an index of IDs and indexes
|
var lobby_text = "%s (%d/%d players)" % [lobby["name"], lobby["currentPlayers"], lobby["maxPlayers"]]
|
||||||
lobbies.add_item(name)
|
if lobbies_map.has(id):
|
||||||
lobbies.set_item_metadata(lobbies.get_item_count() - 1, { "id": id })
|
print("Updated Lobby ", lobby)
|
||||||
|
var i = lobbies_map[id]
|
||||||
|
lobbies.set_item_metadata(i, lobby)
|
||||||
|
lobbies.set_item_text(i, lobby_text)
|
||||||
|
else:
|
||||||
|
print("New Lobby ", lobby)
|
||||||
|
lobbies.add_item(lobby_text)
|
||||||
|
lobbies_map[id] = lobbies.get_item_count() - 1
|
||||||
|
lobbies.set_item_metadata(lobbies_map[id], lobby)
|
||||||
|
|
||||||
if Global.join_first_available_lobby:
|
if Global.join_first_available_lobby:
|
||||||
Global.join_first_available_lobby = false
|
Global.join_first_available_lobby = false
|
||||||
|
@ -58,10 +68,10 @@ func _lobby_new(new_lobbies):
|
||||||
lobbies_label.text = "Active Lobbies: %d" % lobbies.get_item_count()
|
lobbies_label.text = "Active Lobbies: %d" % lobbies.get_item_count()
|
||||||
|
|
||||||
func _lobby_delete(id):
|
func _lobby_delete(id):
|
||||||
for i in range(lobbies.get_item_count()):
|
if lobbies_map.has(id):
|
||||||
if id == lobbies.get_item_metadata(i)["id"]:
|
var i = lobbies_map[id]
|
||||||
|
# TODO: this will break our current mappings due to re-order
|
||||||
lobbies.remove_item(i)
|
lobbies.remove_item(i)
|
||||||
return
|
|
||||||
lobbies_label.text = "Active Lobbies: %d" % lobbies.get_item_count()
|
lobbies_label.text = "Active Lobbies: %d" % lobbies.get_item_count()
|
||||||
|
|
||||||
func _on_lobbies_item_activated(_index):
|
func _on_lobbies_item_activated(_index):
|
|
@ -4,8 +4,8 @@ extends Node
|
||||||
This module sets up WebRTC peer connections.
|
This module sets up WebRTC peer connections.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
var multiplayer_url = "wss://webrtc-signaller.deno.dev:443"
|
# var multiplayer_url = "wss://webrtc-signaller.deno.dev:443"
|
||||||
# var multiplayer_url = "ws://localhost:8888"
|
var multiplayer_url = "ws://localhost:8888"
|
||||||
# var multiplayer_url = "ws://echo.websocket.org"
|
# var multiplayer_url = "ws://echo.websocket.org"
|
||||||
var webrtc_ice_servers = [
|
var webrtc_ice_servers = [
|
||||||
{ "urls": ["stun:stun.l.google.com:19302"] },
|
{ "urls": ["stun:stun.l.google.com:19302"] },
|
|
@ -28,6 +28,8 @@ onready var peer_id = null
|
||||||
onready var display_name = "UnnamedPlayer"
|
onready var display_name = "UnnamedPlayer"
|
||||||
onready var lobby_name = null
|
onready var lobby_name = null
|
||||||
|
|
||||||
|
func is_host(): return peer_id == 1
|
||||||
|
|
||||||
const DISPLAY_NAME_FILE = "user://display_name.txt"
|
const DISPLAY_NAME_FILE = "user://display_name.txt"
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
@ -104,6 +106,18 @@ func set_display_name(new_display_name: String):
|
||||||
func _send(s: String):
|
func _send(s: String):
|
||||||
return ws.get_peer(1).put_packet(s.to_utf8())
|
return ws.get_peer(1).put_packet(s.to_utf8())
|
||||||
|
|
||||||
|
func set_lobby_name(s: String):
|
||||||
|
if is_host():
|
||||||
|
_send("json:%s" % JSON.print({"type": "update_lobby", "data": {"name": s}}))
|
||||||
|
|
||||||
|
func lock_lobby():
|
||||||
|
if is_host():
|
||||||
|
_send("json:%s" % JSON.print({"type": "update_lobby", "data": {"locked": true}}))
|
||||||
|
|
||||||
|
func set_lobby_max_players(n: int):
|
||||||
|
if is_host():
|
||||||
|
_send("json:%s" % JSON.print({"type": "update_lobby", "data": {"maxPlayers": n}}))
|
||||||
|
|
||||||
func _parse_msg():
|
func _parse_msg():
|
||||||
var msg: String = ws.get_peer(1).get_packet().get_string_from_utf8()
|
var msg: String = ws.get_peer(1).get_packet().get_string_from_utf8()
|
||||||
if msg.begins_with("json:"):
|
if msg.begins_with("json:"):
|
||||||
|
@ -124,7 +138,7 @@ func handle_message(data: Dictionary):
|
||||||
emit_signal("peer_id_set", peer_id)
|
emit_signal("peer_id_set", peer_id)
|
||||||
|
|
||||||
"lobby_list": emit_signal("lobby_new", data["data"])
|
"lobby_list": emit_signal("lobby_new", data["data"])
|
||||||
"lobby_new": emit_signal("lobby_new", [{"id": data["id"], "name": data["name"]}])
|
"lobby_new": emit_signal("lobby_new", [data])
|
||||||
"lobby_delete": emit_signal("lobby_delete", data["id"])
|
"lobby_delete": emit_signal("lobby_delete", data["id"])
|
||||||
|
|
||||||
"lobby_joined":
|
"lobby_joined":
|
||||||
|
@ -139,10 +153,8 @@ func handle_message(data: Dictionary):
|
||||||
|
|
||||||
"peer_joined":
|
"peer_joined":
|
||||||
print(typeof(data), data)
|
print(typeof(data), data)
|
||||||
if data.get("id") != null:
|
if data.get("id") != null: emit_signal("peer_joined", [data])
|
||||||
emit_signal("peer_joined", [{"id": data["id"], "name": data["name"], "peerId": data["peerId"]}])
|
else: emit_signal("peer_joined", data["data"])
|
||||||
else:
|
|
||||||
emit_signal("peer_joined", data["data"])
|
|
||||||
"peer_left":
|
"peer_left":
|
||||||
print("Peer Left: %s" % data)
|
print("Peer Left: %s" % data)
|
||||||
emit_signal("peer_left", data["data"])
|
emit_signal("peer_left", data["data"])
|
136
server.ts
136
server.ts
|
@ -1,6 +1,6 @@
|
||||||
// import { randomInt } from "./deps.ts";
|
// import { randomInt } from "./deps.ts";
|
||||||
|
|
||||||
const SERVER_VERSION = "0.1.0";
|
const SERVER_VERSION = "0.2.0";
|
||||||
// TODO: version comparison
|
// TODO: version comparison
|
||||||
|
|
||||||
type ID = string;
|
type ID = string;
|
||||||
|
@ -14,8 +14,11 @@ interface DataMessage {
|
||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerDataObject = Record<string, string | number | symbol | null>;
|
type ServerDataObject = Record<
|
||||||
type ServerData = ServerDataObject[] | ServerDataObject | string;
|
string,
|
||||||
|
string | number | symbol | null | boolean
|
||||||
|
>;
|
||||||
|
type ServerData = ServerDataObject[] | ServerDataObject | string | boolean;
|
||||||
type Message = string | DataMessage;
|
type Message = string | DataMessage;
|
||||||
|
|
||||||
const buildMessage = (
|
const buildMessage = (
|
||||||
|
@ -35,6 +38,7 @@ class Client {
|
||||||
name: string;
|
name: string;
|
||||||
socket: WebSocket;
|
socket: WebSocket;
|
||||||
lobby: Lobby | null;
|
lobby: Lobby | null;
|
||||||
|
ready: boolean;
|
||||||
|
|
||||||
constructor(socket: WebSocket) {
|
constructor(socket: WebSocket) {
|
||||||
this.id = crypto.randomUUID();
|
this.id = crypto.randomUUID();
|
||||||
|
@ -42,6 +46,7 @@ class Client {
|
||||||
this.peerId = null;
|
this.peerId = null;
|
||||||
this.name = "Client";
|
this.name = "Client";
|
||||||
this.lobby = null;
|
this.lobby = null;
|
||||||
|
this.ready = false;
|
||||||
|
|
||||||
allClients.set(this.id, this);
|
allClients.set(this.id, this);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +55,13 @@ class Client {
|
||||||
return this.socket.readyState == WebSocket.OPEN;
|
return this.socket.readyState == WebSocket.OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setReady(ready: boolean) {
|
||||||
|
this.ready = ready;
|
||||||
|
this.lobby?.broadcast(
|
||||||
|
buildMessage("ready_change", { id: this.id, ready: this.ready }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
this.lobbyLeave();
|
this.lobbyLeave();
|
||||||
if (this.isConnected()) {
|
if (this.isConnected()) {
|
||||||
|
@ -83,25 +95,54 @@ class Client {
|
||||||
|
|
||||||
peerList() {
|
peerList() {
|
||||||
if (!this.lobby) return;
|
if (!this.lobby) return;
|
||||||
const peers: { id: ID; name: string; peerId: number | null }[] = [];
|
const peers: {
|
||||||
this.lobby.clients.forEach(({ id, name, peerId }) =>
|
id: ID;
|
||||||
peers.push({ id, name, peerId })
|
name: string;
|
||||||
|
peerId: number | null;
|
||||||
|
ready: boolean;
|
||||||
|
}[] = [];
|
||||||
|
this.lobby.clients.forEach(({ id, name, peerId, ready }) =>
|
||||||
|
peers.push({ id, name, peerId, ready })
|
||||||
);
|
);
|
||||||
this.send(buildMessage("peer_joined", peers));
|
this.send(buildMessage("peer_joined", peers));
|
||||||
// TODO: chunk async?
|
// TODO: chunk async?
|
||||||
}
|
}
|
||||||
|
|
||||||
lobbyList() {
|
lobbyList() {
|
||||||
const netLobbies: { id: ID; name: string }[] = [];
|
const netLobbies: {
|
||||||
allLobbies.forEach(({ id, name }) => netLobbies.push({ id, name }));
|
id: ID;
|
||||||
|
name: string;
|
||||||
|
maxPlayers: number;
|
||||||
|
locked: boolean;
|
||||||
|
currentPlayers: number;
|
||||||
|
}[] = [];
|
||||||
|
allLobbies.forEach((lobby) => {
|
||||||
|
const { id, name, maxPlayers, locked } = lobby;
|
||||||
|
netLobbies.push({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
maxPlayers,
|
||||||
|
locked,
|
||||||
|
currentPlayers: lobby.clients.size,
|
||||||
|
});
|
||||||
|
});
|
||||||
// TODO: chunk async?
|
// TODO: chunk async?
|
||||||
this.send(buildMessage("lobby_list", netLobbies));
|
this.send(buildMessage("lobby_list", netLobbies));
|
||||||
}
|
}
|
||||||
|
|
||||||
lobbyNew({ id, name }: Lobby) {
|
lobbyNew(lobby: Lobby) {
|
||||||
// if the client is already in a lobby, we don't care about new lobbies
|
// if the client is already in a lobby, they don't care about new lobbies
|
||||||
if (this.lobby) return;
|
if (this.lobby) return;
|
||||||
this.send(buildMessage("lobby_new", { id, name }));
|
const { id, name, maxPlayers, locked } = lobby;
|
||||||
|
this.send(
|
||||||
|
buildMessage("lobby_new", {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
maxPlayers,
|
||||||
|
locked,
|
||||||
|
currentPlayers: lobby.clients.size,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
lobbyDelete({ id }: Lobby) {
|
lobbyDelete({ id }: Lobby) {
|
||||||
|
@ -109,14 +150,14 @@ class Client {
|
||||||
this.send(buildMessage("lobby_delete", { id }));
|
this.send(buildMessage("lobby_delete", { id }));
|
||||||
}
|
}
|
||||||
|
|
||||||
lobbyCreate(name?: string) {
|
lobbyCreate(opts?: Partial<Lobby>) {
|
||||||
if (this.lobby) {
|
if (this.lobby) {
|
||||||
this.send(
|
this.send(
|
||||||
`[info] cannot create lobby (already in lobby ${this.lobby.id})`,
|
`[info] cannot create lobby (already in lobby ${this.lobby.id})`,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new Lobby(this, name || `${this.name}'s lobby`);
|
new Lobby(this, opts?.name || `${this.name}'s lobby`, opts?.maxPlayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
lobbyJoin(lobby: Lobby) {
|
lobbyJoin(lobby: Lobby) {
|
||||||
|
@ -155,16 +196,54 @@ class Lobby {
|
||||||
name: string;
|
name: string;
|
||||||
clients: Map<ID, Client>;
|
clients: Map<ID, Client>;
|
||||||
hostClientId: ID;
|
hostClientId: ID;
|
||||||
|
maxPlayers: number;
|
||||||
|
locked: boolean;
|
||||||
|
|
||||||
constructor(host: Client, name?: string) {
|
constructor(host: Client, name?: string, maxPlayers = 20) {
|
||||||
this.id = crypto.randomUUID();
|
this.id = crypto.randomUUID();
|
||||||
this.hostClientId = host.id;
|
this.hostClientId = host.id;
|
||||||
this.clients = new Map<ID, Client>();
|
this.clients = new Map<ID, Client>();
|
||||||
this.name = name || this.id;
|
this.name = name || this.id;
|
||||||
|
this.maxPlayers = maxPlayers;
|
||||||
|
this.locked = false;
|
||||||
|
|
||||||
allLobbies.set(this.id, this);
|
allLobbies.set(this.id, this);
|
||||||
host.peerId = 1;
|
host.peerId = 1;
|
||||||
host.lobbyJoin(this);
|
host.lobbyJoin(this);
|
||||||
|
this.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
update(
|
||||||
|
requestor: Client,
|
||||||
|
newValues: { name?: string; maxPlayers?: number; locked?: boolean },
|
||||||
|
) {
|
||||||
|
if (requestor.peerId === 1) {
|
||||||
|
for (const k in newValues) {
|
||||||
|
switch (k) {
|
||||||
|
case "name":
|
||||||
|
if (newValues?.name) this.name = newValues.name;
|
||||||
|
break;
|
||||||
|
case "maxPlayers":
|
||||||
|
if (
|
||||||
|
newValues?.maxPlayers && typeof newValues.maxPlayers === "number"
|
||||||
|
) {
|
||||||
|
this.maxPlayers = newValues.maxPlayers;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "locked":
|
||||||
|
if (newValues?.locked) this.locked = newValues.locked;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.notify();
|
||||||
|
} else {
|
||||||
|
requestor.send(
|
||||||
|
"[info] you cannot update this lobby (you are not the host!)",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notify() {
|
||||||
allClients.forEach((client) => client.lobbyNew(this));
|
allClients.forEach((client) => client.lobbyNew(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +283,7 @@ class Lobby {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
this.clients.set(client.id, client);
|
this.clients.set(client.id, client);
|
||||||
|
this.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
removeClient({ id }: Client) {
|
removeClient({ id }: Client) {
|
||||||
|
@ -213,11 +293,18 @@ class Lobby {
|
||||||
console.warn("Host left!");
|
console.warn("Host left!");
|
||||||
this.remove();
|
this.remove();
|
||||||
}
|
}
|
||||||
|
this.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ClientMessage {
|
interface ClientMessage {
|
||||||
type: "candidate" | "offer" | "answer" | "init" | "lobby_create";
|
type:
|
||||||
|
| "candidate"
|
||||||
|
| "offer"
|
||||||
|
| "answer"
|
||||||
|
| "init"
|
||||||
|
| "lobby_create"
|
||||||
|
| "update_lobby";
|
||||||
data: ServerDataObject;
|
data: ServerDataObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,9 +315,18 @@ function onMessage(client: Client, ev: MessageEvent) {
|
||||||
if (msg === "pong") return;
|
if (msg === "pong") return;
|
||||||
console.log("Client Message Received", msg);
|
console.log("Client Message Received", msg);
|
||||||
if (msg === "init") {
|
if (msg === "init") {
|
||||||
client.send(buildMessage("init", { id: client.id, name: client.name }));
|
client.send(
|
||||||
|
buildMessage("init", {
|
||||||
|
id: client.id,
|
||||||
|
name: client.name,
|
||||||
|
serverVersion: SERVER_VERSION,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (msg === "lobby_create") client.lobbyCreate();
|
if (msg === "lobby_create") client.lobbyCreate();
|
||||||
|
if (msg.startsWith("set_ready:")) {
|
||||||
|
client.setReady(JSON.parse(msg.split(":", 2)[1]));
|
||||||
|
}
|
||||||
if (msg === "lobby_leave") client.lobbyLeave();
|
if (msg === "lobby_leave") client.lobbyLeave();
|
||||||
if (msg === "request_lobby_list") client.lobbyList();
|
if (msg === "request_lobby_list") client.lobbyList();
|
||||||
if (msg === "request_peer_list") {
|
if (msg === "request_peer_list") {
|
||||||
|
@ -259,8 +355,14 @@ function onMessage(client: Client, ev: MessageEvent) {
|
||||||
client.name = data.data.name.toString();
|
client.name = data.data.name.toString();
|
||||||
}
|
}
|
||||||
client.send(buildMessage("init", { id: client.id, name: client.name }));
|
client.send(buildMessage("init", { id: client.id, name: client.name }));
|
||||||
|
} else if (data.type === "update_lobby") {
|
||||||
|
if (client.lobby) {
|
||||||
|
client.lobby.update(client, data["data"]);
|
||||||
|
} else {
|
||||||
|
client.send("[info] cannot update lobby (you're not even in one!)");
|
||||||
|
}
|
||||||
} else if (data.type === "lobby_create") {
|
} else if (data.type === "lobby_create") {
|
||||||
client.lobbyCreate(data.data?.name?.toString());
|
client.lobbyCreate({ name: data.data?.name?.toString() });
|
||||||
if (data.data.name) {
|
if (data.data.name) {
|
||||||
client.name = data.data.name.toString();
|
client.name = data.data.name.toString();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue