Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Remove reinterpret_casts from AG race timer script and add method and chat command to get current server uptime #1673

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
9 changes: 9 additions & 0 deletions dGame/dUtilities/SlashCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,15 @@ void SlashCommandHandler::Startup() {
};
RegisterCommand(InstanceInfoCommand);

Command ServerUptimeCommand{
.help = "Display the time the current world server has been active",
.info = "Display the time the current world server has been active",
.aliases = { "uptime" },
.handle = GMZeroCommands::ServerUptime,
.requiredLevel = eGameMasterLevel::DEVELOPER
};
RegisterCommand(ServerUptimeCommand);

//Commands that are handled by the client

Command faqCommand{
Expand Down
9 changes: 7 additions & 2 deletions dGame/dUtilities/SlashCommands/GMZeroCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,13 @@ namespace GMZeroCommands {
ChatPackets::SendSystemMessage(sysAddr, u"Map: " + (GeneralUtils::to_u16string(zoneId.GetMapID())) + u"\nClone: " + (GeneralUtils::to_u16string(zoneId.GetCloneID())) + u"\nInstance: " + (GeneralUtils::to_u16string(zoneId.GetInstanceID())));
}

// Display the server uptime
void ServerUptime(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
const auto time = Game::server->GetUptime();
const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(time).count();
ChatPackets::SendSystemMessage(sysAddr, u"Server has been up for " + GeneralUtils::to_u16string(seconds) + u" s");
}

//For client side commands
void ClientHandled(Entity* entity, const SystemAddress& sysAddr, const std::string args) {}

};

1 change: 1 addition & 0 deletions dGame/dUtilities/SlashCommands/GMZeroCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace GMZeroCommands {
void LeaveZone(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void Resurrect(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void InstanceInfo(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void ServerUptime(Entity* entity, const SystemAddress& sysAddr, const std::string args);
void ClientHandled(Entity* entity, const SystemAddress& sysAddr, const std::string args);
}

Expand Down
7 changes: 7 additions & 0 deletions dNet/dServer.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include <string>
#include <chrono>
#include <csignal>
#include "RakPeerInterface.h"
#include "ReplicaManager.h"
Expand Down Expand Up @@ -80,6 +81,11 @@ class dServer {

const ServerType GetServerType() const { return mServerType; }

[[nodiscard]]
std::chrono::steady_clock::duration GetUptime() const {
return std::chrono::steady_clock::now() - mStartTime;
}

private:
bool Startup();
void Shutdown();
Expand Down Expand Up @@ -114,4 +120,5 @@ class dServer {
SystemAddress mMasterSystemAddress;
std::string mMasterIP;
int mMasterPort;
std::chrono::steady_clock::time_point mStartTime = std::chrono::steady_clock::now();
};
106 changes: 54 additions & 52 deletions dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,104 +3,106 @@
#include "ScriptedActivityComponent.h"
#include "GameMessages.h"
#include "LeaderboardManager.h"
#include "dServer.h"
#include "eMissionTaskType.h"
#include "eMissionState.h"
#include "MissionComponent.h"
#include <ctime>
#include <chrono>

void NpcAgCourseStarter::OnStartup(Entity* self) {

}
void NpcAgCourseStarter::OnStartup(Entity* self) {}

void NpcAgCourseStarter::OnUse(Entity* self, Entity* user) {
auto* scriptedActivityComponent = self->GetComponent<ScriptedActivityComponent>();
auto* const scriptedActivityComponent = self->GetComponent<ScriptedActivityComponent>();
if (!scriptedActivityComponent) return;

if (scriptedActivityComponent == nullptr) {
return;
}
const auto selfId = self->GetObjectID();
const auto userId = user->GetObjectID();
const auto& userSysAddr = user->GetSystemAddress();

if (scriptedActivityComponent->GetActivityPlayerData(user->GetObjectID()) != nullptr) {
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"exit", 0, 0, LWOOBJID_EMPTY, "", user->GetSystemAddress());
if (scriptedActivityComponent->GetActivityPlayerData(userId) != nullptr) {
GameMessages::SendNotifyClientObject(selfId, u"exit", 0, 0, LWOOBJID_EMPTY, "", userSysAddr);
} else {
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"start", 0, 0, LWOOBJID_EMPTY, "", user->GetSystemAddress());
GameMessages::SendNotifyClientObject(selfId, u"start", 0, 0, LWOOBJID_EMPTY, "", userSysAddr);
}
}

void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) {
auto* scriptedActivityComponent = self->GetComponent<ScriptedActivityComponent>();
auto* const scriptedActivityComponent = self->GetComponent<ScriptedActivityComponent>();
if (!scriptedActivityComponent) return;

if (scriptedActivityComponent == nullptr) {
return;
}
const auto selfId = self->GetObjectID();
const auto senderId = sender->GetObjectID();
const auto& senderSysAddr = sender->GetSystemAddress();

if (identifier == u"player_dialog_cancel_course" && button == 1) {
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"stop_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress());

GameMessages::SendNotifyClientObject(self->GetObjectID(), u"cancel_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress());
GameMessages::SendNotifyClientObject(selfId, u"stop_timer", 0, 0, LWOOBJID_EMPTY, "", senderSysAddr);
GameMessages::SendNotifyClientObject(selfId, u"cancel_timer", 0, 0, LWOOBJID_EMPTY, "", senderSysAddr);

scriptedActivityComponent->RemoveActivityPlayerData(sender->GetObjectID());
scriptedActivityComponent->RemoveActivityPlayerData(senderId);

Game::entityManager->SerializeEntity(self);
} else if (identifier == u"player_dialog_start_course" && button == 1) {
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"start_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress());

GameMessages::SendActivityStart(self->GetObjectID(), sender->GetSystemAddress());

auto* data = scriptedActivityComponent->AddActivityPlayerData(sender->GetObjectID());
GameMessages::SendNotifyClientObject(selfId, u"start_timer", 0, 0, LWOOBJID_EMPTY, "", senderSysAddr);
GameMessages::SendActivityStart(selfId, senderSysAddr);

auto* const data = scriptedActivityComponent->AddActivityPlayerData(senderId);
if (data->values[1] != 0) return;

time_t startTime = std::time(0) + 4; // Offset for starting timer

data->values[1] = *reinterpret_cast<float*>(&startTime);
const auto raceStartTime = Game::server->GetUptime() + std::chrono::seconds(4); // Offset for starting timer
const auto fRaceStartTime = std::chrono::duration<float, std::ratio<1>>(raceStartTime).count();
data->values[1] = fRaceStartTime;

Game::entityManager->SerializeEntity(self);
} else if (identifier == u"FootRaceCancel") {
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"stop_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress());
GameMessages::SendNotifyClientObject(selfId, u"stop_timer", 0, 0, LWOOBJID_EMPTY, "", senderSysAddr);

if (scriptedActivityComponent->GetActivityPlayerData(sender->GetObjectID()) != nullptr) {
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"exit", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress());
if (scriptedActivityComponent->GetActivityPlayerData(senderId) != nullptr) {
GameMessages::SendNotifyClientObject(selfId, u"exit", 0, 0, LWOOBJID_EMPTY, "", senderSysAddr);
} else {
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"start", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress());
GameMessages::SendNotifyClientObject(selfId, u"start", 0, 0, LWOOBJID_EMPTY, "", senderSysAddr);
}

scriptedActivityComponent->RemoveActivityPlayerData(sender->GetObjectID());
scriptedActivityComponent->RemoveActivityPlayerData(senderId);
}
}

void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
auto* scriptedActivityComponent = self->GetComponent<ScriptedActivityComponent>();
if (scriptedActivityComponent == nullptr) return;
auto* const scriptedActivityComponent = self->GetComponent<ScriptedActivityComponent>();
if (!scriptedActivityComponent) return;

auto* data = scriptedActivityComponent->GetActivityPlayerData(sender->GetObjectID());
if (data == nullptr) return;
const auto selfId = self->GetObjectID();
const auto senderId = sender->GetObjectID();
const auto& senderSysAddr = sender->GetSystemAddress();

auto* const data = scriptedActivityComponent->GetActivityPlayerData(senderId);
if (!data) return;

if (args == "course_cancel") {
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"cancel_timer", 0, 0,
LWOOBJID_EMPTY, "", sender->GetSystemAddress());
scriptedActivityComponent->RemoveActivityPlayerData(sender->GetObjectID());
GameMessages::SendNotifyClientObject(selfId, u"cancel_timer", 0, 0,
LWOOBJID_EMPTY, "", senderSysAddr);
scriptedActivityComponent->RemoveActivityPlayerData(senderId);
} else if (args == "course_finish") {
time_t endTime = std::time(0);
time_t finish = (endTime - *reinterpret_cast<time_t*>(&data->values[1]));

data->values[2] = *reinterpret_cast<float*>(&finish);
const auto raceEndTime = Game::server->GetUptime();
const auto fRaceEndTime = std::chrono::duration<float, std::ratio<1>>(raceEndTime).count();
const auto raceTimeElapsed = fRaceEndTime - data->values[1];
data->values[2] = raceTimeElapsed;

auto* missionComponent = sender->GetComponent<MissionComponent>();
auto* const missionComponent = sender->GetComponent<MissionComponent>();
if (missionComponent != nullptr) {
missionComponent->ForceProgressTaskType(1884, 1, 1, false);
missionComponent->Progress(eMissionTaskType::PERFORM_ACTIVITY, -finish, self->GetObjectID(),
missionComponent->Progress(eMissionTaskType::PERFORM_ACTIVITY, -raceTimeElapsed, selfId,
"performact_time");
}

Game::entityManager->SerializeEntity(self);
LeaderboardManager::SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), static_cast<float>(finish));
LeaderboardManager::SaveScore(senderId, scriptedActivityComponent->GetActivityID(), raceTimeElapsed);

GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard",
scriptedActivityComponent->GetActivityID(), 0, sender->GetObjectID(),
"", sender->GetSystemAddress());
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"stop_timer", 1, finish, LWOOBJID_EMPTY, "",
sender->GetSystemAddress());
GameMessages::SendNotifyClientObject(selfId, u"ToggleLeaderBoard",
scriptedActivityComponent->GetActivityID(), 0, senderId,
"", senderSysAddr);
GameMessages::SendNotifyClientObject(selfId, u"stop_timer", 1, raceTimeElapsed, LWOOBJID_EMPTY, "",
senderSysAddr);

scriptedActivityComponent->RemoveActivityPlayerData(sender->GetObjectID());
scriptedActivityComponent->RemoveActivityPlayerData(senderId);
}
}
1 change: 1 addition & 0 deletions docs/Commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
|setannmsg|`/setannmsg <title>`|Sets the message of an announcement.|8|
|setanntitle|`/setanntitle <title>`|Sets the title of an announcement.|8|
|shutdownuniverse|`/shutdownuniverse`|Sends a shutdown message to the master server. This will send an announcement to all players that the universe will shut down in 10 minutes.|9|
|uptime|`/uptime`|Displays the time the current world server has been active.|8|

## Development Commands

Expand Down
Loading