fix: 装备属性面板避让逻辑 + 多项功能更新
- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
# auth_peer_close_bridge_test —— 40250 CAccountConnector::OnRemoteDisconnect
|
||||
# 到 M2Client LoginPhase owner 的回归。运行时需要 MT_PROTOCOL=classic。
|
||||
extends SceneTree
|
||||
|
||||
var _fail := 0
|
||||
var _login_failures := 0
|
||||
var _connect_failures := 0
|
||||
|
||||
func _ck(ok: bool, message: String) -> void:
|
||||
if not ok:
|
||||
_fail += 1
|
||||
printerr("FAIL: " + message)
|
||||
|
||||
func _init() -> void:
|
||||
call_deferred("_run")
|
||||
|
||||
func _run() -> void:
|
||||
if not ClassDB.class_exists("M2Client"):
|
||||
_ck(false, "M2Client extension is registered")
|
||||
_finish()
|
||||
return
|
||||
|
||||
var server := TCPServer.new()
|
||||
var listen_error := server.listen(0, "127.0.0.1")
|
||||
_ck(listen_error == OK, "local auth peer-close fixture listens")
|
||||
if listen_error != OK:
|
||||
_finish()
|
||||
return
|
||||
|
||||
var client: Node = ClassDB.instantiate("M2Client")
|
||||
get_root().add_child(client)
|
||||
client.connect("login_failed", Callable(self, "_on_login_failure"))
|
||||
if client.has_signal("connect_failed"):
|
||||
client.connect("connect_failed", Callable(self, "_on_connect_failure"))
|
||||
else:
|
||||
_ck(false, "M2Client exposes connect_failed")
|
||||
|
||||
client.connect_to_server("127.0.0.1", server.get_local_port(),
|
||||
"127.0.0.1", 1, "admin", "secret")
|
||||
for _i in range(30):
|
||||
if server.is_connection_available():
|
||||
break
|
||||
await process_frame
|
||||
_ck(server.is_connection_available(), "auth peer-close fixture accepts the connection")
|
||||
if server.is_connection_available():
|
||||
var peer := server.take_connection()
|
||||
_ck(peer != null, "auth peer-close fixture gets the accepted peer")
|
||||
if peer != null:
|
||||
peer.disconnect_from_host()
|
||||
|
||||
# Let M2Client observe EOF and run the same pump that the real LoginWindow
|
||||
# receives after CAccountConnector::OnRemoteDisconnect.
|
||||
for _i in range(30):
|
||||
await process_frame
|
||||
|
||||
_ck(_login_failures == 0,
|
||||
"auth peer close is not reported as credential login failure")
|
||||
_ck(_connect_failures == 0,
|
||||
"auth peer close is not reported as connect failure")
|
||||
_ck(String(client.get_stage()) != "failed",
|
||||
"auth peer close retains a non-terminal LoginPhase owner")
|
||||
|
||||
# The Offline owner must remain usable: a second LoginWindow.Connect replaces
|
||||
# only the auth transport, then the same peer-close rule applies again.
|
||||
var retry_server := TCPServer.new()
|
||||
var retry_error := retry_server.listen(0, "127.0.0.1")
|
||||
_ck(retry_error == OK, "auth peer-close retry fixture listens")
|
||||
if retry_error == OK:
|
||||
client.retry_login("127.0.0.1", retry_server.get_local_port(),
|
||||
"127.0.0.1", 1, "admin", "secret")
|
||||
for _i in range(30):
|
||||
if retry_server.is_connection_available():
|
||||
break
|
||||
await process_frame
|
||||
_ck(retry_server.is_connection_available(),
|
||||
"auth peer-close retry replaces the old auth transport")
|
||||
if retry_server.is_connection_available():
|
||||
var retry_peer := retry_server.take_connection()
|
||||
if retry_peer != null:
|
||||
retry_peer.disconnect_from_host()
|
||||
for _i in range(30):
|
||||
await process_frame
|
||||
_ck(_login_failures == 0 and _connect_failures == 0,
|
||||
"auth peer-close retry remains separate from both failure callbacks")
|
||||
_ck(String(client.get_stage()) != "failed",
|
||||
"auth peer-close retry keeps the LoginPhase owner non-terminal")
|
||||
|
||||
client.disconnect_from_server()
|
||||
client.queue_free()
|
||||
server.stop()
|
||||
retry_server.stop()
|
||||
_finish()
|
||||
|
||||
func _finish() -> void:
|
||||
if _fail == 0:
|
||||
print("PASS: auth_peer_close_bridge_test")
|
||||
else:
|
||||
printerr("%d check(s) failed" % _fail)
|
||||
quit(0 if _fail == 0 else 1)
|
||||
|
||||
func _on_login_failure(_reason: String) -> void:
|
||||
_login_failures += 1
|
||||
|
||||
func _on_connect_failure(_reason: String) -> void:
|
||||
_connect_failures += 1
|
||||
Reference in New Issue
Block a user