建立套件
本指南帶你從一個空儲存庫出發,做出任何人都能用 lip 安裝的套件:編寫 lip.toml,在自己的伺服器上測試,再用 git 標籤發佈。
套件是 lip 能安裝到伺服器裡的東西:模組、庫、工具、一組檔案。從技術上說,它是一個根部帶有 lip.toml 檔案的歸檔,通常是一個 git 儲存庫。lip.toml 是所有欄位的參考;本指南講常見的用法。
開始之前
你需要:
儲存庫地址去掉 https:// 和 .git 就是套件 ID:github.com/user/MyMod。使用者通過這個 ID 安裝你的套件。
從 lip pkg init 開始
在儲存庫的根目錄中執行:
lip pkg initlip 會詢問套件 ID,回答不是有效的 ID 時會一直重新詢問。然後它寫入 lip.toml:
format = 4
id = "github.com/user/MyMod"
version = "0.1.0"
[[variants.""]]
side = "server"
platform = "win-x64"如果已經存在 lip.toml,或者命令沒有執行在終端機中而無法詢問,命令會失敗。在介面中,工具頁的建立 lip.toml 對目前工作區做同樣的事。
lip.toml 的結構
format = 4 # 始终为 4
id = "github.com/user/MyMod" # 包 ID:仓库的路径
version = "1.0.0" # 版本,不带前导 "v"
[info] # 给人和模组列表看的;lip 忽略它
name = "My Mod"
description = "A short description"
tags = ["utility"]
[[variants.""]] # 默认变体的一个条目
side = "server" # "server" 或 "client"
platform = "win-x64" # lip 只安装 win-x64 的条目
[variants."".deps] # 这个条目依赖什么
"github.com/LiteLDev/LeviLamina" = ">=1.0.0 <2.0.0"
[[variants."".assets]] # 文件从哪里来
type = "mcmod"
urls = ["https://github.com/user/MyMod/releases/download/v{{version}}/MyMod-server-win-x64.zip"]需要知道三件事:
- 條目。
variants把變體名映射到一組條目。每個條目只對應一個執行端和一個平臺。[[variants.""]]向預設變體""新增一個條目。 - lip 只安裝
win-x64的server條目,在任何系統上都是如此。在 Linux 和 macOS 上,它通過 Wine 執行 Windows 版伺服器。因此服務端模組需要一個platform = "win-x64"的server條目。 - 模板。 每個字串都是模板:
{{version}}會變成檔案中的version。把它用在 URL 裡,這樣發佈新版本時只需要改version。
模組套件
模組是帶有 mcmod 類型資源的條目:這個資源是一個 ZIP 歸檔,根部有該模組的 LeviLamina manifest.json。lip 把整個歸檔寫入 mods/<name>/,其中 <name> 是該 manifest.json 中的 name。
-
組建你的模組,讓
manifest.json和模組的檔案位於同一個目錄中。 -
封裝這個目錄:
shelllip pkg pack build/ -o MyMod-server-win-x64.zip -
在你的 git 託管平臺上,把這個 ZIP 檔案附加到該版本的發佈中。
-
在
lip.toml中指向它:tomlformat = 4 id = "github.com/user/MyMod" version = "1.0.0" [info] name = "My Mod" [[variants.""]] side = "server" platform = "win-x64" preserve = ["mods/MyMod/config/"] [variants."".deps] "github.com/LiteLDev/LeviLamina" = ">=1.0.0 <2.0.0" [[variants."".assets]] type = "mcmod" urls = ["https://github.com/user/MyMod/releases/download/v{{version}}/MyMod-server-win-x64.zip"]
lip 唯讀取 manifest.json 中的 name,並原樣安裝這個檔案。它不讀取其中的 dependencies:你的模組需要什麼,請自己寫進 deps。
preserve 保留使用者改過的內容:安裝或更新套件時,已存在的檔案不會被覆寫;解除安裝時也不會被刪除。它的模式相對於伺服器目錄,所以要寫 mods/MyMod/config/,而不是 config/。
檔案套件
檔案套件是所有不是模組的套件:它把檔案放到伺服器目錄中。每個資源指明從哪個歸檔取檔案,它的 place 說明哪些檔案放到哪裡:
format = 4
id = "github.com/user/MyTool"
version = "1.0.0"
[[variants.""]]
side = "server"
platform = "win-x64"
preserve = ["plugins/mytool/config.json"]
[[variants."".assets]]
type = "self"
place = [{ src = "config/", dest = "plugins/mytool/" }]
[[variants."".assets]]
type = "zip"
urls = ["https://github.com/user/MyTool/releases/download/v{{version}}/MyTool-win-x64.zip"]
place = [{ src = "MyTool.exe", dest = "MyTool.exe" }]| 資源類型 | 檔案來自 |
|---|---|
self | 套件自身的歸檔:標籤處的儲存庫。 |
zip | lip 從 urls 下載的 ZIP 檔案。 |
place 的形式 | src | 作用 |
|---|---|---|
| 檔案 | MyTool.exe | 把這個檔案寫到 dest。 |
| 目錄 | config/(以 / 結尾) | 把它之下的每個檔案寫到 dest 之下。 |
| glob | plugins/*.dll | 把每個符合的檔案寫到 dest 之下。 |
一個條目可以混用多種資源:模組可以在 mcmod 資源之外再帶一個 zip 資源,用來放置 mods/ 之外的檔案。
相依
deps 把每個相依的套件 ID 映射到一個版本範圍。lip 會連同你的套件一起安裝這些相依;如果一組套件的範圍無法同時滿足,lip 會拒絕安裝。
[variants."".deps]
"github.com/LiteLDev/LeviLamina" = ">=1.0.0 <2.0.0"
"github.com/user/MyLib" = "^0.3.0"
"github.com/LiteLDev/LegacyScriptEngine#lua" = "^0.9.0"- 鍵是
<包 ID>;相依某個套件的某個變體時,寫<包 ID>#<变体>。 - 範圍的寫法與 Semver for .NET 相同:
^1.2.0、~1.2.0、>=1.0.0 <2.0.0、1.2.*。單獨寫1.2.3表示恰好這個版本。 - 模組應當相依
github.com/LiteLDev/LeviLamina,並寫明它能配合的版本範圍。lip 就是靠這個知道你的模組支援哪些 LeviLamina,進而支援哪些遊戲版本。範圍要如實填寫:如果伺服器的 LeviLamina 不在範圍內,lip 會拒絕把模組裝進去。
變體
用變體可以從一個儲存庫提供多個套件。使用者用 #<variant> 選擇其中一個,例如 lip install github.com/user/MyEngine#lua;不寫 # 時得到預設變體 ""。
[[variants.lua]]
side = "server"
platform = "win-x64"
assets = [{ type = "self", place = [{ src = "lua/", dest = "plugins/myengine/lua/" }] }]
[[variants.quickjs]]
side = "server"
platform = "win-x64"
assets = [{ type = "self", place = [{ src = "quickjs/", dest = "plugins/myengine/quickjs/" }] }]變體名由小寫字母、數字和 _ 組成,中間最多有一個 /。每個變體作為一個獨立的套件 <包 ID>#<变体> 安裝,所以多個變體可以同時安裝。其他套件用鍵 <包 ID>#<变体> 來相依某個變體。
執行端和平臺
一個條目對應一個執行端和一個平臺。lip 自己只使用 server 和 win-x64;其他啟動器(例如客戶端的 LeviLauncher)會讀取其他條目。你支援的每個執行端和平臺各加一個條目,每個條目有自己的資源:
[[variants.""]]
side = "server"
platform = "win-x64"
assets = [{ type = "mcmod", urls = ["https://github.com/user/MyMod/releases/download/v{{version}}/MyMod-server-win-x64.zip"] }]
[[variants.""]]
side = "client"
platform = "win-x64"
assets = [{ type = "mcmod", urls = ["https://github.com/user/MyMod/releases/download/v{{version}}/MyMod-client-win-x64.zip"] }]同一個變體的兩個條目不能有相同的執行端和平臺。
鉤子
hooks 是 lip 在安裝和解除安裝前後、在伺服器目錄中執行的命令:
[variants."".hooks]
post_install = ["echo MyTool installed"]
pre_uninstall = ["MyTool.exe --unregister"]| 鉤子 | 執行時機 |
|---|---|
pre_install | 寫入檔案之前。 |
post_install | 寫入檔案之後。 |
pre_uninstall | 刪除檔案之前。 |
post_uninstall | 刪除檔案之後。 |
使用之前需要知道:
- 命令由
cmd執行,在 Linux 和 macOS 上也是如此,那裡的cmd執行在 Wine 中。請寫 Windows 命令,並避免在其中使用":在 Wine 下,含有"的命令無法按原樣到達cmd。 - 以非 0 結束代碼結束的命令會讓整個操作失敗。
- 操作失敗時,lip 會復原它對檔案的變更,但不會復原你的命令做過的事。請寫可以安全地執行兩次的命令。
- 更新會先執行舊版本的解除安裝鉤子,再執行新版本的安裝鉤子。
preserve 和 purge 夠用的時候,優先用它們而不是鉤子:purge 列出解除安裝時要額外刪除的路徑,例如你的模組寫出的日誌。
本機測試
發佈之前,請在真實的伺服器中測試你的套件。
TIP
mcmod 和 zip 資源始終從它的 urls 下載,即使套件來自一個目錄也是如此。要在發佈存在之前測試,請先把歸檔上傳到某個能通過 HTTPS 訪問的地方,或者在開發期間使用 self 資源。
在一個伺服器的目錄中:
-
檢查 lip 能否讀取你的
lip.toml。它會以 JSON 輸出套件檔(模板已填好),或者說明哪裡有問題:shelllip pkg view ../MyMod -
看看安裝會做什麼,而不做任何變更:
shelllip install ../MyMod --dry-run -
從目錄安裝它:
shelllip install ../MyMod lip list -
用
lip run啟動伺服器,試用模組。 -
修改之後,重新讀取這個目錄,或者移除這個套件:
shelllip update ../MyMod lip uninstall ../MyMod
lip update 只在 version 變了的時候才取代已安裝的套件。測試期間,請提高 version,或者解除安裝後重新安裝。
要測試 ZIP 檔案的使用者實際得到的內容,請封裝這個套件並安裝歸檔:
lip pkg pack ../MyMod -o ../MyMod.zip
lip install ../MyMod.zip介面的工具頁做同樣的事:封裝 ZIP… 就是 lip pkg pack,檢視套件資訊… 就是 lip pkg view。
發佈版本
套件的一個版本就是一個名為 v 加版本號的 git 標籤:
-
把
lip.toml中的version設為新版本,例如1.0.0,然後提交。 -
建立
urls指向的發佈資源,例如MyMod-server-win-x64.zip。 -
給這個提交打標籤,並推送標籤:
shellgit tag v1.0.0 git push origin v1.0.0 -
在任意目錄中檢查 lip 能否看到這個版本:
shelllip pkg view github.com/user/MyModversions中列出了1.0.0,manifest就是你打標籤的那個檔案。
lip 檢查的規則:
lip.toml中的id必須是儲存庫的路徑。否則這個提交不是套件。- 在標籤
v1.0.0處,version必須是1.0.0。否則 lip 跳過這個標籤。 - 標籤必須是
v加完整的 SemVer 版本。v1.0不是版本。v1.1.0-beta.1是預發行版本。 - 儲存庫必須能在不登入的情況下通過
https://<包 ID>.git訪問。
之後使用者就可以用 lip install github.com/user/MyMod 安裝它。不發佈版本時,他們仍然可以安裝某個分支或提交:lip install github.com/user/MyMod@branch:main。
上架
介面的取得模組頁和 levimc.org/mods 顯示的是 LeviMC 目錄中的模組。這個目錄由 levimc.org 維護,而不是 lip:套件怎樣進入目錄,請檢視 levimc.org。
不在目錄中的套件同樣可以通過它的 ID 安裝。
info.tags 幫助人們在這類清單中找到你的套件;lip 自己忽略標籤。清單會優先顯示下面這些標籤,配上翻譯後的名稱,並允許使用者按它們篩選。請按這裡的寫法填寫 ID,使用小寫;還可以再加上你喜歡的其他標籤:
[info]
tags = ["management", "economy"]推薦標籤
| 標籤 | 名稱 | 適用於 |
|---|---|---|
library | 前置庫 / API | 其他模組相依的庫或 API,例如事件、表單或導出函數。 |
utility | 實用工具 | 玩家日常使用的工具,例如背套件輔助、資訊顯示、物品提示和配方檢視。 |
management | 伺服器管理 | 運營伺服器,例如備份、封禁、白名單、登入、命令和領地。 |
game-mechanics | 遊戲機制 | 改變遊戲玩法,例如原版增強功能和成就。 |
adventure | 內容與冒險 | 可供探索的新內容,例如世界生成、地形和生物群系。 |
visual | 視覺與介面 | 玩家看到的內容,例如 HUD、側邊欄、光影、回放和錄製。 |
economy | 經濟 | 貨幣、商店和交易。 |
teleport | 傳送 | 傳送命令、家園、傳送點和傳送石碑。 |
anticheat | 反作弊 | 檢測和阻止作弊,例如反礦透。 |
optimization | 性能優化 | 提升性能,例如實體和掉落物清除。 |
bugfix | 錯誤修復 | 修復遊戲的錯誤。 |
technology | 技術與紅石 | 紅石、活塞和自動化。 |
protocol | 協議與多版本 | 網路協議,例如讓多個遊戲版本的客戶端加入。 |
不需要用標籤標明執行端或平臺,也不需要標明這個套件是 LeviLamina 模組:條目和 deps 已經說明了這些。
lip v0.x 的套件
lip v0.x 的套件用 tooth.json 而不是 lip.toml。lip 仍然能安裝它們,但不再建立它們。要轉換這樣的套件,參見移轉套件。
另請參閱
- lip.toml:每一個欄位。
lip pkg init、lip pkg pack、lip pkg view- 工具:介面中同樣的操作。
- 移轉套件