Class MapleInventoryManipulator
提供新增(addById(MapleClient, int, short, String)/addbyItem(MapleClient, Item)/addFromDrop(MapleClient, Item, boolean)/addbyId_Gachapon(MapleClient, int, short))、
移除(removeFromSlot(MapleClient, MapleInventoryType, short, short, boolean)/removeById(MapleClient, MapleInventoryType, int, int, boolean, boolean)/removeAllByInventoryId)、移動(move(MapleClient, MapleInventoryType, short, short))、
穿脫裝備(equip(MapleClient, short, short)/unequip(MapleClient, short, short))、丟棄(drop(MapleClient, MapleInventoryType, short, short))與容量檢查(checkSpace(MapleClient, int, int, String))等操作,
並在異動後透過 InventoryPacket 等封包同步客戶端。
關鍵協作者:道具屬性查 MapleItemInformationProvider、實際槽位由 MapleInventory
維護、面向呼叫端的角色為 MapleCharacter/MapleClient;由 InventoryHandler、
商店/交易/掉落拾取與大量 NPC 腳本共用。
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic booleanaddById(MapleClient c, int itemId, short quantity, String gmLog) 依道具代碼新增道具到背包(無擁有者、無寵物、無期限)。static booleanaddById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period) 依道具代碼新增道具到背包,並設定擁有者、寵物與到期天數(無 GM 記錄)。static booleanaddById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period, String gmLog) 依道具代碼新增道具到背包的完整布林版多載(擁有者/寵物/到期/GM 記錄)。static booleanaddById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, String gmLog) 依道具代碼新增道具到背包,並設定擁有者與寵物(無期限)。static booleanaddById(MapleClient c, int itemId, short quantity, String owner, String gmLog) 依道具代碼新增道具到背包並設定擁有者(無寵物、無期限)。static ItemaddbyId_Gachapon(MapleClient c, int itemId, short quantity) 轉蛋專用的道具放入流程,成功時回傳實際寫入背包的道具實例。static booleanaddbyItem(MapleClient c, Item item) 將既有道具實例放入角色背包(非現金商品流程)。static shortaddbyItem(MapleClient c, Item item, boolean fromcs) 將既有道具實例放入角色對應類型的背包,並回送背包封包。static booleanaddFromDrop(MapleClient c, Item item, boolean show) 將地面掉落道具放入角色背包(不強化、非寵物拾取)。static booleanaddFromDrop(MapleClient c, Item item, boolean show, boolean enhance, boolean isPetPickup) 將地面掉落道具的既有實例放入角色背包的核心實作。static byteaddId(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period, String gmLog) 依道具代碼建立並放入道具的核心實作,背包不足時逐格分裝並回送對應封包。static byteaddId(MapleClient c, int itemId, short quantity, String owner, String gmLog) 依道具代碼新增道具到背包並回傳起始槽位(無寵物、無期限)。static voidaddRing(MapleCharacter chr, int itemId, int ringId, int sn, String partner) 將指定戒指加入角色的點數背包,並回送購買戒指封包。static booleancheckSpace(MapleClient c, int itemid, int quantity, String owner) 檢查背包是否有足夠空間容納指定數量的道具(不實際放入)。static booleandrop(MapleClient c, MapleInventoryType type, short src, short quantity) 將背包道具丟到地面(非 NPC 觸發)。static booleandrop(MapleClient c, MapleInventoryType type, short src, short quantity, boolean npcInduced) 將背包道具丟到角色當前地圖的地面,並回送背包更新/丟棄封包的核心實作。static voidequip(MapleClient c, short src, short dst) 將 EQUIP 背包中的裝備穿戴到指定的 EQUIPPED 欄位,並回送裝備變更封包。static intgetUniqueId(int itemId, MaplePet pet) 為道具計算應使用的唯一 ID(unique id)。static voidmove(MapleClient c, MapleInventoryType type, short src, short dst) 在同一背包內移動或合併道具,並回送對應的移動/合併封包。static voidremoveAllByInventoryId(MapleClient c, long inventoryitemid) 依背包道具的內部唯一 ID 刪除複製裝備(反作弊用),並廣播 GM 訊息與寫入記錄。static booleanremoveById(MapleClient c, MapleInventoryType type, int itemId, int quantity, boolean fromDrop, boolean consume) 依道具代碼跨多個槽位扣除指定總數量。static booleanremoveById_Lock(MapleClient c, MapleInventoryType type, int itemId) 依道具代碼扣除一個未受保護的同 ID 道具。static booleanremoveFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop) 從指定背包槽位扣除道具數量(非消耗語意)。static booleanremoveFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop, boolean consume) 從指定背包槽位扣除道具數量,並回送清除或更新背包格封包。static booleanremoveFromSlot_Lock(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop, boolean consume) 扣除指定槽位道具,但先檢查鎖定/不可交易旗標,受保護則拒絕。static voidunequip(MapleClient c, short src, short dst) 將 EQUIPPED 欄位的裝備脫下到 EQUIP 背包的指定槽位,並回送移動封包。
-
Constructor Details
-
MapleInventoryManipulator
public MapleInventoryManipulator()
-
-
Method Details
-
addRing
將指定戒指加入角色的點數背包,並回送購買戒指封包。透過
CashItemFactory解析現金商品序號,再以chr.getCashInventory()產生戒指實例; 若序號無效、或產生的戒指其唯一 ID/道具代碼與傳入參數不符,則靜默不做任何事。成功時會將戒指寫入點數背包並 向客戶端送出MTSCSPacket.sendBoughtRings(boolean, Item, int, int, String)封包。- Parameters:
chr- 取得戒指的角色itemId- 戒指道具代碼(須與產生的戒指相符)ringId- 戒指的唯一 IDsn- 現金商品序號partner- 配對對象名稱(用於封包顯示)
-
addbyItem
將既有道具實例放入角色背包(非現金商品流程)。委派至
addbyItem(MapleClient, Item, boolean)(fromcs=false),背包已滿時會送出 背包已滿提示封包。- Parameters:
c- 目標客戶端item- 要放入的道具實例- Returns:
- 成功放入回傳
true;背包已滿(槽位 -1)回傳false
-
addbyItem
將既有道具實例放入角色對應類型的背包,並回送背包封包。依
GameConstants.getInventoryType(int)決定背包類型後嘗試加入。若加入失敗(槽位為 -1)且fromcs為false,會送出背包已滿與「背包已滿」提示封包。成功時:必要時配置裝備唯一 ID (hasSetOnlyId)、採集工具會觸發handleProfessionTool、送出新增背包格封包,並呼叫havePartyQuest檢查組隊任務道具。- Parameters:
c- 目標客戶端item- 要放入的道具實例fromcs- 是否來自現金商店流程;為true時即使背包已滿也不送出提示封包- Returns:
- 放入後的槽位;背包已滿時回傳 -1
-
getUniqueId
為道具計算應使用的唯一 ID(unique id)。寵物道具沿用傳入寵物的唯一 ID(
pet為null時新配置一個);現金道具 (CASH 背包或isCash)亦新配置一個唯一 ID;其餘道具回傳 -1(不需唯一 ID)。- Parameters:
itemId- 道具代碼pet- 寵物實例,可為null- Returns:
- 唯一 ID;非寵物且非現金道具時回傳 -1
-
addById
依道具代碼新增道具到背包(無擁有者、無寵物、無期限)。委派至
addById(MapleClient, int, short, String, MaplePet, long, String)。- Parameters:
c- 目標客戶端itemId- 道具代碼quantity- 數量gmLog- GM 記錄字串,可為null- Returns:
- 全數成功放入回傳
true,否則false
-
addById
public static boolean addById(MapleClient c, int itemId, short quantity, String owner, String gmLog) 依道具代碼新增道具到背包並設定擁有者(無寵物、無期限)。委派至
addById(MapleClient, int, short, String, MaplePet, long, String)。- Parameters:
c- 目標客戶端itemId- 道具代碼quantity- 數量owner- 擁有者名稱,可為nullgmLog- GM 記錄字串,可為null- Returns:
- 全數成功放入回傳
true,否則false
-
addId
依道具代碼新增道具到背包並回傳起始槽位(無寵物、無期限)。委派至
addId(MapleClient, int, short, String, MaplePet, long, String)。- Parameters:
c- 目標客戶端itemId- 道具代碼quantity- 數量owner- 擁有者名稱,可為nullgmLog- GM 記錄字串,可為null- Returns:
- 放入後的槽位(截為 byte);失敗時回傳 -1
-
addById
public static boolean addById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, String gmLog) 依道具代碼新增道具到背包,並設定擁有者與寵物(無期限)。委派至
addById(MapleClient, int, short, String, MaplePet, long, String)。- Parameters:
c- 目標客戶端itemId- 道具代碼quantity- 數量owner- 擁有者名稱,可為nullpet- 寵物實例,可為nullgmLog- GM 記錄字串,可為null- Returns:
- 全數成功放入回傳
true,否則false
-
addById
public static boolean addById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period) 依道具代碼新增道具到背包,並設定擁有者、寵物與到期天數(無 GM 記錄)。委派至
addId(MapleClient, int, short, String, MaplePet, long, String)。- Parameters:
c- 目標客戶端itemId- 道具代碼quantity- 數量owner- 擁有者名稱,可為nullpet- 寵物實例,可為nullperiod- 到期天數,<= 0表示永久- Returns:
- 全數成功放入回傳
true,否則false
-
addById
public static boolean addById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period, String gmLog) 依道具代碼新增道具到背包的完整布林版多載(擁有者/寵物/到期/GM 記錄)。委派至
addId(MapleClient, int, short, String, MaplePet, long, String)並將其槽位回傳轉為成敗布林。- Parameters:
c- 目標客戶端itemId- 道具代碼quantity- 數量owner- 擁有者名稱,可為nullpet- 寵物實例,可為nullperiod- 到期天數,<= 0表示永久gmLog- GM 記錄字串,可為null- Returns:
- 全數成功放入回傳
true,否則false
-
addId
public static byte addId(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period, String gmLog) 依道具代碼建立並放入道具的核心實作,背包不足時逐格分裝並回送對應封包。行為要點:
- 道具不存在會記錄到
logs/except/不存在道具.txt並回傳 -1。 - 禁止重複拾取(
isPickupRestricted)且玩家已持有時,送出背包已滿/道具無法取得封包並回傳 -1。 - 非裝備且非可充值道具:先把既有同 ID(同擁有者、未到期)槽位補滿至上限,再以新格放入剩餘數量。
- 可充值道具(飛鏢/子彈):不論數量一律放進單一格。
- 裝備:數量必須為 1,否則丟出
InventoryException;採集工具會觸發handleProfessionTool。 - 任一格放入失敗(槽位 -1)即回送背包已滿封包並回傳 -1。
ServerConstants.LOG_TRACE_INVENTORY開啟時會將取得道具的呼叫堆疊寫入/StackTrace/items/<角色名>.txt。成功時送出新增/更新背包格封包並呼叫havePartyQuest。- Parameters:
c- 目標客戶端itemId- 道具代碼quantity- 數量(裝備必須為 1)owner- 擁有者名稱,可為nullpet- 寵物實例,可為nullperiod- 到期天數,> 0才設定到期時間gmLog- GM 記錄字串,可為null- Returns:
- 最後放入的槽位(截為 byte);失敗時回傳 -1
- Throws:
InventoryException- 當對裝備傳入非 1 的數量時
- 道具不存在會記錄到
-
addbyId_Gachapon
轉蛋專用的道具放入流程,成功時回傳實際寫入背包的道具實例。與
addId(MapleClient, int, short, String, String)類似但語意有別:開頭即要求 EQUIP/USE/ETC/SETUP 四大背包皆至少有一個空格,否則回傳null;裝備會先經randomizeStats隨機化屬性。逐格分裝時,若先前已成功放入部分數量但後續格滿, 仍回傳已建立的道具實例(而非null)。送出新增/更新背包格封包並呼叫havePartyQuest。- Parameters:
c- 目標客戶端itemId- 道具代碼quantity- 數量(裝備必須為 1)- Returns:
- 放入背包的道具實例;空間不足、道具不存在或完全未放入時回傳
null - Throws:
InventoryException- 當對裝備傳入非 1 的數量時
-
addFromDrop
將地面掉落道具放入角色背包(不強化、非寵物拾取)。委派至
addFromDrop(MapleClient, Item, boolean, boolean, boolean)。- Parameters:
c- 目標客戶端item- 拾取到的道具實例show- 是否向客戶端顯示「取得道具」效果- Returns:
- 成功放入回傳
true;背包已滿或道具不可取得回傳false
-
addFromDrop
public static boolean addFromDrop(MapleClient c, Item item, boolean show, boolean enhance, boolean isPetPickup) 將地面掉落道具的既有實例放入角色背包的核心實作。與
addId(MapleClient, int, short, String, String)的差異在於直接沿用掉落道具的旗標/擁有者/到期/寵物/GM 記錄等屬性,並依isPetPickup決定是否以「寵物拾取」靜默模式送出背包封包。行為要點:- 道具不存在會記錄到
logs/except/不存在道具.txt並回傳false。 - 禁止重複拾取且已持有、或玩家為
null時,送出無法取得封包並回傳false。 - 非裝備非可充值:先補滿同 ID(同擁有者、同到期)既有格,再以新格放入剩餘;中途格滿會回填剩餘數量到原道具並回傳
false。 - 裝備(數量須為 1):
enhance為true時經checkEnhanced機率重置潛能;數量非 1 會丟出RuntimeException。
另含若干特例副作用:道具 2340000 累積達 50 會將玩家標記為監控(
setMonitored);首次取得活動道具 (AramiaFireWorks的火藥桶/陽光等)有保留的提示分支。最後呼叫havePartyQuest, 並在show為true時送出取得道具效果封包。- Parameters:
c- 目標客戶端item- 拾取到的道具實例(裝備被強化時可能被替換為新實例)show- 是否向客戶端顯示「取得道具」效果enhance- 是否對裝備套用強化/潛能重置判定isPetPickup- 是否為寵物自動拾取(影響背包封包的顯示旗標)- Returns:
- 成功放入回傳
true;背包已滿、數量不合法或道具不可取得回傳false - Throws:
RuntimeException- 當對裝備傳入非 1 的數量時
- 道具不存在會記錄到
-
checkSpace
檢查背包是否有足夠空間容納指定數量的道具(不實際放入)。非裝備道具會先把同擁有者的既有未滿格納入計算,再依上限換算所需新格數,判斷對應背包是否已滿; 裝備則直接檢查 EQUIP 背包是否還有一格。下列情況直接回傳
false:玩家為null、 禁止重複拾取且已持有、道具不存在、或非可充值道具但數量<= 0(並可能送出enableActions)。- Parameters:
c- 目標客戶端itemid- 道具代碼quantity- 欲放入的數量owner- 擁有者名稱(影響既有格能否合併),可為null- Returns:
- 有足夠空間回傳
true,否則false
-
removeFromSlot
public static boolean removeFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop) 從指定背包槽位扣除道具數量(非消耗語意)。委派至
removeFromSlot(MapleClient, MapleInventoryType, short, short, boolean, boolean)(consume=false)。- Parameters:
c- 目標客戶端type- 背包類型slot- 槽位quantity- 扣除數量fromDrop- 是否因丟棄/使用觸發(影響背包更新封包旗標)- Returns:
- 成功扣除回傳
true;該槽位無道具回傳false
-
removeFromSlot
public static boolean removeFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop, boolean consume) 從指定背包槽位扣除道具數量,並回送清除或更新背包格封包。扣除後若數量歸零且非「可充值消耗」情形(
allowZero=consume && isRechargable),送出 清除背包格封包;否則送出更新背包格封包。採集工具會觸發handleProfessionTool。- Parameters:
c- 目標客戶端type- 背包類型slot- 槽位quantity- 扣除數量fromDrop- 是否因丟棄/使用觸發(影響背包封包旗標)consume- 是否為消耗道具語意;對可充值道具允許數量歸零而保留空殼- Returns:
- 成功扣除回傳
true;玩家或背包為null、或該槽位無道具回傳false
-
removeById
public static boolean removeById(MapleClient c, MapleInventoryType type, int itemId, int quantity, boolean fromDrop, boolean consume) 依道具代碼跨多個槽位扣除指定總數量。遍歷該背包中所有同 ID 道具,逐格透過
removeFromSlot(MapleClient, MapleInventoryType, short, short, boolean)扣除直到滿足數量為止。- Parameters:
c- 目標客戶端type- 背包類型itemId- 道具代碼quantity- 欲扣除的總數量fromDrop- 是否因丟棄/使用觸發(影響背包封包旗標)consume- 是否為消耗道具語意- Returns:
- 成功扣足回傳
true;玩家或背包為null、或數量不足回傳false
-
removeFromSlot_Lock
public static boolean removeFromSlot_Lock(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop, boolean consume) 扣除指定槽位道具,但先檢查鎖定/不可交易旗標,受保護則拒絕。若道具帶有
ItemFlag.LOCK或ItemFlag.UNTRADEABLE旗標,直接回傳false不扣除; 否則委派至removeFromSlot(MapleClient, MapleInventoryType, short, short, boolean, boolean)。- Parameters:
c- 目標客戶端type- 背包類型slot- 槽位quantity- 扣除數量fromDrop- 是否因丟棄/使用觸發consume- 是否為消耗道具語意- Returns:
- 成功扣除回傳
true;道具受鎖定/不可交易保護、不存在或玩家為null回傳false
-
removeById_Lock
依道具代碼扣除一個未受保護的同 ID 道具。遍歷同 ID 道具,對第一個成功通過鎖定檢查(
removeFromSlot_Lock(MapleClient, MapleInventoryType, short, short, boolean, boolean))並扣除 1 個的槽位即返回。- Parameters:
c- 目標客戶端type- 背包類型itemId- 道具代碼- Returns:
- 成功扣除一個回傳
true;找不到可扣除(皆受保護或不存在)回傳false
-
move
在同一背包內移動或合併道具,並回送對應的移動/合併封包。處理一般格位互換、可堆疊道具的合併(同 ID、同擁有者、同到期、非可充值、非 CASH),以及擴充背包 (ETC 大於上限的虛擬背包格)的進出搬移。下列情況直接返回:來源/目的槽位為負、來源等於目的、類型為
EQUIPPED、或來源道具為null。搬入擴充背包失敗時會dropMessage提示並送出enableActions。採集工具會觸發handleProfessionTool。- Parameters:
c- 目標客戶端type- 背包類型(不得為EQUIPPED)src- 來源槽位dst- 目的槽位
-
equip
將 EQUIP 背包中的裝備穿戴到指定的 EQUIPPED 欄位,並回送裝備變更封包。會執行大量穿戴前驗證:來源存在且耐久不為 0、非採集工具、GM 限定裝備的權限、目的欄位與道具類型相符 (龍/機甲/現金欄位等特例)、以及
canEquip的等級/職業/屬性需求。任一檢查失敗即送出enableActions並返回。chr為null或dst == -55時直接返回;GM 限定裝備 在無權限時會被移除(removeAll)並提示。穿戴成功會更新角色裝備狀態並廣播給周圍玩家。- Parameters:
c- 目標客戶端src- EQUIP 背包中的來源槽位dst- 目的 EQUIPPED 欄位(負數)
-
unequip
將 EQUIPPED 欄位的裝備脫下到 EQUIP 背包的指定槽位,並回送移動封包。dst < 0、來源為null或src == -55時直接返回;若目的格已有裝備且來源來自欄位 (src <= 0)則拒絕互換並送出背包已滿封包。脫下武器/騎乘/機器人等會取消對應 buff 或移除機器人/精靈; 若裝備帶有潛能或插槽附加技能(state >= 17/socketState > 15),會移除這些附加技能 (changeSkillLevel_Skip)。最後呼叫equipChanged重算並廣播角色裝備。- Parameters:
c- 目標客戶端src- EQUIPPED 欄位中的來源槽位(負數)dst- EQUIP 背包中的目的槽位
-
drop
將背包道具丟到地面(非 NPC 觸發)。委派至
drop(MapleClient, MapleInventoryType, short, short, boolean)(npcInduced=false)。- Parameters:
c- 目標客戶端type- 背包類型src- 來源槽位(負數代表 EQUIPPED 欄位)quantity- 丟棄數量- Returns:
- 成功丟出回傳
true,否則false
-
drop
public static boolean drop(MapleClient c, MapleInventoryType type, short src, short quantity, boolean npcInduced) 將背包道具丟到角色當前地圖的地面,並回送背包更新/丟棄封包的核心實作。來源槽位為負時類型改判為
EQUIPPED。下列情況拒絕丟棄並送出enableActions後回傳false:伺服器關閉中、玩家或地圖為null、數量不合法、寵物道具(非 NPC 觸發)、PVP 中、 不可丟棄道具(notdrop/贊助專屬擁有者)、鎖定旗標、或對裝備丟出非 1 數量。丟出數量小於持有量時拆出部分數量並更新原格;否則整格移除。地面生成依道具屬性決定:受丟棄限制/帳號共享 道具會清除 KARMA 旗標後落地或直接消失(
disappearingItemDrop),寵物或不可交易道具會落地後消失, 其餘正常落地(spawnItemDrop)。從欄位丟出會觸發equipChanged;ServerConstants.log_drop開啟且符合條件時記錄到logs/data/丟東西.txt。- Parameters:
c- 目標客戶端type- 背包類型(來源為負時內部改為EQUIPPED)src- 來源槽位(負數代表 EQUIPPED 欄位)quantity- 丟棄數量npcInduced- 是否由 NPC 流程觸發(為true才允許丟棄寵物道具)- Returns:
- 成功丟出回傳
true;任一前置檢查失敗回傳false
-
removeAllByInventoryId
依背包道具的內部唯一 ID 刪除複製裝備(反作弊用),並廣播 GM 訊息與寫入記錄。分別在 EQUIP 背包、EQUIPPED 欄位與倉庫中尋找具同一
inventoryitemid的道具並移除, 每刪除一處皆向所有 GM 廣播[GM密語]訊息(World.Broadcast.broadcastGMMessage)並寫入logs/hack/複製裝備_已刪除.txt。玩家為null時直接返回。- Parameters:
c- 目標客戶端inventoryitemid- 要清除的背包道具內部唯一 ID
-