北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
123
返回列表 发新帖
楼主: but

发布一个全新的客户端,基于vscode的插件

[复制链接]
发表于 2025-4-7 20:03:18 | 显示全部楼层
应该是的

记得正确设置后进mud会有提示
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2025-4-7 20:05:19 | 显示全部楼层
jarlyyn 发表于 2025-4-7 08:03 PM
应该是的

记得正确设置后进mud会有提示

ok,应该可以了。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2025-4-7 20:20:00 | 显示全部楼层
but 发表于 2025-4-7 08:05 PM
ok,应该可以了。

对,这样就可以统计了。后面可以加版本号或者平台标记以便你分析使用情况,不过要等到你的客户端从左侧“其他”类里独立出来成为一个单独的分类之后,才可以双击查看客户端组成,类似paotin或者mudlet

本帖子中包含更多资源

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

x
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 7 天前 | 显示全部楼层
使用js很大的好处是可以利用 AI 写不少代码,你看以下的函数大部分都是利用cursor来实现的
  1. // 基础插件,可以参考,请不用修改
  2. let api;
  3. module.exports = {
  4.     init: function (apiInstance) {
  5.         api = apiInstance;
  6.         api.action('您要将另一个连线中的相同人物赶出去', 'y');
  7.         //实现对fullme命令的解析,解析图片显示在主界面的右边,@开头的指令是私有指令
  8.         api.action(/http:\/\/fullme\.pkuxkx\.net\/robot\.php\?filename=(.*)/, '@fullme $1');
  9.     },
  10.     /**
  11.      * 用xy替代@go ,实现同步到达目标地点,并执行回调函数或命令
  12.      * await sys.xy('晋阳', 'sw;w;w;w;s');//到达晋阳后执行sw;w;w;w;s
  13.      * @param {string} target 目标地点
  14.      * @param {function|string} callback 回调函数或命令
  15.      * @param {number} timeout 超时时间
  16.      * @returns
  17.      */
  18.     xy: async function (target, callback, timeout = 30) {
  19.         await this.sync('@go ' + target, '你到达了' + target, timeout);
  20.         if (!callback) return;
  21.         if (typeof callback === 'function') {
  22.             callback();
  23.         } else if (typeof callback === 'string') {
  24.             api.send(callback);
  25.         }
  26.     },
  27.     delay: function (time, cmd) {
  28.         setTimeout(() => {
  29.             api.send(cmd);
  30.         }, time * 1000);
  31.     },
  32.     tick: function (time, cmd) {
  33.         return setInterval(() => {
  34.             api.send(cmd);
  35.         }, time * 1000);
  36.     },
  37.     untick: function (id) {
  38.         clearInterval(id);
  39.     },
  40.     // 睡眠 await sys.sleep(2);等待2秒
  41.     sleep: function (time) {
  42.         return new Promise((resolve) => {
  43.             setTimeout(resolve, time * 1000);
  44.         });
  45.     },
  46.     /**
  47.      * 异步转同步,执行命令后,会等待successAction触发才判断结束,才可以继续执行下一条指令
  48.      * await sys.sync('@go 晋阳', '你到达了晋阳',30);//到晋阳之后执行其它命令,判断的标准就是屏幕出现了"你到达了晋阳"
  49.      * @param {string} cmd 命令
  50.      * @param {string} successAction 成功后执行的命令
  51.      * @param {number} timeout 超时时间
  52.      * @returns
  53.      */
  54.     sync: function (cmd, successAction, timeout = 5) {
  55.         return new Promise((resolve) => {
  56.             this.busywait = true;

  57.             // 监听成功事件
  58.             const successHandler = () => {
  59.                 api.unaction(successAction);
  60.                 this.busywait = false;
  61.                 clearTimeout(timeoutid);
  62.                 resolve();
  63.             };
  64.             // 注册一次性触发器
  65.             api.action(successAction, successHandler);
  66.             api.send(cmd);

  67.             // 设置超时,防止无限等待
  68.             const timeoutid = setTimeout(() => {
  69.                 this.busywait = false;
  70.                 resolve();
  71.             }, timeout * 1000); // 超时

  72.         });
  73.     },
  74.     /**
  75.      * 批量执行命令,每条命令之间延迟delaySeconds秒
  76.      * await sys.batch(['ask hao about 帮助', 'give hao zi', 'ask hao about 交个朋友', 'ask hao about 独门秘方', 'ask hao about 木桶'], 2);
  77.      * @param {string[]} commands 命令列表
  78.      * @param {number} delaySeconds 延迟时间
  79.      */
  80.     async batch(commands, delaySeconds) {
  81.         for (const command of commands) {
  82.             try {
  83.                 api.send(command);
  84.                 await this.sleep(delaySeconds);
  85.             } catch (error) {
  86.                 api.echo(`命令 "${command}" 执行失败: ${error.message}`, true);
  87.             }
  88.         }
  89.     },
  90.     /**
  91.      * 反转路径字符串
  92.      * reversePath('sw;w;#3 w;s') 返回 'n;#3 e;e;ne'
  93.      * @param {string} pathString 路径字符串,例如 'sw;w;w;w;s' 或 '#4 w;s'
  94.      * @returns {string} 反转后的路径字符串
  95.      */
  96.     reversePath(pathString) {
  97.         if (!pathString) {
  98.             return '';
  99.         }

  100.         const oppositeDirections = {
  101.             'n': 's',
  102.             's': 'n',
  103.             'e': 'w',
  104.             'w': 'e',
  105.             'ne': 'sw',
  106.             'nw': 'se',
  107.             'se': 'nw',
  108.             'sw': 'ne',
  109.             'nu': 'sd', // northup -> southdown
  110.             'nd': 'su', // northdown -> southup
  111.             'eu': 'wd', // eastup -> westdown
  112.             'ed': 'wu', // eastdown -> westup
  113.             'su': 'nd', // southup -> northdown
  114.             'sd': 'nu', // southdown -> northup
  115.             'wu': 'ed', // westup -> eastdown
  116.             'wd': 'eu', // westdown -> eastup
  117.             'u': 'd',   // up -> down
  118.             'd': 'u',   // down -> up
  119.             'enter': 'out', // 假设 enter/out 互为反向
  120.             'out': 'enter'
  121.             // 可以根据需要添加其他特殊移动指令的反向
  122.         };

  123.         const commands = pathString.split(';');
  124.         const reversedCommands = commands.reverse();

  125.         const processedCommands = reversedCommands.map(cmd => {
  126.             cmd = cmd.trim();
  127.             if (!cmd) return ''; // 处理可能的空字符串

  128.             // 匹配指令,例如 "#3 w" 或 "ne"
  129.             const match = cmd.match(/^(#\d+\s+)?([a-z]+)$/i);

  130.             if (match) {
  131.                 const prefix = match[1] || ''; // 前缀,例如 "#3 " 或空字符串
  132.                 const direction = match[2];    // 方向,例如 "w" 或 "ne"
  133.                 const opposite = oppositeDirections[direction.toLowerCase()];

  134.                 if (opposite) {
  135.                     return prefix + opposite;
  136.                 } else {
  137.                     // 如果找不到反向,可能是不支持的方向或特殊指令,原样返回
  138.                     return cmd;
  139.                 }
  140.             } else {
  141.                 // 如果不匹配模式(可能是特殊指令),原样返回
  142.                 return cmd;
  143.             }
  144.         });

  145.         // 过滤掉处理过程中可能产生的空字符串
  146.         return processedCommands.filter(cmd => cmd).join(';');
  147.     }
  148. }
复制代码
利用上面的工具函数,实现药浴任务的一些代码
  1. yaoyu: function () {
  2.         api.alias('yaoyu.buy', async () => {
  3.             await sys.batch(['buy im_212', 'buy im_212', 'buy im_700', 'buy im_947', 'buy im_768'], 3);
  4.         })
  5.         api.alias('yaoyu.gomutong', async () => {
  6.             await sys.xy('晋阳', 'sw;w;w;w;s');
  7.         })
  8.         api.alias('yaoyu.backmutong', async () => {
  9.             let backpath = sys.reversePath('sw;w;w;w;s');
  10.             await sys.batch([backpath,'@go 扬州'], 2);
  11.         })
  12.         api.alias('yaoyu.askmutong', async () => {
  13.             await sys.batch(['ask hao about 帮助', 'give hao zi', 'ask hao about 交个朋友', 'ask hao about 独门秘方', 'ask hao about 木桶'], 2);
  14.         })
  15.     }
复制代码
后续逐渐更新到wiki上
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 7 天前 | 显示全部楼层
but 发表于 2025-4-9 07:37 AM
使用js很大的好处是可以利用 AI 写不少代码,你看以下的函数大部分都是利用cursor来实现的
利用上面的工具 ...

实际上每个指令都会有失败,比如ask和购买的失败处理。

最好还是注册标准指令后处理。

我以前的洗澡代码大概是这样的

  1. (function (App) {
  2.     App.Quest.Common.Bath = {}
  3.     App.Quest.Common.Bath.Data = {}
  4.     App.Quest.Common.Bath.Start = function (param) {
  5.         if (!param) {
  6.             throw "洗澡的房间不能为空"
  7.         }
  8.         App.Quest.Common.Bath.Data = {
  9.             Home: param,
  10.         }
  11.         App.Quest.Common.Bath.Main()
  12.     }
  13.     App.Quest.Common.Bath.Finish = function () {
  14.         App.Core.Quest.Cooldown("bath", 60 * 60 * 1000)
  15.         App.Next()
  16.     }
  17.     App.Quest.Common.Bath.Main = function () {
  18.         App.Core.Sell.SetNoSell("gouqi")
  19.         App.Core.Sell.SetNoSell("digu pi")
  20.         App.Core.Sell.SetNoSell("shechuang zi")
  21.         App.Core.Sell.SetNoSell("gancao")
  22.         App.Core.Sell.SetNoSell("sheng gancao")
  23.         App.Commands([
  24.             App.NewCommand('prepare', App.PrapareFull),
  25.             App.NewCommand('function', App.Quest.Common.Bath.Next)
  26.         ]).Push()
  27.         App.Next()
  28.     }
  29.     App.Quest.Common.Bath.Next = function () {
  30.         if (App.GetItemByName("地骨皮", true) == null) {
  31.             if (App.GetItemByName("枸杞", true) == null) {
  32.                 App.Commands([
  33.                     App.NewCommand("to", App.Options.NewWalk("lingzhou-jiuguan")),
  34.                     App.NewCommand('do', "buy gouqi;i2"),
  35.                     App.NewCommand('nobusy'),
  36.                     App.NewCommand('function', App.Quest.Common.Bath.Main),
  37.                 ]).Push()
  38.                 App.Next()
  39.                 return
  40.             } else {
  41.                 App.Commands([
  42.                     App.NewCommand('do', "xiao gouqi;i2"),
  43.                     App.NewCommand('nobusy'),
  44.                     App.NewCommand('function', App.Quest.Common.Bath.Main),
  45.                 ]).Push()
  46.                 App.Next()
  47.                 return
  48.             }
  49.         }
  50.         if (App.GetItemByName("生甘草", true) == null) {
  51.             if (App.GetItemByName("甘草", true) == null) {
  52.                 App.Commands([
  53.                     App.NewCommand("to", App.Options.NewWalk("yzdp")),
  54.                     App.NewCommand('do', "buy im_190;i2"),
  55.                     App.NewCommand('nobusy'),
  56.                     App.NewCommand('function', App.Quest.Common.Bath.Main),
  57.                 ]).Push()
  58.                 App.Next()
  59.                 return
  60.             } else {
  61.                 App.Commands([
  62.                     App.NewCommand('do', "bo gancao;i2"),
  63.                     App.NewCommand('nobusy'),
  64.                     App.NewCommand('function', App.Quest.Common.Bath.Main),
  65.                 ]).Push()
  66.                 App.Next()
  67.                 return
  68.             }
  69.         }
  70.         if (App.GetItemObj("Pot", true) == null) {
  71.             App.Commands([
  72.                 App.NewCommand("to", App.Options.NewWalk("yz-zhp")),
  73.                 App.NewCommand('do', "buy pot;i2"),
  74.                 App.NewCommand('nobusy'),
  75.                 App.NewCommand('function', App.Quest.Common.Bath.Main),
  76.             ]).Push()
  77.             App.Next()
  78.             return
  79.         }
  80.         if (App.GetItemByName("蛇床子", true) == null) {
  81.             App.Commands([
  82.                 App.NewCommand("to", App.Options.NewWalk("suzhoudp")),
  83.                 App.NewCommand('do', "buy im_226;i2"),
  84.                 App.NewCommand('nobusy'),
  85.                 App.NewCommand('function', App.Quest.Common.Bath.Main),
  86.             ]).Push()
  87.             App.Next()
  88.             return
  89.         }
  90.         if (App.GetItemByName("大木桶", true) == null) {
  91.             App.Commands([
  92.                 App.NewCommand("to", App.Options.NewWalk("jinyangyp")),
  93.                 App.NewCommand('ask', App.Options.NewQuestion("hao ba", "帮助")),
  94.                 App.NewCommand('nobusy'),
  95.                 App.NewCommand('do', "give shechuang zi to hao ba"),
  96.                 App.NewCommand('nobusy'),
  97.                 App.NewCommand('ask', App.Options.NewQuestion("hao ba", "交个朋友")),
  98.                 App.NewCommand('nobusy'),
  99.                 App.NewCommand('ask', App.Options.NewQuestion("hao ba", "独门秘方")),
  100.                 App.NewCommand('nobusy'),
  101.                 App.NewCommand('ask', App.Options.NewQuestion("hao ba", "木桶")),
  102.                 App.NewCommand('nobusy'),
  103.                 App.NewCommand('do', "i2"),
  104.                 App.NewCommand('function', App.Quest.Common.Bath.Main),
  105.             ]).Push()
  106.             App.Next()
  107.             return
  108.         }
  109.         App.Commands([
  110.             App.NewCommand("to", App.Options.NewWalk("xinyang-tqc")),
  111.             App.NewCommand('do', "fill pot;i2"),
  112.             App.NewCommand('nobusy'),
  113.             App.NewCommand("to", App.Options.NewWalk("yz-sczh")),
  114.             App.NewCommand("move", App.Options.NewPath("enter " + App.Quest.Common.Bath.Data.Home)),
  115.             App.NewCommand("do", "add shechuang zi;add digu pi;add sheng gancao;pour tong;pour tong;pour tong;bath"),
  116.             App.NewCommand("delay", 120),
  117.             App.NewCommand("nobusy"),
  118.             App.NewCommand('function', App.Quest.Common.Bath.Finish),
  119.         ]).Push()
  120.         App.Next()
  121.     }
  122. })(App)
复制代码


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

本版积分规则

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

GMT+8, 2025-4-16 01:40 AM , Processed in 0.011169 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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