mirror of
https://github.com/Jous99/F4MP.git
synced 2026-01-13 00:00:54 +01:00
153 lines
4.8 KiB
C++
153 lines
4.8 KiB
C++
|
|
#include <Services/CalendarService.h>
|
||
|
|
|
||
|
|
#include <GameServer.h>
|
||
|
|
#include <World.h>
|
||
|
|
|
||
|
|
#include <Events/PlayerJoinEvent.h>
|
||
|
|
#include <Events/UpdateEvent.h>
|
||
|
|
|
||
|
|
#include <Messages/ServerTimeSettings.h>
|
||
|
|
|
||
|
|
#include "Game/Player.h"
|
||
|
|
|
||
|
|
CalendarService::CalendarService(World& aWorld, entt::dispatcher& aDispatcher)
|
||
|
|
: m_world(aWorld)
|
||
|
|
{
|
||
|
|
m_updateConnection = aDispatcher.sink<UpdateEvent>().connect<&CalendarService::OnUpdate>(this);
|
||
|
|
m_joinConnection = aDispatcher.sink<PlayerJoinEvent>().connect<&CalendarService::OnPlayerJoin>(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CalendarService::OnUpdate(const UpdateEvent&) noexcept
|
||
|
|
{
|
||
|
|
if (!m_lastTick)
|
||
|
|
m_lastTick = GameServer::Get()->GetTick();
|
||
|
|
|
||
|
|
auto now = GameServer::Get()->GetTick();
|
||
|
|
|
||
|
|
// client got ahead, we wait
|
||
|
|
if (now < m_lastTick)
|
||
|
|
return;
|
||
|
|
|
||
|
|
auto delta = now - m_lastTick;
|
||
|
|
m_lastTick = now;
|
||
|
|
m_dateTime.Update(delta);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CalendarService::OnPlayerJoin(const PlayerJoinEvent& acEvent) noexcept
|
||
|
|
{
|
||
|
|
ServerTimeSettings timeMsg;
|
||
|
|
// the player with the furthest date is used
|
||
|
|
bool playerHasFurthestTime = acEvent.PlayerTime.GetTimeInDays() > m_dateTime.GetTimeInDays();
|
||
|
|
|
||
|
|
if (playerHasFurthestTime)
|
||
|
|
{
|
||
|
|
// Note that this doesn't set timescale because the server config should set that.
|
||
|
|
if (!m_timeSetFromFirstPlayer)
|
||
|
|
{
|
||
|
|
m_dateTime.m_timeModel.Time = acEvent.PlayerTime.m_timeModel.Time;
|
||
|
|
m_timeSetFromFirstPlayer = true;
|
||
|
|
}
|
||
|
|
m_dateTime.m_timeModel.Day = acEvent.PlayerTime.m_timeModel.Day;
|
||
|
|
m_dateTime.m_timeModel.Month = acEvent.PlayerTime.m_timeModel.Month;
|
||
|
|
m_dateTime.m_timeModel.Year = acEvent.PlayerTime.m_timeModel.Year;
|
||
|
|
}
|
||
|
|
timeMsg.timeModel.TimeScale = m_dateTime.m_timeModel.TimeScale;
|
||
|
|
timeMsg.timeModel.Time = m_dateTime.m_timeModel.Time;
|
||
|
|
timeMsg.timeModel.Day = m_dateTime.m_timeModel.Day;
|
||
|
|
timeMsg.timeModel.Month = m_dateTime.m_timeModel.Month;
|
||
|
|
timeMsg.timeModel.Year = m_dateTime.m_timeModel.Year;
|
||
|
|
|
||
|
|
if (playerHasFurthestTime)
|
||
|
|
GameServer::Get()->SendToPlayers(timeMsg);
|
||
|
|
else
|
||
|
|
acEvent.pPlayer->Send(timeMsg);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool CalendarService::SetTime(int aHours, int aMinutes, float aScale) noexcept
|
||
|
|
{
|
||
|
|
m_dateTime.m_timeModel.TimeScale = aScale;
|
||
|
|
|
||
|
|
if (aHours >= 0 && aHours <= 23 && aMinutes >= 0 && aMinutes <= 59)
|
||
|
|
{
|
||
|
|
// encode time as skyrim time
|
||
|
|
auto minutes = static_cast<float>(aMinutes) * 0.17f;
|
||
|
|
minutes = floor(minutes * 100) / 1000;
|
||
|
|
m_dateTime.m_timeModel.Time = static_cast<float>(aHours) + minutes;
|
||
|
|
|
||
|
|
SendTimeResync();
|
||
|
|
|
||
|
|
GameServer::Get()->GetWorld().GetScriptService().HandleSetTime(aHours, aMinutes, aScale);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool CalendarService::SetDate(int aDay, int aMonth, float aYear) noexcept
|
||
|
|
{
|
||
|
|
if (aMonth >= 0 && aMonth < 12 && aYear >= 0 && aYear <= 999)
|
||
|
|
{
|
||
|
|
auto maxDays = m_dateTime.GetNumberOfDaysByMonthIndex(aMonth);
|
||
|
|
if (aDay >= 0 && aDay < maxDays)
|
||
|
|
{
|
||
|
|
m_dateTime.m_timeModel.Day = aDay;
|
||
|
|
m_dateTime.m_timeModel.Month = aMonth;
|
||
|
|
m_dateTime.m_timeModel.Year = aYear;
|
||
|
|
SendTimeResync();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CalendarService::SendTimeResync() noexcept
|
||
|
|
{
|
||
|
|
ServerTimeSettings timeMsg;
|
||
|
|
timeMsg.timeModel.TimeScale = m_dateTime.m_timeModel.TimeScale;
|
||
|
|
timeMsg.timeModel.Time = m_dateTime.m_timeModel.Time;
|
||
|
|
timeMsg.timeModel.Day = m_dateTime.m_timeModel.Day;
|
||
|
|
timeMsg.timeModel.Month = m_dateTime.m_timeModel.Month;
|
||
|
|
timeMsg.timeModel.Year = m_dateTime.m_timeModel.Year;
|
||
|
|
GameServer::Get()->SendToLoaded(timeMsg);
|
||
|
|
}
|
||
|
|
|
||
|
|
CalendarService::TTime CalendarService::GetTime() const noexcept
|
||
|
|
{
|
||
|
|
const auto hour = floor(m_dateTime.m_timeModel.Time);
|
||
|
|
const auto minutes = (m_dateTime.m_timeModel.Time - hour) / 17.f;
|
||
|
|
|
||
|
|
const auto flatMinutes = static_cast<int>(ceil((minutes * 100.f) * 10.f));
|
||
|
|
return {static_cast<int>(hour), flatMinutes};
|
||
|
|
}
|
||
|
|
|
||
|
|
CalendarService::TTime CalendarService::GetRealTime() noexcept
|
||
|
|
{
|
||
|
|
const auto t = std::time(nullptr);
|
||
|
|
int h = (t / 3600) % 24;
|
||
|
|
int m = (t / 60) % 60;
|
||
|
|
return {h, m};
|
||
|
|
}
|
||
|
|
|
||
|
|
CalendarService::TDate CalendarService::GetDate() const noexcept
|
||
|
|
{
|
||
|
|
return {m_dateTime.m_timeModel.Day, m_dateTime.m_timeModel.Month, m_dateTime.m_timeModel.Year};
|
||
|
|
}
|
||
|
|
|
||
|
|
bool CalendarService::SetTimeScale(float aScale) noexcept
|
||
|
|
{
|
||
|
|
if (aScale >= 0.f && aScale <= 1000.f)
|
||
|
|
{
|
||
|
|
m_dateTime.m_timeModel.TimeScale = aScale;
|
||
|
|
|
||
|
|
ServerTimeSettings timeMsg;
|
||
|
|
timeMsg.timeModel.TimeScale = m_dateTime.m_timeModel.TimeScale;
|
||
|
|
timeMsg.timeModel.Time = m_dateTime.m_timeModel.Time;
|
||
|
|
timeMsg.timeModel.Day = m_dateTime.m_timeModel.Day;
|
||
|
|
timeMsg.timeModel.Month = m_dateTime.m_timeModel.Month;
|
||
|
|
timeMsg.timeModel.Year = m_dateTime.m_timeModel.Year;
|
||
|
|
GameServer::Get()->SendToPlayers(timeMsg);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|