feat: expand multiplayer, chat, and release support

- add network NPC synchronization and dialogue interactions
- add world bulletin publishing and display
- improve authentication, session refresh, and appearance sync
- synchronize player direction and movement animations
- improve input focus and progressive Web loading
- add macOS/Windows builds and deployment configuration
- include required fonts, shaders, and runtime assets
This commit is contained in:
2026-09-08 21:37:43 +08:00
parent 175621f66c
commit fc6c3c1bd3
87 changed files with 4546 additions and 506 deletions

View File

@@ -69,7 +69,7 @@ enum ConnectionState {
# ============================================================================
# WebSocket 服务器 URL原生 WebSocket
const WEBSOCKET_URL: String = "wss://whaletownend.xinghangee.icu/game"
const WEBSOCKET_URL: String = "wss://whaletown.novamailio.com/game"
# 默认最大重连次数
const DEFAULT_MAX_RECONNECT_ATTEMPTS: int = 5
@@ -119,6 +119,9 @@ var _heartbeat_timer: Timer
# 心跳间隔(秒)
const HEARTBEAT_INTERVAL: float = 30.0
const HEARTBEAT_TIMEOUT: float = 75.0
var _last_server_message_at_msec: int = 0
# ============================================================================
# 生命周期方法
@@ -149,6 +152,7 @@ func _process(_delta: float) -> void:
while _websocket_peer.get_available_packet_count() > 0:
var packet: PackedByteArray = _websocket_peer.get_packet()
var message: String = packet.get_string_from_utf8()
_last_server_message_at_msec = Time.get_ticks_msec()
# 发射消息接收信号
data_received.emit(message)
@@ -194,9 +198,6 @@ func connect_to_game_server(is_reconnect_attempt: bool = false) -> void:
_set_connection_state(ConnectionState.ERROR)
return
# 启动心跳
_start_heartbeat()
# 断开 WebSocket 连接
func disconnect_websocket() -> void:
_disconnect()
@@ -358,9 +359,12 @@ func _on_websocket_connected() -> void:
reconnection_succeeded.emit()
_set_connection_state(ConnectionState.CONNECTED)
_last_server_message_at_msec = Time.get_ticks_msec()
_start_heartbeat()
# WebSocket 连接关闭处理
func _on_websocket_closed() -> void:
_stop_heartbeat()
if not _manual_disconnect_requested and _auto_reconnect_enabled:
connection_lost.emit()
_attempt_reconnect()
@@ -382,13 +386,6 @@ func _setup_reconnect_timer() -> void:
# 尝试重连
func _attempt_reconnect() -> void:
# 检查是否超过最大重连次数
if _reconnect_attempt >= _max_reconnect_attempts:
push_error("WebSocketManager: 达到最大重连次数 (%d),停止重连" % _max_reconnect_attempts)
reconnection_failed.emit(_reconnect_attempt, _max_reconnect_attempts)
_set_connection_state(ConnectionState.ERROR)
return
_reconnect_attempt += 1
_set_connection_state(ConnectionState.RECONNECTING)
@@ -401,7 +398,8 @@ func _attempt_reconnect() -> void:
# 计算重连延迟(指数退避)
func _calculate_reconnect_delay() -> float:
# 指数退避: base_delay * 2^(attempt-1)
var delay: float = _reconnect_base_delay * pow(2.0, _reconnect_attempt - 1)
var cappedAttempt := mini(_reconnect_attempt, maxi(_max_reconnect_attempts, 1))
var delay: float = _reconnect_base_delay * pow(2.0, cappedAttempt - 1)
# 限制最大延迟
return min(delay, MAX_RECONNECT_DELAY)
@@ -434,9 +432,16 @@ func _stop_heartbeat() -> void:
# 心跳超时处理
func _on_heartbeat() -> void:
# 不发送心跳,避免服务器返回 "消息格式错误"
# 如果需要心跳,服务器应该支持特定格式
pass
if _websocket_peer.get_ready_state() != WebSocketPeer.STATE_OPEN:
return
var now := Time.get_ticks_msec()
if _last_server_message_at_msec > 0 and now - _last_server_message_at_msec > int(HEARTBEAT_TIMEOUT * 1000.0):
push_warning("WebSocketManager: 心跳超时,正在重新连接")
_websocket_peer.close(4000, "Heartbeat timeout")
return
var err := _websocket_peer.send_text(JSON.stringify({"type": "ping"}))
if err != OK:
push_warning("WebSocketManager: 心跳发送失败 - %s" % error_string(err))
# ============================================================================
# 工具方法
@@ -455,7 +460,7 @@ func get_state_description() -> String:
ConnectionState.CONNECTED:
return "已连接"
ConnectionState.RECONNECTING:
return "重连中 (%d/%d)" % [_reconnect_attempt, _max_reconnect_attempts]
return "重连中 (%d)" % _reconnect_attempt
ConnectionState.ERROR:
return "错误"
_: