197 lines
5.4 KiB
GDScript
197 lines
5.4 KiB
GDScript
extends Control
|
|
|
|
var server := "seba-geek.de"
|
|
var port := "3784"
|
|
var ws_url := "wss://seba-geek.de/godot/cw-generator-ws/"
|
|
var IS_DEBUG = false
|
|
var ws := WebSocketPeer.new()
|
|
|
|
var available_freqs = []
|
|
var mmb_self: MultiMorseBanner
|
|
var mmb_others: Dictionary[String, MultiMorseBanner]
|
|
|
|
class PlayerData:
|
|
var num: int
|
|
var color: Color
|
|
var tone: int
|
|
|
|
func _init(num, color, tone):
|
|
self.num = num
|
|
self.color = color
|
|
self.tone = tone
|
|
|
|
var player_data := [
|
|
PlayerData.new(0, Color( 0, 255, 0), 880),
|
|
PlayerData.new(1, Color(255, 0, 0), 1200),
|
|
PlayerData.new(2, Color( 0, 0, 255), 600),
|
|
PlayerData.new(3, Color(255, 0, 255), 500),
|
|
]
|
|
|
|
func _ready() -> void:
|
|
# FIXME: connection handling / reconnect
|
|
# FIXME: status / error messages
|
|
# FIXME: randomize default join frquency
|
|
# FIXME: automatic refresh
|
|
if not IS_DEBUG:
|
|
print(ws_url)
|
|
ws.connect_to_url(ws_url)
|
|
else:
|
|
print("ws://%s:%s" % [server, port])
|
|
ws.connect_to_url("ws://%s:%s" % [server, port])
|
|
|
|
|
|
func refresh_list() -> void:
|
|
pass
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
ws.poll()
|
|
var state := ws.get_ready_state()
|
|
# print("moin ", state)
|
|
while state == WebSocketPeer.STATE_OPEN and ws.get_available_packet_count():
|
|
_handle_packet()
|
|
if state != WebSocketPeer.STATE_OPEN:
|
|
print("Error: websocket in state", state)
|
|
|
|
func _handle_packet() -> void:
|
|
var data := ws.get_packet().get_string_from_utf8()
|
|
print(data)
|
|
var parsed: Dictionary = JSON.parse_string(data)
|
|
if typeof(parsed) != TYPE_DICTIONARY or not parsed.has("type"):
|
|
return
|
|
print("parsed ", parsed)
|
|
|
|
match parsed["type"]:
|
|
"hello":
|
|
# fetch frequency list on first join
|
|
_on_refresh_button_pressed()
|
|
"join":
|
|
_join_freq(parsed["freq"], parsed["self_id"], parsed["other_players"])
|
|
|
|
"freq-list":
|
|
%FreqList.clear()
|
|
for freq in parsed["freqs"]:
|
|
var text = "%s MHz (%d present)" % [freq["freq"], freq["players"]]
|
|
print("Adding ", text)
|
|
var idx: int = %FreqList.add_item(text)
|
|
%FreqList.set_item_metadata(idx, freq)
|
|
|
|
"morse-state":
|
|
var from_player: String = parsed["from_player"]
|
|
if from_player not in mmb_others:
|
|
print("Error: Got morse state from unknown player ", from_player)
|
|
return
|
|
mmb_others[from_player].set_morse_state(parsed["state"])
|
|
|
|
"player-joined":
|
|
var new_player: String = parsed["player"]
|
|
if new_player in mmb_others:
|
|
print("Error: got player join message, but player ", new_player, " is already present")
|
|
return
|
|
|
|
# find free player id
|
|
var player_n := 1
|
|
while true:
|
|
var found := false
|
|
for other in mmb_others.values():
|
|
if other.num == player_n:
|
|
print("New player, num ", player_n, " already taken")
|
|
found = true
|
|
break
|
|
if not found:
|
|
break
|
|
player_n += 1
|
|
|
|
make_player(player_n, new_player)
|
|
|
|
"player-left":
|
|
var player: String = parsed["player"]
|
|
if player not in mmb_others:
|
|
print("Error: player not part of freq ", player)
|
|
return
|
|
remove_player(parsed["player"])
|
|
"leave":
|
|
%MorseView.hide()
|
|
mmb_self.set_morse_state(false)
|
|
for mmb: MultiMorseBanner in mmb_others.values():
|
|
mmb.set_morse_state(false)
|
|
mmb_self = null
|
|
mmb_others.clear()
|
|
for child in %PlayerContainer.get_children():
|
|
%PlayerContainer.remove_child(child)
|
|
%ConnectView.show()
|
|
_:
|
|
print("Unhandled message: ", parsed["type"])
|
|
|
|
|
|
func _join_freq(freq: String, player_id: String, other_players: Array):
|
|
for child in %PlayerContainer.get_children():
|
|
%PlayerContainer.remove_child(child)
|
|
|
|
mmb_self = make_player(0, player_id)
|
|
for n in range(other_players.size()):
|
|
make_player(n + 1, other_players[n])
|
|
|
|
%FreqLabel.text = "%s MHz" % freq
|
|
%ConnectView.hide()
|
|
%MorseView.show()
|
|
|
|
func _on_refresh_button_pressed() -> void:
|
|
var refresh_cmd := {"cmd": "list", "type": "cw-generator"}
|
|
var data := JSON.stringify(refresh_cmd) + "\n"
|
|
ws.send_text(data)
|
|
|
|
|
|
func _on_create_button_pressed() -> void:
|
|
var freq: String = "%.3f" % float(%FrequencyCreator.text)
|
|
var refresh_cmd := {"cmd": "create", "type": "cw-generator", "freq": freq}
|
|
var data := JSON.stringify(refresh_cmd) + "\n"
|
|
ws.send_text(data)
|
|
|
|
|
|
func _on_freq_list_join(index: int, at_position: Vector2, mouse_button_index: int) -> void:
|
|
var meta = %FreqList.get_item_metadata(index)
|
|
var freq: String = meta["freq"]
|
|
print("Yop ", index, " metadata ", freq)
|
|
var join_cmd := {"cmd": "join", "freq": freq, "type": "cw-generator"}
|
|
ws.send_text(JSON.stringify(join_cmd) + "\n")
|
|
|
|
func make_player(no: int, player_id: String):
|
|
var pd: PlayerData
|
|
if no < player_data.size():
|
|
pd = player_data[no]
|
|
else:
|
|
pd = PlayerData.new(no, Color(randi_range(0, 255), randi_range(0, 255), randi_range(0, 255)), randi_range(440, 440 * 3))
|
|
|
|
var mmb = MultiMorseBanner.new_banner(pd.num, pd.color, pd.tone)
|
|
%PlayerContainer.add_child(mmb)
|
|
mmb_others[player_id] = mmb
|
|
return mmb
|
|
|
|
func remove_player(player_id: String):
|
|
mmb_others[player_id].set_morse_state(false)
|
|
%PlayerContainer.remove_child(mmb_others[player_id])
|
|
mmb_others.erase(player_id)
|
|
|
|
func set_morse_state(state: bool):
|
|
mmb_self.set_morse_state(state)
|
|
send_data({"cmd": "morse-state", "state": state})
|
|
|
|
func send_data(data: Dictionary):
|
|
var text := JSON.stringify(data) + "\n"
|
|
ws.send_text(text)
|
|
|
|
func _on_morse_button_button_down() -> void:
|
|
if not mmb_self:
|
|
return
|
|
set_morse_state(true)
|
|
|
|
func _on_morse_button_button_up() -> void:
|
|
if not mmb_self:
|
|
return
|
|
set_morse_state(false)
|
|
|
|
|
|
func _on_leave_button_pressed() -> void:
|
|
send_data({"cmd": "leave"})
|