Время сервера "/time" не совпадает с картой - Форум администраторов игровых серверов
Форум администраторов игровых серверов StormWall - Защита от DDos атак
Регистрация Мнения Справка Пользователи Календарь Все разделы прочитаны
Вернуться   Форум администраторов игровых серверов > MMO > Lineage II > Работа со скриптами

Работа со скриптами Помощь в редактировании и написании квестов к Java серверам, а так же эвентов.
Описание темы:Разное время на карте и при вводе команды /time

Ответ
Опции темы
Непрочитано 03.05.2017, 12:14   #1
Аватар для ntking
Пользователь

Автор темы (Топик Стартер) Время сервера "/time" не совпадает с картой

Какое-то время работы сервера эти 2 времени совпадают, потом в какой-то нехороший момент внутриигровое время, отображаемое на карте начинает разниться с временем, отображаемым командой /time. Отсюда все вытекающие: день/ночь, Закен, Хеллбонд/Шадай и т.д.
Из-за чего может разниться время и можно ли поставить какую-то патчину, которая будет синхронизировать время на карте и реальное серверное, например раз в полчаса?

В конфиге есть такая вот строчка:
Код:
# Интервал сохранения игрового времени (в секундах)
SaveGameTimeInterval = 120
Сборка Phenix/Open-Team.

P.S. Извините, если уже было и я плохо искал.
ntking вне форума Отправить сообщение для ntking с помощью ICQ Ответить с цитированием
Непрочитано 03.05.2017, 13:22   #2
Аватар для n3k0nation
Antihero

По умолчанию Re: Время сервера "/time" не совпадает с картой

Видимо в коде нет синхронизации внутригрового времени, нужно сделать что-то вроде этого:
Код:
        ...
        ThreadPoolManager.getInstance().scheduleGeneralAtFixedDelay(this::refreshClients, TimeUnit.HOURS.toMillis(1), TimeUnit.HOURS.toMillis(1));
        ...

    public void refreshClients() {
        WorldManager.getInstance().getMainWorld().getAllPlayers().stream()
            .forEach(player -> player.sendPacket(RequestTimeCheck.getInstance()));
    }
Ну и сами пакеты:
Код:
package ru.catssoftware.gameserver.network.serverpackets;

import lombok.Getter;

/**
 * @author PointerRage
 *
 */
public class RequestTimeCheck extends L2GameServerPacket {
	private final static String PINFO = "[S] RequestTimeCheckPacket (cd)";
	@Getter private final static RequestTimeCheck instance = new RequestTimeCheck();
	
	private RequestTimeCheck() {
	}

	@Override
	protected void write() throws Throwable {
		writeC(0xBB);
		writeD(0x00); //?
	}
	
	@Override
	public String getType() {
		return PINFO;
	}
}
Опкод 0x97 (в интерлюде, в других версиях смотрите сами), ингейм стейт.
Код:
package ru.catssoftware.gameserver.network.clientpackets;

import fork2.gs.time.GameTimeController;
import ru.catssoftware.gameserver.network.serverpackets.ClientSetTime;

/**
 * @author PointerRage
 *
 */
public class SendTimeCheck extends L2GameClientPacket {
	private final static String PINFO = "[C] 0x97 SendTimeCheckPacket (cdd)";
	private int clientTime;
	private int clientTimescale;
	
	@Override
	protected void read() throws Throwable {
		clientTime = readD();
		clientTimescale = readD();
	}

	@Override
	protected void execute() throws Throwable {
		if(clientTime != GameTimeController.getInstance().getGameTime() || clientTimescale != GameTimeController.getInstance().getTimescale())
			sendPacket(ClientSetTime.STATIC_PACKET);
	}
	
	@Override
	public String getType() {
		return PINFO;
	}

}
Код:
/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package ru.catssoftware.gameserver.network.serverpackets;

import fork2.gs.time.GameTimeController;

public class ClientSetTime extends L2GameServerPacket {
	private static final String _S__F2_CLIENTSETTIME = "[S] 0xEC ClientSetTime [cdd]";
	public static final ClientSetTime STATIC_PACKET = new ClientSetTime();

	private ClientSetTime() {
		
	}

	@Override
	protected final void write() {
		writeC(0xec);
		writeD(GameTimeController.getInstance().getGameTime()); // time in client minutes
		writeD(GameTimeController.getInstance().getTimescale());
	}

	@Override
	public String getType() {
		return _S__F2_CLIENTSETTIME;
	}
}
__________________
m0nster.art - clear client patches, linkz to utils & code.
Гадаю по капче.
n3k0nation вне форума Ответить с цитированием
Непрочитано 03.05.2017, 18:09   #3
Аватар для ntking
Пользователь

Автор темы (Топик Стартер) Re: Время сервера "/time" не совпадает с картой

Жаль, что я почти ничего не понял((
Мои умозаключения: При входе персонажа внутриигровое серверное время и время на карте (внутриигровое клиентское) практически идентичное, разница всего в минуту-три (внутриигровых). Но после большого времени в онлайне эти два показателя расходятся, сервер "убегает" вперед от клиента.
Т.к. при входе серверное время отсылается в клиент - это все реализовано. Я так понял, не хватает периодической синхронизации серверного и клиентского времени, например раз в 15-30мин.
Можно использовать те же пакеты отправки времени от сервера клиенту при входе персонажа, отправляя их раз скажем в 15 минут тем самым синхронизировать время? Где примерно/точно может находится код отправки данного пакета в ядре сервера?
ntking вне форума Отправить сообщение для ntking с помощью ICQ Ответить с цитированием
Непрочитано 03.05.2017, 18:25   #4
Изгнанные

По умолчанию Re: Время сервера "/time" не совпадает с картой

Цитата:
Сообщение от ntking Посмотреть сообщение
Жаль, что я почти ничего не понял((
Мои умозаключения: При входе персонажа внутриигровое серверное время и время на карте (внутриигровое клиентское) практически идентичное, разница всего в минуту-три (внутриигровых). Но после большого времени в онлайне эти два показателя расходятся, сервер "убегает" вперед от клиента.
Т.к. при входе серверное время отсылается в клиент - это все реализовано. Я так понял, не хватает периодической синхронизации серверного и клиентского времени, например раз в 15-30мин.
Можно использовать те же пакеты отправки времени от сервера клиенту при входе персонажа, отправляя их раз скажем в 15 минут тем самым синхронизировать время? Где примерно/точно может находится код отправки данного пакета в ядре сервера?


Тебе человек именно это и предоставил, все по полочкам разложив что куда и где менять.
Код:
@Override
	protected void execute() throws Throwable {
		if(clientTime != GameTimeController.getInstance().getGameTime() || clientTimescale != GameTimeController.getInstance().getTimescale())
			sendPacket(ClientSetTime.STATIC_PACKET);
	}
Вот собственно сам пакет.

А вот его отправка
Если прошло какое то время
Код:
ThreadPoolManager.getInstance().scheduleGeneralAtFixedDelay(this::refreshClients, TimeUnit.HOURS.toMillis(1), TimeUnit.HOURS.toMillis(1));
Отправляем
Код:
public void refreshClients() {
        WorldManager.getInstance().getMainWorld().getAllPlayers().stream()
            .forEach(player -> player.sendPacket(RequestTimeCheck.getInstance()));

Смотри где у тебя в сборке определяется scheduleGeneralAtFixedDelay (или что-то подобное с задержкой по времени) , и пихай туда, главное чтобы это был глобальный обработчик, а не под что-то отдельное.
defenderk1 вне форума Ответить с цитированием
Непрочитано 04.05.2017, 14:52   #5
Аватар для ntking
Пользователь

Автор темы (Топик Стартер) Re: Время сервера "/time" не совпадает с картой

Не предупредил, что с программированием у меня все туго, но решение все же мне удалось наваять (осторожно, индийский код!):
Код:
			int gameTime = GameTimeController.getInstance().getGameTime();
				int h = gameTime / 60 % 24;
				int m = gameTime % 60;
				if(m >= 3 && m <= 9)
				{
				for(L2Player player : L2ObjectsStorage.getAllPlayersForIterate())
					{
					player.sendPacket(new ClientSetTime());
					}
				}
Я нашел сервис, который с промежутком во времени проверяет себя на запущенность каждые 2 минуты ну и засунул туда свой код. Время синхронизации выставил внутриигровое, каждый час (получение часов и минут уже было в коде). В сервис пришлось импортировать:
Код:
import gameserver.model.L2Player;
import gameserver.model.L2ObjectsStorage;
import gameserver.serverpackets.ClientSetTime;
Всем спасибо за желание помочь!

Последний раз редактировалось ntking; 04.05.2017 в 16:33.
ntking вне форума Отправить сообщение для ntking с помощью ICQ Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
"Freeman`s days. Day One" - проект фан-фильма по игре "Half-life 2" Ashe Курилка / Yak floor 2 04.04.2013 15:34
Error "time synchronization poorness caused to block connection" Aleser Сервер 15 17.12.2010 17:23
"Одноразовые персы" или "Дисконнект с сервера" =( eXeSS Сервер 1 01.08.2009 16:09


© 2007–2024 «Форум администраторов игровых серверов»
Защита сайта от DDoS атак — StormWall
Работает на Булке неизвестной версии с переводом от zCarot
Текущее время: 13:35. Часовой пояс GMT +3.

Вверх