fix: 装备属性面板避让逻辑 + 多项功能更新
- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
This commit is contained in:
@@ -25,13 +25,22 @@ var _deadline := 0.0
|
||||
var _sent := false
|
||||
var _classic := false
|
||||
var _classic_rx := PackedByteArray()
|
||||
var _status_body_rx := PackedByteArray()
|
||||
|
||||
func query(host: String, port: int, callback: Callable = Callable(), timeout_s := 3.0) -> void:
|
||||
# ServerStateChecker owns one probe stream. Cancel the previous transport
|
||||
# before replacing it so a repeated request cannot leave an old socket alive
|
||||
# behind the new callback.
|
||||
if _peer != null:
|
||||
_peer.disconnect_from_host()
|
||||
_peer = null
|
||||
set_process(false)
|
||||
_cb = callback
|
||||
_peer = StreamPeerTCP.new()
|
||||
_sent = false
|
||||
_classic = OS.get_environment("MT_PROTOCOL") == "classic"
|
||||
_classic_rx = PackedByteArray()
|
||||
_status_body_rx = PackedByteArray()
|
||||
_deadline = _now() + timeout_s
|
||||
if _peer.connect_to_host(host, port) != OK:
|
||||
_finish({})
|
||||
@@ -132,24 +141,41 @@ func _try_parse() -> void:
|
||||
_peer.get_data(rest)
|
||||
|
||||
func _read_body() -> void:
|
||||
# 已消费 4 字节头;接着 int32 count + count × {i16 port, u8 status}
|
||||
if _peer.get_available_bytes() < 4:
|
||||
# 已消费 4 字节头;接着 int32 count + count × {i16 port, u8 status}。
|
||||
# StreamPeerTCP 可能把 body 分成多个到达批次,必须保留已收到的
|
||||
# 字节,不能像旧实现一样在第一条不完整 record 时提前 finish。
|
||||
var avail := _peer.get_available_bytes()
|
||||
if avail > 0:
|
||||
var chunk: Array = _peer.get_data(avail)
|
||||
if chunk[0] != OK:
|
||||
_finish({})
|
||||
return
|
||||
_status_body_rx.append_array(chunk[1])
|
||||
if _status_body_rx.size() < 4:
|
||||
return
|
||||
var count: int = _status_body_rx.decode_s32(0)
|
||||
if count < 0 or count > 4096:
|
||||
_finish({})
|
||||
return
|
||||
var total := 4 + count * 3
|
||||
if _status_body_rx.size() < total:
|
||||
return
|
||||
var cnt_r: Array = _peer.get_data(4)
|
||||
var count: int = (cnt_r[1] as PackedByteArray).decode_s32(0)
|
||||
var out := {}
|
||||
for i in count:
|
||||
if _peer.get_available_bytes() < 3:
|
||||
break
|
||||
var rec: PackedByteArray = _peer.get_data(3)[1]
|
||||
out[rec.decode_s16(0)] = rec.decode_u8(2)
|
||||
var off := 4 + i * 3
|
||||
out[_status_body_rx.decode_s16(off)] = _status_body_rx.decode_u8(off + 2)
|
||||
_finish(out)
|
||||
|
||||
func _finish(m: Dictionary) -> void:
|
||||
# Capture the callback before emitting `done`: a listener may immediately
|
||||
# start the next probe. Calling the mutable `_cb` afterwards would deliver
|
||||
# the old result to the new request (a stale re-entrant callback).
|
||||
var callback := _cb
|
||||
_cb = Callable()
|
||||
set_process(false)
|
||||
if _peer:
|
||||
_peer.disconnect_from_host()
|
||||
_peer = null
|
||||
done.emit(m)
|
||||
if _cb.is_valid():
|
||||
_cb.call(m)
|
||||
if callback.is_valid():
|
||||
callback.call(m)
|
||||
|
||||
Reference in New Issue
Block a user