如果想要试用当小白鼠的话,可以看看项目开源地址,里面的 release 页面有编译好的版本可以下载,下载后再简单设置一下就可以用了。然而题目还是要自己写
我写这个项目的契机是什么呢?其实理由并不高大上,只不过是我懒得人工审核果然懒惰是推动科技发展的动力。虽然这个插件的原理和理由一样,都没有什么高大上的内容,但我还是研究了好一阵子才研究出了完整的前后端程序。那么下面就来聊聊整个开发过程吧。
首先是前后端的通信方式。我在一开始时是想用 websocket 长链接通信,但由于没有相关基础,所以研究了一段时间都没研究出来。于是我便转向了 http 轮询的方式。但使用这种方式,又遇到了另一个问题:消息队列。由于轮询无法及时向客户端推送消息,因此需要做一个队列缓存消息,当客户端轮询时再读取队列并推送。然而就是这个问题无法解决,无论用什么方案都无法保证稳定性,以及轮询需要消耗数倍的资源来运行,因此我便放弃了这种方式,转为 socketio。
虽然说 socketio 是 websocket 的封装库,理论上使用方法是比纯 websocket 简单的,但在使用过程中我还是遇到了一个问题,这个问题我用了接近两天都没能解决(上一篇文章说的就是这件事)。最后还是在 v2ex 大神的帮助下解决了。这个问题似乎是开发过程中最困难的那个,解决完这个问题后开发进度一日千里,不久后便完成了整个项目并没有。
连接方式确定了,那么接下要确定就是前后端框架了。后端使用的自然是 flask 以及 flask-socketio,毕竟这是我最熟悉的 web 框架。但在客户端方面我却犯了难。如果只需要接收消息,那么只需要一个 socketio 库就能搞定,然而问题正是出在如何添加白名单这里。
由于我服很早就开始使用 mcdreforged,而我现在只会 python,因此我便果断选择了 mcdreforged 进行开发。但在开发时,大麻烦出现了:mcdr 插件中的代码是默认同步进行的,也就是说必须执行完插件中的代码,才会接着进行下一步操作。然而因为我的插件需要保持长连接,mcdr 等不到我的代码执行完毕,所以线程就会无限堵塞,无法执行其他指令。虽然 mcdr 自带了一个多线程功能,但这个多线程功能又及其不完善,无法关闭线程,也就是说如果插件重启了,会同时有两个线程连接后端。权衡利弊之下,我打算放弃 mcdr 平台,另辟蹊径:直接操作 whitelist.json。
如果是直接操作的话,就可以不用考虑多线程之类的操作,也无需担心线程堵塞了。于是我便在这条路上越走越远,最终写出了第一个可以正常使用的产品。
在刚写完没多久,我便后悔了:我根本没有考虑过给盗版服使用。由于 whitelist.json 需要同时存储玩家 id 和 uuid,因此我在程序中写死了从 mojang 官方获取 uuid 的方法。虽然说盗版服的 uuid 是可以随便乱写的,直接获取正版 uuid 也是可以使用的,但就怕有的盗版玩家 id 没有对应的正版 uuid。看来外置程序并不是万能的,还是内置插件的方案比较稳妥。
虽然我不会 java,但万幸的是,我找到了愿意合作的人。相信不久后,fabric 版和 spigot 版就能面世了。希望这个项目能越做越好,毕竟这是第一个我发起的真正有研究方向和前景的项目。
2022.7.26