Files
mtgodot-poc/project/ui/reconnect_ui.gd
T
shenandClaude Sonnet 5 47baf6c0c6 Metin2 game client (P0–P11) + mobile asset pipeline
Networked client on the existing Godot 4.7 + libgr2 renderer:
- net: m2dev wire protocol (libsodium KX + XChaCha20), auth/select/game
  phases, EntityStore world model, ~all GC/CG headers. char create/delete,
  private shop / mall / cube, SHOP_GC_START_EX, guild, party (+ CG_PARTY_SET_STATE),
  quests, dragon soul, refine, safebox, exchange.
- UI: in-game windows migrated 1:1 from the reference uiscript/root .py —
  char status (/stat), inventory+equipment, select-item ([SELECT_ITEM] quest
  token), system-option + game-option + ESC system menu, private-shop 39-grid,
  party info board, shop tabs, atlas, minimap, quickbar, chat, …
- EterGrnLib polish: GR2 material blend/two-sided, LOD crossfade, motion-event
  dispatch, contact shadow, ray-AABB picking, weapon grip pre-transform.

Portable asset IO (A1) — all extension/libgr2/formats/mtproto reads routed
through godot::FileAccess (res:// PCK works on iOS/Android); standalone-lib
*_path() kept for the non-Godot CTests. AssetResolver + PropertyRegistry
switched to a baked index (bake_asset_index.gd) instead of std::filesystem.

Mobile builds: build-{android,ios}.sh, export-android.sh, pack-assets.sh,
gen-debug-keystore.sh. Assets ship as a zip mounted at runtime by
project/asset_pack.gd (adb push now; HTTP download is a drop-in later).

ctest 10/10, 34 GDScript suites, macOS/iOS/Android all build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EJxkHiNKS4kybHS3XKyAJ
2026-08-31 20:02:12 +09:00

107 lines
3.0 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ReconnectUI (P10) —— 断线遮罩 + 自动重连倒计时 + 手动重连。
#
# var rc := preload("res://ui/reconnect_ui.gd").new()
# add_child(rc)
# rc.setup(m2client)
#
# `disconnected(reason)` → 显示遮罩 + "N 秒后自动重连";到点调 client.reconnect()。
# `entered_game` 或任何非 offline 的 phase_changed → 隐藏。
# 按钮:立即重连 / 停止(不再自动)。
extends CanvasLayer
const AUTO_DELAY := 5.0
const MAX_TRIES := 5
var client: Node
var _panel: ColorRect
var _msg: Label
var _count: Label
var _left := 0.0
var _tries := 0
var _auto := true
var _armed := false
func setup(m2client: Node) -> void:
client = m2client
layer = 70
_build()
if client.has_signal("disconnected"):
client.disconnected.connect(_on_disconnected)
if client.has_signal("entered_game"):
client.entered_game.connect(func(): _dismiss())
if client.has_signal("phase_changed"):
client.phase_changed.connect(func(p):
if String(p).to_lower() not in ["offline", "", "close"]:
_dismiss())
func is_showing() -> bool:
return _panel.visible
func _on_disconnected(reason: String) -> void:
_msg.text = "连接断开:%s" % reason
_panel.visible = true
_armed = true
_tries = 0
_left = AUTO_DELAY
func _dismiss() -> void:
_panel.visible = false
_armed = false
func _retry_now() -> void:
if client == null or not client.has_method("reconnect"):
return
_tries += 1
_count.text = "重连中…(第 %d 次)" % _tries
_left = AUTO_DELAY
var ok: bool = client.reconnect()
if not ok:
_count.text = "重连失败,%0.0f 秒后再试" % AUTO_DELAY
func _process(dt: float) -> void:
if not _panel.visible or not _armed:
return
if not _auto:
_count.text = "自动重连已停止"
return
if _tries >= MAX_TRIES:
_count.text = "已重试 %d 次,仍失败" % _tries
return
_left -= dt
_count.text = "%0.0f 秒后自动重连(%d/%d" % [maxf(_left, 0.0), _tries, MAX_TRIES]
if _left <= 0.0:
_retry_now()
func _build() -> void:
_panel = ColorRect.new()
_panel.color = Color(0.05, 0.02, 0.02, 0.92)
_panel.set_anchors_preset(Control.PRESET_FULL_RECT)
_panel.visible = false
add_child(_panel)
var box := VBoxContainer.new()
box.set_anchors_preset(Control.PRESET_CENTER)
box.position = Vector2(-160, -70)
box.custom_minimum_size = Vector2(320, 0)
box.add_theme_constant_override("separation", 12)
_panel.add_child(box)
_msg = Label.new()
_msg.text = "连接断开"
_msg.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_msg.add_theme_font_size_override("font_size", 16)
box.add_child(_msg)
_count = Label.new()
_count.text = ""
_count.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
box.add_child(_count)
var row := HBoxContainer.new()
row.alignment = BoxContainer.ALIGNMENT_CENTER
box.add_child(row)
var now_btn := Button.new()
now_btn.text = "立即重连"
now_btn.pressed.connect(_retry_now)
row.add_child(now_btn)
var stop_btn := Button.new()
stop_btn.text = "停止"
stop_btn.pressed.connect(func(): _auto = false)
row.add_child(stop_btn)