@@InPutString触发的输入框把玩家填的内容存进S变量,但这个变量直接拿去用的话,玩家输什么就会存什么。特殊符号乱入会导致脚本逻辑断掉,甚至触发引擎未预料的跳转。非法字符过滤和变量清洗这两个步骤必须做掉。
非法字符过滤的机制在不同引擎里有差异。Hero引擎在M2Server的查看→列表信息→其他设置里配置过滤词库,玩家提交输入后自动匹配库里的词条,命中的话跳转到[@IsInFilterList]标签。3K引擎的过滤配置在插件管理的消息过滤里,匹配后跳转[@MsgFilter]。GOM和GEE引擎则通过UI输入组件的参数控制,或者用脚本命令做二次检测。
常见的非法字符包括引号、分号、换行符、脚本跳转符号等。单引号和双引号会破坏字符串定界,分号在部分引擎里被当作注释符,换行符则可能让玩家伪造对话内容。更关键的是@@和@符号,如果玩家输入的内容被直接拼接进后续的GOTO或CALL指令,可能造成非预期的流程跳转。
不做过滤的后果很直接。输入框让玩家写名字,结果填了@@InPutString这样的内容,引擎可能会把这个当成指令重新执行一次输入框弹出,造成无限循环。更严重的情况是玩家在输入框里填入脚本段落的跳转标签,如果后续脚本里用了GOTO@<$STR(S1)>这种写法,输入的内容直接变成跳转目标,可能绕过条件判断直接执行未授权的操作。
变量处理的核心是空值检测。玩家点了确定但没打字就提交,S变量的值变成了空字符串。后续的逻辑如果直接用这个空变量做字符串拼接,会导致GOTO后面的标签名变成空,引擎找不到跳转目标就报错或卡死。用CheckStringLength命令检测S变量的字符数,等于0就弹提示让玩家重新输入,不能用空值往下走。
长度限制同样重要。有的版本里S变量的最大长度是64字符,输入超长的内容时引擎会自动截断,但截断后的部分可能丢失关键信息导致功能出错。用CheckStringLength配合上限值做检测,超过上限就提示重新输入,不直接往下处理。不同引擎的字符编码方式不同,一个中文字符在部分版本里算1个长度,在另一些版本里算2个,测试时要注意。
内容清洗的具体做法是先用Trim去除首尾空格,防止玩家用空格绕过空值检测。然后逐字符扫描或使用正则匹配替换,把敏感符号替换成空或转义字符。GOM和GEE引擎支持自定义输入过滤配置,在输入框属性里直接指定允许的字符集,比如只允许中文、字母和数字。Hero引擎没有输入框级别的过滤,需要在回调段里手动清洗。
清洗完的内容存到新的变量里再往下传。直接复用S变量可能引发数据污染,用Mov命令把清洗后的内容转到其他编号的S变量,比如MovS10S1,然后用S10参与后续逻辑。这样即使原始S1被其他操作覆盖,清洗后的数据依然保留。
输出玩家输入内容时避免直接拼接。用SENDMSG或SAY输出玩家名字时,直接放$STR(S1)没问题,但如果要把这个值塞进GOTO、CALL或者CHECK命令里,得先做合法性校验。判断输入内容是否以@开头,如果是就拦截掉,防止玩家用输入内容伪造跳转标签。判断内容是否包含空格或特殊符号,有些版本里空格会被引擎当作参数分隔符,导致命令解析错位。
输入内容的转义处理经常被忽略。玩家输入的内容里如果包含\字符,在文件路径操作里会被当作转义符,导致路径解析失败。包含%符号的话,在格式字符串里可能被当成占位符。这些符号在中文字符集里出现概率不高,但一旦出现就会造成奇怪的错误。建议只允许字母、数字、中文字符和下划线,其他符号一概过滤掉。
回显玩家输入内容时同样要注意格式。在SAY对话框里显示玩家的名字、留言或自定义内容,如果内容里包含换行符,会导致对话框布局错乱。在对话框文本里用<BR>或换行符来控制排版,玩家的输入内容里不应该包含排版控制符,发现就替换掉。
配置过滤词库时要考虑繁体中文和简体中文同时覆盖。有些引擎的词库区分简繁体,玩家用繁体输入敏感词就绕过检测了。用转换命令把繁体转简体后再做匹配,或者词库里同时包含简繁两种写法。
不同引擎对S变量的编号范围限制不同,超过范围的使用可能导致变量被覆盖。尽量使用10到99之间的编号,避开0到9这些可能被系统占用的低编号变量。多个输入框同时使用时,每个输入框用独立的变量编号,避免相互覆盖。
测试过滤逻辑的时机也很重要。输入框回调段里做过滤检测,检测通过后再执行扣物品或加属性的操作。不能先扣东西再检查输入内容,万一内容非法导致后续逻辑出错,玩家的东西已经扣掉了但没给奖励,这种问题最难挽回。
非法字符过滤的机制在不同引擎里有差异。Hero引擎在M2Server的查看→列表信息→其他设置里配置过滤词库,玩家提交输入后自动匹配库里的词条,命中的话跳转到[@IsInFilterList]标签。3K引擎的过滤配置在插件管理的消息过滤里,匹配后跳转[@MsgFilter]。GOM和GEE引擎则通过UI输入组件的参数控制,或者用脚本命令做二次检测。
常见的非法字符包括引号、分号、换行符、脚本跳转符号等。单引号和双引号会破坏字符串定界,分号在部分引擎里被当作注释符,换行符则可能让玩家伪造对话内容。更关键的是@@和@符号,如果玩家输入的内容被直接拼接进后续的GOTO或CALL指令,可能造成非预期的流程跳转。
不做过滤的后果很直接。输入框让玩家写名字,结果填了@@InPutString这样的内容,引擎可能会把这个当成指令重新执行一次输入框弹出,造成无限循环。更严重的情况是玩家在输入框里填入脚本段落的跳转标签,如果后续脚本里用了GOTO@<$STR(S1)>这种写法,输入的内容直接变成跳转目标,可能绕过条件判断直接执行未授权的操作。
变量处理的核心是空值检测。玩家点了确定但没打字就提交,S变量的值变成了空字符串。后续的逻辑如果直接用这个空变量做字符串拼接,会导致GOTO后面的标签名变成空,引擎找不到跳转目标就报错或卡死。用CheckStringLength命令检测S变量的字符数,等于0就弹提示让玩家重新输入,不能用空值往下走。
长度限制同样重要。有的版本里S变量的最大长度是64字符,输入超长的内容时引擎会自动截断,但截断后的部分可能丢失关键信息导致功能出错。用CheckStringLength配合上限值做检测,超过上限就提示重新输入,不直接往下处理。不同引擎的字符编码方式不同,一个中文字符在部分版本里算1个长度,在另一些版本里算2个,测试时要注意。
内容清洗的具体做法是先用Trim去除首尾空格,防止玩家用空格绕过空值检测。然后逐字符扫描或使用正则匹配替换,把敏感符号替换成空或转义字符。GOM和GEE引擎支持自定义输入过滤配置,在输入框属性里直接指定允许的字符集,比如只允许中文、字母和数字。Hero引擎没有输入框级别的过滤,需要在回调段里手动清洗。
清洗完的内容存到新的变量里再往下传。直接复用S变量可能引发数据污染,用Mov命令把清洗后的内容转到其他编号的S变量,比如MovS10S1,然后用S10参与后续逻辑。这样即使原始S1被其他操作覆盖,清洗后的数据依然保留。
输出玩家输入内容时避免直接拼接。用SENDMSG或SAY输出玩家名字时,直接放$STR(S1)没问题,但如果要把这个值塞进GOTO、CALL或者CHECK命令里,得先做合法性校验。判断输入内容是否以@开头,如果是就拦截掉,防止玩家用输入内容伪造跳转标签。判断内容是否包含空格或特殊符号,有些版本里空格会被引擎当作参数分隔符,导致命令解析错位。
输入内容的转义处理经常被忽略。玩家输入的内容里如果包含\字符,在文件路径操作里会被当作转义符,导致路径解析失败。包含%符号的话,在格式字符串里可能被当成占位符。这些符号在中文字符集里出现概率不高,但一旦出现就会造成奇怪的错误。建议只允许字母、数字、中文字符和下划线,其他符号一概过滤掉。
回显玩家输入内容时同样要注意格式。在SAY对话框里显示玩家的名字、留言或自定义内容,如果内容里包含换行符,会导致对话框布局错乱。在对话框文本里用<BR>或换行符来控制排版,玩家的输入内容里不应该包含排版控制符,发现就替换掉。
配置过滤词库时要考虑繁体中文和简体中文同时覆盖。有些引擎的词库区分简繁体,玩家用繁体输入敏感词就绕过检测了。用转换命令把繁体转简体后再做匹配,或者词库里同时包含简繁两种写法。
不同引擎对S变量的编号范围限制不同,超过范围的使用可能导致变量被覆盖。尽量使用10到99之间的编号,避开0到9这些可能被系统占用的低编号变量。多个输入框同时使用时,每个输入框用独立的变量编号,避免相互覆盖。
测试过滤逻辑的时机也很重要。输入框回调段里做过滤检测,检测通过后再执行扣物品或加属性的操作。不能先扣东西再检查输入内容,万一内容非法导致后续逻辑出错,玩家的东西已经扣掉了但没给奖励,这种问题最难挽回。

