跳转至内容
  • 运行于云服务器的Mud客户端

    2 2
    2 主题
    2 帖子
    jarlyynJ
    版本号 1.2026.01.13 主要内容为 修复v8 内存泄漏问题 修复v8的HTTP接口内存泄漏问题 部分UI微调 下载链接:https://github.com/jarlyyn/hellclient/releases/tag/2026.01.13
  • 允许于Android/iOS/Windows/Linux/Mac的Hellclient管理软件

    3 3
    3 主题
    3 帖子
    jarlyynJ
    更新内容: 修正连接按钮状态bug 部分UI调整 iOS及MacOS版请在AppStore更新 发布地址
  • 跨平台跨客户端的mud 地图信息维护及Mapper程序

    3 3
    3 主题
    3 帖子
    jarlyynJ
    hellmapamanager.ts是一款将HellMapManager中C#的数据维护/调用代码用Typescript重写的项目。 用于在不使用http接口的情况下,使用v8/luajit等高性能脚本引擎直接调用HellMapmanager中的相应算法。 项目支持 hmm格式文件的维护 编译到javascript/lua格式 项目地址为 https://github.com/hellclient-scripts/hellmapmanager.ts
  • 一起来沟通Mud机器人脚本

    28 28
    28 主题
    28 帖子
    jarlyynJ
    对于整个移动模块来说,最核心的可能就是移动失败处理了。 本身对于大部分系统来说,失败/意外流程处理都是最复杂的。而移动模块的失败处理大部分面对的是wiz的恶意,所以更强调可扩展性和可维护性。 对于移动失败,本质来说,就是: 发出移动指令 2.预期会收到成功信号,或者各种失败信号 3.如果收到成功信号,则对当前移动的这一步进行核销。 4.如果受到的是失败信号,则根据具体的失败信号数据进行处理,重规划路线/重试/放弃失败。 因此,移动失败是一个很典型是预期管理 我做的预期管理模块有很大一部分目的就是为了移动失败处理设计的。如果是其他语言/客户端的机器,也能通过各种类库或者触发器分组的功能进行预期管理。 以newhelljs为例,代码地址 App.Map.StepPlan = new App.Plan( App.Map.Position, function (task) { App.Move.RetryStep = false let tt = task.AddTimer(App.Map.StepTimeout, function (timer) { return App.Map.OnStepTimeout() }).WithName("timeout") task.AddCatcher("core.longtimestep", function () { tt.Reset(App.Move.LongtimeStepDelay) return true }) task.AddCatcher("core.retrymove", function () { App.Move.RetryStep = true return true }) task.AddCatcher("core.movereset").WithName("movereset") task.AddCatcher("core.wrongway").WithName("wrongway") task.AddCatcher("core.walkbusy").WithName("walkbusy") task.AddCatcher("core.walkresend").WithName("walkresend") task.AddCatcher("core.walkretry").WithName("walkretry") task.AddCatcher("core.walkfail").WithName("walkfail") task.AddCatcher("core.blocked2", (catcher, event) => { if (App.Core.Room.Current.ID == "") { return true; } }).WithName("blocked2") task.AddCatcher("core.blocked", (catcher, event) => { catcher.WithData(event.Data) }).WithName("blocked") task.AddCatcher("core.needrest").WithName("needrest") }, function (result) { switch (result.Type) { case "cancel": break default: switch (result.Name) { case "timeout": break case "movereset": App.Map.Room.ID = "" App.Map.Retry() break case "wrongway": if (App.Move.RetryStep) { App.Map.Resend(0) return } App.Map.Room.ID = "" App.Sync(() => { App.Map.Retry() }) break case "walkbusy": App.Map.Resend() break case "walkresend": App.Map.Resend(0) break case "walkretry": App.Map.Retry() break case "blocked": App.Move.OnBlocker(result.Data) break case "blocked2": App.Core.Blocker.BlockStepRetry() break case "needrest": App.Move.NeedRest() break case "walkfail": App.Move.OnWalkFail() break default: } } } ) 很明显,是对于整个移动做了预期。 首先这个预期是基于App.Map.Position的 Map库中有两个Position App.Map.Position 当前房间范围 App.Map.MovePosition 当前移动的范围 所以,当成功移动时,整个移动处理会因为离开范围而被"cancel" 当没有Cacnel时,说明意外出现了。 不同的信号(事件)会根据在switch里做分支判断,调用各种异常。 这也就是整个失败处理的底层逻辑 在 完全基于hmm开发的hongchengjs中,我为了可维护性,做了些调整,将常见的移动失败作为一个文本保存,启动时调入内存放在一个Hash表里,直接做表匹配模拟事件,算是一个小的结构优化。 代码地址 在失败处理中,有四个处理是最为典型的 第一个是路线错误 也就是"core.wrongway"事件。 触发后会清空当前房间信息,调用当前移动的Retry方法进行重新规划和移动。 第二中是路线禁用 也就是"core.blocked2"事件。 出发该事件后,说明被拦截,而且不该击杀然路Npc,会把当前房间和目标房间的出口临时禁用,然后重新规划路线。 第三种是插入战斗 "core.blocked"事件 会把当前移动进行快照,然后击杀拦路npc,再对快照进行还原,继续移动。也是很经典的形式。 最后是重新规划 "walkretry"事件 这个事件和路线错误一样都是直接调用重新规划。 区别是这个事件本质是一个衍生事件,在我的事件系统中,一般会调用Filter进行处理,一般是调整当前Move的上下文标签。然后再根据最新上下文标签进行重新规划。 这四种基本就是主要的移动失败处理的内容。当然,不同的Mud可能还会有一些细节上的调整。 移动失败处理的主要处理方式就是 重试。 调整上下文,重新规划,避免失败出口。 挂起移动,解决意外,还原移动并继续,
  • 欢迎自己倒腾mud客户端的一起沟通

    1 1
    1 主题
    1 帖子
    jarlyynJ
    大部分Mud玩家,在有能力制作一个可用的机器人后,都会起自己制作客户端的念头。让自己的机器人在自己的客户端里刷刷的跑,能给一个Mud爱好者带来极大的满足感。 在科技发展到现在,各种语言和框架层出不穷,电脑的硬件也极度丰富,外加AI技术的发展,写一个Mud客户端对普通爱好者已经不是一个遥不可及的事情了。 这系列文章,就是集合我在制作Hellclient时的一些心得体会,希望能给其他同好带来帮助。 而本文,个人希望,类似于武侠小说中的武功总纲,体现出大体框架,然后通过一篇篇细节文章,把整个自建客户端的关键点串起来。 首先,我们要明确,一个Mud客户端要解决几个问题。 我归纳下来,主要是以下几个方面 与Mud服务器的信息交互(telnet/ansi) 用户的快速工具(触发,别名,计时器) 合适的机器配置格式(比如变量) 脚本引擎 用户界面 扩展性 Telnet/ANSI库 telnet可以说是一个老旧的成熟的协议了。大部分的语言都有telnet库,没有telnet库的小众语言利用AI照着现成语言的库抄一个也不算难事。 对于Mud来说,主要是处理一些指令,和subnegotiation协议拓展出来的指令就行。 而ANSI的话,也是定义了另一套显示控制的指令。 从我个人经验来看,telnet和ansi的原始数据在客户端能应该需要一个中间模型(model),能快速的供界面渲染和引擎调用。有些客户端直接渲染,再从渲染完的结果倒过来取数据。个人觉得这样不好,会极大的增加脚本制作的复杂度。 触发/别名/计时器 这三个东西代表了一起机器主要要处理的问题: 服务器返回的响应 用户的输入 时间的流逝 对这个核心,我的思路也有过很多变化。就目前的思路来说: 客户端的触发/别名/计时器,应该从好用,易用的角度出发,让用户能很方便的添加临时功能。 脚本引擎应该抽象出 服务器交互/用户输入/时间层出来,不受客户端限制,不利用客户端的特殊功能。 当然,这只是建议,和一个状态下的想法。整体还是要根据你做客户端的目的来开发。 机器配置 在很多客户端里,变量是和触发/别名/计时器评级的概念。 从我的理解来说,并不是这样。 变量(机器配置)应该是和脚本直接绑定的。 按现代开发的概念,变量至少是 一个Config文件,决定了机器的启动设置。 如果是变量名对应变量值的形式,它更接近于环境变量 这个概念。 同时,个人建议,也是我Hellclient的做法,变量要有备注或注释的空间,可以让用户理解变量怎么使用。 脚本引擎 在真实世界中,嵌入式脚本引擎其实只有两个玩家,javascript和lua。 Lua是老牌玩家,各个语言都有lua的实现或者Binding,语法简单速度快。有可能的话建议使用luajit库,性能还是很不错的。 Javascript又是另一个话题。Javascript是目前使用最广泛的脚本语言,npm上有大量的js库。但嵌入js库不是很容易的一件事情。本质来说,js生态就是v8生态。但不是每个语言都能很容易的嵌入v8引擎。hellclient嵌入v8也是将一个半废弃状态的库进行了一定的魔改。还遇到了Windows下的msys和vc编译器兼容的问题。 所以,个人意见,能方便的用v8的(比如C#有微软官方ClearScript支持,建议一定要支持javascript,lua的话,建议都可以支持一下。 用户界面 就目前的现状来说,除非你使用特殊的技术栈或者技术,不然大部分情况下的软件开发都是跨平台,Windows/Linux/Mac全支持的。 具体到用户界面的形式,其实是3种 浏览器 浏览器形式的(主要是electron,少数如tarui会使用系统自带浏览器) 最大的优势是界面多样话,自定义方便,美观迅速。 缺点是非nodejs方案会多引入与浏览器的交互,性能有上限。而nodejs本身的单线程模型要改造的话工程量很大,强如微软也在vscode里堆了一堆C代码。 客户端 客户端的方案的话,其实主要是qt和skia 两个图形库的方案。qt基本绑定c++,不是那么容易上手(pyqt选手另论)。skia的话,有flutter/dart和avalonia/c# 两员大将,都是不错的方案。 客户端型界面最大的优势是性能有保证。缺点是实现美观/华丽的界面麻烦 无头模式 无头模式就是指提供接口,供网页/其他客户端显示。 理论上说,无头模式一般都会实现一个网页界面。 但他和网页界面的区别是,无头模式由于要支持多种终端,无法充分利用网页界面的华丽/可制定性强,在界面上有很大的妥协。 无头模式的特点是: 1.轻量级,可扩展性高,适合云端运行,通过网页/客户端/app等多种形式连接。 2.界面受限,需要维护多个程序。 Hellclient就是无头模式的客户端。 扩展性 扩展性其实主要就是3个方案 动态链接库(so/dll) 通过lua加载动态链接库可以很容易的对lua进行扩展。性能和功能都是最强大的。但同样的对开发人员的要求也是最高的,安全性上也容易出问题。 Com技术 如果你把自己局限在Windows平台,使用C++/C#开发,activex/com技术是极为强大的。mush本身除了lua的语言也都是通过activex来实现的。但com技术已经是一个事实上逐渐被非主流化的技术,不是很建议绑定的Com技术上 http/websocket技术 通过基于http的api 接口或者websocket实时调用。这个方案在性能上会有所损失,但同时有能够云化集群化的优点。Hellclient就是基于这种方案来提供扩展性。 我的建议 Hellclient是使用go写,采用无头模式,通过http/websocket进行扩展的。 如果让我从头来过,我可能会换成c#,因为go在windows平台下嵌入v8有点蛋疼。 我推荐的语言选型为 c# 综合的王者 flutter/dart 桌面/app全能 electorn/nodejs electorn也是目前桌面端很主流的选择 python web/pyqt方案 这个只适合自用,发布打包都太麻烦了
  • 关于论坛本身的意见与反馈

    1 1
    1 主题
    1 帖子
    jarlyynJ
    欢迎您访问Hellclient社区。 这里是Hellclient客户端及相关mud软件和脚本的沟通社区。欢迎在这里对Hellclient软件,和Mud相关的软件开发和脚本制作进行沟通。 在这里,我们会以下讨论的规范要求每一个用户 仅讨论软件的使用问题和Mud的技术问题。 不要对别的用户,Mud,和机器人进行评论。Mud本身已经是一个粉丝向的小圈子了,大家都是非专业的玩家,请互相保持友好。 由于 Mud 圈本身的互相借鉴和借用的现象很严重,所以本社区不支持任何资料的上传。有代码或程序分享的需要,请上传至github/coding/gitee等平台。 请不要分享破解或者攻击软件/服务器/游戏的经验。 尊重您玩的Mud的规矩,不要讨论和分享针对某个Mud使用,又不被Mud Owner允许的功能。 不建议使用您在游戏里的常用ID,把您在游戏的恩怨情仇蔓延于此。 热爱国家,遵纪守法,不违背公序良俗。 说的有点多,希望我们的社区能能给每一个访问者带来快乐和收获。