Здравствуйте, опять я. Наткнулся на проблему некорректного возрождения. При воскрешении после смерти от долгого падения персонаж умирает второй раз сразу после появления на респе. Может кто-то сталкивался с таким? PlayerReviveService.java всему виной?
ну вариантов может быть куча , а вообще да сервис правильный ) P.S. Где вы такие кривые сборки то берете )?
Нужно работать с StackTrace чтобы узнать где вызван метод был. Thread.currentThread().getStackTrace();
А у меня в сборку на серверном на всех базах мобы удваивается при появление, укажите путь где это исправить, спасибо !
никакого упоминания stacktrace в сборке нет вот сам сервис, может кто-то накосячил в коде и вы заметите: Код: package com.aionemu.gameserver.services.player; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.aionemu.gameserver.configs.administration.AdminConfig; import com.aionemu.gameserver.model.EmotionType; import com.aionemu.gameserver.model.gameobjects.Item; import com.aionemu.gameserver.model.gameobjects.Kisk; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.gameobjects.state.CreatureState; import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION; import com.aionemu.gameserver.network.aion.serverpackets.SM_ITEM_USAGE_ANIMATION; import com.aionemu.gameserver.network.aion.serverpackets.SM_MOTION; import com.aionemu.gameserver.network.aion.serverpackets.SM_PLAYER_INFO; import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE; import com.aionemu.gameserver.services.teleport.TeleportService; import com.aionemu.gameserver.taskmanager.tasks.TeamMoveUpdater; import com.aionemu.gameserver.utils.audit.AuditLogger; import com.aionemu.gameserver.utils.PacketSendUtility; import com.aionemu.gameserver.world.World; import com.aionemu.gameserver.world.WorldMap; import com.aionemu.gameserver.world.WorldPosition; /** * @author Jego, xTz */ public class PlayerReviveService { private static final Logger log = LoggerFactory.getLogger(PlayerReviveService.class); public static final void duelRevive(Player player) { revive(player, 30, 30, false); PacketSendUtility.broadcastPacket(player, new SM_EMOTION(player, EmotionType.RESURRECT), true); player.getGameStats().updateStatsAndSpeedVisually(); player.unsetResPosState(); } public static final void skillRevive(Player player) { if (!(player.getResStatus())) { cancelRes(player); return; } player.setTelEffect(2); boolean isFlyingBeforeDeath = player.getIsFlyingBeforeDeath(); revive(player, 10, 10, true); if (isFlyingBeforeDeath) player.setState(CreatureState.FLYING); PacketSendUtility.broadcastPacket(player, new SM_EMOTION(player, EmotionType.RESURRECT), true); PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_REBIRTH_MASSAGE_ME); player.getGameStats().updateStatsAndSpeedVisually(); if (player.isInPrison()) TeleportService.teleportToPrison(player); if (player.isInResPostState()) TeleportService.teleportTo(player, player.getWorldId(), player.getInstanceId(), player.getResPosX(), player.getResPosY(), player.getResPosZ(), 0, true); player.unsetResPosState(); //if player was flying before res, start flying if (isFlyingBeforeDeath) { player.getFlyController().startFly(); } } public static final void rebirthRevive(Player player) { if (!player.canUseRebirthRevive()) { return; } player.setTelEffect(2); if (player.getRebirthResurrectPercent() <= 0) { PacketSendUtility.sendMessage(player, "Error: Rebirth effect missing percent."); player.setRebirthResurrectPercent(5); } boolean soulSickness = true; int rebirthResurrectPercent = player.getRebirthResurrectPercent(); if(player.getAccessLevel() >= AdminConfig.ADMIN_AUTO_RES) { rebirthResurrectPercent = 100; soulSickness = false; } boolean isFlyingBeforeDeath = player.getIsFlyingBeforeDeath(); revive(player, rebirthResurrectPercent, rebirthResurrectPercent, soulSickness); if (isFlyingBeforeDeath) player.setState(CreatureState.FLYING); PacketSendUtility.broadcastPacket(player, new SM_EMOTION(player, EmotionType.RESURRECT), true); PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_REBIRTH_MASSAGE_ME); player.getGameStats().updateStatsAndSpeedVisually(); if (player.isInPrison()) TeleportService.teleportToPrison(player); player.unsetResPosState(); //if player was flying before res, start flying if (isFlyingBeforeDeath) { player.getFlyController().startFly(); } } public static final void bindRevive(Player player) { player.setTelEffect(4); revive(player, 25, 25, true); PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_REBIRTH_MASSAGE_ME); // TODO: It is not always necessary. // sendPacket(new SM_QUEST_LIST(activePlayer)); player.getGameStats().updateStatsAndSpeedVisually(); PacketSendUtility.sendPacket(player, new SM_PLAYER_INFO(player, false)); PacketSendUtility.sendPacket(player, new SM_MOTION(player.getObjectId(), player.getMotions().getActiveMotions())); if (player.isInPrison()) TeleportService.teleportToPrison(player); else TeleportService.moveToBindLocation(player, true); player.unsetResPosState(); } public static final void kiskRevive(Player player) { Kisk kisk = player.getKisk(); if (kisk == null) { return; } player.setTelEffect(2); if (player.isInPrison()) TeleportService.teleportToPrison(player); else if (kisk.isActive()) { WorldPosition bind = kisk.getPosition(); kisk.resurrectionUsed(player); PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_REBIRTH_MASSAGE_ME); revive(player, 25, 25, false); player.getGameStats().updateStatsAndSpeedVisually(); //PacketSendUtility.sendPacket(player, new SM_PLAYER_INFO(player, false)); // send by TeleportService //PacketSendUtility.sendPacket(player, new SM_MOTION(player.getObjectId(), player.getMotions().getActiveMotions())); // send by TeleportService player.unsetResPosState(); TeleportService.moveToKiskLocation(player, bind); } } public static final void instanceRevive(Player player) { // Revive in Instances try { if (player.getPosition().getWorldMapInstance().getInstanceHandler().onReviveEvent(player)) { return; } } catch (Exception ex) { log.warn("[PlayerReviveService] Error call onReviveEvent player: " + player.getName()); bindRevive(player); return; } WorldMap map = World.getInstance().getWorldMap(player.getWorldId()); if (map == null) { bindRevive(player); return; } player.setTelEffect(4); revive(player, 25, 25, true); PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_REBIRTH_MASSAGE_ME); player.getGameStats().updateStatsAndSpeedVisually(); PacketSendUtility.sendPacket(player, new SM_PLAYER_INFO(player, false)); PacketSendUtility.sendPacket(player, new SM_MOTION(player.getObjectId(), player.getMotions().getActiveMotions())); if (map.isInstanceType() && (player.getInstanceStartPosX() != 0 && player.getInstanceStartPosY() != 0 && player.getInstanceStartPosZ() != 0)) { TeleportService.teleportTo(player, player.getWorldId(), player.getInstanceStartPosX(), player.getInstanceStartPosY(), player.getInstanceStartPosZ(), 0); } else { bindRevive(player); } player.unsetResPosState(); } public static final void revive(final Player player, int hpPercent, int mpPercent, boolean setSoulsickness) { player.setPlayerResActivate(false); player.getLifeStats().setCurrentHpPercent(hpPercent); player.getLifeStats().setCurrentMpPercent(mpPercent); if (player.getCommonData().getDp() > 0) player.getCommonData().setDp(0); player.getLifeStats().triggerRestoreOnRevive(); if (setSoulsickness) { player.getController().updateSoulSickness(); } player.getAggroList().clear(); player.getController().onBeforeSpawn(); //unset isflyingbeforedeath player.setIsFlyingBeforeDeath(false); if(player.isInGroup2()){ TeamMoveUpdater.getInstance().startTask(player); } PacketSendUtility.sendPacket(player, new SM_EMOTION(player, EmotionType.RESURRECT)); } public static final void itemSelfRevive(Player player) { Item item = player.getSelfRezStone(); if (item == null) { cancelRes(player); return; } // Add Cooldown and use item int useDelay = item.getItemTemplate().getDelayTime(); player.addItemCoolDown(item.getItemTemplate().getDelayId(), System.currentTimeMillis() + useDelay, useDelay / 1000); player.getController().cancelUseItem(); PacketSendUtility.broadcastPacket(player, new SM_ITEM_USAGE_ANIMATION(player.getObjectId(), item.getObjectId(), item.getItemTemplate().getTemplateId()), true); if (!player.getInventory().decreaseByObjectId(item.getObjectId(), 1)) { cancelRes(player); return; } boolean isFlyingBeforeDeath = player.getIsFlyingBeforeDeath(); // Tombstone Self-Rez retail verified 15% revive(player, 15, 15, true); if (isFlyingBeforeDeath) player.setState(CreatureState.FLYING); PacketSendUtility.broadcastPacket(player, new SM_EMOTION(player, EmotionType.RESURRECT), true); PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_REBIRTH_MASSAGE_ME); player.getGameStats().updateStatsAndSpeedVisually(); if (player.isInPrison()) TeleportService.teleportToPrison(player); player.unsetResPosState(); //if player was flying before res, start flying if (isFlyingBeforeDeath) { player.getFlyController().startFly(); } } private static final void cancelRes(Player player) { AuditLogger.info(player, "Possible selfres hack."); player.getController().sendDie(); } }
Или может кто-нибудь рабочий даст, для такой сборки. Я в интернете поискал такой сервис и безуспешно. Везде ReviveController как я понял вместо этого сервиса
Проблема ещё серьёзнее - умершего в воздухе нельзя реснуть другим игрокам - не правильная цель. А при саморесе он сразу же опять умирает.
Так это в другом месте лечится) веселый у вас эмулятор) стактрейс вам самим нужно вызывать, это для дебага используют)
вернее нашёл Код: package com.aionemu.gameserver.network.aion.clientpackets; import com.aionemu.gameserver.model.gameobjects.VisibleObject; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.team2.TeamMember; import com.aionemu.gameserver.network.aion.AionClientPacket; import com.aionemu.gameserver.network.aion.AionConnection.State; import com.aionemu.gameserver.network.aion.serverpackets.SM_TARGET_SELECTED; import com.aionemu.gameserver.network.aion.serverpackets.SM_TARGET_UPDATE; import com.aionemu.gameserver.utils.PacketSendUtility; /** * Client Sends this packet when /Select NAME is typed.<br> * I believe it's the same as mouse click on a character.<br> * If client want's to select target - d is object id.<br> * If client unselects target - d is 0; * * @author SoulKeeper, Sweetkr, KID */ public class CM_TARGET_SELECT extends AionClientPacket { /** * Target object id that client wants to select or 0 if wants to unselect */ private int targetObjectId; private int type; /** * Constructs new client packet instance. * * @param opcode */ public CM_TARGET_SELECT(int opcode, State state, State... restStates) { super(opcode, state, restStates); } /** * Read packet.<br> * d - object id; c - selection type; */ @Override protected void readImpl() { targetObjectId = readD(); type = readC(); } /** * Do logging */ @Override protected void runImpl() { Player player = getConnection().getActivePlayer(); VisibleObject obj = null;; if (targetObjectId == player.getObjectId()) obj = player; else { obj = player.getKnownList().getObject(targetObjectId); if(obj == null && player.isInTeam()){ TeamMember<Player> member = player.getCurrentTeam().getMember(targetObjectId); if(member != null){ obj = member.getObject(); } } } if (obj != null && obj instanceof VisibleObject) { if (type == 1) { if (obj.getTarget() == null) return; player.setTarget(obj.getTarget()); } else { player.setTarget(obj); } } else { player.setTarget(null); } sendPacket(new SM_TARGET_SELECTED(player)); PacketSendUtility.broadcastPacket(player, new SM_TARGET_UPDATE(player)); } }
Методом проб и ошибок вставлял строки по типу revive(player, 10, 10, true); в разные места PlayerReviveService.java Получается только окончательно доламать воскрешение, что персонаж сразу же умирает во всех случаях после воскрешения, но вот исправить вышеописанные баги никак. Надеюсь на помощь.
В методе revive. удали строку PacketSendUtility.sendPacket(player, new SM_EMOTION(player, EmotionType.RESURRECT)); и потестируй.
Это в двух словах не объяснить, учите хотябы основы програмирования. Чтобы вашу ошибку исправить нужны исходники, время и желание. Я пока занят и желания особо нет.