跳到正文
本頁目錄

建立套件

本指南帶你從一個空儲存庫出發,做出任何人都能用 lip 安裝的套件:編寫 lip.toml,在自己的伺服器上測試,再用 git 標籤發佈。

套件是 lip 能安裝到伺服器裡的東西:模組、庫、工具、一組檔案。從技術上說,它是一個根部帶有 lip.toml 檔案的歸檔,通常是一個 git 儲存庫。lip.toml 是所有欄位的參考;本指南講常見的用法。

開始之前

你需要:

  • 已安裝的 lip;
  • 一個放套件的 git 儲存庫,例如 https://github.com/user/MyMod;
  • 一個用來測試的伺服器。請在另一個目錄中建立一個。

儲存庫地址去掉 https:// 和 .git 就是套件 ID:github.com/user/MyMod。使用者通過這個 ID 安裝你的套件。

從 lip pkg init 開始

在儲存庫的根目錄中執行:

shell
lip pkg init

lip 會詢問套件 ID,回答不是有效的 ID 時會一直重新詢問。然後它寫入 lip.toml:

toml
format = 4
id = "github.com/user/MyMod"
version = "0.1.0"

[[variants.""]]
side = "server"
platform = "win-x64"

如果已經存在 lip.toml,或者命令沒有執行在終端機中而無法詢問,命令會失敗。在介面中,工具頁的建立 lip.toml 對目前工作區做同樣的事。

lip.toml 的結構

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。

  1. 組建你的模組,讓 manifest.json 和模組的檔案位於同一個目錄中。

  2. 封裝這個目錄:

    shell
    lip pkg pack build/ -o MyMod-server-win-x64.zip
  3. 在你的 git 託管平臺上,把這個 ZIP 檔案附加到該版本的發佈中。

  4. 在 lip.toml 中指向它:

    toml
    format = 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 說明哪些檔案放到哪裡:

toml
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套件自身的歸檔:標籤處的儲存庫。
ziplip 從 urls 下載的 ZIP 檔案。
place 的形式src作用
檔案MyTool.exe把這個檔案寫到 dest。
目錄config/(以 / 結尾)把它之下的每個檔案寫到 dest 之下。
globplugins/*.dll把每個符合的檔案寫到 dest 之下。

一個條目可以混用多種資源:模組可以在 mcmod 資源之外再帶一個 zip 資源,用來放置 mods/ 之外的檔案。

相依

deps 把每個相依的套件 ID 映射到一個版本範圍。lip 會連同你的套件一起安裝這些相依;如果一組套件的範圍無法同時滿足,lip 會拒絕安裝。

toml
[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;不寫 # 時得到預設變體 ""。

toml
[[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)會讀取其他條目。你支援的每個執行端和平臺各加一個條目,每個條目有自己的資源:

toml
[[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 在安裝和解除安裝前後、在伺服器目錄中執行的命令:

toml
[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 資源。

在一個伺服器的目錄中:

  1. 檢查 lip 能否讀取你的 lip.toml。它會以 JSON 輸出套件檔(模板已填好),或者說明哪裡有問題:

    shell
    lip pkg view ../MyMod
  2. 看看安裝會做什麼,而不做任何變更:

    shell
    lip install ../MyMod --dry-run
  3. 從目錄安裝它:

    shell
    lip install ../MyMod
    lip list
  4. 用 lip run 啟動伺服器,試用模組。

  5. 修改之後,重新讀取這個目錄,或者移除這個套件:

    shell
    lip update ../MyMod
    lip uninstall ../MyMod

lip update 只在 version 變了的時候才取代已安裝的套件。測試期間,請提高 version,或者解除安裝後重新安裝。

要測試 ZIP 檔案的使用者實際得到的內容,請封裝這個套件並安裝歸檔:

shell
lip pkg pack ../MyMod -o ../MyMod.zip
lip install ../MyMod.zip

介面的工具頁做同樣的事:封裝 ZIP… 就是 lip pkg pack,檢視套件資訊… 就是 lip pkg view。

發佈版本

套件的一個版本就是一個名為 v 加版本號的 git 標籤:

  1. 把 lip.toml 中的 version 設為新版本,例如 1.0.0,然後提交。

  2. 建立 urls 指向的發佈資源,例如 MyMod-server-win-x64.zip。

  3. 給這個提交打標籤,並推送標籤:

    shell
    git tag v1.0.0
    git push origin v1.0.0
  4. 在任意目錄中檢查 lip 能否看到這個版本:

    shell
    lip pkg view github.com/user/MyMod

    versions 中列出了 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,使用小寫;還可以再加上你喜歡的其他標籤:

toml
[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 仍然能安裝它們,但不再建立它們。要轉換這樣的套件,參見移轉套件。

另請參閱