完善客户端功能并同步差距文档

This commit is contained in:
shenlei
2026-09-03 18:40:01 +09:00
parent f93a172296
commit 13ccb8d02d
135 changed files with 21881 additions and 1259 deletions
+106
View File
@@ -0,0 +1,106 @@
# chat_tail_test —— §8.8 头顶「聊天 / 信息」尾标 1:1:
# CPythonTextTail::RegisterChatTail / RegisterInfoTail 的白 / 淡红色、bNameFlag、
# gs_TextTail_LivingTime5000assert >1000)、m_ChatTailMap 每 vid 一条 + chat/info 共表、
# UpdateAllTextTail 的 LivingTime < now 删除、IsChatTextTail,以及
# RecvChatPacket 的 "名字: " 前缀剥离 + SHOUT/COMMAND 不进尾标。
# godot --headless --path project --script chat_tail_test.gd
# 退出码 0 = 全过。
extends SceneTree
const ChatTail = preload("res://chat_tail.gd")
var _fail := 0
func _ck(c: bool, m: String) -> void:
if not c:
_fail += 1
printerr("FAIL: " + m)
func _init() -> void:
_run()
if _fail == 0:
print("PASS: chat_tail_test (§8.8 RegisterChatTail / RegisterInfoTail / LivingTime 1:1)")
quit(0)
else:
printerr("%d check(s) failed" % _fail)
quit(1)
func _run() -> void:
# --- 0. 常量(PythonTextTail.cpp / Packet.h---------------------------------
_ck(ChatTail.CHAT_COLOR.is_equal_approx(Color(1, 1, 1)), "c_TextTail_Chat_Color == white")
_ck(ChatTail.INFO_COLOR.is_equal_approx(Color(1.0, 0.785, 0.785)), "c_TextTail_Info_Color == (1,.785,.785)")
_ck(ChatTail.LIVING_TIME_DEFAULT == 5000, "gs_TextTail_LivingTime == 5000")
_ck(ChatTail.LIVING_TIME_MIN == 1000, "TextTail_GetLivingTime assert 下界 == 1000")
_ck(ChatTail.HEIGHT_ADD == 10.0, "新建分支高度 = 角色高 + 10")
# EChatType 枚举顺序(Packet.h:1410
_ck(ChatTail.CT_TALKING == 0 and ChatTail.CT_INFO == 1 and ChatTail.CT_NOTICE == 2, "EChatType 0/1/2")
_ck(ChatTail.CT_PARTY == 3 and ChatTail.CT_GUILD == 4 and ChatTail.CT_COMMAND == 5, "EChatType 3/4/5")
_ck(ChatTail.CT_SHOUT == 6 and ChatTail.CT_WHISPER == 7 and ChatTail.CT_BIG_NOTICE == 8, "EChatType 6/7/8")
# --- 1. TextTail_GetLivingTime / SetLivingTime ------------------------------
_ck(ChatTail.living_time() == 5000, "living_time() 默认 5000")
ChatTail.set_living_time(8000)
_ck(ChatTail.living_time() == 8000, "set_living_time(8000) 生效")
ChatTail.set_living_time(ChatTail.LIVING_TIME_DEFAULT) # 还原,避免污染同进程后续测试
_ck(ChatTail.living_time() == 5000, "restore: living_time 回 5000")
# --- 2. strip_name_prefixstrchr(buf,':') ? p+2 : buf --------------------
_ck(ChatTail.strip_name_prefix("Alice: hello world") == "hello world", "去掉 \"Alice: \" 前缀")
_ck(ChatTail.strip_name_prefix("nocolon here") == "nocolon here", "无冒号 -> 原样")
_ck(ChatTail.strip_name_prefix("A: x: y") == "x: y", "只吃第一个冒号")
_ck(ChatTail.strip_name_prefix("Bob: ") == "", "\"Bob: \" -> 空")
# --- 3. line_for_tailswitch 里 TALKING/PARTY/GUILD/SHOUT/WHISPER 去前缀 ----
_ck(ChatTail.line_for_tail(ChatTail.CT_TALKING, "Kane: hi") == "hi", "TALKING 去前缀")
_ck(ChatTail.line_for_tail(ChatTail.CT_PARTY, "Kane: hi") == "hi", "PARTY 去前缀")
_ck(ChatTail.line_for_tail(ChatTail.CT_GUILD, "Kane: hi") == "hi", "GUILD 去前缀")
_ck(ChatTail.line_for_tail(ChatTail.CT_WHISPER, "Kane: hi") == "hi", "WHISPER 去前缀")
_ck(ChatTail.line_for_tail(ChatTail.CT_SHOUT, "Kane: hi") == "hi", "SHOUT 也走去前缀分支")
_ck(ChatTail.line_for_tail(ChatTail.CT_INFO, "You got 10 gold") == "You got 10 gold", "INFO 原样")
_ck(ChatTail.line_for_tail(ChatTail.CT_NOTICE, "server: down soon") == "server: down soon", "NOTICE 原样")
_ck(ChatTail.line_for_tail(ChatTail.CT_BIG_NOTICE, "boss: alive") == "boss: alive", "BIG_NOTICE 原样")
# --- 4. wants_chat_tailRecvChatPacket 除 SHOUT / COMMAND 外都进尾标 --------
_ck(ChatTail.wants_chat_tail(ChatTail.CT_TALKING), "TALKING 进尾标")
_ck(ChatTail.wants_chat_tail(ChatTail.CT_PARTY), "PARTY 进尾标")
_ck(ChatTail.wants_chat_tail(ChatTail.CT_GUILD), "GUILD 进尾标")
_ck(ChatTail.wants_chat_tail(ChatTail.CT_WHISPER), "WHISPER 进尾标")
_ck(ChatTail.wants_chat_tail(ChatTail.CT_INFO), "INFO 进尾标")
_ck(ChatTail.wants_chat_tail(ChatTail.CT_NOTICE), "NOTICE 进尾标")
_ck(ChatTail.wants_chat_tail(ChatTail.CT_BIG_NOTICE), "BIG_NOTICE 进尾标")
_ck(not ChatTail.wants_chat_tail(ChatTail.CT_SHOUT), "SHOUT 不进尾标(:1372 显式排除)")
_ck(not ChatTail.wants_chat_tail(ChatTail.CT_COMMAND), "COMMAND 不进尾标(提前 return")
# --- 5. RegisterChatTail:新建 / 原地替换 / bNameFlag / LivingTime ----------
var tails := {}
var t0 := 100000
var c := ChatTail.register_chat(tails, 42, "hello", t0)
_ck(tails.size() == 1 and tails.has(42), "register_chat -> m_ChatTailMap 里一条 vid 42")
_ck(c["text"] == "hello", "chat tail 文本 == hello")
_ck(c["color"].is_equal_approx(Color(1, 1, 1)), "chat tail 色 == 白")
_ck(c["name_flag"] == true, "chat tail bNameFlag == TRUE")
_ck(int(c["living_time"]) == t0 + 5000, "chat tail LivingTime == now + GetLivingTime()")
# 同 vid 再来一条 —— 原地替换(find != end 分支),仍只有一条
var c2 := ChatTail.register_chat(tails, 42, "hello again", t0 + 1000)
_ck(tails.size() == 1, "同 vid 再 register_chat 不新增键")
_ck(c2["text"] == "hello again" and int(c2["living_time"]) == t0 + 6000, "原地改文本 + 续命")
_ck(ChatTail.is_chat_text_tail(tails, 42), "IsChatTextTail(42) == true")
_ck(not ChatTail.is_chat_text_tail(tails, 99), "IsChatTextTail(99) == false")
# --- 6. RegisterInfoTail:淡红 + bNameFlag FALSE,与 chat 共用 m_ChatTailMap --
var i := ChatTail.register_info(tails, 42, "used skill fail", t0 + 2000)
_ck(tails.size() == 1, "info tail 覆盖同 vid 的 chat tail(共表),仍一条")
_ck(i["color"].is_equal_approx(Color(1.0, 0.785, 0.785)), "info tail 色 == 淡红")
_ck(i["name_flag"] == false, "info tail bNameFlag == FALSE")
_ck(i["text"] == "used skill fail", "info tail 文本替换")
var i2 := ChatTail.register_info(tails, 7, "no arrows", t0)
_ck(tails.size() == 2 and i2["name_flag"] == false, "另一 vid 的 info tail 独立成键")
# --- 7. expireUpdateAllTextTail 的 LivingTime < now 删除 -----------------
# vid 42 LivingTime = t0+2000+5000 = t0+7000vid 7 = t0+5000
var dead := ChatTail.expire(tails, t0 + 6000)
_ck(dead == [7], "expire(now=t0+6000) 清掉 vid 7LivingTime t0+5000")
_ck(tails.size() == 1 and tails.has(42), "vid 42 未到点,保留")
var dead2 := ChatTail.expire(tails, t0 + 7001)
_ck(dead2 == [42], "expire(now=t0+7001) 清掉 vid 42")
_ck(tails.is_empty(), "全部到点后 m_ChatTailMap 空")
_ck(ChatTail.expire(tails, t0 + 99999) == [], "空表 expire 返回 []")