jarlyyn 发表于 2021-9-6 10:19:49

在完善了基本信息的收集后,我们的接下去要做什么功能呢?



[*]数据发送
[*]当前位置判断
[*]忙判断
[*]路径行走

在这些问题都接完之后,才能让我那饿了几个月的id吃上热乎的饭菜。


jarlyyn 发表于 2021-9-6 10:45:13

先让我们解决发送的问题。

mush里最简单的发送自然是world.Send里,填什么发什么,这不是很简单么?

当然没那么简单,发送要解决4个问题


[*]速率控制
[*]全局控制(如回显)
[*]命令标准化
[*]自定义功能

速率控制比较重要,单独开一个回复

全局控制很容易理解,是为了能同意的管理发送的表现。如果你要给所有的发送命令的地方价格命令统计,不全局控制是要改死人的。这是一个工程化的问题

命令标准化呢,略微复杂点

比如一个e,我可以直接发送e,也可以发送>e,也可以发送?e,最后实际发送到mud的可能都是e。

这个主要是用在路径里的。直接向东走可以直接发e,走过去有busy的可能发个e然后等busy结束,等等。

最后一个自定义功能么,很简单,有些控制性的变量可能不直接发送到mud,比如zmud经典的#wa 2000,又比如有些命令可能会进行展开,比如#study,通过变量和设置展开为 study fu zi literate



jarlyyn 发表于 2021-9-6 11:12:19

然后是速率控制

正常mud都有速率控制的,不然就是比岁网速好,每秒能发更多的命令了。

超过限制往往会发生让人很痛苦的事,比如我玩的mud可能是被雷P,北侠据我测试似乎是吞命令。

那么怎么控制速率呢?

熟悉mush的人立刻会说,用Speedwalk。

您很聪明,学会了防御式开发的防呆式开发,可以跳过这个回复向后看了。

那么,如果不聪明的方式,应该怎么办?

或者说,speedwalk有什么问题吗?

主要是mud,至少侠客行类的mud是通过心跳来计算命令限制的。


在这个模式下,speedwalk其实只有三个问题


[*]在非均匀发送时的效率问题。(这个是小问题,主要在等>发送一堆命令>等的状态下效率看着没那么高)
[*]发送的两个命令的间隔时间的问题。(先open再行走容易遇到被门关住,对npc下kill后容易因为延时被npc先下pfm)
[*]DiscardQueue后部分重要命令被吞的问题(切换技能,练技能,切换回来,结果刚切换过去就被团了,造成无法使用正常的技能)

要解决speedwalk的问题,我们需要自己接管命令的发送。

我先是在mush的机器里做了一个实现,然后在我的客户端引入了一个节拍器的概念

节拍器的逻辑很简单,设置一个周期和命令数


[*]维护一个待发送队列,储存需要发送的命令组(多个命令)列表
[*]支持按组发送命令,在要么一起发送,要么等下一个心跳一起发送
[*]维护一个类似令牌桶的已发送的历史,所以被发送内容的发送时间会放在里面
[*]设置一个高频计时器(mush支持0.1的timer),在发送和计时器触发时,先清理令牌桶里的过期令牌(超过周期),再看令牌桶的剩余空间(命令数-剩余令牌)。如果空间够,发送当前命令组。否则将令牌桶填满,等待下次清理后发送
[*]加入锁定命令,可以锁定当前队列里的所有命令,只有强制Discard才会清理,保证部分命令必定执行。



go语言的版本代码为

https://github.com/jarlyyn/hellclient/blob/master/src/vendor/modules/world/component/metronome/metronome.go

lua版本为

https://github.com/hellclient-scripts/helllua/blob/walk/script/mods/queue.lua


js版本的代码为

https://github.com/hellclient-scripts/zsz-self.jvs/blob/7c325dfa64362c542295ea3ddf8f26f88c5c2d53/script/queue.js

中被注释的部分。

我还写过一个mush机器人的 js 补丁,作为附件上传了



windygreen 发表于 2021-9-6 15:06:45

几点建议
房间除了名字,还要给一个unique number id,因为有非常多的重名。
出口除了方向,还要加上该方向的room id,这样便于将来的遍历

jarlyyn 发表于 2021-9-6 15:55:59

windygreen 发表于 2021-9-6 03:06 PM
几点建议
房间除了名字,还要给一个unique number id,因为有非常多的重名。
出口除了方向,还要加上该方向 ...

谢谢你的建议。

因为北侠不支持全自动机器人

所以这次我并不准备做mapper信息。

mrzhe 发表于 2021-9-6 16:50:21

包神威武

yxdaoer 发表于 2021-9-6 22:33:27

高手风范

jarlyyn 发表于 2021-9-7 01:01:09

制作发送模块

因为是比较核心的模块,适当的加了备注。

主要提供3个功能


[*]发送命令,参数为分号分割的命令,和是否强制按组发送
[*]注册命令,可以将回调(重要部分,之后的回复会解释)注册为命令
[*]组合命令,将分号分割的命令转化为&&分割的命令

命令的特殊语法为

[*]英文句号[.] 和上标号[^]开头的,当作标志(命令),发送时去掉前置的标志位发送
[*]&&分割的当作分组发送(必须一起发送)
[*]井号[#]开头的作为命令,如果将#和第一个空格之间的文字作为指令,第一个空格后的文字作为数据调用指令
[*]#号开头的命令强制分割分组
[*]如果#之后是数字,正数,而且没注册,将数据作为重复发送的命令(zmud的 #5 e)

发送的代码为


https://github.com/hellclient-scripts/pkuxkx.noob/blob/c45bb9de2c31b456c2f01e523208eb9c91ad9677/script/core/send.js

然后在游戏里进行测试

首先

/App.Send("#30 l")

会发现先发送 20个l(我设置的每秒发送限制),然后再断断续续的发送10个l

再测试分组

/App.Send("#15 l\;l&&l&&l&&l&&l&&l&&l&&l&&l&&l&&l&&l&&l&&l&&l")

发现命令分两次发送

第一次连续发送15个

等1秒

第二次还是连续发送15个

完成目标




jarlyyn 发表于 2021-9-7 01:16:02

本帖最后由 jarlyyn 于 2021-9-8 04:10 PM 编辑

接下来看回调。

回调是什么

回调的用途是定义一个函数,在需要的时候进行执行

如发送命令,进入房间,不忙等。

我这里的特殊点是,所有的回调必须先用字符串形式注册到全局(App内),在使用的地方仅使用字符串

无他,方便debug。

比如你设置了进入房间调用的函数,如果是个字符串, 你至少还能打印出来,这个事件帮顶了多少回调。

如果是函数,完全无法debug。

回调通过App.RegisterCallback注册到App.Callbacks里

同时,我还建立了简单的 App.Bind和App.Rasie函数

实现了简单的事件机制

具体代码见

https://github.com/hellclient-sc ... d9677/script/app.js

很明显,通过/Bound()可以打印出所有监听的时间和对应回调

比如我现在就是

{
"OnRoomObj": [
    "info.room.objlocate"
],
"OnRoomExits": [
    "info.room.namelocate"
]
}很简单清晰



jarlyyn 发表于 2021-9-7 01:34:01

今天还把 i2(道具),skills(技能),jifa(激发) 三个数据的也处理好了

https://github.com/hellclient-scripts/pkuxkx.noob/blob/c45bb9de2c31b456c2f01e523208eb9c91ad9677/script/core/player.js

具体的也没啥好说的,都是基本功

所以,现在只要/App.Send("l;score;hp;i2;cha;jifa")

就能 得到 mud中的所有基本信息了

通过/Debug() 命令打印如下

{
"Room": {
    "ID": "yzkd",
    "Name": "客店",
    "Desc": "",
    "Tags": "[大宋国] [城市] [存盘点]",
    "Objs": [
      {
      "ID": "Board",
      "Name": "客店留言板"
      },
      {
      "ID": "Tianshen suicong",
      "Name": "节日使者 天神随从"
      },
      {
      "ID": "Song shengyi",
      "Name": "日月神教 引路人 宋生亦"
      },
      {
      "ID": "Xiao er",
      "Name": "店小二"
      },
      {
      "ID": "Xxsmallthree",
      "Name": "少林罗汉堂弟子 慧无"
      },
      {
      "ID": "Marsh",
      "Name": "武学大家 莫小贝"
      },
      {
      "ID": "Xzg",
      "Name": "武学大师 全真派 人仙 小猪哥"
      },
      {
      "ID": "Dome",
      "Name": "天眷者 金陵镖局总镖头「面面俱到╰._.╯牛气冲天」渡我"
      },
      {
      "ID": "Azerob",
      "Name": "天地会 堂主 无所谓"
      },
      {
      "ID": "Bber",
      "Name": "明教 教众 无忧"
      },
      {
      "ID": "Shendu",
      "Name": "天龙寺第十五代弟子 本慎"
      },
      {
      "ID": "Jxyu",
      "Name": "日月神教 香主 还是潇洒"
      },
      {
      "ID": "Zues",
      "Name": "叶绿风"
      },
      {
      "ID": "Luzuo",
      "Name": "五毒教山门弟子「有请金蚕蛊大人现身」陆左"
      },
      {
      "ID": "Huke",
      "Name": "五毒教山门弟子「四门馆在读学士大唐子爵大人」虎克"
      },
      {
      "ID": "Sip",
      "Name": "少林达摩院弟子 澄思"
      },
      {
      "ID": "Ldyz",
      "Name": "丐帮二袋弟子 雷迪亚兹"
      },
      {
      "ID": "Shanzhaifuyi",
      "Name": "丐帮一袋弟子 芐莒"
      },
      {
      "ID": "Grobot",
      "Name": "普通百姓「华丽转身」大高手"
      },
      {
      "ID": "Turnleft",
      "Name": "日月神教 香主 向左转"
      },
      {
      "ID": "Phoenix",
      "Name": "灵鹫宫首领 凤"
      },
      {
      "ID": "Endless",
      "Name": "绝情谷入室弟子 无尽"
      },
      {
      "ID": "Dream",
      "Name": "普通百姓 梦"
      },
      {
      "ID": "Dragon",
      "Name": "天地会 护法 龙"
      },
      {
      "ID": "Veyron",
      "Name": "大宋 忠武将军 威龙"
      },
      {
      "ID": "Kickb",
      "Name": "天龙寺第十五代弟子 本鬼"
      },
      {
      "ID": "Raider",
      "Name": "少林达摩院弟子 渡鬼"
      },
      {
      "ID": "Walnut",
      "Name": "明教 教众 核桃"
      },
      {
      "ID": "Jsysj",
      "Name": "普通百姓 宋江"
      },
      {
      "ID": "Yqlljy",
      "Name": "普通百姓 卢俊义"
      },
      {
      "ID": "Luyoujiao",
      "Name": "丐帮一袋弟子「请君试问东流水,别意与之谁短长!」鲁有角"
      },
      {
      "ID": "Shotone",
      "Name": "大宋 昭武校尉 一品"
      },
      {
      "ID": "Lixchh",
      "Name": "武当派真人「1743」眼前又黑"
      }
    ],
    "Exits": [
      "up",
      "west"
    ]
},
"HP": {
    "eff_jing": 112,
    "jing": 142,
    "per_jing": 100,
    "eff_jingli": 100,
    "jingli": 100,
    "jiajing": 0,
    "eff_zhenqi": 0,
    "zhengqi": 330,
    "eff_jingqi": null,
    "jingqi": 3475,
    "eff_drink": 0,
    "drink": 330,
    "drink_status": "饥渴",
    "exp": 131,
    "status": "受伤"
},
"Score": {
    "rank": "武当派第四代弟子",
    "name": "杰林修",
    "id": "Jarlyyn",
    "bl": 23,
    "wx": 17,
    "gg": 21,
    "sf": 19,
    "fy": 15,
    "rm": 18,
    "lx": 30,
    "ds": "?",
    "country": "无国籍",
    "family": "武当派",
    "age": 16,
    "teacher": "谷虚道长",
    "gender": "男性",
    "loyalty": 0,
    "birthday": "戊子年十一月二十一日子时七刻",
    "chushi": "无",
    "marry": "未婚",
    "panshi": "无",
    "kill": 0,
    "job": "未入职",
    "saving": 0,
    "killed": 0,
    "morality": 0,
    "wuxuepoint": 0,
    "deaths": 1,
    "reputation": 0,
    "guojiapoint": 0,
    "shaqi": "正常",
    "wish": 0,
    "shizhan": 0
},
"Skills": {
    "All": []
},
"Jifa": [],
"Items": [
      {
      "ID": "Jiudai",
      "Name": "牛皮酒袋"
      },
      {
      "ID": "Gan liang",
      "Name": "四块干粮"
      },
      {
      "ID": "Silver",
      "Name": "九两白银"
      },
      {
      "ID": "Ma xie",
      "Name": "麻鞋"
      },
      {
      "ID": "Pao",
      "Name": "青色道袍"
      },
      {
      "ID": "Jin nang",
      "Name": "锦囊"
      }
    ],
"Equipments": [
      {
      "ID": "Ma xie",
      "Name": "麻鞋"
      },
      {
      "ID": "Pao",
      "Name": "青色道袍"
      },
      {
      "ID": "Jin nang",
      "Name": "锦囊"
      }
    ],
"Load": 9,
"Weapon": "",
"WeaponID": ""
}
主动获取内容部分告一段落

页: 1 [2] 3 4 5 6 7 8 9
查看完整版本: 一步一步在北侠做机器人