diff --git a/SDK b/SDK index 65bfbda62..29211bdc8 160000 --- a/SDK +++ b/SDK @@ -1 +1 @@ -Subproject commit 65bfbda62bd8d3e7e817de8ccd3b9bbc5d084fde +Subproject commit 29211bdc8d838c2328b41e0448db71a1b7cd26a6 diff --git a/Server/Components/Pawn/Manager/Manager.cpp b/Server/Components/Pawn/Manager/Manager.cpp index a520bfada..78d0294e1 100644 --- a/Server/Components/Pawn/Manager/Manager.cpp +++ b/Server/Components/Pawn/Manager/Manager.cpp @@ -460,6 +460,13 @@ void PawnManager::openAMX(PawnScript& script, bool isEntryScript, bool restartin script.Register("IsRepeatingTimer", &utils::pawn_IsRepeatingTimer); script.Register("GetTimerRemaining", &utils::pawn_GetTimerRemaining); script.Register("GetTimerInterval", &utils::pawn_GetTimerInterval); + script.Register("SetTimerInterval", &utils::pawn_SetTimerInterval); + script.Register("PauseTimer", &utils::pawn_PauseTimer); + script.Register("ContinueTimer", &utils::pawn_ContinueTimer); + script.Register("IsTimerPaused", &utils::pawn_IsTimerPaused); + script.Register("KillAllTimers", &utils::pawn_KillAllTimers); + script.Register("IsTimerRunning", &utils::pawn_IsTimerRunning); + script.Register("GetRunningTimersCount", &utils::pawn_GetRunningTimersCount); script.Register("SetModeRestartTime", &utils::pawn_SetModeRestartTime); script.Register("GetModeRestartTime", &utils::pawn_GetModeRestartTime); diff --git a/Server/Components/Pawn/utils.hpp b/Server/Components/Pawn/utils.hpp index 2a4a7d821..b1d944950 100644 --- a/Server/Components/Pawn/utils.hpp +++ b/Server/Components/Pawn/utils.hpp @@ -15,6 +15,7 @@ #include "format.hpp" #include "timers.hpp" +#include "../Timers/timer.hpp" extern "C" { @@ -235,12 +236,103 @@ inline cell AMX_NATIVE_CALL pawn_GetTimerInterval(AMX* amx, cell const* params) return timer->interval().count(); } +inline cell AMX_NATIVE_CALL pawn_SetTimerInterval(AMX* amx, cell const* params) +{ + AMX_MIN_PARAMETERS("SetTimerInterval", params, 2); + ITimer* timer = PawnTimerImpl::Get()->getTimer(params[1]); + if (timer == nullptr || !timer->running()) + { + return false; + } + + int interval = static_cast(params[2]); + + if(interval < 1) + { + return false; + } + + timer->setInterval(static_cast(interval)); + return true; +} + +inline cell AMX_NATIVE_CALL pawn_KillAllTimers(AMX* amx, cell const* params) +{ + AMX_MIN_PARAMETERS("KillAllTimers", params, 0); + ITimersComponent* timers = PawnManager::Get()->timers; + for (int timerid = 0; timerid < timers->count(); timerid++) + { + ITimer* timer = PawnTimerImpl::Get()->getTimer(timerid); + if (timer == nullptr || !timer->running()) + { + return false; + } + timer->kill(); + } + return true; +} + +inline cell AMX_NATIVE_CALL pawn_IsTimerRunning(AMX* amx, cell const* params) +{ + GET_TIMER(timer, "IsTimerRunning", false) + return timer->running(); +} + inline cell AMX_NATIVE_CALL pawn_IsRepeatingTimer(AMX* amx, cell const* params) { GET_TIMER(timer, "IsRepeatingTimer", false) return timer->calls() == 0; } +inline cell AMX_NATIVE_CALL pawn_GetRunningTimersCount(AMX* amx, cell const* params) +{ + AMX_MIN_PARAMETERS("GetRunningTimersCount", params, 0); + return PawnManager::Get()->timers->count(); +} + +inline cell AMX_NATIVE_CALL pawn_IsTimerPaused(AMX* amx, cell const* params) +{ + AMX_MIN_PARAMETERS("IsTimerPaused", params, 1); + ITimer* timer = PawnTimerImpl::Get()->getTimer(params[1]); + if (timer == nullptr || !timer->running()) + { + return false; + } + + if (!timer->paused()) + { + return false; + } + + return true; +} + +inline cell AMX_NATIVE_CALL pawn_PauseTimer(AMX* amx, cell const* params) +{ + AMX_MIN_PARAMETERS("PauseTimer", params, 1); + ITimer* timer = PawnTimerImpl::Get()->getTimer(params[1]); + if (timer == nullptr || !timer->running()) + { + return false; + } + + timer->togglePause(true); + return true; +} + +inline cell AMX_NATIVE_CALL pawn_ContinueTimer(AMX* amx, cell const* params) +{ + AMX_MIN_PARAMETERS("ContinueTimer", params, 1); + ITimer* timer = PawnTimerImpl::Get()->getTimer(params[1]); + if (timer == nullptr || !timer->running()) + { + return false; + } + + timer->togglePause(false); + return true; +} + inline cell AMX_NATIVE_CALL pawn_SetModeRestartTime(AMX* amx, cell const* params) { AMX_CHECK_PARAMETERS("SetModeRestartTime", params, 1); diff --git a/Server/Components/Timers/timer.hpp b/Server/Components/Timers/timer.hpp index 1b76c8c8f..98ad03a8b 100644 --- a/Server/Components/Timers/timer.hpp +++ b/Server/Components/Timers/timer.hpp @@ -12,9 +12,11 @@ class Timer final : public ITimer { private: bool running_; + bool paused_; unsigned int count_; - const Milliseconds interval_; + Milliseconds interval_; TimePoint timeout_; + TimePoint pausedTime_; TimerTimeOutHandler* const handler_; public: @@ -28,6 +30,27 @@ class Timer final : public ITimer timeout_ = timeout; } + TimePoint getPausedTime() const + { + return pausedTime_; + } + + void togglePause(bool paused) override + { + paused_ = paused; + + if (paused) + { + pausedTime_ = Time::now(); + } + else + { + TimePoint now = Time::now(); + Milliseconds pauseDuration = duration_cast(now - pausedTime_); + timeout_ += pauseDuration; + } + } + Timer(TimerTimeOutHandler* handler, Milliseconds initial, Milliseconds interval, unsigned int count) : running_(true) , count_(count) @@ -42,6 +65,11 @@ class Timer final : public ITimer return running_; } + bool paused() const override + { + return paused_; + } + Milliseconds remaining() const override { return duration_cast(timeout_ - Time::now()); @@ -57,6 +85,12 @@ class Timer final : public ITimer return interval_; } + void setInterval(Milliseconds interval) override + { + interval_ = interval; + timeout_ = Time::now() + interval_; + } + TimerTimeOutHandler* handler() const override { return handler_; diff --git a/Server/Components/Timers/timers_main.cpp b/Server/Components/Timers/timers_main.cpp index c45d0878f..ad3556d46 100644 --- a/Server/Components/Timers/timers_main.cpp +++ b/Server/Components/Timers/timers_main.cpp @@ -73,6 +73,12 @@ class TimersComponent final : public ITimersComponent, public CoreEventHandler } else { + if (timer->paused()) + { + ++it; + continue; + } + const TimePoint now = Time::now(); const Milliseconds diff = duration_cast(now - timer->getTimeout()); if (diff.count() >= 0)