jarlyyn 发表于 2024-5-22 11:12:16

杰哥乱弹琴之任务多行文字处理

本帖最后由 jarlyyn 于 2024-5-23 01:44 AM 编辑

众所周知,Mud客户端的触发器是一个很常用很重要的功能。

正常的Mud会需要触发器做单行或2-3行的文字匹配,获取任务信息,进而完成任务。

但北侠比较,怎么说呢,另辟蹊径吧,WIZ不喜欢简单明快的把任务信息给到玩家,需要玩家收集多行信息甚至处理颜色进行分析。

对于没有经验的玩家来说,收集任务信息会显得比较蛋疼。

我做了一个方便处理任务多行信息模块,希望能够帮助到有需要的人。

这是这个帖子的背景。

jarlyyn 发表于 2024-5-22 11:15:10

使用库之前先要进行安装。

目前这个库支持GBK编码的mushclient和utf8编码的mudlet

具体安装说明见

https://www.pkuxkx.net/forum/thread-49188-1-1.html

此帖的2楼

jarlyyn 发表于 2024-5-22 11:18:46

本帖最后由 jarlyyn 于 2024-5-22 11:39 AM 编辑

在这个帖子中,我们主要会用到以下工具

Hclua.HC.history:getLines(length,offset)从历史信息里获取指定长度的行,可以偏差offset行

Hclua.HC.recorder:start(999)默认记录器开始记录信息,最多999条

Hclua.HC.recorder:getLines()默认记录器获取已经记录的信息

Hclua.HC.lineutils多行信息的处理工具

jarlyyn 发表于 2024-5-22 11:21:40

本帖最后由 jarlyyn 于 2024-5-22 11:25 AM 编辑

关于行信息。

由于我的库的设计目标是跨客户端使用的,所以我必须把行信息抽出来做一个独立于客户端的存在

具体的信息具体如下

行信息标准

[*]一个行代表一串带样式的文字
[*]行信息来源应该为Mud客户端匹配的一行服务器文字
[*]正常情况下,行信息不应该包含换行符号
[*]行的内容包括 Text(行正文)和Words(词列表)
[*]Words词列表指将原始服务器文字,按样式不同(而非ansi指令)进行分割,按原始顺序排序
[*]Text行正文等于所有Words中的词的正文的拼接
[*]每个Word词包含如下属性:Text文本,Color色彩,Backgroud背景,Bold加粗,Underlined下划线,Blinking闪烁,Inverse反色
[*]Word词的Text指一段样式对应的文本。
[*]Word词的Color和Backgroud都是字符串,分为标准色和RGB色
[*]标准色为''[默认],'Black'[黑色],'Red'[红色],'Green'[绿色],'Yellow'[黄色],'Blue'[蓝色],'Magenta'[紫色],'Cyan'[青色],'White'[白色],'BrightBlack'[浅黑],'BrightRed'[浅红],'BrightGreen'[浅绿],'BrightYellow'[浅黄],'BrightBlue'[浅蓝],'BrightMagenta'[浅紫],'BrightCyan'[浅青],'BrightWhite'[浅白]
[*]标准色一般根据客户端实现来取值,如有冲突,按上一条的顺序进行优先匹配。色彩和背景色的默认一般指客户端设置的不同的颜色
[*]RGB色为以#开头,6位大写16进制数,如'#CCCCCC'
[*]Bold加粗指ansi控制符1的效果,具体取决于客户端实现,值为布尔值
[*]Underline下划线指ansi控制符4的效果,具体取决于客户端实现,值为布尔值
[*]Blink闪烁指ansi控制符5,6或3的效果,具体取决于客户端实现,值为布尔值
[*]Inverse反色指ansi控制符7的效果,具体取决于客户端实现,值为布尔值
行信息短描述
行信息短描述是一种将带样式的行信息格式化为紧凑,易识别,易保存,易维护,能直接比较的格式.范例如下#0AA0标准色文字#1CCCCCCCCCCCC1纯RGB色加粗文字#1CCCCCC*A5RGB色标准背景闪烁加粗文字#1*ACCCCCCE标准色RGB背景加粗下划线闪烁反色文字

具体格式如下
[*]短描述分为样式和正文部分,样式部分在正文部分之前
[*]样式部分以#号开始,正文中所有的#都转义为##
[*]短描述样式部分为#开头,后接版本数0或1
[*]#0为标准色模式样式,格式为#0AA0,第3为字母A开始的色彩序号,第4为字母A开始的背景色序号,第5位为16进制数表示的样式
[*]#1为RGB模式样式,格式为#1CCCCCCCCCCCCC0,#1*ACCCCCC0,#1CCCCCC*A0 格式。第三位开始为色彩表号,*开头表示后一位为字母A开始的色彩序号,否者之后6位为大写16进制色彩。最后一位为16进制数表示的样式
[*]16进制数表示的样式为2进制标志位,其中Bold为1位,Underline为2位,Blinking为4位,Inverse为8位
[*]多个词的短描述可以直接作为字符串拼接,以#作为标志分割

具体来说大体可以这么认为

[*]行信息就是把mushclient的getStyleInfo有用的部分,一个个取出来,放在一个table里,每个style一个Word放在Words里。
[*]Word有Text对应原本的文字,有Bold,Underlined,Blink,Inverse对应本来的stlye
[*]由于table无法直接比较和保存,提供了一个短描述功能,将带样式的字符串专成能比较易读写的字符串格式。方便处理。

具体参考:https://github.com/hellclient-scripts/hc-lua/tree/main/src/hclua/lib/line

jarlyyn 发表于 2024-5-22 11:36:28

本帖最后由 jarlyyn 于 2024-5-22 11:39 AM 编辑

接下来开始举例使用了

我们有一个很常见的需求,是于到指定触发后,获取之前N行的内容。

比如武当炼丹的新人任务,在看到调整火大小的提示后,需要看之前的图形的颜色。

那很简单,我们先做一个提示的触发,触发中将以下内容发送的lua

local lines=Hclua.HC.history:getLines(1,3)取出倒数三行,长度为1的内容

假设颜色判断是判断mush第5个字符出的颜色,我们就可以取得
local colorline=lines:slice(5,1):slice切片功能,代表从第5个字符开始切1个字符,这比较适合喜欢把文字信息当word使用的北侠巫师
color就是去切出来的内容的第一个词组(就是mush的style)的颜色

如果你是utf8的客户端,比如Mudlet,由于utf8是变长的,不能直接这样切.不过不用急,我也提供了utf8版本的对应功能,叫UTF8Mono,对应代码如下
local colorline=Hclua.lineutils.UTF8Mono(lines,5,1)

然后Color取出来的值应该是一下的值之一
Black
      Red
      Green
      Yellow
      Blue
      Magenta
      Cyan
      White
      BrightBlack
      BrightRed
      BrightGreen
      BrightYellow
      BrightBlue
      BrightMagenta
      BrightCyan
      BrightWhite

一个if判断下,这个任务就分分钟完成了。

这就是行信息库最基本的功能:获取历史信息,裁切需要的部分,直接获取样式和文字

jarlyyn 发表于 2024-5-22 11:46:36

好了,我们再看下一个内容。

大部分任务,并不是向上面这样处理的,而是先想NPC ask一个内容,做判断。

为了这个场景,我还做了一个记录器对象。功能很简单。

Hclua.HC.recorder:start(999)开始录音
Hclua.HC.recorder:getLines()获取到已经录音的内容

实际使用的时候,一般是触发 ^你向XXXX打听关于『XXXX』的事,开始录音。

同时再ask之后发送一个resonse R:questfinish

触发获取之间的内容,就可以玩了

local result=Hclua.HC.recorder:getLines()

if result=="NPC告诉你XXX" then
end

if result=="NPC告诉你你来的太早了,哪凉快哪边去
end

jarlyyn 发表于 2024-5-22 11:49:34

补充一个小技巧

如果于到之前偷学的帖子里,回答持续很久,不知道什么时候结束怎么办?

很简单,做个timer,每隔两秒发送一个'response R:answertimeout'

触发成功就关time,获取内容,不然就等触发成功。

如果是烟花哪种固定时间的,直接定一个timer response就行。

jarlyyn 发表于 2024-5-22 12:04:33

在来说说 toshort,

toShort主要有两个功能,一个是整个行的toShort,这个不太常用,一般是裁切后再使用。

另一个行Words的里每个Word,
有word:toShort,带文字转换,
和word:toShortStlye,单纯样式

都能有很多的用途。

比如一个常见任务,取出一段文字中出现较少的文字

<div>local lines=Hclua.HC.record:getLines()</div><div>local result={}</div><div>for index,line in ipairs(lines) do</div><div>    for index,word in ipairs(lines.Words) do</div><div>          local style=word:toShortStyle()</div><div>          if result==nil then result="" end</div><div>          result=result..word.Text</div><div>    end</div><div>end</div>这样就会把记录的文字都按样式放到数组result内了,剩下就是利用table.sort功能做个排序处理,按实际规则来使用了

jarlyyn 发表于 2024-5-22 12:05:16

午休,去拉个引体,回来继续

jarlyyn 发表于 2024-5-22 13:10:32

本帖最后由 jarlyyn 于 2024-5-22 01:13 PM 编辑

之前的部分我们了解了行信息的基本用法。

但这个库其实比较有价值的部分是lineutils带来的块操作。

所谓快操作,就是把多个行当作图形,进行截取合并后再处理内容。

主要用到的函数如下:

Hclua.HC.lineutils.sliceLines(lines,start,length,max)

将给定的行信息数组进行切片,即统一按开始位置和长度切除新的矩形信息。

第一个参数为行信息数组

第二个参数为切片的开始位置,应该为正整数

第三个参数为切片的长途,应该为正整数

第四个参数为最大行数。默热是保留所有行。

返回值为新的行信息数组。

如果开始位置或长度无效,则返回空



Hclua.HC.lineutils.linesUTF8Mono(lines,start,length,max)

将给定的行信息数组进行utf8显示宽切片,utf8显示宽的批量版本。

第一个参数为行信息数组

第二个参数为切片的开始位置,应该为正整数

第三个参数为切片的长途,应该为正整数

第四个参数为最大行数。默热是保留所有行。

返回值为新的行信息数组。

如果开始位置或长度无效,则返回空




Hclua.HC.lineutils.combineLines(lines,nonewline)

将给到的行信息数组的正文合并为一个字符串

默认用换行分割,第二个参数为true则不加入换行直接合并



Hclua.HC.lineutils.combineLinesShort(lines,nonewline)

将给到的行信息数组的短描述合并为一个字符串

默认用换行分割,第二个参数为true则不加入换行直接合并


Hclua.HC.history和Hclua.HC.recorder负责Y轴裁切

Hclua.lineutils.sliceLines和Hclua.lineutils.linesUTF8Mono负责X轴裁切

Hclua.lineutils.combineLines和Hclua.lineutils.combineLinesShort 负责合并有效数据

具体API参考见https://github.com/hellclient-scripts/hc-lua/blob/main/src/hclua/compontent/lineutils/README.md

页: [1] 2 3
查看完整版本: 杰哥乱弹琴之任务多行文字处理