diff --git a/gradle.properties b/gradle.properties index e9157af4d..af86da4e1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ org.gradle.jvmargs=-Xmx1024m +# spikehd was here :) diff --git a/src/main/java/emu/grasscutter/game/dungeons/DungeonSystem.java b/src/main/java/emu/grasscutter/game/dungeons/DungeonSystem.java index 30cf583da..dd380a9b1 100644 --- a/src/main/java/emu/grasscutter/game/dungeons/DungeonSystem.java +++ b/src/main/java/emu/grasscutter/game/dungeons/DungeonSystem.java @@ -1,122 +1,122 @@ -package emu.grasscutter.game.dungeons; - -import emu.grasscutter.GameConstants; -import emu.grasscutter.Grasscutter; -import emu.grasscutter.data.GameData; -import emu.grasscutter.data.binout.ScenePointEntry; -import emu.grasscutter.data.excels.DungeonData; -import emu.grasscutter.game.player.Player; -import emu.grasscutter.game.props.SceneType; -import emu.grasscutter.game.quest.enums.QuestTrigger; -import emu.grasscutter.game.world.Scene; -import emu.grasscutter.net.packet.BasePacket; -import emu.grasscutter.net.packet.PacketOpcodes; -import emu.grasscutter.server.game.BaseGameSystem; -import emu.grasscutter.server.game.GameServer; -import emu.grasscutter.server.packet.send.PacketDungeonEntryInfoRsp; -import emu.grasscutter.server.packet.send.PacketPlayerEnterDungeonRsp; -import emu.grasscutter.utils.Position; -import java.util.List; - -public class DungeonSystem extends BaseGameSystem { - private static final BasicDungeonSettleListener basicDungeonSettleObserver = - new BasicDungeonSettleListener(); - - public DungeonSystem(GameServer server) { - super(server); - } - - public void getEntryInfo(Player player, int pointId) { - ScenePointEntry entry = GameData.getScenePointEntryById(player.getScene().getId(), pointId); - - if (entry == null) { - // Error - player.sendPacket(new PacketDungeonEntryInfoRsp()); - return; - } - - player.sendPacket(new PacketDungeonEntryInfoRsp(player, entry.getPointData())); - } - - public boolean enterDungeon(Player player, int pointId, int dungeonId) { - DungeonData data = GameData.getDungeonDataMap().get(dungeonId); - - if (data == null) { - return false; - } - Grasscutter.getLogger() - .info( - "{}({}) is trying to enter dungeon {}", - player.getNickname(), - player.getUid(), - dungeonId); - - int sceneId = data.getSceneId(); - player.getScene().setPrevScene(sceneId); - - if (player.getWorld().transferPlayerToScene(player, sceneId, data)) { - player.getScene().addDungeonSettleObserver(basicDungeonSettleObserver); - player.getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_ENTER_DUNGEON, data.getId()); - } - - player.getScene().setPrevScenePoint(pointId); - player.sendPacket(new PacketPlayerEnterDungeonRsp(pointId, dungeonId)); - return true; - } - - /** used in tower dungeons handoff */ - public boolean handoffDungeon( - Player player, int dungeonId, List dungeonSettleListeners) { - DungeonData data = GameData.getDungeonDataMap().get(dungeonId); - - if (data == null) { - return false; - } - Grasscutter.getLogger() - .info( - "{}({}) is trying to enter tower dungeon {}", - player.getNickname(), - player.getUid(), - dungeonId); - - if (player.getWorld().transferPlayerToScene(player, data.getSceneId(), data)) { - dungeonSettleListeners.forEach(player.getScene()::addDungeonSettleObserver); - } - return true; - } - - public void exitDungeon(Player player) { - Scene scene = player.getScene(); - - if (scene == null || scene.getSceneType() != SceneType.SCENE_DUNGEON) { - return; - } - - // Get previous scene - int prevScene = scene.getPrevScene() > 0 ? scene.getPrevScene() : 3; - - // Get previous position - DungeonData dungeonData = scene.getDungeonData(); - Position prevPos = new Position(GameConstants.START_POSITION); - - if (dungeonData != null) { - ScenePointEntry entry = GameData.getScenePointEntryById(prevScene, scene.getPrevScenePoint()); - - if (entry != null) { - prevPos.set(entry.getPointData().getTranPos()); - } - } - // clean temp team if it has - player.getTeamManager().cleanTemporaryTeam(); - player.getTowerManager().clearEntry(); - - // Transfer player back to world - player.getWorld().transferPlayerToScene(player, prevScene, prevPos); - player.sendPacket(new BasePacket(PacketOpcodes.PlayerQuitDungeonRsp)); - } - - public void updateDailyDungeons() { - GameData.getScenePointEntries() - .forEach((id, entry) -> entry.getPointData().updateDailyDungeon()); - } -} +package emu.grasscutter.game.dungeons; + +import emu.grasscutter.GameConstants; +import emu.grasscutter.Grasscutter; +import emu.grasscutter.data.GameData; +import emu.grasscutter.data.binout.ScenePointEntry; +import emu.grasscutter.data.excels.DungeonData; +import emu.grasscutter.game.player.Player; +import emu.grasscutter.game.props.SceneType; +import emu.grasscutter.game.quest.enums.QuestTrigger; +import emu.grasscutter.game.world.Scene; +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.server.game.BaseGameSystem; +import emu.grasscutter.server.game.GameServer; +import emu.grasscutter.server.packet.send.PacketDungeonEntryInfoRsp; +import emu.grasscutter.server.packet.send.PacketPlayerEnterDungeonRsp; +import emu.grasscutter.utils.Position; +import java.util.List; + +public class DungeonSystem extends BaseGameSystem { + private static final BasicDungeonSettleListener basicDungeonSettleObserver = + new BasicDungeonSettleListener(); + + public DungeonSystem(GameServer server) { + super(server); + } + + public void getEntryInfo(Player player, int pointId, int sceneId) { + ScenePointEntry entry = GameData.getScenePointEntryById(sceneId, pointId); + + if (entry == null) { + // Error + player.sendPacket(new PacketDungeonEntryInfoRsp()); + return; + } + + player.sendPacket(new PacketDungeonEntryInfoRsp(player, entry.getPointData())); + } + + public boolean enterDungeon(Player player, int pointId, int dungeonId) { + DungeonData data = GameData.getDungeonDataMap().get(dungeonId); + + if (data == null) { + return false; + } + Grasscutter.getLogger() + .info( + "{}({}) is trying to enter dungeon {}", + player.getNickname(), + player.getUid(), + dungeonId); + + int sceneId = data.getSceneId(); + player.getScene().setPrevScene(sceneId); + + if (player.getWorld().transferPlayerToScene(player, sceneId, data)) { + player.getScene().addDungeonSettleObserver(basicDungeonSettleObserver); + player.getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_ENTER_DUNGEON, data.getId()); + } + + player.getScene().setPrevScenePoint(pointId); + player.sendPacket(new PacketPlayerEnterDungeonRsp(pointId, dungeonId)); + return true; + } + + /** used in tower dungeons handoff */ + public boolean handoffDungeon( + Player player, int dungeonId, List dungeonSettleListeners) { + DungeonData data = GameData.getDungeonDataMap().get(dungeonId); + + if (data == null) { + return false; + } + Grasscutter.getLogger() + .info( + "{}({}) is trying to enter tower dungeon {}", + player.getNickname(), + player.getUid(), + dungeonId); + + if (player.getWorld().transferPlayerToScene(player, data.getSceneId(), data)) { + dungeonSettleListeners.forEach(player.getScene()::addDungeonSettleObserver); + } + return true; + } + + public void exitDungeon(Player player) { + Scene scene = player.getScene(); + + if (scene == null || scene.getSceneType() != SceneType.SCENE_DUNGEON) { + return; + } + + // Get previous scene + int prevScene = scene.getPrevScene() > 0 ? scene.getPrevScene() : 3; + + // Get previous position + DungeonData dungeonData = scene.getDungeonData(); + Position prevPos = new Position(GameConstants.START_POSITION); + + if (dungeonData != null) { + ScenePointEntry entry = GameData.getScenePointEntryById(prevScene, scene.getPrevScenePoint()); + + if (entry != null) { + prevPos.set(entry.getPointData().getTranPos()); + } + } + // clean temp team if it has + player.getTeamManager().cleanTemporaryTeam(); + player.getTowerManager().clearEntry(); + + // Transfer player back to world + player.getWorld().transferPlayerToScene(player, prevScene, prevPos); + player.sendPacket(new BasePacket(PacketOpcodes.PlayerQuitDungeonRsp)); + } + + public void updateDailyDungeons() { + GameData.getScenePointEntries() + .forEach((id, entry) -> entry.getPointData().updateDailyDungeon()); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerCombatInvocationsNotify.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerCombatInvocationsNotify.java index 1bbddceed..4c7fd5875 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerCombatInvocationsNotify.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerCombatInvocationsNotify.java @@ -1,191 +1,191 @@ -package emu.grasscutter.server.packet.recv; - -import emu.grasscutter.Grasscutter; -import emu.grasscutter.game.entity.GameEntity; -import emu.grasscutter.game.player.Player; -import emu.grasscutter.game.props.FightProperty; -import emu.grasscutter.net.packet.Opcodes; -import emu.grasscutter.net.packet.PacketHandler; -import emu.grasscutter.net.packet.PacketOpcodes; -import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult; -import emu.grasscutter.net.proto.CombatInvocationsNotifyOuterClass.CombatInvocationsNotify; -import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry; -import emu.grasscutter.net.proto.EntityMoveInfoOuterClass.EntityMoveInfo; -import emu.grasscutter.net.proto.EvtAnimatorParameterInfoOuterClass.EvtAnimatorParameterInfo; -import emu.grasscutter.net.proto.EvtBeingHitInfoOuterClass.EvtBeingHitInfo; -import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; -import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState; -import emu.grasscutter.net.proto.PlayerDieTypeOuterClass; -import emu.grasscutter.server.event.entity.EntityMoveEvent; -import emu.grasscutter.server.game.GameSession; -import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; -import emu.grasscutter.utils.Position; - -@Opcodes(PacketOpcodes.CombatInvocationsNotify) -public class HandlerCombatInvocationsNotify extends PacketHandler { - - private float cachedLandingSpeed = 0; - private long cachedLandingTimeMillisecond = 0; - private boolean monitorLandingEvent = false; - - @Override - public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { - CombatInvocationsNotify notif = CombatInvocationsNotify.parseFrom(payload); - for (CombatInvokeEntry entry : notif.getInvokeListList()) { - // Handle combat invoke - switch (entry.getArgumentType()) { - case COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT -> { - EvtBeingHitInfo hitInfo = EvtBeingHitInfo.parseFrom(entry.getCombatData()); - AttackResult attackResult = hitInfo.getAttackResult(); - Player player = session.getPlayer(); - - // Check if the player is invulnerable. - if (attackResult.getAttackerId() - != player.getTeamManager().getCurrentAvatarEntity().getId() - && player.getAbilityManager().isAbilityInvulnerable()) break; - - // Handle damage - player.getAttackResults().add(attackResult); - player.getEnergyManager().handleAttackHit(hitInfo); - } - case COMBAT_TYPE_ARGUMENT_ENTITY_MOVE -> { - // Handle movement - EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData()); - GameEntity entity = session.getPlayer().getScene().getEntityById(moveInfo.getEntityId()); - if (entity != null) { - // Move player - MotionInfo motionInfo = moveInfo.getMotionInfo(); - MotionState motionState = motionInfo.getState(); - - // Call entity move event. - EntityMoveEvent event = - new EntityMoveEvent( - entity, - new Position(motionInfo.getPos()), - new Position(motionInfo.getRot()), - motionState); - event.call(); - - entity.move(event.getPosition(), event.getRotation()); - entity.setLastMoveSceneTimeMs(moveInfo.getSceneTime()); - entity.setLastMoveReliableSeq(moveInfo.getReliableSeq()); - entity.setMotionState(motionState); - - session - .getPlayer() - .getStaminaManager() - .handleCombatInvocationsNotify(session, moveInfo, entity); - - // TODO: handle MOTION_FIGHT landing which has a different damage factor - // Also, for plunge attacks, LAND_SPEED is always -30 and is not useful. - // May need the height when starting plunge attack. - - // MOTION_LAND_SPEED and MOTION_FALL_ON_GROUND arrive in different packets. - // Cache land speed for later use. - if (motionState == MotionState.MOTION_STATE_LAND_SPEED) { - cachedLandingSpeed = motionInfo.getSpeed().getY(); - cachedLandingTimeMillisecond = System.currentTimeMillis(); - monitorLandingEvent = true; - } - if (monitorLandingEvent) { - if (motionState == MotionState.MOTION_STATE_FALL_ON_GROUND) { - monitorLandingEvent = false; - handleFallOnGround(session, entity, motionState); - } - } - - // MOTION_STATE_NOTIFY = Dont send to other players - if (motionState == MotionState.MOTION_STATE_NOTIFY) { - continue; - } - } - } - case COMBAT_TYPE_ARGUMENT_ANIMATOR_PARAMETER_CHANGED -> { - EvtAnimatorParameterInfo paramInfo = - EvtAnimatorParameterInfo.parseFrom(entry.getCombatData()); - if (paramInfo.getIsServerCache()) { - paramInfo = paramInfo.toBuilder().setIsServerCache(false).build(); - entry = entry.toBuilder().setCombatData(paramInfo.toByteString()).build(); - } - } - default -> {} - } - - session.getPlayer().getCombatInvokeHandler().addEntry(entry.getForwardType(), entry); - } - } - - private void handleFallOnGround(GameSession session, GameEntity entity, MotionState motionState) { - if (session.getPlayer().inGodmode()) { - return; - } - // People have reported that after plunge attack (client sends a FIGHT instead of - // FALL_ON_GROUND) they will die - // if they talk to an NPC (this is when the client sends a FALL_ON_GROUND) without jumping - // again. - // A dirty patch: if not received immediately after MOTION_LAND_SPEED, discard this packet. - // 200ms seems to be a reasonable delay. - int maxDelay = 200; - long actualDelay = System.currentTimeMillis() - cachedLandingTimeMillisecond; - Grasscutter.getLogger() - .trace( - "MOTION_FALL_ON_GROUND received after " - + actualDelay - + "/" - + maxDelay - + "ms." - + (actualDelay > maxDelay ? " Discard" : "")); - if (actualDelay > maxDelay) { - return; - } - float currentHP = entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP); - float maxHP = entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP); - float damageFactor = 0; - if (cachedLandingSpeed < -23.5) { - damageFactor = 0.33f; - } - if (cachedLandingSpeed < -25) { - damageFactor = 0.5f; - } - if (cachedLandingSpeed < -26.5) { - damageFactor = 0.66f; - } - if (cachedLandingSpeed < -28) { - damageFactor = 1f; - } - float damage = maxHP * damageFactor; - float newHP = currentHP - damage; - if (newHP < 0) { - newHP = 0; - } - if (damageFactor > 0) { - Grasscutter.getLogger() - .debug( - currentHP - + "/" - + maxHP - + "\tLandingSpeed: " - + cachedLandingSpeed - + "\tDamageFactor: " - + damageFactor - + "\tDamage: " - + damage - + "\tNewHP: " - + newHP); - } else { - Grasscutter.getLogger().trace(currentHP + "/" + maxHP + "\tLandingSpeed: 0\tNo damage"); - } - entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP); - entity - .getWorld() - .broadcastPacket( - new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP)); - if (newHP == 0) { - session - .getPlayer() - .getStaminaManager() - .killAvatar(session, entity, PlayerDieTypeOuterClass.PlayerDieType.PLAYER_DIE_TYPE_FALL); - } - cachedLandingSpeed = 0; - } -} +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.Grasscutter; +import emu.grasscutter.game.entity.GameEntity; +import emu.grasscutter.game.player.Player; +import emu.grasscutter.game.props.FightProperty; +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult; +import emu.grasscutter.net.proto.CombatInvocationsNotifyOuterClass.CombatInvocationsNotify; +import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry; +import emu.grasscutter.net.proto.EntityMoveInfoOuterClass.EntityMoveInfo; +import emu.grasscutter.net.proto.EvtAnimatorParameterInfoOuterClass.EvtAnimatorParameterInfo; +import emu.grasscutter.net.proto.EvtBeingHitInfoOuterClass.EvtBeingHitInfo; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; +import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState; +import emu.grasscutter.net.proto.PlayerDieTypeOuterClass; +import emu.grasscutter.server.event.entity.EntityMoveEvent; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; +import emu.grasscutter.utils.Position; + +@Opcodes(PacketOpcodes.CombatInvocationsNotify) +public class HandlerCombatInvocationsNotify extends PacketHandler { + + private float cachedLandingSpeed = 0; + private long cachedLandingTimeMillisecond = 0; + private boolean monitorLandingEvent = false; + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + CombatInvocationsNotify notif = CombatInvocationsNotify.parseFrom(payload); + for (CombatInvokeEntry entry : notif.getInvokeListList()) { + // Handle combat invoke + switch (entry.getArgumentType()) { + case COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT -> { + EvtBeingHitInfo hitInfo = EvtBeingHitInfo.parseFrom(entry.getCombatData()); + AttackResult attackResult = hitInfo.getAttackResult(); + Player player = session.getPlayer(); + + // Check if the player is invulnerable. + if (attackResult.getAttackerId() + != player.getTeamManager().getCurrentAvatarEntity().getId() + && player.getAbilityManager().isAbilityInvulnerable()) break; + + // Handle damage + player.getAttackResults().add(attackResult); + player.getEnergyManager().handleAttackHit(hitInfo); + } + case COMBAT_TYPE_ARGUMENT_ENTITY_MOVE -> { + // Handle movement + EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData()); + GameEntity entity = session.getPlayer().getScene().getEntityById(moveInfo.getEntityId()); + if (entity != null) { + // Move player + MotionInfo motionInfo = moveInfo.getMotionInfo(); + MotionState motionState = motionInfo.getState(); + + // Call entity move event. + EntityMoveEvent event = + new EntityMoveEvent( + entity, + new Position(motionInfo.getPos()), + new Position(motionInfo.getRot()), + motionState); + event.call(); + + entity.move(event.getPosition(), event.getRotation()); + entity.setLastMoveSceneTimeMs(moveInfo.getSceneTime()); + entity.setLastMoveReliableSeq(moveInfo.getReliableSeq()); + entity.setMotionState(motionState); + + session + .getPlayer() + .getStaminaManager() + .handleCombatInvocationsNotify(session, moveInfo, entity); + + // TODO: handle MOTION_FIGHT landing which has a different damage factor + // Also, for plunge attacks, LAND_SPEED is always -30 and is not useful. + // May need the height when starting plunge attack. + + // MOTION_LAND_SPEED and MOTION_FALL_ON_GROUND arrive in different packets. + // Cache land speed for later use. + if (motionState == MotionState.MOTION_STATE_LAND_SPEED) { + cachedLandingSpeed = motionInfo.getSpeed().getY(); + cachedLandingTimeMillisecond = System.currentTimeMillis(); + monitorLandingEvent = true; + } + if (monitorLandingEvent) { + if (motionState == MotionState.MOTION_STATE_FALL_ON_GROUND) { + monitorLandingEvent = false; + handleFallOnGround(session, entity, motionState); + } + } + + // as long as one of these two packets be forwarded to client, the animation of avatar will be interrupted + if (motionState == MotionState.MOTION_STATE_NOTIFY || motionState == MotionState.MOTION_STATE_FIGHT) { + continue; + } + } + } + case COMBAT_TYPE_ARGUMENT_ANIMATOR_PARAMETER_CHANGED -> { + var paramInfo = + EvtAnimatorParameterInfo.parseFrom(entry.getCombatData()); + if (paramInfo.getIsServerCache()) { + paramInfo = paramInfo.toBuilder().setIsServerCache(false).build(); + entry = entry.toBuilder().setCombatData(paramInfo.toByteString()).build(); + } + } + default -> {} + } + + session.getPlayer().getCombatInvokeHandler().addEntry(entry.getForwardType(), entry); + } + } + + private void handleFallOnGround(GameSession session, GameEntity entity, MotionState motionState) { + if (session.getPlayer().inGodmode()) { + return; + } + // People have reported that after plunge attack (client sends a FIGHT instead of + // FALL_ON_GROUND) they will die + // if they talk to an NPC (this is when the client sends a FALL_ON_GROUND) without jumping + // again. + // A dirty patch: if not received immediately after MOTION_LAND_SPEED, discard this packet. + // 200ms seems to be a reasonable delay. + int maxDelay = 200; + long actualDelay = System.currentTimeMillis() - cachedLandingTimeMillisecond; + Grasscutter.getLogger() + .trace( + "MOTION_FALL_ON_GROUND received after " + + actualDelay + + "/" + + maxDelay + + "ms." + + (actualDelay > maxDelay ? " Discard" : "")); + if (actualDelay > maxDelay) { + return; + } + float currentHP = entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP); + float maxHP = entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP); + float damageFactor = 0; + if (cachedLandingSpeed < -23.5) { + damageFactor = 0.33f; + } + if (cachedLandingSpeed < -25) { + damageFactor = 0.5f; + } + if (cachedLandingSpeed < -26.5) { + damageFactor = 0.66f; + } + if (cachedLandingSpeed < -28) { + damageFactor = 1f; + } + float damage = maxHP * damageFactor; + float newHP = currentHP - damage; + if (newHP < 0) { + newHP = 0; + } + if (damageFactor > 0) { + Grasscutter.getLogger() + .debug( + currentHP + + "/" + + maxHP + + "\tLandingSpeed: " + + cachedLandingSpeed + + "\tDamageFactor: " + + damageFactor + + "\tDamage: " + + damage + + "\tNewHP: " + + newHP); + } else { + Grasscutter.getLogger().trace(currentHP + "/" + maxHP + "\tLandingSpeed: 0\tNo damage"); + } + entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP); + entity + .getWorld() + .broadcastPacket( + new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP)); + if (newHP == 0) { + session + .getPlayer() + .getStaminaManager() + .killAvatar(session, entity, PlayerDieTypeOuterClass.PlayerDieType.PLAYER_DIE_TYPE_FALL); + } + cachedLandingSpeed = 0; + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerDungeonEntryInfoReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerDungeonEntryInfoReq.java index 052aed0bf..0067e3bd9 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerDungeonEntryInfoReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerDungeonEntryInfoReq.java @@ -1,18 +1,18 @@ -package emu.grasscutter.server.packet.recv; - -import emu.grasscutter.net.packet.Opcodes; -import emu.grasscutter.net.packet.PacketHandler; -import emu.grasscutter.net.packet.PacketOpcodes; -import emu.grasscutter.net.proto.DungeonEntryInfoReqOuterClass.DungeonEntryInfoReq; -import emu.grasscutter.server.game.GameSession; - -@Opcodes(PacketOpcodes.DungeonEntryInfoReq) -public class HandlerDungeonEntryInfoReq extends PacketHandler { - - @Override - public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { - DungeonEntryInfoReq req = DungeonEntryInfoReq.parseFrom(payload); - - session.getServer().getDungeonSystem().getEntryInfo(session.getPlayer(), req.getPointId()); - } -} +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.DungeonEntryInfoReqOuterClass.DungeonEntryInfoReq; +import emu.grasscutter.server.game.GameSession; + +@Opcodes(PacketOpcodes.DungeonEntryInfoReq) +public class HandlerDungeonEntryInfoReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + DungeonEntryInfoReq req = DungeonEntryInfoReq.parseFrom(payload); + + session.getServer().getDungeonSystem().getEntryInfo(session.getPlayer(), req.getPointId(), req.getSceneId()); + } +}