diff --git a/SDK b/SDK index 3dc9cf854..72362f773 160000 --- a/SDK +++ b/SDK @@ -1 +1 @@ -Subproject commit 3dc9cf854c2a002a683baf50d5845f396c634e2c +Subproject commit 72362f77321c32b15811014b81165a38ebee9d61 diff --git a/Server/Components/Pawn/Manager/Manager.cpp b/Server/Components/Pawn/Manager/Manager.cpp index a520bfada..cdacb1eff 100644 --- a/Server/Components/Pawn/Manager/Manager.cpp +++ b/Server/Components/Pawn/Manager/Manager.cpp @@ -460,6 +460,9 @@ 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("ToggleTimerPause", &utils::pawn_ToggleTimerPause); + script.Register("IsTimerPaused", &utils::pawn_IsTimerPaused); 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..e330933b6 100644 --- a/Server/Components/Pawn/utils.hpp +++ b/Server/Components/Pawn/utils.hpp @@ -202,6 +202,36 @@ inline cell AMX_NATIVE_CALL pawn_settimerex(AMX* amx, cell const* params) return PawnTimerImpl::Get()->setTimerEx(callback, Milliseconds(params[2]), params[3], fmt, amx, ¶ms[5]); } +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_ToggleTimerPause(AMX* amx, cell const* params) +{ + AMX_MIN_PARAMETERS("ToggleTimerPause", params, 2); + ITimer* timer = PawnTimerImpl::Get()->getTimer(params[1]); + if (timer == nullptr || !timer->running()) + { + return false; + } + + timer->togglePause(params[2]); + return true; +} + #define GET_TIMER(timer, name, failRet) \ AMX_MIN_PARAMETERS(name, params, 1); \ ITimer* timer = PawnTimerImpl::Get()->getTimer(params[1]); \ @@ -235,6 +265,26 @@ 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_IsRepeatingTimer(AMX* amx, cell const* params) { GET_TIMER(timer, "IsRepeatingTimer", false) diff --git a/Server/Components/Timers/timer.hpp b/Server/Components/Timers/timer.hpp index 1b76c8c8f..5ca5bf6e9 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,8 +30,30 @@ 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) + , paused_(false) , count_(count) , interval_(interval) , timeout_(Time::now() + initial) @@ -42,6 +66,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 +86,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_; @@ -65,6 +100,7 @@ class Timer final : public ITimer void kill() override { running_ = false; + paused_ = false; } bool trigger() override 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)