Class NPCHandler
MapleServerHandler 的封包分派表呼叫。
本類別為一組 static 方法的集合,將玩家點擊/回應 NPC 的封包(以
LittleEndianAccessor 讀取)橋接到對話腳本與相關子系統,並以
NPCPacket 等建構器回送。涵蓋範圍包括:
- NPC 動畫與移動廣播(
NPCAnimation); - 商店買/賣/補充彈藥(
NPCShop,委由MapleShop)與倉庫存取(Storage,委由MapleStorage); - 對話腳本啟動與選項回呼(
NPCTalk/NPCMoreTalk,透過NPCScriptManager/NPCConversationManager); - 任務的接受/完成/回呼(
QuestAction/UpdateQuest,透過MapleQuest)、裝備修理與剪刀石頭布小遊戲(RPSGame,RockPaperScissors)。
關鍵協作者:MapleItemInformationProvider、MapScriptMethods、
AutobanManager(防作弊封鎖)、MapleInventoryManipulator。
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic final voidNPCAnimation(LittleEndianAccessor slea, MapleClient c) 處理 NPC 動畫/移動封包,並原封轉發成SendPacketOpcode.NPC_ACTION回送給客戶端。static final voidNPCMoreTalk(LittleEndianAccessor slea, MapleClient c) 處理 NPC 對話的後續回應(按下「下一步」、選項、輸入文字/數字或結束對話),驅動對話腳本續行。static final voidNPCShop(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理 NPC 商店的購買/販售/補充彈藥操作,委由角色目前開啟的MapleShop執行。static final voidNPCTalk(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理玩家點擊 NPC 的封包:開啟商店或啟動對話腳本。static final voidOpenPublicNpc(LittleEndianAccessor slea, MapleClient c) 處理開啟「公用 NPC」(不需實際在場、可全地圖呼叫的功能性 NPC)的封包。static final voidQuestAction(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理任務動作封包(接受、完成、放棄、腳本式接受/完成、補回遺失道具)。static final voidrepair(LittleEndianAccessor slea, MapleClient c) 處理「修理單件裝備」請求(僅限利夫雷地圖 240000000),對指定欄位的裝備計算費用並修復耐久。static final void處理「修理全部裝備」請求(僅限利夫雷地圖 240000000),一次計算並收費修復所有耐久不足的裝備。static final voidRPSGame(LittleEndianAccessor slea, MapleClient c) 處理剪刀石頭布小遊戲(RockPaperScissors)封包:開始、出拳、逾時、續局與離開。static final voidStorage(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理倉庫(MapleStorage)操作:取出、存入道具、整理、楓幣存提與關閉。static final voidUpdateQuest(LittleEndianAccessor slea, MapleClient c) 處理客戶端要求更新某任務顯示狀態的封包。static final voidUseItemQuest(LittleEndianAccessor slea, MapleClient c) 處理「對任務使用道具」封包:以 ETC 任務道具更新任務自訂資料並消耗該道具。
-
Constructor Details
-
NPCHandler
public NPCHandler()
-
-
Method Details
-
NPCAnimation
處理 NPC 動畫/移動封包,並原封轉發成SendPacketOpcode.NPC_ACTION回送給客戶端。依封包剩餘長度區分兩種情形:長度恰為
10視為 NPC 對話動畫(讀取 NPC oid、動畫與 訊息序號重新打包);長度大於10視為 NPC 移動(原樣拷貝移動位元組)。其餘長度直接忽略不回送。- Parameters:
slea- 來源封包讀取器c- 發出此封包的客戶端連線;動畫封包會回送給它
-
NPCShop
處理 NPC 商店的購買/販售/補充彈藥操作,委由角色目前開啟的MapleShop執行。首位元組為模式:
0購買、1販售、2補充彈藥,三者皆需角色持有有效的MapleCharacter.getShop()(為null時直接返回)。後續欄位(道具 id、格位、數量) 依模式讀取後分派至MapleShop.buy(MapleClient, int, short)/MapleShop.sell(MapleClient, MapleInventoryType, byte, short)/MapleShop.recharge(MapleClient, byte), 由其完成背包與楓幣的變動並回送封包。未知模式則以MapleCharacter.setConversation(int)重設對話狀態。- Parameters:
slea- 來源封包讀取器c- 發出此封包的客戶端連線chr- 操作的角色;為null時直接返回
-
NPCTalk
處理玩家點擊 NPC 的封包:開啟商店或啟動對話腳本。依封包中的 oid 取得地圖上的
MapleNPC;若 NPC 帶商店則設定對話狀態為1並 呼叫MapleNPC.sendShop(MapleClient),否則經NPCScriptManager.start(MapleClient, int)啟動該 NPC 的對話腳本。角色或其地圖為null、找不到 NPC、或MapleCharacter.hasBlockedInventory()(背包鎖定,防作弊閘門)時均直接返回。- Parameters:
slea- 來源封包讀取器,含被點擊 NPC 的 oidc- 發出此封包的客戶端連線chr- 點擊 NPC 的角色;為null時直接返回
-
QuestAction
處理任務動作封包(接受、完成、放棄、腳本式接受/完成、補回遺失道具)。首位元組為動作碼,其後為任務 id,據以取得
MapleQuest並分派:0:補回遺失的任務道具(MapleQuest.RestoreLostItem(MapleCharacter, int));1:接受任務(無起始腳本時呼叫MapleQuest.start(MapleCharacter, int));2:完成任務(無結束腳本時呼叫MapleQuest.complete(MapleCharacter, int),可帶選擇的獎勵 id);3:放棄任務(可放棄者呼叫MapleQuest.forfeit(MapleCharacter),否則提示不可放棄);4/5:腳本式接受/完成,分派至NPCScriptManager.startQuest(MapleClient, int, int)/NPCScriptManager.endQuest(MapleClient, int, int, boolean);完成時並對自身與地圖廣播完成特效。
MapleCharacter.hasBlockedInventory()) 時腳本式動作直接返回。- Parameters:
slea- 來源封包讀取器c- 發出此封包的客戶端連線chr- 執行任務動作的角色;為null時直接返回
-
Storage
處理倉庫(MapleStorage)操作:取出、存入道具、整理、楓幣存提與關閉。首位元組為模式:
4取出、5存入、6整理、7楓幣存提、8關閉。 進入時先驗證角色狀態(地圖存在、無交易中、存活、對話狀態為4),不符則重設倉庫操作旗標並 提示後返回。存/取會收取楓幣手續費(自由市場地圖 910000000 費率較高),並寫入倉庫操作記錄訊息。含多項防作弊與失敗保護:存入時道具 id/數量與背包不符會以
AutobanManager.addPoints(MapleClient, int, long, String)記點;楓幣存提對溢位與超額一律以失敗保護返回或記點。寵物、 撿取限制重複道具、零數量飛鏢/彈丸等情形拒絕存入。倉庫已滿時回送NPCPacket.getStorageFull()。 會變動背包、倉庫內容、角色楓幣並回送多種封包。- Parameters:
slea- 來源封包讀取器c- 發出此封包的客戶端連線chr- 操作倉庫的角色;為null時直接返回
-
NPCMoreTalk
處理 NPC 對話的後續回應(按下「下一步」、選項、輸入文字/數字或結束對話),驅動對話腳本續行。讀取上一則訊息型別與動作碼。先處理特殊的方向資訊劇情(
MapScriptMethods.startDirectionInfo(MapleCharacter, boolean)); 接著取得此客戶端的NPCConversationManager,校驗對話狀態與訊息序號(不符且非特殊劇情地圖時返回, 並在偵錯模式下輸出診斷資訊)。依訊息型別讀取玩家輸入:型別3讀取輸入字串、型別4為 數字輸入(負值視為取消而dispose),其餘讀取選項索引。 隨後依腳本型別(接受任務/完成任務/一般)分派至NPCScriptManager.startQuest(MapleClient, int, int)/NPCScriptManager.endQuest(MapleClient, int, int, boolean)/NPCScriptManager.action(MapleClient, byte, byte, int), 由腳本續送對話封包;取消或非法輸入則 dispose 結束對話。- Parameters:
slea- 來源封包讀取器,含上一則訊息型別、動作碼與玩家輸入c- 發出此封包的客戶端連線
-
repairAll
處理「修理全部裝備」請求(僅限利夫雷地圖 240000000),一次計算並收費修復所有耐久不足的裝備。掃描角色背包與已裝備欄位中的所有
Equip,依各自耐久缺口與MapleItemInformationProvider.getPrice(int)/MapleItemInformationProvider.getReqLevel(int)累計總費用(需求等級 70 以下費率為 1/100)。楓幣不足或無可修裝備時提示所需費用並返回;否則扣款後將 每件裝備耐久回復至上限並MapleCharacter.forceReAddItem(Item, MapleInventoryType)重新加回對應欄位。會變動角色楓幣與裝備狀態。- Parameters:
c- 發出此封包的客戶端連線;非 240000000 地圖直接返回
-
repair
處理「修理單件裝備」請求(僅限利夫雷地圖 240000000),對指定欄位的裝備計算費用並修復耐久。讀取裝備所在欄位(負值代表已裝備)取得
Equip;若耐久未低於上限或道具無耐久屬性則返回。 依耐久缺口與道具售價計算費用(需求等級 70 以下費率為 1/100),楓幣不足時提示所需費用並返回;否則 扣款後將耐久回復至上限並MapleCharacter.forceReAddItem(Item, MapleInventoryType)重新加回。會變動角色楓幣與該裝備狀態。- Parameters:
slea- 來源封包讀取器,含欲修理裝備的欄位位置c- 發出此封包的客戶端連線;非 240000000 地圖或封包不足直接返回
-
UpdateQuest
處理客戶端要求更新某任務顯示狀態的封包。依封包中的任務 id 取得
MapleQuest,存在時呼叫MapleCharacter.updateQuest(MapleQuestStatus)將該任務 狀態回送同步給玩家。- Parameters:
slea- 來源封包讀取器,含任務 idc- 發出此封包的客戶端連線
-
UseItemQuest
處理「對任務使用道具」封包:以 ETC 任務道具更新任務自訂資料並消耗該道具。讀取格位、道具 id 與任務 id,於 ETC 背包中尋找對應的任務道具(道具群組 422)並透過
MapleItemInformationProvider.questItemInfo(int)驗證其關聯的任務與允許的道具 id 清單。驗證通過、 任務存在且進行中(狀態為1)時,將封包帶入的新資料寫入任務自訂欄位、MapleCharacter.updateQuest(MapleQuestStatus)同步狀態,並MapleInventoryManipulator.removeFromSlot(MapleClient, MapleInventoryType, short, short, boolean)扣除一個道具。會變動任務狀態與背包。- Parameters:
slea- 來源封包讀取器,含格位、道具 id、任務 id 與新資料c- 發出此封包的客戶端連線
-
RPSGame
處理剪刀石頭布小遊戲(RockPaperScissors)封包:開始、出拳、逾時、續局與離開。需玩家所在地圖存在賭場 NPC 9000019,否則清理既有對局並返回。首位元組為模式:
0/5:開始/重新開始(先結算上一局獎勵,楓幣達 1000 才建立新對局,否則回送錯誤模式);1:出拳作答(RockPaperScissors.answer(MapleClient, int));2:時間到(RockPaperScissors.timeOut(MapleClient));3:續局(RockPaperScissors.nextRound(MapleClient));4:離開(RockPaperScissors.dispose(MapleClient))。
CField.getRPSMode(byte, int, int, int))。- Parameters:
slea- 來源封包讀取器,含遊戲模式與出拳等資料c- 發出此封包的客戶端連線
-
OpenPublicNpc
處理開啟「公用 NPC」(不需實際在場、可全地圖呼叫的功能性 NPC)的封包。讀取 NPC id,僅當其列於
GameConstants.publicNpcIds白名單時,才經NPCScriptManager.start(MapleClient, int)啟動對應對話腳本。背包鎖定、處於封鎖地圖 (MapleCharacter.isInBlockedMap())或等級低於 10 時直接返回(防作弊/資格閘門)。- Parameters:
slea- 來源封包讀取器,含欲開啟的 NPC idc- 發出此封包的客戶端連線
-