From fd8654de978bd48a95ebf78e0191721df6869660 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 28 Feb 2021 09:59:37 -0600 Subject: [PATCH] add area locking --- include/aoclient.h | 11 +++++++-- src/aoclient.cpp | 16 ++++++++++++- src/commands.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++ src/packets.cpp | 4 ++++ 4 files changed, 85 insertions(+), 3 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 7225c99..55b331f 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -171,6 +171,9 @@ class AOClient : public QObject { void cmdUnCM(int argc, QStringList argv); void cmdInvite(int argc, QStringList argv); void cmdUnInvite(int argc, QStringList argv); + void cmdLock(int argc, QStringList argv); + void cmdSpectatable(int argc, QStringList argv); + void cmdUnLock(int argc, QStringList argv); void cmdGetAreas(int argc, QStringList argv); void cmdGetArea(int argc, QStringList argv); void cmdSetBackground(int argc, QStringList argv); @@ -227,8 +230,12 @@ class AOClient : public QObject { {"cleardoc", {ACLFlags.value("NONE"), 0, &AOClient::cmdClearDoc}}, {"cm", {ACLFlags.value("NONE"), 0, &AOClient::cmdCM}}, {"uncm", {ACLFlags.value("NONE"), 0, &AOClient::cmdUnCM}}, - {"invite", {ACLFlags.value("NONE"), 0, &AOClient::cmdInvite}}, - {"uninvite", {ACLFlags.value("NONE"), 0, &AOClient::cmdUnInvite}} + {"invite", {ACLFlags.value("NONE"), 1, &AOClient::cmdInvite}}, + {"uninvite", {ACLFlags.value("NONE"), 1, &AOClient::cmdUnInvite}}, + {"lock", {ACLFlags.value("NONE"), 0, &AOClient::cmdLock}}, + {"spectatable", {ACLFlags.value("NONE"), 0, &AOClient::cmdSpectatable}}, + {"unlock", {ACLFlags.value("NONE"), 0, &AOClient::cmdUnLock}}, + }; QString partial_packet; diff --git a/src/aoclient.cpp b/src/aoclient.cpp index a4f4da9..c0d8e99 100644 --- a/src/aoclient.cpp +++ b/src/aoclient.cpp @@ -173,7 +173,21 @@ void AOClient::arup(ARUPType type, bool broadcast) } } else if (type == ARUPType::LOCKED) { - arup_data.append(area->locked ? "LOCKED" : "FREE"); + QString lock_status; + switch (area->locked) { + case FREE: + lock_status = "FREE"; + break; + case LOCKED: + lock_status = "LOCKED"; + break; + case SPECTATABLE: + lock_status = "SPECTATABLE"; + break; + default: + break; + } + arup_data.append(lock_status); } else return; } diff --git a/src/commands.cpp b/src/commands.cpp index d4f7cd0..43b3cda 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -454,6 +454,8 @@ void AOClient::cmdUnCM(int argc, QStringList argv) sendServerMessage("You are no longer CM in this area."); arup(ARUPType::CM, true); } + if (area->owners.isEmpty()) + area->invited.clear(); } void AOClient::cmdInvite(int argc, QStringList argv) { @@ -499,6 +501,61 @@ void AOClient::cmdUnInvite(int argc, QStringList argv) area->invited.removeAll(uninvited_id); sendServerMessage("You uninvited ID " + argv[0]); } +void AOClient::cmdLock(int argc, QStringList argv) +{ + AreaData* area = server->areas[current_area]; + if (!area->owners.contains(id)) { + sendServerMessage("You are not a CM in this area."); + return; + } + else if (area->locked == LOCKED) { + sendServerMessage("This area is already locked."); + return; + } + sendServerMessage("This area is now locked."); + area->locked = LOCKED; + for (AOClient* client : server->clients) { + if (client->current_area == current_area && client->joined) { + area->invited.append(client->id); + } + } + arup(ARUPType::LOCKED, true); +} +void AOClient::cmdSpectatable(int argc, QStringList argv) +{ + AreaData* area = server->areas[current_area]; + if (!area->owners.contains(id)) { + sendServerMessage("You are not a CM in this area."); + return; + } + else if (area->locked == SPECTATABLE) { + sendServerMessage("This area is already in spectate mode."); + return; + } + sendServerMessage("This area is now spectatable."); + area->locked = SPECTATABLE; + for (AOClient* client : server->clients) { + if (client->current_area == current_area && client->joined) { + area->invited.append(client->id); + } + } + arup(ARUPType::LOCKED, true); +} +void AOClient::cmdUnLock(int argc, QStringList argv) +{ + AreaData* area = server->areas[current_area]; + if (!area->owners.contains(id)) { + sendServerMessage("You are not a CM in this area."); + return; + } + else if (area->locked == FREE) { + sendServerMessage("This area is not locked."); + return; + } + sendServerMessage("This area is now unlocked."); + area->locked = FREE; + arup(ARUPType::LOCKED, true); +} QStringList AOClient::buildAreaList(int area_idx) diff --git a/src/packets.cpp b/src/packets.cpp index 8036462..464d9c4 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -319,6 +319,10 @@ AOPacket AOClient::validateIcPacket(AOPacket packet) // Spectators cannot use IC return invalid; + if (current_area->locked == SPECTATABLE && !current_area->invited.contains(id)) + // Non-invited players cannot speak in spectatable areas + return invalid; + QList incoming_args; for (QString arg : packet.contents) { incoming_args.append(QVariant(arg));