工程参考/配置文件/Server/StringTable.txt

来自天龙知识库
雪舞留言 | 贡献2026年9月12日 (六) 00:49的版本 (维护配置文件知识库:完整字段、读取范围、手工修改实例与核对状态)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航跳到搜索


首页 · 配置文件索引 · 修改约定

StringTable.txt 是一张「编号 → 文本」的对照表,服务端各处用 StringTable_GetText(编号) 取文案,例如阵亡提示、邮件兜底文本。样本 310 行、2 列,读入后放进一个 1024 桶的哈希表。

它是纯服务端文案,不影响客户端界面;客户端有自己的资源与脚本文本。

位置与生效 · 文件格式 · 字段详解 · 修改实例

文件位置与生效

项目 说明
运行文件 ./Config/StringTable.txt,由 FileDef.h 的 FILE_STRING_TABLE 定义,相对于读取进程的工作目录。World 与 Server 都要有一份。
读取程序 World 与 Server 各自调用 StringTable_LoadFromFile(FILE_STRING_TABLE, …) 加载一份;Common/StringTable.cpp 负责解析,LuaFn 与各处的 StringTable_GetText 调用方按编号取文本
生效方法 正常保存并停服后重启对应进程。World 与 Server 各读一份,改动后两个都要重启。当前检索未发现单独重载本文件的可用入口。
样本格式 GB18030-compatibleCRLF。保留原编码;源码读取器不会自动把中文转为 UTF-8。

加载流程在 Common/StringTable.cpp:StringTable_LoadFromFile 用 DBC 读取器打开文件后交给 StringTable_T::LoadFromMemory,逐行读第 1 列编号与第 2 列文本,装进哈希表。

约束 行为
编号重复 哈希分桶时如果发现同号节点,直接 return false——整张表算加载失败。
文案为空 该行跳过,不进表;按编号取不到就返回 "Unknown String"。
取不到编号 GetStringByID 返回 "Unknown String",不会抛错也不会空指针。
表没就绪 构造函数把 m_bReady 置为 false,加载失败时所有调用都返回 "Unknown String"。

很多条目并不是普通句子,而是带 %s 之类占位符的格式串(样本 0 号就是「你被玩家: %s 杀死」)。替换参数由调用方自己传,本表只负责存格式串本身。

文件格式

首行是类型行:INT STRING;第二行是列名行,程序跳过其内容;从第三行开始读取数据。各列用真实 Tab 分隔,保留首列、空列及行尾,不用空格代替。数据行行首 # 表示注释,分号不是此表的注释规则。首列为空的行被跳过;不足的尾列补为空值,多余列不参与本页字段读取。空整数和非数字经 atoi 可能成为 0,空字符串仍为空,不把解析成功当作业务合法。第一列须唯一,重复会触发读取器错误。

字段详解

列号从 1 开始,源码列下标从 0 开始。

字段与类型 含义与修改要点 缺项或特殊值
第 1 列
INT:ID
文案编号,也是 StringTable_GetText 的查询键。分桶用 nID & 1023(负数改成取绝对值再取模),所以编号本身不必连续。 必须唯一;空值解析为 0 也会占一个位置。重复编号会让 LoadFromMemory 提前返回 false,结果是整张表加载失败、所有文案变成 Unknown String。
第 2 列
STRING:字符串$1$
文案正文。常见形态是带占位符的格式串(%s、%d),也可能是一句完整的话。 空串会被整行跳过,等价于这个编号不存在(取用时返回 Unknown String)。

常用修改实例

示例为局部教学片段,先备份原运行文件,再修改对应行并保留其余配置。教学值不是程序默认值。 以下代码块保留真实 Tab;本地示例文件保留原样本编码、中文表头与 CRLF。网页文字使用浏览器编码显示,不表示运行文件应改存 UTF-8。

把 0 号文案换成英文,同时保留 %s 占位符

修改前:

INT	STRING
ID	字符串$1$
0	你被玩家: %s 杀死

修改后:

INT	STRING
ID	字符串$1$
0	You were killed by %s.

按第 1 列定位 0 号。原文案是「你被玩家: %s 杀死」,改成英文后仍然保留 %s 占位符——调用方会用自己的参数去填它,占位符的个数和顺序必须和调用方的实参一致。

这一列建议整条替换:只删掉一半占位符不会报错,但运行时会把玩家名字拼到错误的位置。改完重启 World 与 Server;客户端不需要动。示例块含类型行、列名行与该行原文,不能覆盖整表。

验证与排查

World 与 Server 启动后分别会用到这张表;取不到文案时表现为 "Unknown String" 而不是崩溃,所以要主动验证:在样本里新增一个编号并把调用它的代码路径走一遍。故意把两行写成同一个编号,可以看到整表加载失败、所有文案都变成 Unknown String。改错久案不会有明确报错,保存时注意保留编码与 CRLF。

本地化参数是被丢掉的

StringTable_LoadFromFile(szFile, nLocalizationID) 的第二参数在函数体里只有一句 (VOID)nLocalizationID;,也就是说语言 ID **没有参与任何逻辑**——不会去读 StringTable.txt.en、StringTable.txt.cn 之类的本地化副本。

FileNameAfterLocalization 确实会拼出例如 StringTable.txt.cn 这样的名字,但它唯一的作用是**拼报错信息**:加载失败时日志里显示那个名字,并不代表程序试图打开过它。想做多语言必须自己改代码。

重复编号是整表级故障

哈希插入时遇到同号会 return false,整个 LoadFromMemory 提前退出。后果是**所有**文案取不到,不是只影响重复的那一行。

空串等于不存在

长度为 0 的行会被 continue 跳过,既不占位也不报错,等同于删掉这一行。

World 与 Server 各持一份

两个进程分别加载自己工作目录下的文件,两份内容不一致时会出现「同一句提示在不同进程里文案不同」的现象。

关联与依据

其他配置及整理状态 · 服务端外网设置 · Lua 接口索引

  • Common/StringTable.cpp:实际加载、解析、字段使用或示例关联依据
  • Common/StringTable.h:实际加载、解析、字段使用或示例关联依据
  • Server/Server/WorldServer/World/Main/WorldTable.cpp:实际加载、解析、字段使用或示例关联依据
  • Server/Server/GameServer/Server/Main/GameTable.cpp:实际加载、解析、字段使用或示例关联依据
  • Common/ServerBase/FileDef.h:实际加载、解析、字段使用或示例关联依据
  • Common/DataBase/TLBB_DBC.cpp:实际加载、解析、字段使用或示例关联依据
  • Common/DataBase/TLBB_DBC.h:实际加载、解析、字段使用或示例关联依据
  • Server/Server/GameServer/Server/Script/LuaFnTbl_Mission.h:实际加载、解析、字段使用或示例关联依据
  • resources/Server/Config/StringTable.txt:实际加载、解析、字段使用或示例关联依据

本页核对 StringTable_LoadFromFile / LoadFromMemory / GetStringByID 的实现与 FILE_STRING_TABLE 宏,以及本地化参数被丢弃的事实;未启动服务端与游戏,实际提示文案需要实测。