#nop vim: set filetype=tt:; /* 本文件属于 PaoTin++ 的一部分。 PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp ) 享有并保留一切法律权利 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。 */ #nop 本文件是 xtintin 的一部分,实现了一些实用命令。; ///=== { ///// 实用命令: // // ## xtt.Tick <代码> <间隔时间> // 跟 #tick 功能类似,但是会立即执行一次代码。对于间隔时间比较长的定时器来说尤其有用。 // 你也可以通过 Tick 别名来使用本别名。 // }; #alias {Tick} {xtt.Tick}; #alias {xtt.Tick} { #local id {%1}; #local code {%2}; #local interval {%3}; #line sub var #untick {$id}; #line sub var #tick {$id} {$code} $interval; $code; }; ///=== { // ## xtt.ListTicker // 列出系统中所有的定时器。因为定时器一般不会很多因此暂时没有做过滤功能。 // 你也可以通过 TICKS 别名来使用本别名。 // }; #alias {TICKS} {xtt.ListTicker}; #alias {xtt.ListTicker} { #info tickers save; #echo {<128> %-30s %+20s %+10s %+20s} {所属模块} {定时器名称} {执行周期} {距离下次执行(s)}; #draw Yellow scroll line 1 1 1 90; #format utime %U; #local index {}; #loop {1} {&info[TICKERS][]} {index} { #local uval {}; #math uval $info[TICKERS][+$index][arg3] * 1000000; #echo { %-30s %+20s %+10s %+20m} {@genModuleLink{$info[TICKERS][+$index][class];MOD}} {$info[TICKERS][+$index][arg1]} {$info[TICKERS][+$index][arg3]} {($uval - ($utime - $info[TICKERS][+$index][arg4]) % $uval) / 1000000.00}; }; }; ///=== { // ## xtt.ListAlias [<正则表达式>] // 列出系统中符合条件的别名,如果省略条件则列出所有别名。 // 一些不够规整的别名不会被列出。只有符合 PaoTin++ 规范的别名才会被列出。 // 正则表达式会被运用到别名所属模块名称和别名名称上,两者符合其一即可被列出。 // 你也可以通过 ALIASES 别名来使用本别名。 // }; #alias {ALIASES} {xtt.ListAlias}; #alias {xtt.ListAlias} { #local pattern {%1}; #info aliases save; #local aliasTable {}; #local index {}; #loop {1} {&info[ALIASES][]} {index} { #local name {$info[ALIASES][+$index][arg1]}; #local class {$info[ALIASES][+$index][class]}; #if { "$class" == "" && "$pattern" != "all" } { #continue; }; #if { "$class" == "" } { #local class {未分组}; }; #if { "$name" == "%*{[^a-zA-Z0-9-_.]}%*" } { #continue; }; #if { "$pattern" != "{|all}" && "$class/$name" != "%*$pattern%*" } { #continue; }; #list {aliasTable[$class]} sort {$name}; }; #local format { %-30s %-30s %-10s}; #echo {<128>$format} {class} {别名} {类型}; #draw Yellow scroll line 1 1 1 80; #local classList {@list.Sort{*aliasTable[]}}; #local class {}; #foreach {$classList} {class} { #local name {}; #foreach {${aliasTable[$class][]}} {name} { #local type {<130>自定义<070>}; #if { "$name" == "%*.{[A-Z][a-zA-Z0-9]+}" } { #local type {<120>开放API<070>}; }; #if { "$class" == "module-loader" } { #if { "$name" == "{[A-Z]+}" } { #local type {<160>快捷方式<070>}; }; #else { #local type {<020>语法增强<070>}; } }; #if { "${class}.$name" == "main.class.%*" } { #local type {<020>语法增强<070>}; }; #if { "${class}.$name" == "main.load-file" } { #local type {<020>语法增强<070>}; }; #if { "${class}.$name" == "main.%*Log" } { #local type {<120>日志接口<070>}; }; #if { "$pattern" == "" && "$type" == "%*自定义%*" } { #continue; }; #echo {<060>$format} {@genModuleLink{$class;MOD}<060>} {@linkToHelp{$class;$name}} {$type}; }; }; }; ///=== { // ## xtt.ListVar [<正则表达式>] // 列出系统中符合条件的变量,如果省略条件则列出所有变量。 // 一些不够规整的变量不会被列出。只有符合 PaoTin++ 规范的变量才会被列出。 // 正则表达式会被运用到变量所属模块名称和变量名称上,两者符合其一即可被列出。 // 你也可以通过 VARS 别名来使用本别名。 // }; #alias {VARS} {xtt.ListVar}; #alias {xtt.ListVar} { #local pattern {%1}; #info variable save; #local varTable {}; #local index {}; #loop {1} {&info[VARIABLES][]} {index} { #local name {$info[VARIABLES][+$index][arg1]}; #local class {$info[VARIABLES][+$index][class]}; #local value {$info[VARIABLES][+$index][arg2]}; #local nest {$info[VARIABLES][+$index][nest]}; #if { "$class" == "" && "$pattern" != "all" } { #continue; }; #if { "$class" == "" } { #local class {未分组}; }; #if { "$pattern" != "{|all}" && "$class/$name" != "%*$pattern%*" } { #continue; }; #local {varTable[$class][$name]} { {nest}{$nest} {value}{$value} }; }; #local format { %-30s %-30s %-10s %s}; #echo {<128>$format} {class} {变量} {类型} {值}; #draw Yellow scroll line 1 1 1 80; #local classList {@slist.Sort{*varTable[]}}; #local class {}; #foreach {$classList} {class} { #local name {}; #local nameList {@slist.Sort{*varTable[$class][]}}; #foreach {$nameList} {name} { #local type {<020>字符串<070>}; #local value {<160>$varTable[$class][$name][value]<070>}; #local nest {$varTable[$class][$name][nest]}; #if { $nest > 0 } { #local type {<050>表格<070>}; #local value {@mslp.Var{$name;<130>[... 共 $nest 项数据]<070>}}; }; #echo {<060>$format} {@genModuleLink{$class;MOD}<060>} {@linkToHelp{$class;$name}} {$type} {$value}; }; }; }; ///=== { // ## xtt.ListFunc [<正则表达式>] // 列出系统中符合条件的函数,如果省略条件则列出所有函数。 // 正则表达式会被运用到函数所属模块名称和函数名称上,两者符合其一即可被列出。 // 一些不够规整的函数不会被列出。只有符合 PaoTin++ 规范的函数才会被列出。 // 你也可以通过 FUNCS 别名来使用本别名。 // }; #alias {FUNCS} {xtt.ListFunc}; #alias {xtt.ListFunc} { #local pattern {%1}; #info functions save; #local funcsTable {}; #local index {}; #loop {1} {&info[FUNCTIONS][]} {index} { #local name {$info[FUNCTIONS][+$index][arg1]}; #local class {$info[FUNCTIONS][+$index][class]}; #if { "$class" == "" && "$pattern" != "all" } { #continue; }; #if { "$class" == "" } { #local class {未分组}; }; #if { "$name" == "%*{[^a-zA-Z0-9_./-]}%*" } { #continue; }; #if { "$pattern" != "{|all}" && "$class/$name" != "%*$pattern%*" } { #continue; }; #list {funcsTable[$class]} sort {$name}; }; #local format { %-30s %-30s %-10s}; #echo {<128>$format} {class} {函数} {类型}; #draw Yellow scroll line 1 1 1 80; #local classList {@list.Sort{*funcsTable[]}}; #local class {}; #foreach {$classList} {class} { #local name {}; #foreach {${funcsTable[$class][]}} {name} { #local type {<130>自定义<070>}; #if { "$name" == "%*.{[A-Z][a-zA-Z0-9]+}" } { #local type {<120>开放API<070>}; }; #if { "$class" == "{lib/xtintin|main}" } { #local type {<020>语法增强<070>}; }; #if { "${class}.$name" == "main.%*Log" } { #local type {<120>日志接口<070>}; }; #if { "$pattern" == "" && "$type" == "%*自定义%*" } { #continue; }; #echo {<060>$format} {@genModuleLink{$class;MOD}<060>} {@linkToHelp{$class;$name}} {$type}; }; }; }; ///=== { // ## xtt.Send <命令> [<参数> ...] // 向服务器发送命令。如果命令拦截总开关被打开,则不会真的向服务器发送。 // }; #alias {xtt.Send} { #if { "$xttOptions[DisableOutput]" == "true" } { #echo {<160>命令已被抑制: <420>%p<070>} {%0}; #return; }; #send %0; }; ///=== { // ## xtt.SendAtOnce <分号分隔的命令序列> // 一次性向服务器发送多条命令。 // 有的 MUD 服务器专门为这种方式开辟了通道,本方法可以使用这种通道。 // TODO: 需要区分 MUD,需要支持定制的命令分隔符。 // }; #alias {xtt.SendAtOnce} { #local cmds {%1}; #send {#$cmds#}; }; ///=== { // ## xtt.Answer <问题答复> // 如果游戏中有需要回答的问题,并且给出了特定的提示符(就是不带换行的文本), // 那么由于 TinTin++ 的某种机制,导致回答的内容和问题就会有重叠,不能正确显示。 // 此时建议用 xtt.Answer 来回答此类问题。将会留下美观的 buffer 记录。 // }; #alias {xtt.Answer} { #delay 0 { #echo {}; #buffer end; #send {%1}; }; }; ///=== { // ## xtt.Stop <命令> // 暂时阻断某个命令的执行。 // 某些基于触发的机器会周而复始地执行动作。本命令可以用来终止它的运行,并保留状态。 // 例如新手机器人会循环执行 ask job/do/finish 流程,那么只需要输入 xtt.Stop ask, // 就可以在下一次 ask NPC 时,暂停机器执行,但并不影响机器状态。此时玩家可以手动 // 操作角色,临时去做点别的,比如收个包袱之类的,然后回到房间,手动执行一次 ask 命令, // 就可以继续机器运行了。 // }; #alias {xtt.Stop} { #line oneshot #alias {%1} {halt; #echo {<110>任务已暂停,请输入 <130>%1 %s <110>继续运行。<070>} {%%0}} }; ///=== { // ## xtt.DisableAllCommand // 禁止发送任何命令。 // 某些游戏模式下,玩家必须小心地输入,否则一旦输错会造成损失。此时可以用本 // 命令来禁止所有的触发、定时器、快捷键,等等,防止误发命令。 // 此时玩家只能用 #send {.....} 命令来发送命令。 // }; #alias {xtt.DisableAllCommand} { #class disable-all-command open; #alias {xtt.UndoDisableAllCommand} { #class disable-all-command kill; #line quiet #ignore actions off; #line quiet #ignore tickers off; #line quiet #ignore delays off; #line quiet #ignore events off; #line quiet #ignore macros off; okLog 命令已恢复正常。; } {1.000}; #alias {^%*{|ID=paotin/disable-all-command}$} { #echo {<110>命令已被抑制,可用 <120>#send<110> 强制发送。撤销请用 <120>xtt.UndoDisableAllCommand<110> : <130>%s<070>} {%%0} } {1.001}; #line quiet #ignore actions on; #line quiet #ignore tickers on; #line quiet #ignore delays on; #line quiet #ignore events on; #line quiet #ignore macros on; #class disable-all-command close; }; #func {linkToHelp} { #local module {%1}; #local keyword {%2}; #local text {$keyword}; #local cmd {HELP $keyword}; #if { "$keyword" == "" } { #local text {$module}; #local keyword {MODULE}; #local cmd {HELP $module}; }; #if { "$module" == "" } { #return {$text}; }; #if { &xtt.module-doc[$module][] == 0 } { #return {$text}; }; #if { &xtt.module-doc[$module][$keyword][] == 0 } { #return {$text}; }; #return {<140>@mslp.Exec{{$cmd};{$text}}<270>}; };