PDA

Просмотр полной версии : [Вопрос] Как правильно настроить таймер, чтобы команда срабатывал каждый час?



vladivanovx
11.12.2016, 17:24
Привет всем!
У меня настроен таймер, который запущен на ежесекундное обновление. В нем есть условие, при которое должно срабатывать в том случае если старое время меньше нового и минуты равны нулю, если это так должна запуститься функция PayDay(). Но он работает некорректно. В том случае если я нахожусь на сервере (не АФК), то он срабатывает, а если при этом у меня свернута игра (в АФК), то при выходи из АФК например на 30 минуте, то timestamp показывает что сработал несколько секунд назад. Как исправить эту проблему?
Вот собственно код:


new g_hour, g_minute, g_second;
new g_year, g_month, g_day;

forward SecondUpdater();

SetTimer("SecondUpdater", 1000, true);
public SecondUpdater() {
foreach(new i : Player) {
if(pInfo[i][pLoggedIn] == false) return 1;
CommonTime(i);
}
return 1;
}

stock CommonTime(playerid) {
new nhour, nminute, nsecond;
gettime(nhour, nminute, nsecond);
if((nhour > g_hour) || (nhour == 0 && g_hour == 23)) {
g_hour = nhour;
SetWorldTime(nhour);
format(string, sizeof(string), "Time %d:00 hours", nhour);
SendClientMessage(playerid, COLOR_WHITE, string);
SendClientMessage(playerid, COLOR_WHITE, "Payday run!");
}

if(nminute == 10 && nsecond == 0 || nminute == 40 && nsecond == 0) {
SendClientMessageToAll(COLOR_WHITE, "Реклама на сервере.");
}
return 1;
}


PS: Что можете сказать вообще о коде? Стоит ли делать foreach? Или хватит простого playerid?

vovandolg
12.12.2016, 00:57
Баг со временем в timestamp это баг клиента, поэтому не как.



(nhour > g_hour)
//ИМХО, это лишняя часть кода в условии
if((nhour > g_hour) || (nhour == 0 && g_hour == 23))

vladivanovx
12.12.2016, 13:48
То есть, если на сервере будет хоть один игрок то все сработает правильно?

qwezert
12.12.2016, 16:53
То есть, если на сервере будет хоть один игрок то все сработает правильно?
Независимо от кол-ва игроков - данный скрипт будет срабатывать точно по времени. Так как эти действия происходят на сервере, а не на стороне клиента, а тот баг - скорее всего просто криво показывает время после АФК(честно никогда с таким не сталкивался или просто не обращал внимания)

DeimoS
12.12.2016, 17:05
то timestamp показывает что сработал несколько секунд назад.

То бишь, тебе не нравится, что если стоять в афк в момент отправки сервером сообщения, а после выйти из афк, то сообщение приходит не тогда, когда сервер его отправил, а когда ты вышел из афк?
Если да, то всё логично. Ведь пока игрок в афк, синхронизация с ним не происходит вообще. И все сообщения "выстраиваются" в очередь, чтоб в момент, когда игрок вышел из афк, отобразить их ему.

vladivanovx
12.12.2016, 21:24
Всем спасибо, теперь все понял. Благодарю.

PS: Вот что еще, нормально ли использовать цикл (там где foreach в таймере), или добавить таймеру playerid, и убрать цикл?

DeimoS
13.12.2016, 05:04
Тогда уж проще сразу вызывать CommonTime таймером

vladivanovx
13.12.2016, 15:40
Хорошо, спасибо. Оставлю как есть, так как там еще есть несколько функций и условий.

vovandolg
13.12.2016, 20:54
Я раньше как то не понимал почему тема с индивидуальным таймером являлась оптимизатором, и только месяц назад где то логически понял что такие переборы при большом или среднем онлайне будут работать один раз и для всех сразу без пауз всяких(что есть капля лагов), а в индивидуме создаётся свой таймер со своим отсчетом и получается что у каждого игрока своё начало апдейта, тем самым сервер не впадает в эту долгую нагрузку.

Nexius_Tailer
13.12.2016, 21:25
Я раньше как то не понимал почему тема с индивидуальным таймером являлась оптимизатором, и только месяц назад где то логически понял что такие переборы при большом или среднем онлайне будут работать один раз и для всех сразу без пауз всяких(что есть капля лагов), а в индивидуме создаётся свой таймер со своим отсчетом и получается что у каждого игрока своё начало апдейта, тем самым сервер не впадает в эту долгую нагрузку.
Более того, этот вариант по эффективности, по-сути, наравне с foreach в цикле, т.к. мало того, что задержки происходят не единовременно, так ещё и только для тех, кто на сервере, вне зависимости от идов игроков (имея, к примеру, максимальный ид онлайн игрока 25, это не будет тратить время на перебор вышедших идов между 0 и максимальным).

vovandolg
13.12.2016, 22:23
Более того, этот вариант по эффективности, по-сути, наравне с foreach в цикле, т.к. мало того, что задержки происходят не единовременно, так ещё и только для тех, кто на сервере, вне зависимости от идов игроков (имея, к примеру, максимальный ид онлайн игрока 25, это не будет тратить время на перебор вышедших идов между 0 и максимальным).

Да да и да) единственный минус то что код не состыкован и ты не знаешь когда именно будет взаимодействие между глобальным и индивидуальными условиями из за того что таймеры эти запускаются в разное время, в прочем это мелочи.