Перейти к содержанию
Авторизация  
Abstragetic

Возможно ли? Снятие хиро по таймеру без релога?

Рекомендуемые сообщения

Сейчас реализовано что юзаешь айтем - даётся хиро, (в табличку ставится 1чка и время во сколько должно закончится)

Проверка идёт по времени т.е. 1чка в табличке остается, но если время уже наступило - не действует.

 

Но проблема в том, что снимается хиро только после релога (при учёте что время еще не кончилось), есть ли какой-то способ решения данной проблемы?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У вас есть исходы или код закрытый у вашей сборки?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У вас есть исходы или код закрытый у вашей сборки?

Конечно есть исходы) 1) итем 2) сам псхендлер

public class DonatorCustomItem implements IItemHandler
{

	public DonatorCustomItem()
	{
	//null
	}

	protected static final Logger _log = Logger.getLogger(DonatorCustomItem.class.getName());
	
	String INSERT_DATA = "REPLACE INTO characters_custom_data (obj_Id, char_name, hero, noble, donator, donator_end_date) VALUES (?,?,?,?,?,?)";

	@Override
	public void useItem(L2PlayableInstance playable, L2ItemInstance item)
	{
		if(Config.DONATOR_CUSTOM_ITEMS)
		{
			if(!(playable instanceof L2PcInstance))
				return;

			L2PcInstance activeChar = (L2PcInstance) playable;

			if(activeChar.isInOlympiadMode())
			{
				activeChar.sendMessage("This Item Cannot Be Used On Olympiad Games.");
			}

			if(activeChar.isDonator())
			{
				activeChar.sendMessage("You Are Already A Premium!.");
			}
			else
			{
                long dtime = System.currentTimeMillis() + (Config.DONATOR_CUSTOM_DAY * 1L * 1L * 60L * 1000L);
				activeChar.broadcastPacket(new SocialAction(activeChar.getObjectId(), 16));
				activeChar.setDonator(true);
                activeChar.setHero(true);
                activeChar.setDonatorEnd(dtime);
				updateDatabase(activeChar, dtime);
				activeChar.sendMessage("You Are Now a Premium user");
				activeChar.broadcastUserInfo();
				playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
				//activeChar.getInventory().addItem("Wings", 6842, 1, activeChar, null);
			}
			activeChar = null;
		}
	}

	@Override
	public int[] getItemIds()
	{
		return ITEM_IDS;
	}
	
	private void updateDatabase(L2PcInstance player, long donatorTime)
	{
		Connection con = null;
		try
		{
			if(player == null)
				return;

			con = L2DatabaseFactory.getInstance().getConnection(false);
			PreparedStatement stmt = con.prepareStatement(INSERT_DATA);

			stmt.setInt(1, player.getObjectId());
			stmt.setString(2, player.getName());
			stmt.setInt(3, player.isHero() ? 1 : 0);
			stmt.setInt(4, player.isNoble() ? 1 : 0);
			stmt.setInt(5, player.isDonator() ? 1 : 0);
			stmt.setLong(6, donatorTime);
			stmt.execute();
			stmt.close();
			stmt = null;
		}
		catch(Exception e)
		{
			if(Config.ENABLE_ALL_EXCEPTIONS)
				e.printStackTrace();
			
			_log.log(Level.SEVERE, "Error: could not update database: ", e);
		}
		finally
		{
			CloseUtil.close(con);
			
			con = null;
		}
	}

	private static final int ITEM_IDS[] =
	{
		Config.DONATOR_CUSTOM_ITEM_ID
	};

}
	 * restore all Custom Data hero/noble/donator.
	 */
	public void restoreCustomStatus()
	{
		if(Config.DEVELOPER)
		{
			_log.info("Restoring character status "+getName()+" from database...");
		}

		int hero = 0;
		int noble = 0;
		int donator = 0;
		long hero_end = 0;
		long donator_end = 0;

		Connection con = null;

		try
		{

			con = L2DatabaseFactory.getInstance().getConnection(false);
			PreparedStatement statement = con.prepareStatement(STATUS_DATA_GET);
			statement.setInt(1, getObjectId());

			ResultSet rset = statement.executeQuery();

			while(rset.next())
			{
				hero = rset.getInt("hero");
				noble = rset.getInt("noble");
				donator = rset.getInt("donator");
				hero_end = rset.getLong("hero_end_date");
				donator_end = rset.getLong("donator_end_date");
				setDonatorEnd(donator_end);
			}
			rset.close();
			statement.close();
			statement = null;
			rset = null;

			
		}
		catch(Exception e)
		{
			if(Config.ENABLE_ALL_EXCEPTIONS)
				e.printStackTrace();
			
			_log.warning("Error: could not restore char custom data info: " + e);
		}
		finally
		{
			CloseUtil.close(con);
		}

		if(hero > 0 && (hero_end == 0 || hero_end > System.currentTimeMillis()))
		{
			setIsHero(true);
		}else{
			//delete wings of destiny
			destroyItem("HeroEnd", 6842, 1, null, false);
		}
		if(donator > 0 && (donator_end == 0 || donator_end > System.currentTimeMillis()))
		{
			setDonator(true);
		}else{
			setIsHero(false);
		}


		if(noble > 0)
		{
			setNoble(true);
		}
	}

Изменено пользователем Abstragetic

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно всё.

Было бы желание и исходный код.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

при заходе на сервер запускаем таск с интервалом "время окончания" - "текущее время", в котором забираем хиров, вы лыже это примерно так:
 

long endTime = player.getDonatorEnd(); // или считываем с базы или другой переменной
if(System.currentTimeMillis() < endTime)
{
    final L2PcInstance pc = player;
    ThreadPoolManager.getInstance().scheduleGeneral(() -> {
       pc.getOlympiadController().takeHero();
    }, endTime - System.currentTimeMillis());
}

П.С. Скрипт всего лишь прототип, писался на скорую руку. Необходимо подправить, по хорошему заканчивать таск при выходе из сервера и тд.

Изменено пользователем Mifesto
  • Upvote 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно всё.

Было бы желание и исходный код.

Ну так, я тут помощи вроде прошу, а не философского совета)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

при заходе на сервер запускаем таск с интервалом "время окончания" - "текущее время", в котором забираем хиров, вы лыже это примерно так:

 

long endTime = player.getHeroEndTime(); // или считываем с базы или другой переменной
final L2PcInstance pc = player;
ThreadPoolManager.getInstance().scheduleGeneral(() -> {
   pc.getOlympiadController().takeHero();
}, endTime - System.currentTimeMillis());

П.С. Скрипт всего лишь прототип, писался на скорую руку. Необходимо подправить, по хорошему заканчивать таск при выходе из сервера и тд.

Так, а если ситуация, что поюзал итем - стал хиро, но стал не на Нное количество дней, а на час - данное решение разве поможет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так, а если ситуация, что поюзал итем - стал хиро, но стал не на Нное количество дней, а на час - данное решение разве поможет?

@Override
public void useItem(L2PlayableInstance playable, L2ItemInstance item)
{
if(Config.DONATOR_CUSTOM_ITEMS)
{
if(!(playable instanceof L2PcInstance))
return;


L2PcInstance activeChar = (L2PcInstance) playable;


if(activeChar.isInOlympiadMode())
{
activeChar.sendMessage("This Item Cannot Be Used On Olympiad Games.");
}


if(activeChar.isDonator())
{
activeChar.sendMessage("You Are Already A Premium!.");
}
else
{
                long dtime = System.currentTimeMillis() + (Config.DONATOR_CUSTOM_DAY * 1L * 1L * 60L * 1000L);
activeChar.broadcastPacket(new SocialAction(activeChar.getObjectId(), 16));
activeChar.setDonator(true);
                activeChar.setHero(true);
                activeChar.setDonatorEnd(dtime);
updateDatabase(activeChar, dtime);
activeChar.sendMessage("You Are Now a Premium user");
activeChar.broadcastUserInfo();
playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
//activeChar.getInventory().addItem("Wings", 6842, 1, activeChar, null);


ThreadPoolManager.getInstance().scheduleGeneral(() -> 
{
activeChar.setHero(false);
}, dtime - System.currentTimeMillis());
}
activeChar = null;
}
}
Изменено пользователем Mifesto
  • Upvote 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

запускаем таск в 2х случаях:

 

1. При заходе на сервер.

2. При покупке.

 

И по хорошему сделать это все в L2PcInstance и создать там поле с типом Future<?> _endHeroTask, которое будем инициализировать ThreadPoolManager.getInstance().scheduleGeneral(...); при покупке\входе и прерывать если запущено при выходе из сервера.

Изменено пользователем Mifesto

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

запускаем таск в 2х случаях:

 

1. При заходе на сервер.

2. При покупке.

 

И по хорошему сделать это все в L2PcInstance и создать там поле с типом Future<?> _endHeroTask, которое будем инициализировать ThreadPoolManager.getInstance().scheduleGeneral(...); при покупке\входе и прерывать если запущено при выходе из сервера.

Спасибо, будем пробовать :)

Изменено пользователем Abstragetic

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...