Lycohinya 是怎麼搭起來的(二):插件怎麼拆
上一篇講了 Lycohinya 的插件分三層。這篇講最上面那層:玩法插件是怎麼拆的,以及為什麼不是每個功能都拆成一顆。
拆之前
2.0 之前,大部分功能都塞在兩顆插件裡:核心插件 LycohinyaCore,和生活功能插件 LycoServerTweaks。插件 JAR 是熱換的最小單位,所以只要改一行使魔設定,就得整顆核心插件熱換,玩家開著的選單會被關掉、排程會重來。生活功能插件也一樣,調一下定時重啟,跟它無關的背包整理、傳送功能都會跟著被打斷。
拆了哪些
2.0 拆出了五顆:
- LycoFamiliar:使魔,原本在核心插件裡,是核心插件最大的一塊。
- LycoTravel:家、傳送點、領地飛行、生態域定位,原本在生活功能插件裡。
- LycoOps:定時重啟、健康檢查、維護時段、管理員警報。
- LycoChat:聊天守則、禁言、洗頻偵測、@提及。
- LycoAlts:小號判定和登入上限。
後面四顆都是從生活功能插件拆出來的。留在原地的是簽到、檢定、玩家偏好、主選單、信箱這些共用同一批玩家資料的功能(核心插件),以及背包整理、催熟、展示框這類沒有資料表、幾乎不會改的小功能(生活功能插件)。
怎麼判斷要不要拆
我不是看功能大小,而是看這幾件事:
- 它有沒有自己的資料表,而且沒有別人在寫。
- 改它的時候,同一顆插件裡的其他功能會不會一起改。
- 熱換它會打斷什麼,例如玩家開著的選單、登入檢查、排程。
- 它有沒有自己的排程、事件監聽、Discord 訂閱這些要收拾的東西。
- 用到它的插件,在它不在的時候能不能退回安全的預設。
拆開之後如果兩邊還要寫同一張表,那就不拆。那樣只是把同一個麻煩分到兩顆插件裡,之後更難修。
資料一列都不搬
拆的時候我沒有搬任何資料。以使魔為例:
---
config:
layout: elk
---
flowchart TB
subgraph lib["LycoLib"]
api["使魔介面"]
end
fam["使魔插件<br/>LycoFamiliar"]
core["核心插件<br/>LycohinyaCore"]
works["工作站插件"]
subgraph db["核心插件的資料庫"]
famt[("使魔的表")]
coret[("玩家共用的表")]
end
fam -- 實作並登記 --> api
core -- 要用時才查 --> api
works -- 要用時才查 --> api
fam -- 唯一能寫 --> famt
core -- 只寫自己的 --> coret
fam -. 讀它的資料庫設定 .-> core使魔的資料表還放在核心插件的資料庫裡,只是改成只有使魔插件能寫。使魔插件啟動時,先確認核心插件在場、讀它的資料庫設定連過去,再檢查自己那幾張表的結構對不對,不對就不啟用,資料一筆都不碰。核心插件則不再讀寫使魔的表。旅行、聊天、小號的表也是一樣,留在生活功能插件的資料庫,由新的插件來寫。
這樣做的好處是不用搬資料,上線時就少一個會出錯的步驟。代價是借出資料庫的那一方脫不了關係:核心插件沒啟動,使魔插件也起不來。
插件之間怎麼互相用
插件之間不直接引用對方,要互相呼叫的介面都放在 LycoLib。使魔插件啟動時把自己登記上去;核心插件、工作站插件要查使魔狀態時,每次都現場去問有沒有人提供。
使魔插件不在的時候,查詢會拿到安全的預設值;如果是「發一隻使魔當獎勵」這種動作,會回「無法使用」,讓商城或抽卡那邊可以退款,不會把玩家的東西吞掉。
拆的時候我定了一條規矩:玩家打的指令、看到的選單入口、權限節點一個都不能變。玩家不需要知道背後換了插件。
拆完之後
現在改使魔不用再碰核心插件,調重啟排程也不會關掉玩家的選單。代價是插件數量變多,每多一顆就多一份設定、一組介面,還有「對方不在時怎麼辦」要想清楚。LycoLib 也因此變成所有人的依賴,它一換版,整串插件都得跟著重載。
如果你的伺服器還沒遇到「熱換一個功能會打斷另一個」,我不建議先拆。等它變成日常再拆,判斷依據也會比較清楚。