跳至主要內容

玩家偽裝

FreeMinecraftModels 可以將任何線上玩家偽裝成已載入的模型。偽裝由指令、公開的 DisguiseAPI 以及每位玩家的 PlayerDisguiseEntity(負責處理被偽裝玩家的隱形與模型渲染)所驅動。

指令​

指令權限說明
/fmm disguise <modelID>freeminecraftmodels.disguise.self偽裝發送者。僅限玩家使用
/fmm disguise <modelID> <player>freeminecraftmodels.disguise.self + freeminecraftmodels.disguise.others偽裝指定的玩家。可從主控台執行
/fmm undisguisefreeminecraftmodels.disguise.self移除發送者的偽裝。僅限玩家使用
/fmm undisguise <player>freeminecraftmodels.disguise.self + freeminecraftmodels.disguise.others移除指定玩家的偽裝。可從主控台執行
/fmm disguiselistfreeminecraftmodels.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 會在關閉流程中移除有效偽裝,之後需要重新套用。如果重新載入在候選內容準備階段遭拒,目前的執行狀態會保留。

偽裝動畫​

每個偽裝都有控制器,在模型實體共用的播放引擎執行前,根據玩家狀態選擇動畫。它不會繞過該引擎。控制器檢查動畫是否存在時區分大小寫,因此保留名稱必須使用小寫。

系統會辨識五個保留的動畫名稱,優先順序如下(由高至低):

優先順序動畫類型觸發條件
1attack一次性玩家揮動手臂
2jump一次性玩家向上離開地面
3sneak循環玩家正在潛行
4walk循環玩家位置自上一個 tick 起移動超過 0.01 個方塊,包括垂直移動
5idle循環其他條件都不適用時

值得知道的行為:

  • 只有模型實際擁有的動畫會被納入考慮。沒有 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 同時使用玩家可見性、實際藥水效果和裝備顯示覆寫;修改其他外掛設定前,先確認衝突行為。