diff --git a/include/aoclient.h b/include/aoclient.h index d5175f7..2a549d5 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -64,6 +64,7 @@ class AOClient : public QObject { {"BGLOCK", 1ULL << 2}, {"MODIFY_USERS", 1ULL << 3}, {"CM", 1ULL << 4}, + {"GLOBAL_TIMER", 1ULL << 5}, {"SUPER", ~0ULL} }; @@ -198,11 +199,13 @@ class AOClient : public QObject { void cmdRollP(int argc, QStringList argv); void cmdDoc(int argc, QStringList argv); void cmdClearDoc(int argc, QStringList argv); + void cmdTimer(int argc, QStringList argv); // Messaging/Client void cmdPos(int argc, QStringList argv); void cmdG(int argc, QStringList argv); // Command helper functions + QString getAreaTimer(int area_idx, QTimer* timer); QStringList buildAreaList(int area_idx); int genRand(int min, int max); void diceThrower(int argc, QStringList argv, RollType Type); @@ -249,6 +252,7 @@ class AOClient : public QObject { {"lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}}, {"spectatable", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}}, {"unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}}, + {"timer", {ACLFlags.value("CM"), 0, &AOClient::cmdTimer}}, }; QString partial_packet; diff --git a/include/area_data.h b/include/area_data.h index 13d30d7..1697ec6 100644 --- a/include/area_data.h +++ b/include/area_data.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include class Logger; class AreaData { @@ -35,7 +37,7 @@ class AreaData { QString description; QString image; }; - + QList timers; QString name; int index; QMap characters_taken; diff --git a/include/server.h b/include/server.h index 1aca99f..ae7db9c 100644 --- a/include/server.h +++ b/include/server.h @@ -32,6 +32,7 @@ #include #include #include +#include class AOClient; class DBManager; @@ -64,6 +65,8 @@ class Server : public QObject { DBManager* db_manager; QString server_name; + QTimer* timer; + signals: public slots: diff --git a/src/aoclient.cpp b/src/aoclient.cpp index 344eebf..7d3a90c 100644 --- a/src/aoclient.cpp +++ b/src/aoclient.cpp @@ -130,6 +130,16 @@ void AOClient::changeArea(int new_area) server->areas[current_area]->characters_taken[current_char] = true; server->updateCharsTaken(server->areas[current_area]); } + for (QTimer* timer : server->areas[current_area]->timers) { + int timer_id = server->areas[current_area]->timers.indexOf(timer) + 1; + if (timer->isActive()) { + sendPacket("TI", {QString::number(timer_id), QString::number(2)}); + sendPacket("TI", {QString::number(timer_id), QString::number(0), QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(timer->remainingTime())))}); + } + else { + sendPacket("TI", {QString::number(timer_id), QString::number(3)}); + } + } sendServerMessage("You moved to area " + server->area_names[current_area]); if (server->areas[current_area]->locked == AreaData::LockStatus::SPECTATABLE) sendServerMessage("Area " + server->area_names[current_area] + " is spectate-only; to chat IC you will need to be invited by the CM."); diff --git a/src/area_data.cpp b/src/area_data.cpp index a444c0a..a2d9373 100644 --- a/src/area_data.cpp +++ b/src/area_data.cpp @@ -43,4 +43,12 @@ AreaData::AreaData(QStringList characters, QString p_name, int p_index) if (log_size == 0) log_size = 500; logger = new Logger(log_size, this); + QTimer* timer1 = new QTimer(); + timers.append(timer1); + QTimer* timer2 = new QTimer(); + timers.append(timer2); + QTimer* timer3 = new QTimer(); + timers.append(timer3); + QTimer* timer4 = new QTimer(); + timers.append(timer4); } diff --git a/src/commands.cpp b/src/commands.cpp index 253c94c..6abee2f 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -554,6 +554,88 @@ void AOClient::cmdUnLock(int argc, QStringList argv) arup(ARUPType::LOCKED, true); } +void AOClient::cmdTimer(int argc, QStringList argv) +{ + AreaData* area = server->areas[current_area]; + + if (argc == 0) { + QStringList timers; + timers.append("Currently active timers:"); + QTimer* global_timer = server->timer; + if (global_timer->isActive()) { + QTime current_time = QTime(0,0).addMSecs(global_timer->remainingTime()); + timers.append("Global timer is at " + current_time.toString("hh:mm:ss.zzz")); + } + for (QTimer* timer : area->timers) { + timers.append(getAreaTimer(area->index, timer)); + } + sendServerMessage(timers.join("\n")); + return; + } + bool ok; + int timer_id = argv[0].toInt(&ok); + if (!ok || timer_id < 0 || timer_id > 4) { + sendServerMessage("Invalid timer ID. Timer ID must be a whole number between 0 and 4."); + return; + } + + if (argc == 1) { + if (timer_id == 0) { + QTimer* global_timer = server->timer; + if (global_timer->isActive()) { + QTime current_time = QTime(0, 0, 0, global_timer->remainingTime()); + sendServerMessage("Global timer is at " + current_time.toString("hh:mm:ss.zzz")); + return; + } + } + else { + QTimer* timer = area->timers[timer_id - 1]; + sendServerMessage(getAreaTimer(area->index, timer)); + return; + } + } + + QTimer* requested_timer; + if (timer_id == 0) { + if (!checkAuth(ACLFlags.value("GLOBAL_TIMER"))) { + sendServerMessage("You are not authorized to alter the global timer."); + return; + } + requested_timer = server->timer; + } + else + requested_timer = area->timers[timer_id - 1]; + QTime requested_time = QTime::fromString(argv[1], "hh:mm:ss"); + if (requested_time.isValid()) { + requested_timer->setInterval(QTime(0,0).msecsTo(requested_time)); + requested_timer->start(); + sendServerMessage("Set timer " + QString::number(timer_id) + " to " + argv[1] + "."); + sendPacket("TI", {QString::number(timer_id), QString::number(2)}); + sendPacket("TI", {QString::number(timer_id), QString::number(0), QString::number(QTime(0,0).msecsTo(requested_time))}); + return; + } + else { + if (argv[1] == "start") { + requested_timer->start(); + sendServerMessage("Started timer " + QString::number(timer_id) + "."); + sendPacket("TI", {QString::number(timer_id), QString::number(2)}); + sendPacket("TI", {QString::number(timer_id), QString::number(0), QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(requested_timer->remainingTime())))}); + } + else if (argv[1] == "pause" || argv[1] == "stop") { + requested_timer->setInterval(requested_timer->remainingTime()); + requested_timer->stop(); + sendServerMessage("Stopped timer " + QString::number(timer_id) + "."); + sendPacket("TI", {QString::number(timer_id), QString::number(1), QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(requested_timer->interval())))}); + } + else if (argv[1] == "hide" || argv[1] == "unset") { + requested_timer->setInterval(0); + requested_timer->stop(); + sendServerMessage("Hid timer " + QString::number(timer_id) + "."); + sendPacket("TI", {QString::number(timer_id), QString::number(3)}); + } + } +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; @@ -657,3 +739,16 @@ void AOClient::diceThrower(int argc, QStringList argv, RollType type) default : break; } } + +QString AOClient::getAreaTimer(int area_idx, QTimer* timer) +{ + AreaData* area = server->areas[area_idx]; + if (timer->isActive()) { + QTime current_time = QTime(0,0).addMSecs(timer->remainingTime()); + return "Timer " + QString::number(area->timers.indexOf(timer) + 1) + " is at " + current_time.toString("hh:mm:ss.zzz"); + } + else { + return "Timer " + QString::number(area->timers.indexOf(timer) + 1) + " is inactive."; + } +} + diff --git a/src/packets.cpp b/src/packets.cpp index 3bc7f30..619849d 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -143,6 +143,23 @@ void AOClient::pktSelectChar(AreaData* area, int argc, QStringList argv, AOPacke server->updateCharsTaken(area); sendPacket("PV", {QString::number(id), "CID", argv[1]}); fullArup(); + if (server->timer->isActive()) { + sendPacket("TI", {QString::number(0), QString::number(2)}); + sendPacket("TI", {QString::number(0), QString::number(0), QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(server->timer->remainingTime())))}); + } + else { + sendPacket("TI", {QString::number(0), QString::number(3)}); + } + for (QTimer* timer : area->timers) { + int timer_id = area->timers.indexOf(timer) + 1; + if (timer->isActive()) { + sendPacket("TI", {QString::number(timer_id), QString::number(2)}); + sendPacket("TI", {QString::number(timer_id), QString::number(0), QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(timer->remainingTime())))}); + } + else { + sendPacket("TI", {QString::number(timer_id), QString::number(3)}); + } + } } void AOClient::pktIcChat(AreaData* area, int argc, QStringList argv, AOPacket packet) diff --git a/src/server.cpp b/src/server.cpp index e5d728e..b9acff4 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -24,6 +24,7 @@ Server::Server(int p_port, int p_ws_port, QObject* parent) : QObject(parent) port = p_port; ws_port = p_ws_port; + timer = new QTimer(); player_count = 0;