# chat_tail_test —— §8.8 头顶「聊天 / 信息」尾标 1:1: # CPythonTextTail::RegisterChatTail / RegisterInfoTail 的白 / 淡红色、bNameFlag、 # gs_TextTail_LivingTime(5000,assert >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_prefix:strchr(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_tail:switch 里 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_tail:RecvChatPacket 除 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. expire:UpdateAllTextTail 的 LivingTime < now 删除 ----------------- # vid 42 LivingTime = t0+2000+5000 = t0+7000;vid 7 = t0+5000 var dead := ChatTail.expire(tails, t0 + 6000) _ck(dead == [7], "expire(now=t0+6000) 清掉 vid 7(LivingTime 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 返回 []")