如果想要試用當小白鼠的話,可以看看項目開源地址,裡面的 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