玩家偽裝
FreeMinecraftModels 可以將任何線上玩家偽裝成已載入的模型。偽裝由指令、公開的 DisguiseAPI 以及每位玩家的 PlayerDisguiseEntity(負責處理被偽裝玩家的隱形與模型渲染)所驅動。
指令
| 指令 | 權限 | 說明 |
|---|---|---|
/fmm disguise <modelID> | freeminecraftmodels.disguise.self | 偽裝發送者。僅限玩家使用 |
/fmm disguise <modelID> <player> | freeminecraftmodels.disguise.self + freeminecraftmodels.disguise.others | 偽裝指定的玩家。可從主控台執行 |
/fmm undisguise | freeminecraftmodels.disguise.self | 移除發送者的偽裝。僅限玩家使用 |
/fmm undisguise <player> | freeminecraftmodels.disguise.self + freeminecraftmodels.disguise.others | 移除指定玩家的偽裝。可從主控台執行 |
/fmm disguiselist | freeminecraftmodels.disguise.others | 列出每位被偽裝的玩家及其偽裝模型 |
freeminecraftmodels.* 萬用字元會以 OP 預設值授予 admin、deleteall、disguise.self 與 disguise.others。它同時也會授予另外註冊的 freeminecraftmodels.bypassregionprotection 權限。
行為
- 偽裝已被偽裝的玩家會乾淨地取代先前的偽裝 — 不需要先取消偽裝。
- FMM 使用
setVisibleByDefault(false)對其他觀察者隱藏玩家,並在玩家尚無隱形藥水效果時加入該效果。裝備顯示覆寫會對其他觀察者隱藏盔甲及手持物品,不改變物品欄。玩家自己的視角不受這些裝備覆寫影響;自身身體的繪製仍取決於客戶端的可見性處理。 - FMM 會在相關效果移除或變更事件以及重生後一個 tick 重新套用隱形,但僅限於該偽裝最初加入此效果的情況。偽裝開始前已有的隱形效果不會被保留或還原。解除偽裝會將預設可見性設回
true,移除 FMM 加入的效果,並重新傳送玩家目前的裝備。 - 玩家加入和世界切換時,會向觀察者重新傳送裝備隱藏資訊。這不會取代玩家實際的盔甲或手持物品。
- 玩家的碰撞箱不變。裝飾性偽裝不會建立封包互動實體,其點擊處理常式也不執行操作,因此不會提供用於攻擊或騎乘的獨立目標。隱形仍可能影響 FMM 以外的行為,不能保證怪物的目標選擇不變。
- 偽裝不會在伺服器重啟、
/fmm reload,或玩家登出後保留 — 它們只在記憶體中追蹤,並由DisguiseListeners.onQuit處理常式在PlayerQuitEvent時移除偽裝。死亡和世界切換不會取消玩家的偽裝。 - 成功的
/fmm reload會在關閉流程中移除有效偽裝,之後需要重新套用。如果重新載入在候選內容準備階段遭拒,目前的執行狀態會保留。
偽裝動畫
每個偽裝都有控制器,在模型實體共用的播放引擎執行前,根據玩家狀態選擇動畫。它不會繞過該引擎。控制器檢查動畫是否存在時區分大小寫,因此保留名稱必須使用小寫。
系統會辨識五個保留的動畫名稱,優先順序如下(由高至低):
| 優先順序 | 動畫 | 類型 | 觸發條件 |
|---|---|---|---|
| 1 | attack | 一次性 | 玩家揮動手臂 |
| 2 | jump | 一次性 | 玩家向上離開地面 |
| 3 | sneak | 循環 | 玩家正在潛行 |
| 4 | walk | 循環 | 玩家位置自上一個 tick 起移動超過 0.01 個方塊,包括垂直移動 |
| 5 | idle | 循環 | 其他條件都不適用時 |
值得知道的行為:
-
只有模型實際擁有的動畫會被納入考慮。沒有
sneak動畫的模型會直接落到walk或idle。 -
一次性動畫會要求立即進行非循環播放,並在固定的 20 tick(20 TPS 下為 1 秒)內暫停所有新的選擇。這只是倒數計時,並非測量動畫長度。較長的動畫可能被下一次選擇中斷,較短的動畫可能在選擇恢復前結束。暫停期間的揮臂會合併成一次待處理攻擊,跳躍狀態變化則不會排入佇列。
-
只有在選中的動畫實際改變時才會重新發出循環,因此穩定行走不會每個 tick 都被重新啟動。
-
與一般模型實體上(目前無作用的)jump 狀態不同,
jump在偽裝中是真正有接上的。請參閱動畫。 -
沒有
idle動畫的偽裝模型,每次偽裝時都會記錄一則警告:Disguise model '<model>' has no 'idle' animation — disguised players using this model will freeze on the last animation frame whenever no other action is active.請為任何你打算用作偽裝的模型附上一個
idle動畫。
Bedrock 客戶端
偽裝依賴 FMM 繪製自訂模型。config.yml 中的預設值 sendCustomModelsToBedrockClientsV2: true 啟用 Bedrock 模型傳送。設為 false 會阻止模型送達 Bedrock 觀察者,而被偽裝的玩家仍然隱形。已停用的 sendCustomModelsToBedrockClients 鍵不再讀取。即使 V2 已啟用,客戶端仍需轉換後的資源包和正常運作的 Geyser/Floodgate 整合。
DisguiseAPI
第三方外掛可以透過 com.magmaguy.freeminecraftmodels.api.DisguiseAPI 以程式化方式驅動偽裝。
import com.magmaguy.freeminecraftmodels.api.DisguiseAPI;
// Disguise (returns false if the model ID is not loaded)
boolean ok = DisguiseAPI.disguise(player, "dragon");
// Undisguise (returns true if a disguise was removed)
DisguiseAPI.undisguise(player);
// Queries
boolean isDisguised = DisguiseAPI.isDisguised(player);
String modelID = DisguiseAPI.getDisguiseModelID(player); // null if not disguised
// Unmodifiable snapshot of all disguised players
Collection<Player> all = DisguiseAPI.getDisguisedPlayers();
該 API 是公開、重構安全的入口點。外掛應呼叫 DisguiseAPI 而非內部的 DisguiseManager。
API 不檢查指令權限,也不正規化模型 ID。請傳入線上玩家和精確的已載入 ID。disguise 會在嘗試建立替代偽裝之前移除現有偽裝,因此未知 ID 會在移除舊偽裝後傳回 false。指令會先檢查模型,所以無效的指令 ID 會保留舊偽裝。API 傳回成功僅確認建立,不確認客戶端繪製或資源包接受情況。
常見使用案例
- 角色扮演與 RPG 伺服器: 將玩家偽裝成 Boss 模型用於過場動畫或任務腳本。
- 活動主持: 將主持人偽裝成巨大的自訂模型。
- 坐騎與載具: 結合
/fmm mount與/fmm disguise創造創意運輸配置。 - EliteMobs 整合: Boss 腳本可以偽裝觸發事件的玩家,產生暫時性的轉換效果。
疑難排解
我執行 /fmm disguise dragon 時沒有任何反應。
模型 ID 必須完全符合已載入的模型。請使用 /fmm admin 或該指令的 Tab 補全來驗證模型名稱。指定目標的形式會在解析模型或玩家之前先檢查 freeminecraftmodels.disguise.others,並直接回報缺少該權限。
我的偽裝在 /fmm reload 後消失了。
完整重新載入成功後,這是預期行為。如需自動重新套用偽裝,請監聽 FmmReloadedEvent;它會被安排在初始化後 40 tick 於主執行緒執行。準備階段遭拒不會移除目前的執行狀態。
Bedrock 玩家看不到偽裝。 請參閱上方 Bedrock 客戶端。
被偽裝的玩家仍然對其他人可見。 檢查玩家在偽裝開始時是否已經隱形:FMM 不接管該效果,效果消失後也不會還原。也應檢查會改變玩家可見性、效果或裝備封包的外掛。FMM 同時使用玩家可見性、實際藥水效果和裝備顯示覆寫;修改其他外掛設定前,先確認衝突行為。