Ir para conteúdo
  • Cadastre-se
  • 0
Entre para seguir isso  
Chaazy

Skill Cooltime ( Skill volta do 0 após restart )

Pergunta

Ha algum tempo venho tentando resolver um problema na l2jfrozen 1132, ja pesquisei em vários fóruns,porem sem sucesso.

O que acontece é o seguinte. Skills que contem o reusedelay maior (buffs como heroic, battle roar, rage, frenzy, zealot, ultimate defense etc...) assim que você os usa e deixa ele carregar 30,50,90% que seja, se o player tomar dc, critical error ou ate mesmo dar restart, o skill volta do 0! Ele simplesmente não volta de onde parou, e mesmo ficando 1 hora sem entrar no jogo a skill não termina de carregar, é como se não salva-se os dados das skills.

Alguém pode ajudar? 

Compartilhar este post


Link para o post
Compartilhar em outros sites

15 respostass a esta questão

Posts recomendados


Precisando de Dedicado ou VPS?

Conheça a L2JCenter
  • 0

Como você mesmo falou, não está salvando no banco de dados essa informação ou essa informação não está sendo restaurada. Você precisa salvar essa informação no método 'onDisconnection' da classe L2GameClient e restaurar no método que carrega os dados do player na classe L2PcInstance. Geralmente essa informação é salva na tabela 'characters_skills_save'.  Infelizmente não conheço a Frozen pra te ajudar além disso.

Editado por KhayrusS
  • Gostei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
 

Como você mesmo falou, não está salvando no banco de dados essa informação ou essa informação não está sendo restaurada. Você precisa salvar essa informação no método 'onDisconnection' da classe L2GameClient e restaurar no método que carrega os dados do player na classe L2PcInstance. Geralmente essa informação é salva na tabela 'characters_skills_save'.  Infelizmente não conheço a Frozen pra te ajudar além disso.

Obrigado mesmo assim, já é um ponto de partida!

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0

Basta ir em L2PcInstance

Procure por
public void restoreEffects(final boolean activateEffects)

Tem todas as informações que você precisa sobre a restauração do player.

Basta corrigir da forma que vc quiser, eu não utilizo frozen, mas corrigi na que eu utilizo à tempos.

Certa vez no meu server, para burlarem o tempo reuse skill, eles trocavam de subclasse, a skill voltava zerada.

Nesse caso precisa modificar tb.

  • Amei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
 

Basta ir em L2PcInstance

Procure por
public void restoreEffects(final boolean activateEffects)

Tem todas as informações que você precisa sobre a restauração do player.

Basta corrigir da forma que vc quiser, eu não utilizo frozen, mas corrigi na que eu utilizo à tempos.

Certa vez no meu server, para burlarem o tempo reuse skill, eles trocavam de subclasse, a skill voltava zerada.

Nesse caso precisa modificar tb.

   

	public void restoreEffects(final boolean activateEffects)
	{
		Connection con = null;
		
		try
		{
			con = L2DatabaseFactory.getInstance().getConnection(false);
			PreparedStatement statement;
			ResultSet rset;
			
			/**
			 * Restore Type 0 These skill were still in effect on the character upon logout. Some of which were self casted and might still have had a long reuse delay which also is restored.
			 */
			statement = con.prepareStatement(RESTORE_SKILL_SAVE);
			statement.setInt(1, getObjectId());
			statement.setInt(2, getClassIndex());
			statement.setInt(3, 0);
			rset = statement.executeQuery();
			
			while (rset.next())
			{
				final int skillId = rset.getInt("skill_id");
				final int skillLvl = rset.getInt("skill_level");
				final int effectCount = rset.getInt("effect_count");
				final int effectCurTime = rset.getInt("effect_cur_time");
				final long reuseDelay = rset.getLong("reuse_delay");
				
				// Just incase the admin minipulated this table incorrectly :x
				if (skillId == -1 || effectCount == -1 || effectCurTime == -1 || reuseDelay < 0)
				{
					continue;
				}
				
				if (activateEffects)
				{
					
					L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
					
					skill.getEffects(this, this, false, false, false);
					skill = null;
					
					for (final L2Effect effect : getAllEffects())
					{
						if (effect.getSkill().getId() == skillId)
						{
							effect.setCount(effectCount);
							effect.setFirstTime(effectCurTime);
						}
					}
				}
				
				if (reuseDelay > 10)
				{
					final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
					
					if (skill == null)
						continue;
					
					disableSkill(skill, reuseDelay);
					addTimeStamp(new TimeStamp(skill, reuseDelay));
				}
				
			}
			DatabaseUtils.close(rset);
			DatabaseUtils.close(statement);
			rset = null;
			statement = null;
			
			/**
			 * Restore Type 1 The remaning skills lost effect upon logout but were still under a high reuse delay.
			 */
			statement = con.prepareStatement(RESTORE_SKILL_SAVE);
			statement.setInt(1, getObjectId());
			statement.setInt(2, getClassIndex());
			statement.setInt(3, 1);
			rset = statement.executeQuery();
			
			while (rset.next())
			{
				final int skillId = rset.getInt("skill_id");
				final int skillLvl = rset.getInt("skill_level");
				final long reuseDelay = rset.getLong("reuse_delay");
				
				if (reuseDelay <= 0)
				{
					continue;
				}
				
				final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
				
				if (skill == null)
					continue;
				
				disableSkill(skill, reuseDelay);
				addTimeStamp(new TimeStamp(skill, reuseDelay));
			}
			DatabaseUtils.close(rset);
			DatabaseUtils.close(statement);
			rset = null;
			
			statement = con.prepareStatement(DELETE_SKILL_SAVE);
			statement.setInt(1, getObjectId());
			statement.setInt(2, getClassIndex());
			statement.executeUpdate();
			DatabaseUtils.close(statement);
			statement = null;
		}
		catch (final Exception e)
		{
			if (Config.ENABLE_ALL_EXCEPTIONS)
				e.printStackTrace();
			
			LOGGER.warn("Could not restore active effect data: " + e);
		}
		finally
		{
			CloseUtil.close(con);
		}
		
		updateEffectIcons();
	}

 

pode me dizer onde devo alterar?

  • Gostei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0

Aparentemente essa parte do código está correta. Procura pelo método que salva essas informações no DB, provavelmente algo parecido com 'storeEffects'.

  • Gostei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
 

Aparentemente essa parte do código está correta. Procura pelo método que salva essas informações no DB, provavelmente algo parecido com 'storeEffects'.

	@SuppressWarnings("null")
	private synchronized void storeEffect()
	{
		if (!Config.STORE_SKILL_COOLTIME)
			return;
		
		Connection con = null;
		try
		{
			con = L2DatabaseFactory.getInstance().getConnection(false);
			PreparedStatement statement;
			// Delete all current stored effects for char to avoid dupe
			statement = con.prepareStatement(DELETE_SKILL_SAVE);
			statement.setInt(1, getObjectId());
			statement.setInt(2, getClassIndex());
			statement.execute();
			DatabaseUtils.close(statement);
			
			// Store all effect data along with calulated remaining
			// reuse delays for matching skills. 'restore_type'= 0.
			final L2Effect[] effects = getAllEffects();
			statement = con.prepareStatement(ADD_SKILL_SAVE);
			
			final List<Integer> storedSkills = new FastList<>();
			
			int buff_index = 0;
			
			for (final L2Effect effect : effects)
			{
				final int skillId = effect.getSkill().getId();
				
				if (storedSkills.contains(skillId))
					continue;
				storedSkills.add(skillId);
				
				if (effect != null && effect.getInUse() && !effect.getSkill().isToggle() && !effect.getStackType().equals("BattleForce") && !effect.getStackType().equals("SpellForce") && effect.getSkill().getSkillType() != SkillType.FORCE_BUFF)
				{
					statement.setInt(1, getObjectId());
					statement.setInt(2, skillId);
					statement.setInt(3, effect.getSkill().getLevel());
					statement.setInt(4, effect.getCount());
					statement.setInt(5, effect.getTime());
					if (ReuseTimeStamps.containsKey(effect.getSkill().getReuseHashCode()))
					{
						final TimeStamp t = ReuseTimeStamps.get(effect.getSkill().getReuseHashCode());
						statement.setLong(6, t.hasNotPassed() ? t.getReuse() : 0);
						statement.setLong(7, t.hasNotPassed() ? t.getStamp() : 0);
					}
					else
					{
						statement.setLong(6, 0);
						statement.setLong(7, 0);
					}
					statement.setInt(8, 0);
					statement.setInt(9, getClassIndex());
					statement.setInt(10, ++buff_index);
					statement.execute();
				}
			}
			// Store the reuse delays of remaining skills which
			// lost effect but still under reuse delay. 'restore_type' 1.
			for (final TimeStamp t : ReuseTimeStamps.values())
			{
				if (t.hasNotPassed())
				{
					final int skillId = t.getSkill().getId();
					final int skillLvl = t.getSkill().getLevel();
					if (storedSkills.contains(skillId))
						continue;
					storedSkills.add(skillId);
					
					statement.setInt(1, getObjectId());
					statement.setInt(2, skillId);
					statement.setInt(3, skillLvl);
					statement.setInt(4, -1);
					statement.setInt(5, -1);
					statement.setLong(6, t.getReuse());
					statement.setLong(7, t.getStamp());
					statement.setInt(8, 1);
					statement.setInt(9, getClassIndex());
					statement.setInt(10, ++buff_index);
					statement.execute();
				}
			}
			DatabaseUtils.close(statement);
		}
		catch (final Exception e)
		{
			LOGGER.warn("Could not store char effect data: ");
			e.printStackTrace();
		}
		finally
		{
			CloseUtil.close(con);
		}
	}

Seria isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0

Isso. Eu preciso só de mais duas informações:

o valor dessa constante  ADD_SKILL_SAVE;

e o código dessa classe: TimeStamp.

 

  • Gostei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
 

Isso. Eu preciso só de mais duas informações:

o valor dessa constante  ADD_SKILL_SAVE;

e o código dessa classe: TimeStamp.

 

Código da TimeStamp 

	public static class TimeStamp
	{
		
		public long getStamp()
		{
			return stamp;
		}
		
		public L2Skill getSkill()
		{
			return skill;
		}
		
		public long getReuse()
		{
			return reuse;
		}
		
		public long getRemaining()
		{
			return Math.max(stamp - System.currentTimeMillis(), 0L);
		}
		
		protected boolean hasNotPassed()
		{
			return System.currentTimeMillis() < stamp;
		}
		
		private final L2Skill skill;
		private final long reuse;
		private final long stamp;
		
		protected TimeStamp(final L2Skill _skill, final long _reuse)
		{
			skill = _skill;
			reuse = _reuse;
			stamp = System.currentTimeMillis() + reuse;
		}
		
		protected TimeStamp(final L2Skill _skill, final long _reuse, final long _systime)
		{
			skill = _skill;
			reuse = _reuse;
			stamp = _systime;
		}
	}

Valor da Constant ADD_SKILL_SAVE seria isso?

	/** The Constant ADD_SKILL_SAVE. */
	// private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (char_obj_id,skill_id,skill_level,effect_count,effect_cur_time,reuse_delay,restore_type,class_index,buff_index) VALUES (?,?,?,?,?,?,?,?,?)";
	private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (char_obj_id,skill_id,skill_level,effect_count,effect_cur_time,reuse_delay,systime,restore_type,class_index,buff_index) VALUES (?,?,?,?,?,?,?,?,?,?)";

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0

É isso mesmo. Existem duas abordagens:

  • A skill ser restaurada com o cooltime  que estava quando o player deslogou;
  • O cooltime ser baseado no tempo real, por exemplo: A skill tem restando 10 min de cooltime, se o player logar apenas depois que os 10 min  passou, a skill já estaria pronta pra uso.

Qual delas você quer ?

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
 

É isso mesmo. Existem duas abordagens:

  • A skill ser restaurada com o cooltime  que estava quando o player deslogou;
  • O cooltime ser baseado no tempo real, por exemplo: A skill tem restando 10 min de cooltime, se o player logar apenas depois que os 10 min  passou, a skill já estaria pronta pra uso.

Qual delas você quer ?

Com o cooltime baseado no tempo real, pois assim resolve o problema de logar bom tempo depois e a skill começando do 0.

Dessa forma se o player tomar dc e voltar 1 minuto depois, a skill vai continuar seu cooltime normalmente? Exemplo:

Tomei dc com heroic 50%, demorei 1 minuto pra logar novamente e o mesmo vai estar 60%.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0

O problema é que está sendo salvo o reuseDelay da skill no DB, por isso ela sempre volta do 0.

Para a skill ser restaurada com o cooltime  que estava quando o player deslogou, no método storeEffect, é necessário apenas mudar essa linha

 

statement.setLong(6, t.getReuse());

para essa :

statement.setLong(6, t.getRemaining());

 

Já para a segunda alternativa a mudança pode ser realizada no método restoreEffects. Após as linhas

final int effectCurTime = rset.getInt("effect_cur_time");
final long reuseDelay = rset.getLong("reuse_delay");

adicionar:

final long coolTime = rset.getLong("systime") - System.currentTimeMillis(); 

Trocar essa parte do código:

if (reuseDelay > 10)
{
  final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);

  if (skill == null)
    continue;

  disableSkill(skill, reuseDelay);
  addTimeStamp(new TimeStamp(skill, reuseDelay));
}

por essa:

if (coolTime > 10)
{
  final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);

  if (skill == null)
    continue;

  disableSkill(skill, coolTime);
  addTimeStamp(new TimeStamp(skill, coolTime));
}

 

Seguir a mesma lógica pra parte mais abaixo do código. Além disso, confirmar que a coluna systime faz parte do select da constante RESTORE_SKILL_SAVE

  • Amei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
 

O problema é que está sendo salvo o reuseDelay da skill no DB, por isso ela sempre volta do 0.

Para a skill ser restaurada com o cooltime  que estava quando o player deslogou, no método storeEffect, é necessário apenas mudar essa linha

para essa :

statement.setLong(6, t.getRemaining());

 

Já para a segunda alternativa a mudança pode ser realizada no método restoreEffects. Após as linhas

final int effectCurTime = rset.getInt("effect_cur_time");
final long reuseDelay = rset.getLong("reuse_delay");

adicionar:

final long coolTime = rset.getLong("systime") - System.currentTimeMillis(); 

Trocar essa parte do código:

if (reuseDelay > 10)
{
  final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);

  if (skill == null)
    continue;

  disableSkill(skill, reuseDelay);
  addTimeStamp(new TimeStamp(skill, reuseDelay));
}

por essa:

if (coolTime > 10)
{
  final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);

  if (skill == null)
    continue;

  disableSkill(skill, coolTime);
  addTimeStamp(new TimeStamp(skill, coolTime));
}

 

Seguir a mesma lógica pra parte mais abaixo do código. Além disso, confirmar que a coluna systime faz parte do select da constante RESTORE_SKILL_SAVE

Muito Obrigado mesmo KhayrusS!!! Me ajudou demais ❤️ Porém fiz algumas alterações nos códigos ficando da seguinte forma:

Adicionei a linha 

final long systime = rset.getLong("systime");

abaixo das linhas 

final int effectCount = rset.getInt("effect_count");
final int effectCurTime = rset.getInt("effect_cur_time");
final long reuseDelay = rset.getLong("reuse_delay");

Troquei esse parte código 

if (reuseDelay > 10)
{
  final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);

  if (skill == null)
    continue;

  disableSkill(skill, reuseDelay);
  addTimeStamp(new TimeStamp(skill, reuseDelay));
}

por esta

				final long remainingTime = systime - System.currentTimeMillis();
				if (remainingTime > 10)
					
				{
					final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
					
					if (skill == null)
						continue;
					
					disableSkill(skill, remainingTime);
					addTimeStamp(new TimeStamp(skill, reuseDelay, systime));
				}

E segui a mesma logica para os codigos abaixo. O meu problema era no RestoreEffects, dessa forma se eu usar a skill e ele tiver 50%, se eu tomar dc ou der restart a skill continua carregando normalmente 😄 e quando voltar a skill vai continuar de onde ela estiver.

Mas com isso tambem apareceu um novo bug, que nao tinha como saber com a skill voltando do 0 toda vez.

Se eu usar uma skill (ex: Heroic) e der 2 restarts seguidos, a skill volta carregada 100%.

Pode me ajudar a arrumar isso também?

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
 

Dois restarts rápidos ? Depois do segundo restart, antes de logar, novamente, valor do systime continua correto no DB ?

Sim 2 restarts rapidos, notei o seguinte. Se usar a skill e atualizar a db com o char logado, não aparece que a skill foi salva, não mostra systime, reuse essas coisas, ai quando dou o primeiro restart com o char e atualizo a db, mostra os dados salvos corretamente, systime e tudo.

Assim que dou o segundo restart, as informações que foram salvas na db somem. Ai a skill volta do 100% 

Editado por Chaazy

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
Entre para seguir isso  

  • Mudanças no Login

    Preste atenção às mudanças no método de login.

    Com a migração para nomes de usuário IPB4 não existe mais.

    Você deve usar seu nome de exibição ou email em vez de nome de usuário.




     



×