jarlyyn 发表于 2021-9-28 17:23:53

加入授权一览和注销功能



jarlyyn 发表于 2021-9-29 10:37:17

然后是验证码输入功能。

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

^(http:\/\/fullme\.pkuxkx\.net\/robot\.php\?filename=\d+)$
然后需要获取php文件内容,里面的验证码地址。

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

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

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


具体代码为

    app.API.Fullme=function(callback){
      let url=app.Core.FullmeUrl
      if (url){
            app.Data.FullmeCallback=callback?callback:""
            app.Core.FullmeReq=HTTP.New("GET",url)
            app.Core.FullmeReq.AsyncExecute("App.Core.OnFullme")
      }
    }

    app.Core.OnFullme=function(name,id,code,data){
      if (code!=0){
            throw data
      }
      if (code==0){
            let result=imgsrcre.exec(app.Core.FullmeReq.ResponseBody())
            if (result==null){
                throw "无法匹配图片地址"
            }
            let url="http://fullme.pkuxkx.net"+result
            app.API.ShowFullme(url)
      }
    }
获取到后,我偷了个懒,用正则匹配,获取实际图片地址

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

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

具体代码见

https://github.com/hellclient-scripts/pkuxkx.noob/blob/2c1ecad25027adf7bff810e047075dff6669098b/script/core/fullme.js


jarlyyn 发表于 2021-9-29 10:44:16

让我们试一下实际效果

先收工输入fullme

然后输入
/App.Fullme()


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



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



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

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



好了,这个功能完成了。

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


jarlyyn 发表于 2021-10-5 00:28:35

节后机器暂时停止更新。

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

届时会有部分代码回馈到这个框架里。

jarlyyn 发表于 2021-10-9 01:50:01

为机器人加入载具模式。

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

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

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

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

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

(function(){
    return {
      "east": "%1east",
      "south": "%1south",
      "west": "%1west",
      "north": "%1north",
      "southeast": "%1southeast",
      "southwest": "%1southwest",
      "northeast": "%1northeast",
      "northwest": "%1northwest",
      "eastup": "%1eastup",
      "eastdown": "%1eastdown",
      "southup": "%1southup",
      "southdown": "%1southdown",
      "westup": "%1westup",
      "westdownwd": "%1westdown",
      "northup": "%1northup",
      "northdown": "%1northdown",
      "up": "%1up",
      "down": "%1down",
      "e": "%1east",
      "s": "%1south",
      "w": "%1west",
      "n": "%1north",
      "se": "%1southeast",
      "sw": "%1southwest",
      "ne": "%1northeast",
      "nw": "%1northwest",
      "eu": "%1eastup",
      "ed": "%1eastdown",
      "su": "%1southup",
      "sd": "%1southdown",
      "wu": "%1westup",
      "wd": "%1westdown",
      "nu": "%1northup",
      "nd": "%1northdown",
      "u": "%1up",
      "d": "%1down",
      "enter": "%1enter",
      "out": "%1out",
      "e·": "%1east",
      "s·": "%1south",
      "w·": "%1west",
      "n·": "%1north",
      "se·": "%1southeast",
      "sw·": "%1southwest",
      "ne·": "%1northeast",
      "nw·": "%1northwest",
      "eu·": "%1eastup",
      "ed·": "%1eastdown",
      "su·": "%1southup",
      "sd·": "%1southdown",
      "wu·": "%1westup",
      "wd·": "%1westdown",
      "nu·": "%1northup",
      "nd·": "%1northdown",
      "u·": "%1up",
      "d·": "%1down",
      "enter·": "%1enter",
      "out·": "%1out",
      "yell boat。":"yell boat",
      "#wait":"#wait"
    }
})()



载具的基础类是
(function(app){
    let _drivepath=Include("include/drivepath.js")
    let Vehicle=function(){
      this.TagDrive=false
      this.MultiStep=false
      this.ID=""
      this.RetryInterval=0.5
      this.Fly=false
      this.Sender=function(cmd){
            app.Send(cmd)
      }
    }
    Vehicle.prototype.Send=function(cmd){
      this.Sender(cmd)
    }
    Vehicle.prototype.ConvertDrivePath=function(cmd,path){
      let p=_drivepath
      if (!p){
            throw "无效的drivepath"+path
      }
      p=p.replace("%1",cmd)
      return p
    }
    return Vehicle
})(App)
默认的run

(function (app) {
    let Vehicle = Include("core/vehicle/vehicle.js")
    let Run = function () {
      Vehicle.call(this)
      this.ID="run"
      this.MultiStep=true
      this.Fly=true
    }
    Run.prototype = Object.create(Vehicle.prototype)
    return Run
})(App)额外的go
(function (app) {
    let Vehicle = Include("core/vehicle/vehicle.js")
    let Go = function () {
      Vehicle.call(this)
      this.ID="go"
      this.TagDrive=true
      this.Sender=function(cmd){
            app.Send(this.ConvertDrivePath("go ",cmd))
      }
    }
    Go.prototype = Object.create(Vehicle.prototype)
    return Go
})(App)
额外的cart
(function (app) {
    let Vehicle = Include("core/vehicle/vehicle.js")
    let Cart = function () {
      Vehicle.call(this)
      this.TagDrive=true
      this.ID="cart"
      this.Sender=function(cmd){
            app.Send(this.ConvertDrivePath("gan che to ",cmd))
      }
    }
    Cart.prototype = Object.create(Vehicle.prototype)
    return Cart
})(App)全局引入 Drive方法切换载具,go方法发送前进命令
    let cart = Include("core/vehicle/cart.js")
    app.Vehicle=null
    app.Vehicles={
      Run:new run(),
      Go:new go(),
      Cart:new cart(),
    }
    app.Vehicle=app.Vehicles.Run
    app.Drive=function(id){
      if(id){
            for (let key in app.Vehicles) {
                                if (app.Vehicles.ID == id){
                  app.Vehicle=app.Vehicles
                  return
                }
                        }
            throw "未知的载具 " +id
      }else{
            app.Vehicle=app.Vehicles.Run
      }
    }
    app.RegisterCallback("core.vehicle.inittags",function(){
      Mapper.settag("drive",app.Vehicle.TagDrive)
    })
    app.Bind("PathInit","core.vehicle.inittags")
    app.Go=function(cmd){
      app.Vehicle.Send(cmd)
    }
并在移动模块里做相应调整。

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

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

更新较多

详细内容见

https://github.com/hellclient-scripts/pkuxkx.noob/commit/de44c7966aae9c2e5cf8b7b48c313484bf9816fa


jarlyyn 发表于 2021-10-9 01:56:24

让我们看看实际效果

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


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





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



xlyh 发表于 2021-10-11 22:47:08

写的不错 期待客户端有win版的

jarlyyn 发表于 2021-10-12 17:35:49

下一步要做的模块是道具和NPC。

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

获取XXX道具

将XXX道具给NPC

找到XXXNPC

杀死XXXNPC


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

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


jarlyyn 发表于 2021-10-12 17:41:46

本帖最后由 jarlyyn 于 2021-10-12 06:58 PM 编辑

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

道具是什么?

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


最基本的,

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

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


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

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

获取命令(buy或者get)


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


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

所以,一个基本的道具的代码可能是这样的
(function(app){
    let Item=function(){
      this.ID=""
      this.Name=""
      this.Label=""
      this.Type=""
      this.Comment=""
      this.Interval=0
      this.Command=""
      this.Location=""
    }
    return Item
})(App)



很明显。这个标志化的格式可以用来保存为文本文件进行管理

jarlyyn 发表于 2021-10-12 17:43:21

本帖最后由 jarlyyn 于 2021-10-12 06:39 PM 编辑

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


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

在明确了Type后,这些道具的Location对应的值也很明显了

[*]goods:获取的地址
[*]resource:路径的ID
[*]trophy:Npc的id
[*]receipt:Npc的id
[*]crafts:需要的道具id和数量的列表

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

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

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

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



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