İlk commit: Stepstead Godot istemci (4.6 Mobile)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
6a1706051d
346 changed files with 14415 additions and 0 deletions
117
autoload/ws_client.gd
Normal file
117
autoload/ws_client.gd
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
extends Node
|
||||
## Canlı multiplayer istemcisi — diğer oyuncuların pozisyonlarını WebSocket ile alır.
|
||||
## Sunucu eventleri: online_list (sadece bağlanınca), player_joined, player_moved,
|
||||
## player_left, pong. Kopunca 5 sn'de bir yeniden bağlanır.
|
||||
|
||||
signal player_joined(p: Dictionary)
|
||||
signal player_moved(p: Dictionary)
|
||||
signal player_left(char_id: int)
|
||||
signal online_list(players: Array)
|
||||
signal chat_received(msg: Dictionary)
|
||||
signal chat_history(messages: Array) # global geçmiş (bağlanınca)
|
||||
signal local_chat_history(messages: Array) # bulunulan lokasyonun geçmişi (istek üzerine)
|
||||
signal connection_changed(is_connected: bool)
|
||||
|
||||
const PING_INTERVAL := 25.0 # sunucu presence TTL 120sn, ping ile yenilenir
|
||||
const RECONNECT_DELAY := 5.0
|
||||
|
||||
var _ws: WebSocketPeer = null
|
||||
var _open := false
|
||||
var _ping_accum := 0.0
|
||||
var _reconnect_accum := 0.0
|
||||
var _should_run := false
|
||||
|
||||
func start() -> void:
|
||||
if _should_run:
|
||||
return
|
||||
_should_run = true
|
||||
_connect_ws()
|
||||
|
||||
func stop() -> void:
|
||||
_should_run = false
|
||||
if _ws != null:
|
||||
_ws.close()
|
||||
_ws = null
|
||||
if _open:
|
||||
_open = false
|
||||
connection_changed.emit(false)
|
||||
|
||||
func _connect_ws() -> void:
|
||||
if Auth.token == "":
|
||||
return
|
||||
var url := Config.get_api_base().replace("https://", "wss://").replace("http://", "ws://") + "/ws?token=" + Auth.token
|
||||
_ws = WebSocketPeer.new()
|
||||
var err := _ws.connect_to_url(url)
|
||||
if err != OK:
|
||||
push_warning("WS bağlantı hatası: %d" % err)
|
||||
_ws = null
|
||||
_ping_accum = 0.0
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not _should_run:
|
||||
return
|
||||
if _ws == null:
|
||||
_reconnect_accum += delta
|
||||
if _reconnect_accum >= RECONNECT_DELAY:
|
||||
_reconnect_accum = 0.0
|
||||
_connect_ws()
|
||||
return
|
||||
_ws.poll()
|
||||
var state := _ws.get_ready_state()
|
||||
if state == WebSocketPeer.STATE_OPEN:
|
||||
if not _open:
|
||||
_open = true
|
||||
connection_changed.emit(true)
|
||||
while _ws.get_available_packet_count() > 0:
|
||||
_handle_packet(_ws.get_packet().get_string_from_utf8())
|
||||
_ping_accum += delta
|
||||
if _ping_accum >= PING_INTERVAL:
|
||||
_ping_accum = 0.0
|
||||
_ws.send_text("{\"type\":\"ping\"}")
|
||||
elif state == WebSocketPeer.STATE_CLOSED:
|
||||
_ws = null
|
||||
_reconnect_accum = 0.0
|
||||
if _open:
|
||||
_open = false
|
||||
connection_changed.emit(false)
|
||||
|
||||
func _handle_packet(text: String) -> void:
|
||||
var json := JSON.new()
|
||||
if json.parse(text) != OK:
|
||||
return
|
||||
if not (json.data is Dictionary):
|
||||
return
|
||||
var msg: Dictionary = json.data
|
||||
match str(msg.get("type", "")):
|
||||
"online_list":
|
||||
var players: Array = msg.get("players", [])
|
||||
online_list.emit(players)
|
||||
"player_joined":
|
||||
player_joined.emit(msg)
|
||||
"player_moved":
|
||||
player_moved.emit(msg)
|
||||
"player_left":
|
||||
player_left.emit(int(msg.get("char_id", 0)))
|
||||
"chat":
|
||||
chat_received.emit(msg)
|
||||
"chat_history":
|
||||
var messages: Array = msg.get("messages", [])
|
||||
if str(msg.get("channel", "global")) == "local":
|
||||
local_chat_history.emit(messages)
|
||||
else:
|
||||
chat_history.emit(messages)
|
||||
"pong":
|
||||
pass
|
||||
|
||||
func send_chat(text: String, channel: String = "global") -> void:
|
||||
if _ws == null or _ws.get_ready_state() != WebSocketPeer.STATE_OPEN:
|
||||
return
|
||||
var trimmed := text.strip_edges()
|
||||
if trimmed == "":
|
||||
return
|
||||
_ws.send_text(JSON.stringify({"type": "chat", "text": trimmed, "channel": channel}))
|
||||
|
||||
func request_local_history() -> void:
|
||||
if _ws == null or _ws.get_ready_state() != WebSocketPeer.STATE_OPEN:
|
||||
return
|
||||
_ws.send_text("{\"type\":\"get_local_history\"}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue