• SiteAnalyzer, технический и SEO-анализ сайтов

Смерть и воскрешение AL

  • Автор темы Автор темы novich
  • Дата начала Дата начала

novich

Рядовой
Здравствуйте, опять я. Наткнулся на проблему некорректного возрождения. При воскрешении после смерти от долгого падения персонаж умирает второй раз сразу после появления на респе. Может кто-то сталкивался с таким? PlayerReviveService.java всему виной?
 
ну вариантов может быть куча , а вообще да сервис правильный )
P.S. Где вы такие кривые сборки то берете )?
 
Нужно работать с StackTrace чтобы узнать где вызван метод был.
Thread.currentThread().getStackTrace();
 
А у меня в сборку на серверном на всех базах мобы удваивается при появление, укажите путь где это исправить, спасибо !
 
ну вариантов может быть куча , а вообще да сервис правильный )
P.S. Где вы такие кривые сборки то берете )?
Ты же вроде там гео правишь и все что только придумать можно) ошибка простая)
никакого упоминания 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));
и потестируй.
 
Назад
Сверху