北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
楼主: jarlyyn

一步一步在北侠做机器人

[复制链接]
 楼主| 发表于 2021-9-28 17:23:53 | 显示全部楼层
加入授权一览和注销功能



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-9-29 10:37:17 | 显示全部楼层
然后是验证码输入功能。

首先是抓取验证码URL并记录,这个简单,加一行出发就行

  1. ^(http:\/\/fullme\.pkuxkx\.net\/robot\.php\?filename=\d+)$
复制代码

然后需要获取php文件内容,里面的验证码地址。

这里我使用了一个异步操作。创建请求,异步发起,指明回调地址。然后代码继续向下走。

请求完成后,回调根据传入的请求是否成功的参数,获取请求的实际数据。

在机器人脚本的场景下,同步请求太坑,利用协程之类还要解决数据竞争问题,和浏览器里JS一样单线程+回调是我觉得比较合适的放案


具体代码为

  1.     app.API.Fullme=function(callback){
  2.         let url=app.Core.FullmeUrl
  3.         if (url){
  4.             app.Data.FullmeCallback=callback?callback:""
  5.             app.Core.FullmeReq=HTTP.New("GET",url)
  6.             app.Core.FullmeReq.AsyncExecute("App.Core.OnFullme")
  7.         }
  8.     }

  9.     app.Core.OnFullme=function(name,id,code,data){
  10.         if (code!=0){
  11.             throw data
  12.         }
  13.         if (code==0){
  14.             let result=imgsrcre.exec(app.Core.FullmeReq.ResponseBody())
  15.             if (result==null){
  16.                 throw "无法匹配图片地址"
  17.             }
  18.             let url="http://fullme.pkuxkx.net"+result[1]
  19.             app.API.ShowFullme(url)
  20.         }
  21.     }
复制代码
获取到后,我偷了个懒,用正则匹配,获取实际图片地址

然后做了个可视化识别输入的组件,弹出输入框让用户填写验证码。

  1.     app.API.ShowFullme=function(url){
  2.         let vp=Userinput.newvisualprompt("验证码","忽略红色字符,如果是方向性文字,每对中括号内文字为一组",url)
  3.         vp.setrefreshcallback("App.Core.OnFullmeRefresh")
  4.         vp.publish("App.Core.OnFullmeSubmit")
  5.     }
复制代码


具体代码见

https://github.com/hellclient-sc ... ript/core/fullme.js


北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-9-29 10:44:16 | 显示全部楼层
让我们试一下实际效果

先收工输入fullme

然后输入
  1. /App.Fullme()
复制代码



弹窗出来了,然后,嗯,认不出,北侠的验证码早晚只有程序才能全认出来。点上方的刷新图标,多刷了几次



这是啥?手挠?继续刷新。



这回看出来,手扶……还拖拉机呢……

填写 手扶 两个字进输入框,提交,机器将我填写的内容发送到mud,fullme成功。



好了,这个功能完成了。

其实北侠要针对别人破解fullme很容易,凡是成功高且快的,一定不是真人……


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-10-5 00:28:35 | 显示全部楼层
节后机器暂时停止更新。

由于我玩的mud节前有大幅度修改,会以这套框架重做部分机器。

届时会有部分代码回馈到这个框架里。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-10-9 01:50:01 | 显示全部楼层
为机器人加入载具模式。

所谓载具,就是行走的工具。

默认的载具是run,快速移动,可以多步移动,直接发送命令。

一个额外的载具是go,  就是在发送命令前加入go,比如 go west,会过滤命令,不会多步移动。

另外引入一个赶车的载具cart,在发送命令前加入gan che to,比如gan che to west,会过滤命令,不会多步移动。

过滤命令是有一个替换列表,具体为

  1. (function(){
  2.     return {
  3.         "east": "%1east",
  4.         "south": "%1south",
  5.         "west": "%1west",
  6.         "north": "%1north",
  7.         "southeast": "%1southeast",
  8.         "southwest": "%1southwest",
  9.         "northeast": "%1northeast",
  10.         "northwest": "%1northwest",
  11.         "eastup": "%1eastup",
  12.         "eastdown": "%1eastdown",
  13.         "southup": "%1southup",
  14.         "southdown": "%1southdown",
  15.         "westup": "%1westup",
  16.         "westdownwd": "%1westdown",
  17.         "northup": "%1northup",
  18.         "northdown": "%1northdown",
  19.         "up": "%1up",
  20.         "down": "%1down",
  21.         "e": "%1east",
  22.         "s": "%1south",
  23.         "w": "%1west",
  24.         "n": "%1north",
  25.         "se": "%1southeast",
  26.         "sw": "%1southwest",
  27.         "ne": "%1northeast",
  28.         "nw": "%1northwest",
  29.         "eu": "%1eastup",
  30.         "ed": "%1eastdown",
  31.         "su": "%1southup",
  32.         "sd": "%1southdown",
  33.         "wu": "%1westup",
  34.         "wd": "%1westdown",
  35.         "nu": "%1northup",
  36.         "nd": "%1northdown",
  37.         "u": "%1up",
  38.         "d": "%1down",
  39.         "enter": "%1enter",
  40.         "out": "%1out",
  41.         "e·": "%1east",
  42.         "s·": "%1south",
  43.         "w·": "%1west",
  44.         "n·": "%1north",
  45.         "se·": "%1southeast",
  46.         "sw·": "%1southwest",
  47.         "ne·": "%1northeast",
  48.         "nw·": "%1northwest",
  49.         "eu·": "%1eastup",
  50.         "ed·": "%1eastdown",
  51.         "su·": "%1southup",
  52.         "sd·": "%1southdown",
  53.         "wu·": "%1westup",
  54.         "wd·": "%1westdown",
  55.         "nu·": "%1northup",
  56.         "nd·": "%1northdown",
  57.         "u·": "%1up",
  58.         "d·": "%1down",
  59.         "enter·": "%1enter",
  60.         "out·": "%1out",
  61.         "yell boat。":"yell boat",
  62.         "#wait":"#wait"
  63.     }
  64. })()
复制代码




载具的基础类是
  1. (function(app){
  2.     let _drivepath=Include("include/drivepath.js")
  3.     let Vehicle=function(){
  4.         this.TagDrive=false
  5.         this.MultiStep=false
  6.         this.ID=""
  7.         this.RetryInterval=0.5
  8.         this.Fly=false
  9.         this.Sender=function(cmd){
  10.             app.Send(cmd)
  11.         }
  12.     }
  13.     Vehicle.prototype.Send=function(cmd){
  14.         this.Sender(cmd)
  15.     }
  16.     Vehicle.prototype.ConvertDrivePath=function(cmd,path){
  17.         let p=_drivepath[path]
  18.         if (!p){
  19.             throw "无效的drivepath"+path
  20.         }
  21.         p=p.replace("%1",cmd)
  22.         return p
  23.     }
  24.     return Vehicle
  25. })(App)
复制代码

默认的run

  1. (function (app) {
  2.     let Vehicle = Include("core/vehicle/vehicle.js")
  3.     let Run = function () {
  4.         Vehicle.call(this)
  5.         this.ID="run"
  6.         this.MultiStep=true
  7.         this.Fly=true
  8.     }
  9.     Run.prototype = Object.create(Vehicle.prototype)
  10.     return Run
  11. })(App)
复制代码
额外的go
  1. (function (app) {
  2.     let Vehicle = Include("core/vehicle/vehicle.js")
  3.     let Go = function () {
  4.         Vehicle.call(this)
  5.         this.ID="go"
  6.         this.TagDrive=true
  7.         this.Sender=function(cmd){
  8.             app.Send(this.ConvertDrivePath("go ",cmd))
  9.         }
  10.     }
  11.     Go.prototype = Object.create(Vehicle.prototype)
  12.     return Go
  13. })(App)
复制代码

额外的cart
  1. (function (app) {
  2.     let Vehicle = Include("core/vehicle/vehicle.js")
  3.     let Cart = function () {
  4.         Vehicle.call(this)
  5.         this.TagDrive=true
  6.         this.ID="cart"
  7.         this.Sender=function(cmd){
  8.             app.Send(this.ConvertDrivePath("gan che to ",cmd))
  9.         }
  10.     }
  11.     Cart.prototype = Object.create(Vehicle.prototype)
  12.     return Cart
  13. })(App)
复制代码
全局引入 Drive方法切换载具,go方法发送前进命令
  1.     let cart = Include("core/vehicle/cart.js")
  2.     app.Vehicle=null
  3.     app.Vehicles={
  4.         Run:new run(),
  5.         Go:new go(),
  6.         Cart:new cart(),
  7.     }
  8.     app.Vehicle=app.Vehicles.Run
  9.     app.Drive=function(id){
  10.         if(id){
  11.             for (let key in app.Vehicles) {
  12.                                 if (app.Vehicles[key].ID == id){
  13.                     app.Vehicle=app.Vehicles[key]
  14.                     return
  15.                 }
  16.                         }
  17.             throw "未知的载具 " +id
  18.         }else{
  19.             app.Vehicle=app.Vehicles.Run
  20.         }
  21.     }
  22.     app.RegisterCallback("core.vehicle.inittags",function(){
  23.         Mapper.settag("drive",app.Vehicle.TagDrive)
  24.     })
  25.     app.Bind("PathInit","core.vehicle.inittags")
  26.     app.Go=function(cmd){
  27.         app.Vehicle.Send(cmd)
  28.     }
复制代码

并在移动模块里做相应调整。

同时#to命令支持设置载具

比如#to yzkd,#to go yzgc,#to cart yzyp

更新较多

详细内容见

https://github.com/hellclient-sc ... 7b48c313484bf9816fa


北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-10-9 01:56:24 | 显示全部楼层
让我们看看实际效果

先是#to yzyp,很明显,多步前进


然后是#to go qfsm,单步前进,带go 的前缀





最后 #to cart ly,嗯,没有车,只是发了个带gan che to的命令……



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-10-11 22:47:08 | 显示全部楼层
写的不错 期待客户端有win版的
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-10-12 17:35:49 | 显示全部楼层
下一步要做的模块是道具和NPC。

根据我的经验,侠客行类游戏有很大一块的内容是围绕道具和NPC。

获取XXX道具

将XXX道具给NPC

找到XXXNPC

杀死XXXNPC


依次找到XXX,XXX,XXX NPC等。

所以,这块可以认为是另一个重要部分


北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-10-12 17:41:46 | 显示全部楼层
本帖最后由 jarlyyn 于 2021-10-12 06:58 PM 编辑

先让我们给道具做一个抽象。

道具是什么?

道具是Mud里可以获取并携带在身上的一种对象。


最基本的,

一个道具有 Name(英文名)和Label(标签)两种属性,理论上还可以有数量。

出于管理需要,我们还可能加上一个独一无二的ID,避免有重名不同属性的,以及显示用的备注


在实际使用中,道具还有一些额外的属性,比如

获取方式(购买,捡取,杀人夺宝)

获取命令(buy或者get)


获取目标(比如购买的位置,所在的NPC等)


获取间隔(可能要等刷新才能获取)

所以,一个基本的道具的代码可能是这样的
  1. (function(app){
  2.     let Item=function(){
  3.         this.ID=""
  4.         this.Name=""
  5.         this.Label=""
  6.         this.Type=""
  7.         this.Comment=""
  8.         this.Interval=0
  9.         this.Command=""
  10.         this.Location=""
  11.     }
  12.     return Item
  13. })(App)
复制代码




很明显。这个标志化的格式可以用来保存为文本文件进行管理
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-10-12 17:43:21 | 显示全部楼层
本帖最后由 jarlyyn 于 2021-10-12 06:39 PM 编辑

然后在整理一下道具获取的形式,大概有这么几种基础类型

  • 货物[goods](固定点获取,前往路径后执行指定命令)
  • 资源[resource](固定区域获取,遍历路径,找到目标后执行制定命令)
  • 战利品[trophy](战斗胜利后获取,与NPC联动,寻找NPC,找到目标后进行战斗,胜利后执行指定命令)
  • 回执[receipt](找到NPC后获取,与NPC联动,寻找NPC.找到后执行指定命令获取)
  • 工艺品[crafts](通过其他物品制作,与其他物品联动,依次获取必备道具,最后在指定位置执行命令获取)
  • 其他

在明确了Type后,这些道具的Location对应的值也很明显了
  • goods:获取的地址
  • resource:路径的ID
  • trophy:Npc的id
  • receipt:Npc的id
  • crafts:需要的道具id和数量的列表

这里特别要注意的就是牵涉到了id,必然会有固定数据和临时数据的id两种

然后,很明显,我们需要一个生产(Produce)方法

用来根据传入的道具ID,成功和失败ID生成一个任务

任务执行后就会去尝试获取对应道具



北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|北大侠客行MUD ( 京ICP备16065414号-1 )

GMT+8, 2024-4-29 04:28 AM , Processed in 0.011647 second(s), 13 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表