北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
查看: 73|回复: 2

北大侠客行Vscode版-js机器人示例讲解

[复制链接]
发表于 3 天前 | 显示全部楼层 |阅读模式
我们以多个示例来讲解新版本客户端机器人代码的编写客户端核心函数其实就几个:
api.alias()
api.action()
api.send()
api.echo()
其它的都是标准的 js 开发


第一个示例:找师父学特殊内功



我们一行行来分析
1. api.loops.xuemaster = true;
[解释]:api是一个全局对象,里面包含了最基本的函数,也可以用它来记录全局变量,这里约定死循环的结束标识都记录在api.loops里,当然这不是必须的,可以随便用一个局部变量也没问题

2. api.alias('xuemaster.stop', function () { api.loops.xuemaster = false })
[解释]:这里定义一个别名,输入 xuemaster.stop 指令的时候,可以停止这个学技能的循环

3. api.alias('xuemaster', async () => {
[解释]:这里定义一个别名,输入 xuemaster 指令的时候,循环启动

4. while (api.loops.xuemaster) {
[解释]:死循环,但是如果api.loops.xuemaster=false,会结束循环

5. if (api.session.player.data.neili < 30) {
[解释]:api.session.player 是玩家的实时数据对象,里面包含了GMCP相关数据,主要是房间信息,人物属性,人物属性包含了各种血量、内力、精力、经验等等,都是实时的数据,你可以通过 api.echo(JSON.stringify(api.session.player)) 来打印详情,这句话的意思如果内力小于30就开始睡觉

6. await sys.retry('sleep', '你一觉醒来,精神抖擞地活动了几下手脚', 5, 60);
[解释]:这里的sys对象是一些工具函数的封装,第一次打开游戏的时候会自动创建 init.js ,sys对象里面包含了很多函数,可以直接在里面看源码,这个函数(sys.retry) 的意思是尝试 sleep,然后等待醒过来,会尝试60次,每隔5秒尝试一次,如果中间醒过来了,这个函数就执行结束,也就是 '你一觉醒来,精神抖擞地活动了几下手脚'触发了就表示醒过来
这里sleep 有多种可能性,比如马上睡着或者提示 刚睡过,不能再睡,我们在这里不管这么多,直接用同步等待的方式,直接不停的sleep,直到睡醒

7. if (api.session.player.data.jing < 20) {
[解释]:同样判断一下当时的精力如果小于 20 的话就吸气

8. sys.sendAndEcho("e2");
[解释]:看名称就知道,就是发送指令并打印指令到屏幕(便于调试),封装的 api.send() 和 api.echo()

9.  await sys.sleep(1);
[解释]:等待1秒


10. this.autofoodwater();
[解释]:这个是封装的一个函数,如果食物<200就吃干粮,水小于200就在剑心居drink,这个函数很多地方用的上,就封装成一个函数

11. await sys.sleep(1);
[解释]:等待1秒

14. sys.sendAndEcho('xue ding for huagong-dafa 5;xue ding for literate 5');

[解释]:真正开始学技能

总结:尽量使用同步的方式,代码看上去逻辑很清晰,如果设置多个action也能异步实现,但是不够简洁。 当然这个只是示例,还有一些特殊情况,需要处理,比如师父跑了,比如没潜能了,比如超出师父的最高等级了等等,都需要处理,不过还是尽量按照同步的方式,做不到再考虑用action 和变量来处理


北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 昨天 08:39 PM | 显示全部楼层
本帖最后由 wendaokoujin 于 2025-4-22 08:43 PM 编辑

示例二  api.alias 和 api.action 的基本用法,这个都是最基本的功能,但是要比一般的客户端功能更强,因为加入了函数

一. alias
1. api.alias 是设置别名
参数1是别名,参数2可以是指令,可以是函数,也可以是一个数组,数组里可以是字符串和函数,如果涉及到变量,用 $1,$2 替代变量,
  api.alias("test_alias1", "pi;hi");
  api.alias("test_alias2", () => { api.send("pi;hi"); });
  api.alias("test_alias3", ["pi","hi",() => { api.send("jump;hi");}]);


  api.alias("test_alias4", "hi $1");
  api.alias("test_alias5", function(args){
    api.send("hi " + args[0]);
  });




2. api.unalias 取消别称
api.unalias("test_alias1");

二. action
1. api.action
参数1是action的文本或正则,参数2是指令,可以是可以是函数,也可以是一个数组,数组里可以是字符串和函数

  api.action("test_action1", "pi;hi");
  api.action("test_action2", () => { api.send("pi;hi"); });
  api.action("test_action3", ["pi","hi",() => { api.send("jump;hi");}]);




这里的 @test 是用来模拟触发action的

api.action(/http:\/\/fullme\.pkuxkx\.net\/robot\.php\?filename=(.*)/, '@fullme $1')
action可以是js的正则表达式,如果不会写js的正则,AI可以帮你

api.action(["test_action4","test_action5"], "hi");
还有一个特殊的用法,就是action还可以是一个字符串数组,可以用来匹配多行文本。





北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 昨天 09:34 PM | 显示全部楼层
示例三 完整的剑心居打坐、吐纳、学习技能、读书、领悟和练习的示例,大家可以参考修改
  1. class Jianxinju {
  2.   //剑心居机器人
  3.   constructor(api, sys) {
  4.     this.api = api;
  5.     this.sys = sys;
  6.     this.init();
  7.   }
  8.   init() {
  9.     const self = this; // 保存this引用
  10.     this.api.alias("learn_skills.stop", () => (self.api.loops.learn_skills = false));
  11.     this.api.alias("learn_skills.start", async () => self.learn_skills());

  12.     this.api.alias("read_shediao.stop", () => (self.api.loops.read_shediao = false));
  13.     this.api.alias("read_shediao.start", async () => self.read_shediao());

  14.     this.api.alias("dazuo.stop", () => (self.api.loops.dazuo = false));
  15.     this.api.alias("dazuo.start", async () => self.dazuo());

  16.     this.api.alias("tuna.stop", () => (self.api.loops.tuna = false));
  17.     this.api.alias("tuna.start", async () => self.tuna());

  18.     this.api.alias("lingwu_lianxi.stop", () => (self.api.loops.lingwu_lianxi = false));
  19.     this.api.alias("lingwu_lianxi.start", async () => self.lingwu_lianxi());

  20.     this.api.action("你的内力修为似乎已经达到了瓶颈。", "dazuo.stop");
  21.     this.api.action("你的精力修为已经达到了瓶颈。", "tuna.stop");
  22.     this.sys.actionOnce("你附近没有 ding 这个人,请用 id here 指令看看周围人物 id 。", "clap 3;teacher;", 60); //找师傅,60秒内只触发一次
  23.   }
  24.   //自动补充食物水
  25.   async auto_food_water() {
  26.     let food = this.api.session.player.data.food;
  27.     let water = this.api.session.player.data.water;
  28.     if (water < 200) {
  29.       this.sys.sendAndEcho("drink");
  30.       await this.sys.sleep(1);
  31.     }
  32.     if (food < 200) {
  33.       this.sys.sendAndEcho("eat gan liang");
  34.       await this.sys.sleep(1);
  35.     }
  36.   }
  37.   //睡眠恢复jing去做消耗jing的动作
  38.   async recover_jing() {
  39.     if (this.api.session.player.data.neili < 30) {
  40.       await this.sys.retry("sleep", "你一觉醒来,精神抖擞地活动了几下手脚", 5, 60);
  41.     }
  42.     if (this.api.session.player.data.jing < 50) {
  43.       this.sys.sendAndEcho("e2");
  44.       await this.sys.sleep(1);
  45.     }
  46.     this.auto_food_water();
  47.     await this.sys.sleep(1);
  48.   }
  49.   async learn_skills() {
  50.     this.api.loops.learn_skills = true;
  51.     while (this.api.loops.learn_skills) {
  52.       await this.recover_jing();
  53.       this.sys.sendAndEcho("xue ding for huagong-dafa 5;xue ding for poison 5");
  54.     }
  55.     this.sys.log("学习技能循环结束");
  56.   }

  57.   async read_shediao() {
  58.     this.api.loops.read_shediao = true;
  59.     while (this.api.loops.read_shediao) {
  60.       await this.recover_jing();
  61.       this.sys.sendAndEcho("read shediao 5");
  62.     }
  63.     this.sys.log("读射雕循环结束");
  64.   }
  65.   async dazuo() {
  66.     this.api.loops.dazuo = true;
  67.     while (this.api.loops.dazuo) {
  68.       let max_neili = this.api.session.player.data.max_neili;
  69.       let neili = this.api.session.player.data.neili;
  70.       let neilipercent = neili / max_neili;
  71.       let qi = this.api.session.player.data.qi;
  72.       if (neilipercent <= 1.2 && qi < 100) {
  73.         await this.sys.retry("sleep", "你一觉醒来,精神抖擞地活动了几下手脚", 5, 30);
  74.       }
  75.       this.auto_food_water();
  76.       if (neili > max_neili * 2 - 30) {
  77.         await this.sys.try("dazuo 10", "你运功完毕,深深吸了口气,站了起来。", 10);
  78.       } else {
  79.         await this.sys.try("dazuo max", "你运功完毕,深深吸了口气,站了起来。", 60);
  80.       }
  81.       await this.sys.sleep(1);
  82.     }
  83.     this.sys.log("打坐循环结束");
  84.   }
  85.   async tuna() {
  86.     this.api.loops.tuna = true;
  87.     while (this.api.loops.tuna) {
  88.       await this.recover_jing();
  89.       let max_jingli = this.api.session.player.data.max_jingli;
  90.       let jingli = this.api.session.player.data.jingli;
  91.       if (jingli > max_jingli * 2 - 20) {
  92.         await this.sys.try("tuna 10", '你吐纳完毕,睁开双眼,站了起来。', 10);
  93.       } else {
  94.         await this.sys.try("tuna max", '你吐纳完毕,睁开双眼,站了起来。', 60);
  95.       }
  96.     }
  97.     this.sys.log("吐纳循环结束");
  98.   }
  99.   async lingwu_lianxi() {
  100.     let self = this;
  101.     let point = 20;
  102.     let cmds = [
  103.       'lian throwing ' + point, 'lingwu throwing ' + point,
  104.       'lingwu force ' + point,
  105.       'lian parry ' + point, 'lingwu parry ' + point,
  106.       'lian dodge ' + point, 'lingwu dodge ' + point,
  107.       'lian strike ' + point, 'lingwu strike ' + point]
  108.     this.api.loops.lingwu_lianxi = true;
  109.     this.api.vars.lingwu_lianxi = 0;
  110.     this.api.action('你需要提高基本功,不然练得再多也没有用', () => (self.api.vars.lingwu_lianxi++));
  111.     this.api.action('不能通过练习来提高了', () => (self.api.vars.lingwu_lianxi++));
  112.     this.api.action('你已经达到你的技能等级极限', () => (self.api.vars.lingwu_lianxi++));
  113.     this.api.action('你的基本功夫比你的高级功夫还高', () => (self.api.vars.lingwu_lianxi++));
  114.     this.api.action('你需要提高基本功,不然练得再多也没有用', () => (self.api.vars.lingwu_lianxi++));
  115.     this.api.action('受限于天资', () => (self.api.vars.lingwu_lianxi++));
  116.     this.api.action('必须空手', 'unwield all;');
  117.     try {
  118.       while (this.api.loops.lingwu_lianxi) {
  119.         this.auto_food_water();
  120.         if (this.api.vars.lingwu_lianxi >= cmds.length) {
  121.           this.api.vars.lingwu_lianxi = 0;
  122.         }
  123.         let neili = this.api.session.player.data.neili;
  124.         let qi = this.api.session.player.data.qi;
  125.         let jing = this.api.session.player.data.jing;
  126.         this.sys.log('当前内力:' + neili + ' 当前气:' + qi+ ' 当前精力:' + jing)
  127.         if (neili < 100 && (qi < 100|| jing < 100)) {
  128.           await this.sys.retry("sleep", "你一觉醒来,精神抖擞地活动了几下手脚", 5, 30);
  129.         }
  130.         await this.sys.sleep(1);
  131.         this.api.send('e1;e2;' + cmds[this.api.vars.lingwu_lianxi])
  132.       }
  133.       this.sys.log("领悟练习结束");
  134.     } catch (e) {
  135.       this.sys.log("领悟练习失败:" + e.message);
  136.       this.api.loops.lingwu_lianxi = false;
  137.     }
  138.   }
  139. }

  140. module.exports = Jianxinju;
复制代码


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

本版积分规则

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

GMT+8, 2025-4-23 04:04 AM , Processed in 0.010513 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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