Class MobHandler
MapleServerHandler 的封包分派表呼叫。
本類別為一組 static 方法的集合,處理客戶端回報的怪物相關封包(以
LittleEndianAccessor 讀取),更新 MapleMonster 在 MapleMap 中的狀態,
並以 MobPacket 等建構器回送。涵蓋範圍包括:
- 怪物移動解析與外掛吸怪偵測(
MoveMonster/CheckMobVac,搭配LifeMovementFragment與CheatingOffense); - 怪物自爆、催眠傷害、自動仇恨與友傷(
MonsterBomb/HypnotizeDmg/AutoAggro/FriendlyDamage); - 怪物節點路徑顯示(
DisplayNode/MobNode); - 親密怪/召喚怪(
MonsterFamiliar)的命名、召喚、移動、攻擊與接觸(SpawnFamiliar/MoveFamiliar/AttackFamiliar/UseFamiliar)。
關鍵協作者:MapleLifeFactory/MapleMonsterStats(怪物生成與屬性)、
MobSkill/MobSkillFactory(怪物技能)、MonsterStatusEffect(怪物狀態)、
StructFamiliar 與 SkillFactory.FamiliarEntry。
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic final voidAttackFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理已召喚親密怪施放技能攻擊的封包。static final voidAutoAggro(int monsteroid, MapleCharacter chr) 處理怪物自動仇恨:在玩家靠近時把怪物的控制權切換給適當的玩家。static voidCheckMobVac(MapleClient c, MapleMonster monster, List<LifeMovementFragment> res, Point startPos) 以怪物本次移動的位移量偵測「吸怪」外掛。static final voidcheckShammos(MapleCharacter chr, MapleMonster mobto, MapleMap map) 處理護送/逃脫類怪物(如 Shammos 護送怪)死亡時的保護道具與失敗懲罰邏輯。static final voidDisplayNode(LittleEndianAccessor slea, MapleCharacter chr) 處理客戶端請求顯示怪物路徑節點屬性的封包。static final voidFriendlyDamage(LittleEndianAccessor slea, MapleCharacter chr) 處理「友方怪物」互毆造成的傷害(怪物 A 攻擊友方護送怪 B)。static final voidHypnotizeDmg(LittleEndianAccessor slea, MapleCharacter chr) 處理催眠(Hypnotize)使友方怪物對另一怪物造成的傷害。static final voidMobBomb(LittleEndianAccessor slea, MapleCharacter chr) 處理具備MonsterStatus.MONSTER_BOMB狀態之怪物的炸彈封包。static final voidMobNode(LittleEndianAccessor slea, MapleCharacter chr) 處理護送怪物沿路徑節點前進(節點抵達回報)的封包。static final voidMonsterBomb(int oid, MapleCharacter chr) 處理怪物自爆(self-destruct)並結算擊殺。static final voidMoveFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理已召喚親密怪的移動封包。static final voidMoveMonster(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理客戶端回報的怪物移動封包,更新怪物位置並可能觸發怪物技能。static final voidRenameFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理玩家替親密怪(MonsterFamiliar)重新命名的封包。static final voidSpawnFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理玩家召喚/收回親密怪的封包。static final voidTouchFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理親密怪以接觸(無技能、近身碰撞)方式攻擊怪物的封包。static final voidUseFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理玩家使用親密怪卡片道具(itemId 前綴 287)以取得或續期親密怪的封包。
-
Constructor Details
-
MobHandler
public MobHandler()
-
-
Method Details
-
CheckMobVac
public static void CheckMobVac(MapleClient c, MapleMonster monster, List<LifeMovementFragment> res, Point startPos) 以怪物本次移動的位移量偵測「吸怪」外掛。由
MoveMonster(LittleEndianAccessor, MapleClient, MapleCharacter)觸發前的移動驗證流程呼叫:累計res中各LifeMovementFragment的起訖位移,依當前地圖與怪物種類套用不同的容許距離門檻(switch特例),超出門檻時呼叫MapleCharacter.addMobVac()累計次數,並在達到計次或位移過大時透過CheatTracker.registerOffense(CheatingOffense)記下CheatingOffense.吸怪違規、 將疑似紀錄寫入logs/hacj/疑似吸怪.txt。整體包覆於 try/catch,任何例外皆被吞掉(記為 debug),確保不影響移動處理主流程。 會飛行(
fly)的怪物略過判定。- Parameters:
c- 發出移動封包的玩家連線(MapleClient.getPlayer()取得對應角色)monster- 被移動的目標怪物res- 解析後的移動片段清單startPos- 移動前的怪物座標
-
MoveMonster
處理客戶端回報的怪物移動封包,更新怪物位置並可能觸發怪物技能。從
slea讀取怪物 oid、移動序號、使用技能旗標與技能資訊,並依序:- 若
useSkill,自怪物技能表隨機挑一技能,檢查冷卻(MobSkill.getCoolTime())、 重複使用限制(MobSkill.onlyOnce())與 HP 門檻後,對chr套用MobSkill.applyEffect(MapleCharacter, MapleMonster, boolean); - 解析移動片段(
MovementParse.parseMovement(LittleEndianAccessor, int)),以MobPacket.moveMonsterResponse(int, short, int, boolean, int, int)回應控制權與技能結果,並透過MapleMap.moveMonster(MapleMonster, Point)更新位置、向同地圖其他玩家廣播MobPacket.moveMonster(boolean, int, int, int, Point, List)。
副作用:突變怪物狀態(座標/最後技能時間)、送出回應封包並對地圖廣播;移動/封包長度異常時寫入
FileoutputUtil紀錄並提前返回。chr或其地圖為null、找不到怪物、或怪物為 連結怪(MapleMonster.getLinkCID()> 0)時直接返回。- Parameters:
slea- 移動封包讀取器c- 發出封包的玩家連線chr- 控制該怪物的角色
- 若
-
FriendlyDamage
處理「友方怪物」互毆造成的傷害(怪物 A 攻擊友方護送怪 B)。自
slea讀取來源怪、玩家 ID 與目標怪 oid;當兩怪皆存在且目標為友方怪 (MapleMonsterStats.isFriendly())時,依目標怪等級隨機計算傷害,呼叫MapleMonster.damage(MapleCharacter, long, boolean)扣血,再交由checkShammos(MapleCharacter, MapleMonster, MapleMap)處理護送怪死亡/治療邏輯。 地圖為null時直接返回。- Parameters:
slea- 友傷封包讀取器chr- 觸發此事件的角色(作為傷害來源歸屬)
-
MobBomb
處理具備MonsterStatus.MONSTER_BOMB狀態之怪物的炸彈封包。自
slea讀取來源怪 oid 後查找怪物;目前僅在來源怪存在且帶有炸彈狀態時保留處理位置 (實作為待補的占位區塊,無實際狀態變更)。地圖為null時直接返回。- Parameters:
slea- 怪物炸彈封包讀取器chr- 觸發此事件的角色
-
checkShammos
處理護送/逃脫類怪物(如 Shammos 護送怪)死亡時的保護道具與失敗懲罰邏輯。當目標怪已死亡且為護送怪(
MapleMonsterStats.isEscort())時:掃描地圖內隊長是否持有保護道具2022698,若有則消耗一個並將怪物完全治癒(MapleMonster.heal(int, int, boolean))以保住護送目標;否則向地圖廣播 保護失敗通知並把所有玩家送回MapleMap.getForcedReturnMap()。 若護送怪仍存活且綁有活動實例,則將其當前 HP 寫入事件實例屬性"HP"。副作用:可能消耗道具、治癒怪物、廣播伺服器通知、強制全員換圖,或更新
MapleMap之事件實例屬性。- Parameters:
chr- 觸發此判定的角色(用於取得強制返回地圖)mobto- 受檢的護送/逃脫怪物map- 怪物所在地圖
-
MonsterBomb
處理怪物自爆(self-destruct)並結算擊殺。依
oid查找怪物,若怪物存在、角色存活且未隱身、且非連結怪 (MapleMonster.getLinkCID()),讀取怪物的自爆動作值(getSelfD());當其不為-1時呼叫MapleMap.killMonster(MapleMonster, MapleCharacter, boolean, boolean, byte)以該自爆動畫結算擊殺。副作用:移除怪物並觸發其擊殺/掉落流程。
- Parameters:
oid- 自爆怪物的物件 IDchr- 結算擊殺所歸屬的角色
-
AutoAggro
處理怪物自動仇恨:在玩家靠近時把怪物的控制權切換給適當的玩家。依
monsteroid查找怪物,當怪物存在、與角色距離平方小於200000且非連結怪時, 透過MapleMonster.switchController(MapleCharacter, boolean)設定控制者:若原控制者已不在地圖則改由chr控制, 否則維持原控制者(皆帶 aggro 旗標)。chr為null、無地圖或隱身時直接返回。- Parameters:
monsteroid- 觸發仇恨的怪物物件 IDchr- 進入仇恨範圍的角色
-
HypnotizeDmg
處理催眠(Hypnotize)使友方怪物對另一怪物造成的傷害。自
slea讀取來源怪、玩家 ID、目標怪 oid 與傷害值;當兩怪皆存在且目標為友方怪 (MapleMonsterStats.isFriendly())時套用傷害。內含防作弊上限:傷害超過30000時 直接返回不處理。扣血後交由checkShammos(MapleCharacter, MapleMonster, MapleMap)結算護送怪邏輯。- Parameters:
slea- 催眠傷害封包讀取器chr- 觸發此事件的角色(作為傷害來源歸屬)
-
DisplayNode
處理客戶端請求顯示怪物路徑節點屬性的封包。自
slea讀取怪物 oid,若怪物存在則向請求的玩家送出MobPacket.getNodeProperties(MapleMonster, MapleMap)(怪物在當前地圖MapleMap的節點資訊)。- Parameters:
slea- 節點顯示封包讀取器chr- 發出請求的角色
-
MobNode
處理護送怪物沿路徑節點前進(節點抵達回報)的封包。自
slea讀取怪物 oid 與新節點編號,查找對應節點(MapleNodes.MapleNodeInfo):- 若節點屬性為對話(
attr == 2),依地圖前綴讓怪物喊話(MapleMap.talkMonster(String, int, int)); - 更新怪物的最後節點(
MapleMonster.setLastNode(int)); - 若抵達地圖最後一個節點,向地圖廣播進入下一階段的通知並移除該怪物(
MapleMap.removeMonster(MapleMonster))。
副作用:可能對地圖廣播喊話/通知封包並移除怪物。怪物為
null、地圖無節點或找不到目標節點時返回。- Parameters:
slea- 節點移動封包讀取器chr- 觸發此事件的角色(用於判定地圖)
- 若節點屬性為對話(
-
RenameFamiliar
public static final void RenameFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理玩家替親密怪(MonsterFamiliar)重新命名的封包。自
slea讀取親密怪索引與新名稱;僅在該親密怪存在、目前仍為原始名稱(尚未改名過)且新名稱通過MapleCharacterUtil.isEligibleCharName(String, boolean)合法性檢查時才套用新名並回送CField.renameFamiliar(MonsterFamiliar), 否則向玩家提示名稱不合法。最後一律送出CWvsContext.enableActions()解除動作鎖。- Parameters:
slea- 改名封包讀取器c- 發出封包的玩家連線chr- 對應角色(用於失敗提示)
-
SpawnFamiliar
public static final void SpawnFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理玩家召喚/收回親密怪的封包。先以封包內的 tick 校時(
MapleCharacter.updateTick(int)),送出CWvsContext.enableActions()並收回現有親密怪(MapleCharacter.removeFamiliar());若指定的親密怪存在且封包要求召喚,則檢查疲勞度 (getFatigue()):仍在冷卻則提示等待秒數,否則呼叫MapleCharacter.spawnFamiliar(MonsterFamiliar)召喚之。副作用:收回/召喚親密怪並送出動作解鎖封包。
- Parameters:
slea- 召喚封包讀取器c- 發出封包的玩家連線chr- 對應角色
-
MoveFamiliar
處理已召喚親密怪的移動封包。解析移動片段(
MovementParse.parseMovement(LittleEndianAccessor, int)),更新已召喚親密怪 (MapleCharacter.getSummonedFamiliar())的位置;若玩家未隱身,向同地圖其他玩家廣播CField.moveFamiliar(int, Point, List)。角色無召喚親密怪或無有效移動時不處理。- Parameters:
slea- 移動封包讀取器c- 發出封包的玩家連線chr- 召喚親密怪的角色
-
AttackFamiliar
public static final void AttackFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理已召喚親密怪施放技能攻擊的封包。自
slea讀取技能 ID 與攻擊目標清單(每個目標含 oid、type 與多段傷害)。流程:- 查驗技能存在(
SkillFactory.getFamiliar(int))、目標數不超過targetCount,並通過防作弊檢查CheatTracker.checkFamiliarAttack(MapleCharacter); - 向同地圖廣播
CField.familiarAttack(int, byte, List),逐一對存活的非友方怪套用上限內的傷害 (超出attackCount或距離過遠時略過/記CheatingOffense.ATTACK_FARAWAY_MONSTER_SUMMON); - 依機率(
makeChanceResult())對怪物套用MonsterStatusEffect狀態並可能切換控制權; - 最後依攻擊目標數累加親密怪疲勞度(
addFatigue)。
副作用:對地圖廣播攻擊封包、對怪物造成傷害/施加狀態、累計疲勞與防作弊違規。角色無召喚親密怪、技能不存在 或攻擊清單為空時提前返回。
- Parameters:
slea- 攻擊封包讀取器c- 發出封包的玩家連線chr- 召喚親密怪的角色(作為傷害來源歸屬)
- 查驗技能存在(
-
TouchFamiliar
public static final void TouchFamiliar(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) 處理親密怪以接觸(無技能、近身碰撞)方式攻擊怪物的封包。自
slea讀取目標怪 oid、type 與傷害值;傷害下限以親密怪原始物攻的 5 倍夾住。當目標非友方怪且通過 防作弊檢查CheatTracker.checkFamiliarAttack(MapleCharacter)時,向地圖廣播CField.touchFamiliar(int, byte, int, int, int, int)、對怪物套用傷害(MapleMonster.damage(MapleCharacter, long, boolean))並累加親密怪疲勞度。 角色無召喚親密怪或找不到目標怪時提前返回。- Parameters:
slea- 接觸攻擊封包讀取器c- 發出封包的玩家連線chr- 召喚親密怪的角色(作為傷害來源歸屬)
-
UseFamiliar
處理玩家使用親密怪卡片道具(itemId 前綴 287)以取得或續期親密怪的封包。先以 tick 校時並送出
CWvsContext.enableActions();驗證背包中對應 USE 道具存在、數量足夠且為親密怪卡片 (itemId / 10000 == 287)。當對應怪物等級不高於玩家等級時:- 已擁有該親密怪則延長到期時間(依活力值決定加 30 天並上限 90 天,或先累加活力);
- 尚未擁有則新建
MonsterFamiliar並加入玩家親密怪表; - 接著消耗該道具(
MapleInventoryManipulator.removeFromSlot(MapleClient, MapleInventoryType, short, short, boolean))並回送CField.registerFamiliar(MonsterFamiliar)。
副作用:突變玩家親密怪集合與到期/活力、扣除道具、送出註冊與動作解鎖封包。角色為
null、死亡、無地圖或背包被鎖 (MapleCharacter.hasBlockedInventory())時僅送出動作解鎖並返回。- Parameters:
slea- 使用道具封包讀取器c- 發出封包的玩家連線chr- 對應角色
-