From 2a9eb18c5ed09c549d55544bf0ef026f70aa116b Mon Sep 17 00:00:00 2001 From: in1tiate Date: Tue, 9 Mar 2021 14:24:03 -0600 Subject: [PATCH 01/46] add net auth + desk mod validation update --- include/aoclient.h | 4 ++++ src/commands.cpp | 8 ++++++-- src/packets.cpp | 26 ++++++++++++-------------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 2a549d5..b912eee 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -68,6 +68,10 @@ class AOClient : public QObject { {"SUPER", ~0ULL} }; + bool is_shaken; + bool is_disemvoweled; + bool is_gimped; + public slots: void clientDisconnected(); void clientData(); diff --git a/src/commands.cpp b/src/commands.cpp index 6abee2f..50fa0cb 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -40,10 +40,12 @@ void AOClient::cmdLogin(int argc, QStringList argv) // TODO: tell the user if no modpass is set if (auth_type == "simple") { if(argv[0] == modpass) { - sendServerMessage("Logged in as a moderator."); // This string has to be exactly this, because it is hardcoded in the client + //sendServerMessage("Logged in as a moderator."); // This string has to be exactly this, because it is hardcoded in the client + sendPacket("AUTH", {"1"}); authenticated = true; } else { sendServerMessage("Incorrect password."); + sendPacket("AUTH", {"0"}); } server->areas.value(current_area)->logger->logLogin(this, authenticated, "moderator"); } @@ -57,11 +59,12 @@ void AOClient::cmdLogin(int argc, QStringList argv) if (server->db_manager->authenticate(username, password)) { moderator_name = username; authenticated = true; - sendServerMessage("Logged in as a moderator."); + sendPacket("AUTH", {"1"}); sendServerMessage("Welcome, " + username); } else { sendServerMessage("Incorrect password."); + sendPacket("AUTH", {"0"}); } server->areas.value(current_area)->logger->logLogin(this, authenticated, username); } @@ -359,6 +362,7 @@ void AOClient::cmdLogout(int argc, QStringList argv) authenticated = false; moderator_name = ""; sendServerMessage("You have been logged out."); + sendPacket("AUTH", {"-1"}); } void AOClient::cmdPos(int argc, QStringList argv) diff --git a/src/packets.cpp b/src/packets.cpp index 619849d..feaa203 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -46,12 +46,12 @@ void AOClient::pktSoftwareId(AreaData* area, int argc, QStringList argv, AOPacke // The only ones that are critical to ensuring the server works are // "noencryption" and "fastloading" QStringList feature_list = { - "noencryption", "yellowtext", "prezoom", - "flipping", "customobjections", "fastloading", - "deskmod", "evidence", "cccc_ic_support", - "arup", "casing_alerts", "modcall_reason", - "looping_sfx", "additive", "effects", - "y_offset" + "noencryption", "yellowtext", "prezoom", + "flipping", "customobjections", "fastloading", + "deskmod", "evidence", "cccc_ic_support", + "arup", "casing_alerts", "modcall_reason", + "looping_sfx", "additive", "effects", + "y_offset", "expanded_desk_mods", "auth_packet" }; sendPacket("PN", {QString::number(server->player_count), max_players}); @@ -345,15 +345,13 @@ AOPacket AOClient::validateIcPacket(AOPacket packet) incoming_args.append(QVariant(arg)); } - // message type - if (incoming_args[0].toInt() == 1) - args.append("1"); - else if (incoming_args[0].toInt() == 0) { - if (incoming_args[0].toString() == "chat") - args.append("chat"); - else - args.append("0"); + // desk modifier + QStringList allowed_desk_mods = ["chat", "0", "1", "2", "3", "4", "5"]; + if (allowed_desk_mods.contains(incoming_args[0])) { + args.append(incoming_args[0]); } + else + return invalid; // preanim args.append(incoming_args[1].toString()); From d2890e6e86ce2494e36662f9d76c7799e0a2007e Mon Sep 17 00:00:00 2001 From: in1tiate Date: Tue, 9 Mar 2021 14:35:23 -0600 Subject: [PATCH 02/46] some fiddling --- src/commands.cpp | 14 +++++++------- src/packets.cpp | 7 ++++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/commands.cpp b/src/commands.cpp index 50fa0cb..1d9727a 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -40,12 +40,12 @@ void AOClient::cmdLogin(int argc, QStringList argv) // TODO: tell the user if no modpass is set if (auth_type == "simple") { if(argv[0] == modpass) { - //sendServerMessage("Logged in as a moderator."); // This string has to be exactly this, because it is hardcoded in the client - sendPacket("AUTH", {"1"}); + sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button." + sendServerMessage("Logged in as a moderator."); // for old clients, this is hardcoded to display the mod UI authenticated = true; } else { + sendPacket("AUTH", {"0"}); // Client: "Login unsuccessful." sendServerMessage("Incorrect password."); - sendPacket("AUTH", {"0"}); } server->areas.value(current_area)->logger->logLogin(this, authenticated, "moderator"); } @@ -59,12 +59,13 @@ void AOClient::cmdLogin(int argc, QStringList argv) if (server->db_manager->authenticate(username, password)) { moderator_name = username; authenticated = true; - sendPacket("AUTH", {"1"}); + sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button." + sendServerMessage("Logged in as a moderator."); // for old clients, this is hardcoded to display the mod UI sendServerMessage("Welcome, " + username); } else { + sendPacket("AUTH", {"0"}); // Client: "Login unsuccessful." sendServerMessage("Incorrect password."); - sendPacket("AUTH", {"0"}); } server->areas.value(current_area)->logger->logLogin(this, authenticated, username); } @@ -361,8 +362,7 @@ void AOClient::cmdLogout(int argc, QStringList argv) } authenticated = false; moderator_name = ""; - sendServerMessage("You have been logged out."); - sendPacket("AUTH", {"-1"}); + sendPacket("AUTH", {"-1"}); // Client: "You were logged out." } void AOClient::cmdPos(int argc, QStringList argv) diff --git a/src/packets.cpp b/src/packets.cpp index feaa203..9766578 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -346,9 +346,10 @@ AOPacket AOClient::validateIcPacket(AOPacket packet) } // desk modifier - QStringList allowed_desk_mods = ["chat", "0", "1", "2", "3", "4", "5"]; - if (allowed_desk_mods.contains(incoming_args[0])) { - args.append(incoming_args[0]); + QStringList allowed_desk_mods; + allowed_desk_mods << "chat" << "0" << "1" << "2" << "3" << "4" << "5"; + if (allowed_desk_mods.contains(incoming_args[0].toString())) { + args.append(incoming_args[0].toString()); } else return invalid; From 953426fea18d916be3fb4ac2fbbea975c713243f Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 02:00:33 -0600 Subject: [PATCH 03/46] fix status in area list, replace number() with str literal --- src/aoclient.cpp | 12 ++++++------ src/commands.cpp | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/aoclient.cpp b/src/aoclient.cpp index 49553b9..984999a 100644 --- a/src/aoclient.cpp +++ b/src/aoclient.cpp @@ -175,20 +175,20 @@ void AOClient::changeCharacter(int char_id) sendPacket("PV", {QString::number(id), "CID", QString::number(char_id)}); 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())))}); + sendPacket("TI", {"0", "2"}); + sendPacket("TI", {"0", "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(server->timer->remainingTime())))}); } else { - sendPacket("TI", {QString::number(0), QString::number(3)}); + sendPacket("TI", {"0", "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())))}); + sendPacket("TI", {QString::number(timer_id), "2"}); + sendPacket("TI", {QString::number(timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(timer->remainingTime())))}); } else { - sendPacket("TI", {QString::number(timer_id), QString::number(3)}); + sendPacket("TI", {QString::number(timer_id), "3"}); } } } diff --git a/src/commands.cpp b/src/commands.cpp index d568471..f29f88b 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -656,28 +656,28 @@ void AOClient::cmdTimer(int argc, QStringList argv) 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))}); + sendPacket("TI", {QString::number(timer_id), "2"}); // Show the timer + sendPacket("TI", {QString::number(timer_id), "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())))}); + sendPacket("TI", {QString::number(timer_id), "2"}); // Show the timer + sendPacket("TI", {QString::number(timer_id), "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())))}); + sendPacket("TI", {QString::number(timer_id), "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)}); + sendPacket("TI", {QString::number(timer_id), "3"}); // Hide the timer } } } @@ -846,7 +846,7 @@ QStringList AOClient::buildAreaList(int area_idx) default: break; } - entries.append("[" + QString::number(area->player_count) + " users][" + area->status + "]"); + entries.append("[" + QString::number(area->player_count) + " users][" + QVariant::fromValue(area->status).toString().replace("_", "-") + "]"); for (AOClient* client : server->clients) { if (client->current_area == area_idx && client->joined) { QString char_entry = "[" + QString::number(client->id) + "] " + client->current_char; From 7157d5410ea91b4a619976b9257724e84fd94d11 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 02:22:03 -0600 Subject: [PATCH 04/46] vastly improve client version string validation --- src/packets.cpp | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/packets.cpp b/src/packets.cpp index 337286f..53a7962 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -55,28 +55,14 @@ void AOClient::pktSoftwareId(AreaData* area, int argc, QStringList argv, AOPacke }; - // Extremely cursed client version string validation - // Ideally version strings should be X.X.X but it can be literally anything - // so we have to be super careful version.string = argv[1]; - QStringList version_raw = version.string.split("."); - bool ok; - int release_version = version_raw[0].toInt(&ok); - if (ok && version_raw.size() >= 1) - version.release = release_version; - if (ok && version_raw.size() >= 2) { - int major_version = version_raw[1].toInt(&ok); - if (ok) - version.major = major_version; + QRegExp rx("\\b(\\d+)\\.(\\d+)\\.(\\d+)\\b"); // matches X.X.X (e.g. 2.9.0, 2.4.10, etc.) + if (rx.indexIn(version.string) != -1) { + QStringList version_raw = rx.capturedTexts(); + version.release = version_raw[0].toInt(); + version.major = version_raw[1].toInt(); + version.minor = version_raw[2].toInt(); } - if (ok && version_raw.size() >= 3) { - int minor_version = version_raw[2].toInt(&ok); - if (ok) - version.minor = minor_version; - } - - - sendPacket("PN", {QString::number(server->player_count), max_players}); sendPacket("FL", feature_list); From bd471eda00e7b51da92de341da910c55f4fb9e69 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 04:32:41 -0600 Subject: [PATCH 05/46] switch to QRegularExpression for client version validation --- include/aoclient.h | 2 +- src/packets.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 4b33f53..7b97907 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #if QT_VERSION > QT_VERSION_CHECK(5, 10, 0) #include diff --git a/src/packets.cpp b/src/packets.cpp index 53a7962..66f32ac 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -56,12 +56,12 @@ void AOClient::pktSoftwareId(AreaData* area, int argc, QStringList argv, AOPacke version.string = argv[1]; - QRegExp rx("\\b(\\d+)\\.(\\d+)\\.(\\d+)\\b"); // matches X.X.X (e.g. 2.9.0, 2.4.10, etc.) - if (rx.indexIn(version.string) != -1) { - QStringList version_raw = rx.capturedTexts(); - version.release = version_raw[0].toInt(); - version.major = version_raw[1].toInt(); - version.minor = version_raw[2].toInt(); + QRegularExpression rx("\\b(\\d+)\\.(\\d+)\\.(\\d+)\\b"); // matches X.X.X (e.g. 2.9.0, 2.4.10, etc.) + QRegularExpressionMatch match = rx.match(version.string); + if (match.hasMatch()) { + version.release = match.captured(1).toInt(); + version.major = match.captured(2).toInt(); + version.minor = match.captured(3).toInt(); } sendPacket("PN", {QString::number(server->player_count), max_players}); From 07a19fe8cd145feec360d1caf7edf0c0291f4411 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 04:52:54 -0600 Subject: [PATCH 06/46] don't allow for locked areas with no cm --- src/aoclient.cpp | 7 +++++++ src/commands.cpp | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/aoclient.cpp b/src/aoclient.cpp index 984999a..71ffe0a 100644 --- a/src/aoclient.cpp +++ b/src/aoclient.cpp @@ -68,10 +68,17 @@ void AOClient::clientDisconnected() false; server->updateCharsTaken(server->areas[current_area]); } + bool update_locks; for (AreaData* area : server->areas) { area->owners.removeAll(id); area->invited.removeAll(id); + if (area->owners.isEmpty() && area->locked != AreaData::FREE) { + area->locked = AreaData::FREE; + update_locks = true; + } } + if (update_locks) + arup(ARUPType::LOCKED, true); arup(ARUPType::CM, true); } diff --git a/src/commands.cpp b/src/commands.cpp index f29f88b..f347a85 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -504,8 +504,13 @@ void AOClient::cmdUnCM(int argc, QStringList argv) area->invited.removeAll(id); sendServerMessage("You are no longer CM in this area."); arup(ARUPType::CM, true); - if (area->owners.isEmpty()) + if (area->owners.isEmpty()) { area->invited.clear(); + if (area->locked != AreaData::FREE) { + area->locked = AreaData::FREE; + arup(ARUPType::LOCKED, true); + } + } } void AOClient::cmdInvite(int argc, QStringList argv) From e60f7e6796c8f626efea59ca4179a86ab6792aab Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 05:29:46 -0600 Subject: [PATCH 07/46] update version string --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 630965b..de6ff3e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,7 +36,7 @@ int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationName("akashi"); - QCoreApplication::setApplicationVersion("0.0.1"); + QCoreApplication::setApplicationVersion("1.0.0-alpha"); std::atexit(cleanup); ConfigManager config_manager; From 9d10431da7ca2c7d82922ef495f06870f2708d02 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 09:57:41 -0600 Subject: [PATCH 08/46] store a position in area config and sort areas numerically --- bin/config_sample/areas.ini | 4 ++-- src/server.cpp | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/bin/config_sample/areas.ini b/bin/config_sample/areas.ini index 14f79ca..632bb2f 100644 --- a/bin/config_sample/areas.ini +++ b/bin/config_sample/areas.ini @@ -1,5 +1,5 @@ -[Basement] +[0:Basement] background=gs4 -[Courtroom 1] +[1:Courtroom 1] background=gs4 diff --git a/src/server.cpp b/src/server.cpp index b9acff4..2f3a17d 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -79,7 +79,16 @@ void Server::start() bg_file.close(); QSettings areas_ini("config/areas.ini", QSettings::IniFormat); - area_names = areas_ini.childGroups(); + area_names = areas_ini.childGroups(); // invisibly does a lexicographical sort, because Qt is great like that + std::sort(area_names.begin(), area_names.end(), [] (const QString &a, const QString &b) {return a.split(":")[0].toInt() < b.split(":")[0].toInt();}); + QStringList sanitized_area_names; + for (QString area_name : area_names) { + QStringList name_split = area_name.split(":"); + name_split.removeFirst(); + QString area_name_sanitized = name_split.join(":"); + sanitized_area_names.append(area_name_sanitized); + } + area_names = sanitized_area_names; for (int i = 0; i < area_names.length(); i++) { QString area_name = area_names[i]; areas.insert(i, new AreaData(characters, area_name, i)); From b5154079677cc91e99f2baf832a80b37988ec8e7 Mon Sep 17 00:00:00 2001 From: scatterflower Date: Thu, 11 Mar 2021 13:32:20 -0600 Subject: [PATCH 09/46] make ms port selection actually work?? --- include/config_manager.h | 2 +- src/config_manager.cpp | 4 ++-- src/main.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/config_manager.h b/include/config_manager.h index 7c5deb0..4c1baa2 100644 --- a/include/config_manager.h +++ b/include/config_manager.h @@ -36,7 +36,7 @@ class ConfigManager { QString ms_ip; int port; int ws_port; - int local_port; + int ms_port; QString name; QString description; bool advertise_server; diff --git a/src/config_manager.cpp b/src/config_manager.cpp index 7f0f93a..7364d9d 100644 --- a/src/config_manager.cpp +++ b/src/config_manager.cpp @@ -139,8 +139,8 @@ bool ConfigManager::loadServerSettings(server_settings* settings) config.value("port", "27016").toInt(&port_conversion_success); settings->ws_port = config.value("webao_port", "27017").toInt(&ws_port_conversion_success); - settings->local_port = - config.value("port", "27016").toInt(&local_port_conversion_success); + settings->ms_port = + config.value("ms_port", "27016").toInt(&local_port_conversion_success); settings->name = config.value("server_name", "My First Server").toString(); settings->description = config.value("server_description", "This is my flashy new server") diff --git a/src/main.cpp b/src/main.cpp index 630965b..7e3a090 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,8 +55,8 @@ int main(int argc, char* argv[]) else { if (settings.advertise_server) { advertiser = - new Advertiser(settings.ms_ip, settings.port, - settings.ws_port, settings.local_port, + new Advertiser(settings.ms_ip, settings.ms_port, + settings.ws_port, settings.port, settings.name, settings.description); advertiser->contactMasterServer(); } From 3e1f9825ca03733a6f69561e36ffb758f6809a3a Mon Sep 17 00:00:00 2001 From: Salanto Date: Thu, 11 Mar 2021 22:42:47 +0100 Subject: [PATCH 10/46] motd. Can't get simpler than that. --- bin/config_sample/config.ini | 1 + include/aoclient.h | 4 +++- include/server.h | 1 + src/commands.cpp | 6 ++++++ src/packets.cpp | 1 + src/server.cpp | 9 +++++++++ 6 files changed, 21 insertions(+), 1 deletion(-) diff --git a/bin/config_sample/config.ini b/bin/config_sample/config.ini index a33f95d..65ed954 100644 --- a/bin/config_sample/config.ini +++ b/bin/config_sample/config.ini @@ -9,6 +9,7 @@ ms_port=27016 port=27016 server_description=This is a placeholder server description. Tell the world of AO who you are here! server_name=An Unnamed Server +motd=Sample MOTD. webao_enable=true webao_port=27017 auth=simple diff --git a/include/aoclient.h b/include/aoclient.h index a7d987f..fa8f91d 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -183,6 +183,7 @@ class AOClient : public QObject { //// Commands void cmdDefault(int argc, QStringList argv); void cmdHelp(int argc, QStringList argv); + void cmdMOTD(int argc, QStringList argv); // Authentication void cmdLogin(int argc, QStringList argv); void cmdChangeAuth(int argc, QStringList argv); @@ -298,7 +299,8 @@ class AOClient : public QObject { {"forcepos", {ACLFlags.value("CM"), 2, &AOClient::cmdForcePos}}, {"currentmusic", {ACLFlags.value("NONE"), 0, &AOClient::cmdCurrentMusic}}, {"pm", {ACLFlags.value("NONE"), 2, &AOClient::cmdPM}}, - {"evidence_mod", {ACLFlags.value("CHANGE_EVI_MOD"), 1, &AOClient::cmdEvidenceMod}} + {"evidence_mod", {ACLFlags.value("CHANGE_EVI_MOD"), 1, &AOClient::cmdEvidenceMod}}, + {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}} }; QString partial_packet; diff --git a/include/server.h b/include/server.h index 152fc37..cd003b3 100644 --- a/include/server.h +++ b/include/server.h @@ -52,6 +52,7 @@ class Server : public QObject { void broadcast(AOPacket packet, int area_index); void broadcast(AOPacket packet); QString getServerName(); + QString getMOTD(); int getDiceValue(QString value_type); int getCharID(QString char_name); diff --git a/src/commands.cpp b/src/commands.cpp index 1b173d9..cb213b8 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -857,6 +857,12 @@ void AOClient::cmdPM(int arc, QStringList argv) target_client->sendServerMessage("Message from " + ooc_name + " (" + QString::number(id) + "): " + message); } +void AOClient::cmdMOTD(int argc, QStringList argv) +{ + QString MOTD = server->getMOTD(); + sendServerMessage(MOTD); +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; diff --git a/src/packets.cpp b/src/packets.cpp index cabbb8c..6628b43 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -112,6 +112,7 @@ void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPack sendPacket("BN", {area->background}); sendPacket("OPPASS", {"DEADBEEF"}); sendPacket("DONE"); + sendServerMessage(server->getMOTD()); } void AOClient::pktCharPassword(AreaData* area, int argc, QStringList argv, AOPacket packet) diff --git a/src/server.cpp b/src/server.cpp index 0f4d23a..5c036dc 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -182,6 +182,15 @@ int Server::getDiceValue(QString value_type) return value; } +QString Server::getMOTD() +{ + QSettings settings("config/config.ini", QSettings::IniFormat); + settings.beginGroup("Options"); + QString MOTD = settings.value("motd", "No MOTD has been set.").toString(); + QString f_MOTD = "=== MOTD ===\r\n" + MOTD + "\r\n============='"; + return f_MOTD; +} + AOClient* Server::getClient(QString ipid) { for (AOClient* client : clients) { From 06864e115a957e16b84cc4b56438045dcc43ce82 Mon Sep 17 00:00:00 2001 From: Salanto Date: Fri, 12 Mar 2021 00:44:27 +0100 Subject: [PATCH 11/46] Make MODT editable - Part 1 --- bin/config_sample/config.ini | 2 +- include/aoclient.h | 1 + include/server.h | 1 + src/commands.cpp | 15 +++++++++++++-- src/packets.cpp | 2 +- src/server.cpp | 11 ++--------- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/bin/config_sample/config.ini b/bin/config_sample/config.ini index 65ed954..eaf63ba 100644 --- a/bin/config_sample/config.ini +++ b/bin/config_sample/config.ini @@ -9,7 +9,7 @@ ms_port=27016 port=27016 server_description=This is a placeholder server description. Tell the world of AO who you are here! server_name=An Unnamed Server -motd=Sample MOTD. +motd=MOTD is not set. webao_enable=true webao_port=27017 auth=simple diff --git a/include/aoclient.h b/include/aoclient.h index fa8f91d..42070e3 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -76,6 +76,7 @@ class AOClient : public QObject { {"CM", 1ULL << 4}, {"GLOBAL_TIMER", 1ULL << 5}, {"CHANGE_EVI_MOD", 1ULL << 6}, + {"CHANGE_MOTD", 1ULL << 7}, {"SUPER", ~0ULL} }; diff --git a/include/server.h b/include/server.h index cd003b3..14c4883 100644 --- a/include/server.h +++ b/include/server.h @@ -66,6 +66,7 @@ class Server : public QObject { QStringList backgrounds; DBManager* db_manager; QString server_name; + QString MOTD; QTimer* timer; diff --git a/src/commands.cpp b/src/commands.cpp index cb213b8..20af10c 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -859,8 +859,19 @@ void AOClient::cmdPM(int arc, QStringList argv) void AOClient::cmdMOTD(int argc, QStringList argv) { - QString MOTD = server->getMOTD(); - sendServerMessage(MOTD); + if (argc == 0) { + sendServerMessage("=== MOTD ===\r\n" + server->MOTD + "\r\n============="); + } + else if (argc == 1) { + unsigned long long user_acl = server->db_manager->getACL(moderator_name); + if ((user_acl & ACLFlags.value("MODIFY_USERS")) == 0) { + sendServerMessage("You do not have permission to change the MOTD"); + } + else { + server->MOTD = argv[0]; + } + + } } QStringList AOClient::buildAreaList(int area_idx) diff --git a/src/packets.cpp b/src/packets.cpp index 6628b43..745334c 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -112,7 +112,7 @@ void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPack sendPacket("BN", {area->background}); sendPacket("OPPASS", {"DEADBEEF"}); sendPacket("DONE"); - sendServerMessage(server->getMOTD()); + sendServerMessage("=== MOTD ===\r\n" + server->MOTD + "\r\n============="); } void AOClient::pktCharPassword(AreaData* area, int argc, QStringList argv, AOPacket packet) diff --git a/src/server.cpp b/src/server.cpp index 5c036dc..e820950 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -51,6 +51,8 @@ void Server::start() qDebug() << "Server listening on" << port; } + MOTD = config.value("motd","MOTD is not set.").toString(); + proxy = new WSProxy(port, ws_port, this); if(ws_port != -1) proxy->start(); @@ -182,15 +184,6 @@ int Server::getDiceValue(QString value_type) return value; } -QString Server::getMOTD() -{ - QSettings settings("config/config.ini", QSettings::IniFormat); - settings.beginGroup("Options"); - QString MOTD = settings.value("motd", "No MOTD has been set.").toString(); - QString f_MOTD = "=== MOTD ===\r\n" + MOTD + "\r\n============='"; - return f_MOTD; -} - AOClient* Server::getClient(QString ipid) { for (AOClient* client : clients) { From f06537973b13900c640ab1c7de7a949ed71a0511 Mon Sep 17 00:00:00 2001 From: Salanto Date: Fri, 12 Mar 2021 00:56:54 +0100 Subject: [PATCH 12/46] Make permission check work; allow changed MOTD to be longer than one word --- src/commands.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/commands.cpp b/src/commands.cpp index 20af10c..e25bd8e 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -862,15 +862,15 @@ void AOClient::cmdMOTD(int argc, QStringList argv) if (argc == 0) { sendServerMessage("=== MOTD ===\r\n" + server->MOTD + "\r\n============="); } - else if (argc == 1) { - unsigned long long user_acl = server->db_manager->getACL(moderator_name); - if ((user_acl & ACLFlags.value("MODIFY_USERS")) == 0) { - sendServerMessage("You do not have permission to change the MOTD"); + else if (argc > 0) { + if (checkAuth(ACLFlags.value("CHANGE_MOTD"))) { + QString MOTD = argv.join(" "); + server->MOTD = MOTD; + sendServerMessage("MOTD has been changed."); } else { - server->MOTD = argv[0]; + sendServerMessage("You do not have permission to change the MOTD"); } - } } From d7870fd017ed2c02021c1ad915eb9403ca488d99 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 19:31:33 -0600 Subject: [PATCH 13/46] call arup in loadingDone instead of changeCharacter --- src/aoclient.cpp | 24 +++--------------------- src/packets.cpp | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/aoclient.cpp b/src/aoclient.cpp index 71ffe0a..16bd350 100644 --- a/src/aoclient.cpp +++ b/src/aoclient.cpp @@ -140,11 +140,11 @@ void AOClient::changeArea(int new_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())))}); + sendPacket("TI", {QString::number(timer_id), "2"}); + sendPacket("TI", {QString::number(timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(timer->remainingTime())))}); } else { - sendPacket("TI", {QString::number(timer_id), QString::number(3)}); + sendPacket("TI", {QString::number(timer_id), "3"}); } } sendServerMessage("You moved to area " + server->area_names[current_area]); @@ -180,24 +180,6 @@ void AOClient::changeCharacter(int char_id) server->updateCharsTaken(area); sendPacket("PV", {QString::number(id), "CID", QString::number(char_id)}); - fullArup(); - if (server->timer->isActive()) { - sendPacket("TI", {"0", "2"}); - sendPacket("TI", {"0", "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(server->timer->remainingTime())))}); - } - else { - sendPacket("TI", {"0", "3"}); - } - for (QTimer* timer : area->timers) { - int timer_id = area->timers.indexOf(timer) + 1; - if (timer->isActive()) { - sendPacket("TI", {QString::number(timer_id), "2"}); - sendPacket("TI", {QString::number(timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(timer->remainingTime())))}); - } - else { - sendPacket("TI", {QString::number(timer_id), "3"}); - } - } } void AOClient::changePosition(QString new_pos) diff --git a/src/packets.cpp b/src/packets.cpp index cabbb8c..d52f23e 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -102,7 +102,7 @@ void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPack area->player_count++; joined = true; server->updateCharsTaken(area); - fullArup(); // Give client all the area data + arup(ARUPType::PLAYER_COUNT, true); // Tell everyone there is a new player sendEvidenceList(area); @@ -112,6 +112,25 @@ void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPack sendPacket("BN", {area->background}); sendPacket("OPPASS", {"DEADBEEF"}); sendPacket("DONE"); + + fullArup(); // Give client all the area data + if (server->timer->isActive()) { + sendPacket("TI", {"0", "2"}); + sendPacket("TI", {"0", "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(server->timer->remainingTime())))}); + } + else { + sendPacket("TI", {"0", "3"}); + } + for (QTimer* timer : area->timers) { + int timer_id = area->timers.indexOf(timer) + 1; + if (timer->isActive()) { + sendPacket("TI", {QString::number(timer_id), "2"}); + sendPacket("TI", {QString::number(timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(timer->remainingTime())))}); + } + else { + sendPacket("TI", {QString::number(timer_id), "3"}); + } + } } void AOClient::pktCharPassword(AreaData* area, int argc, QStringList argv, AOPacket packet) From ee9ae6d7c64eed18029aa4be7fbf9fc914b44b1f Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 20:09:04 -0600 Subject: [PATCH 14/46] rework characters_taken to be a QList --- include/area_data.h | 4 ++-- src/aoclient.cpp | 16 +++++++--------- src/area_data.cpp | 5 +---- src/server.cpp | 6 +++--- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/include/area_data.h b/include/area_data.h index a70553a..49f0a28 100644 --- a/include/area_data.h +++ b/include/area_data.h @@ -31,7 +31,7 @@ class Logger; class AreaData : public QObject { Q_OBJECT public: - AreaData(QStringList p_characters, QString p_name, int p_index); + AreaData(QString p_name, int p_index); struct Evidence { QString name; @@ -41,7 +41,7 @@ class AreaData : public QObject { QList timers; QString name; int index; - QMap characters_taken; + QList characters_taken; QList evidence; int player_count; enum Status { diff --git a/src/aoclient.cpp b/src/aoclient.cpp index 71ffe0a..e392be3 100644 --- a/src/aoclient.cpp +++ b/src/aoclient.cpp @@ -64,8 +64,7 @@ void AOClient::clientDisconnected() arup(ARUPType::PLAYER_COUNT, true); } if (current_char != "") { - server->areas[current_area]->characters_taken[current_char] = - false; + server->areas[current_area]->characters_taken.removeAll(server->getCharID(current_char)); server->updateCharsTaken(server->areas[current_area]); } bool update_locks; @@ -116,8 +115,7 @@ void AOClient::changeArea(int new_area) } if (current_char != "") { - server->areas[current_area]->characters_taken[current_char] = - false; + server->areas[current_area]->characters_taken.removeAll(server->getCharID(current_char)); server->updateCharsTaken(server->areas[current_area]); } server->areas[new_area]->player_count++; @@ -128,13 +126,13 @@ void AOClient::changeArea(int new_area) sendPacket("HP", {"1", QString::number(server->areas[new_area]->def_hp)}); sendPacket("HP", {"2", QString::number(server->areas[new_area]->pro_hp)}); sendPacket("BN", {server->areas[new_area]->background}); - if (server->areas[current_area]->characters_taken[current_char]) { + if (server->areas[current_area]->characters_taken.contains(server->getCharID(current_char))) { server->updateCharsTaken(server->areas[current_area]); current_char = ""; sendPacket("DONE"); } else { - server->areas[current_area]->characters_taken[current_char] = true; + server->areas[current_area]->characters_taken.append(server->getCharID(current_char)); server->updateCharsTaken(server->areas[current_area]); } for (QTimer* timer : server->areas[current_area]->timers) { @@ -157,7 +155,7 @@ void AOClient::changeCharacter(int char_id) AreaData* area = server->areas[current_area]; if (current_char != "") { - area->characters_taken[current_char] = false; + area->characters_taken.removeAll(server->getCharID(current_char)); } if(char_id > server->characters.length()) @@ -165,11 +163,11 @@ void AOClient::changeCharacter(int char_id) if (char_id >= 0) { QString char_selected = server->characters[char_id]; - bool taken = area->characters_taken.value(char_selected); + bool taken = area->characters_taken.contains(char_id); if (taken || char_selected == "") return; - area->characters_taken[char_selected] = true; + area->characters_taken.append(char_id); current_char = char_selected; } else { diff --git a/src/area_data.cpp b/src/area_data.cpp index c85ea25..83bfc38 100644 --- a/src/area_data.cpp +++ b/src/area_data.cpp @@ -17,13 +17,10 @@ ////////////////////////////////////////////////////////////////////////////////////// #include "include/area_data.h" -AreaData::AreaData(QStringList characters, QString p_name, int p_index) +AreaData::AreaData(QString p_name, int p_index) { name = p_name; index = p_index; - for (QString cur_char : characters) { - characters_taken.insert(cur_char, false); - } QSettings areas_ini("config/areas.ini", QSettings::IniFormat); areas_ini.beginGroup(p_name); background = areas_ini.value("background", "gs4").toString(); diff --git a/src/server.cpp b/src/server.cpp index 0f4d23a..131ec47 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -91,7 +91,7 @@ void Server::start() area_names = sanitized_area_names; for (int i = 0; i < area_names.length(); i++) { QString area_name = area_names[i]; - areas.insert(i, new AreaData(characters, area_name, i)); + areas.insert(i, new AreaData(area_name, i)); } } @@ -139,8 +139,8 @@ void Server::clientConnected() void Server::updateCharsTaken(AreaData* area) { QStringList chars_taken; - for (QString cur_char : area->characters_taken.keys()) { - chars_taken.append(area->characters_taken.value(cur_char) + for (QString cur_char : characters) { + chars_taken.append(area->characters_taken.contains(getCharID(cur_char)) ? QStringLiteral("-1") : QStringLiteral("0")); } From f43a498efa1ca20d6ebd86f98478438612e7d35c Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 23:49:42 -0600 Subject: [PATCH 15/46] add /announce, change permission names for consistency --- include/aoclient.h | 11 +++++++---- src/commands.cpp | 7 ++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 42070e3..e2276b8 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -75,8 +75,9 @@ class AOClient : public QObject { {"MODIFY_USERS", 1ULL << 3}, {"CM", 1ULL << 4}, {"GLOBAL_TIMER", 1ULL << 5}, - {"CHANGE_EVI_MOD", 1ULL << 6}, - {"CHANGE_MOTD", 1ULL << 7}, + {"EVI_MOD", 1ULL << 6}, + {"MOTD", 1ULL << 7}, + {"ANNOUNCE", 1ULL << 8}, {"SUPER", ~0ULL} }; @@ -216,6 +217,7 @@ class AOClient : public QObject { void cmdMods(int argc, QStringList argv); void cmdBan(int argc, QStringList argv); void cmdKick(int argc, QStringList argv); + void cmdAnnounce(int argc, QStringList argv); // Casing/RP void cmdPlay(int argc, QStringList argv); void cmdNeed(int argc, QStringList argv); @@ -300,8 +302,9 @@ class AOClient : public QObject { {"forcepos", {ACLFlags.value("CM"), 2, &AOClient::cmdForcePos}}, {"currentmusic", {ACLFlags.value("NONE"), 0, &AOClient::cmdCurrentMusic}}, {"pm", {ACLFlags.value("NONE"), 2, &AOClient::cmdPM}}, - {"evidence_mod", {ACLFlags.value("CHANGE_EVI_MOD"), 1, &AOClient::cmdEvidenceMod}}, - {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}} + {"evidence_mod", {ACLFlags.value("EVI_MOD"), 1, &AOClient::cmdEvidenceMod}}, + {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}}, + {"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}}, }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index e25bd8e..ce8e48e 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -863,7 +863,7 @@ void AOClient::cmdMOTD(int argc, QStringList argv) sendServerMessage("=== MOTD ===\r\n" + server->MOTD + "\r\n============="); } else if (argc > 0) { - if (checkAuth(ACLFlags.value("CHANGE_MOTD"))) { + if (checkAuth(ACLFlags.value("MOTD"))) { QString MOTD = argv.join(" "); server->MOTD = MOTD; sendServerMessage("MOTD has been changed."); @@ -874,6 +874,11 @@ void AOClient::cmdMOTD(int argc, QStringList argv) } } +void AOClient::cmdAnnounce(int argc, QStringList argv) +{ + sendServerBroadcast("=== Announcement ===\r\n" + argv.join(" ") + "\r\n============="); +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; From 8b4929223c2e9d221491ff62f36e32c21f4f96e6 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 11 Mar 2021 23:58:51 -0600 Subject: [PATCH 16/46] implement modchat --- include/aoclient.h | 3 +++ src/commands.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/aoclient.h b/include/aoclient.h index e2276b8..1869bc6 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -78,6 +78,7 @@ class AOClient : public QObject { {"EVI_MOD", 1ULL << 6}, {"MOTD", 1ULL << 7}, {"ANNOUNCE", 1ULL << 8}, + {"MODCHAT", 1ULL << 9}, {"SUPER", ~0ULL} }; @@ -218,6 +219,7 @@ class AOClient : public QObject { void cmdBan(int argc, QStringList argv); void cmdKick(int argc, QStringList argv); void cmdAnnounce(int argc, QStringList argv); + void cmdM(int argc, QStringList argv); // Casing/RP void cmdPlay(int argc, QStringList argv); void cmdNeed(int argc, QStringList argv); @@ -305,6 +307,7 @@ class AOClient : public QObject { {"evidence_mod", {ACLFlags.value("EVI_MOD"), 1, &AOClient::cmdEvidenceMod}}, {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}}, {"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}}, + {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index ce8e48e..8b87a42 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -879,6 +879,17 @@ void AOClient::cmdAnnounce(int argc, QStringList argv) sendServerBroadcast("=== Announcement ===\r\n" + argv.join(" ") + "\r\n============="); } +void AOClient::cmdM(int argc, QStringList argv) +{ + QString sender_name = ooc_name; + QString sender_message = argv.join(" "); + for (AOClient* client : server->clients) { + if (client->checkAuth(ACLFlags.value("MODCHAT"))) + client->sendPacket("CT", {"[M]" + sender_name, sender_message}); + } + return; +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; From a62b12fb7a2d00358e49b2578fa3d90568219b7f Mon Sep 17 00:00:00 2001 From: in1tiate Date: Fri, 12 Mar 2021 05:01:31 -0600 Subject: [PATCH 17/46] fix area config reading based on sanitized name --- src/area_data.cpp | 4 +++- src/packets.cpp | 2 +- src/server.cpp | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/area_data.cpp b/src/area_data.cpp index 83bfc38..b03500d 100644 --- a/src/area_data.cpp +++ b/src/area_data.cpp @@ -19,7 +19,9 @@ AreaData::AreaData(QString p_name, int p_index) { - name = p_name; + QStringList name_split = p_name.split(":"); + name_split.removeFirst(); + name = name_split.join(":"); index = p_index; QSettings areas_ini("config/areas.ini", QSettings::IniFormat); areas_ini.beginGroup(p_name); diff --git a/src/packets.cpp b/src/packets.cpp index 9931391..421688f 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -109,9 +109,9 @@ void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPack sendPacket("HP", {"1", QString::number(area->def_hp)}); sendPacket("HP", {"2", QString::number(area->pro_hp)}); sendPacket("FA", server->area_names); - sendPacket("BN", {area->background}); sendPacket("OPPASS", {"DEADBEEF"}); sendPacket("DONE"); + sendPacket("BN", {area->background}); sendServerMessage("=== MOTD ===\r\n" + server->MOTD + "\r\n============="); diff --git a/src/server.cpp b/src/server.cpp index 64a9ea0..35d0281 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -84,6 +84,7 @@ void Server::start() area_names = areas_ini.childGroups(); // invisibly does a lexicographical sort, because Qt is great like that std::sort(area_names.begin(), area_names.end(), [] (const QString &a, const QString &b) {return a.split(":")[0].toInt() < b.split(":")[0].toInt();}); QStringList sanitized_area_names; + QStringList raw_area_names = area_names; for (QString area_name : area_names) { QStringList name_split = area_name.split(":"); name_split.removeFirst(); @@ -91,8 +92,8 @@ void Server::start() sanitized_area_names.append(area_name_sanitized); } area_names = sanitized_area_names; - for (int i = 0; i < area_names.length(); i++) { - QString area_name = area_names[i]; + for (int i = 0; i < raw_area_names.length(); i++) { + QString area_name = raw_area_names[i]; areas.insert(i, new AreaData(area_name, i)); } } From 56ef0d5958f4a1f45211e25413f0f80825c889f3 Mon Sep 17 00:00:00 2001 From: Salanto Date: Fri, 12 Mar 2021 18:41:21 +0100 Subject: [PATCH 18/46] Add /gm command --- include/aoclient.h | 3 +++ src/commands.cpp | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/aoclient.h b/include/aoclient.h index 1869bc6..75eaa39 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -79,6 +79,7 @@ class AOClient : public QObject { {"MOTD", 1ULL << 7}, {"ANNOUNCE", 1ULL << 8}, {"MODCHAT", 1ULL << 9}, + {"GM", 1ULL << 10}, {"SUPER", ~0ULL} }; @@ -220,6 +221,7 @@ class AOClient : public QObject { void cmdKick(int argc, QStringList argv); void cmdAnnounce(int argc, QStringList argv); void cmdM(int argc, QStringList argv); + void cmdGM(int argc, QStringList argv); // Casing/RP void cmdPlay(int argc, QStringList argv); void cmdNeed(int argc, QStringList argv); @@ -308,6 +310,7 @@ class AOClient : public QObject { {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}}, {"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}}, {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, + {"gm", {ACLFlags.value("GM"), 1, &AOClient::cmdGM}} }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index 8b87a42..71e7557 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -890,6 +890,22 @@ void AOClient::cmdM(int argc, QStringList argv) return; } +void AOClient::cmdGM(int argc, QStringList argv) +{ + if (checkAuth(ACLFlags.value("MOTD"))) { + QString sender_name = ooc_name; + QString sender_area = server->area_names.value(current_area); + QString sender_message = argv.join(" "); + for (AOClient* client : server->clients) { + if (client->global_enabled) + client->sendPacket("CT", {"[G][" + sender_area + "]" + "["+sender_name+"][M]", sender_message}); + } + } + else { + sendServerMessage("You do not have permission to use Global Mod Message."); + } +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; From 69911835eee7a1271edfaa34ca2c8702499fdbea Mon Sep 17 00:00:00 2001 From: Salanto Date: Fri, 12 Mar 2021 18:44:35 +0100 Subject: [PATCH 19/46] Wrong permission --- src/commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands.cpp b/src/commands.cpp index 71e7557..8f7ad14 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -892,7 +892,7 @@ void AOClient::cmdM(int argc, QStringList argv) void AOClient::cmdGM(int argc, QStringList argv) { - if (checkAuth(ACLFlags.value("MOTD"))) { + if (checkAuth(ACLFlags.value("GM"))) { QString sender_name = ooc_name; QString sender_area = server->area_names.value(current_area); QString sender_message = argv.join(" "); From 79d64e6153b4f8b26c32f81e6970021cac214f03 Mon Sep 17 00:00:00 2001 From: Salanto Date: Fri, 12 Mar 2021 22:12:33 +0100 Subject: [PATCH 20/46] Send music update to area instead of a single client --- src/commands.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/commands.cpp b/src/commands.cpp index 8b87a42..45301a0 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -727,7 +727,8 @@ void AOClient::cmdPlay(int argc, QStringList argv) QString song = argv.join(" "); area->current_music = song; area->music_played_by = showname; - sendPacket("MC", {song, QString::number(server->getCharID(current_char)), showname, "1", "0"}); + AOPacket music_change("MC", {song, QString::number(server->getCharID(current_char)), showname, "1", "0"}); + server->broadcast(music_change, current_area); } void AOClient::cmdAreaKick(int argc, QStringList argv) From ed03666a2c5f1b3d142d4fa60d5e42a05a04b5d3 Mon Sep 17 00:00:00 2001 From: Salanto Date: Fri, 12 Mar 2021 22:14:45 +0100 Subject: [PATCH 21/46] Change permission, remove unused permission --- include/aoclient.h | 1 - src/commands.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 75eaa39..6fbb981 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -79,7 +79,6 @@ class AOClient : public QObject { {"MOTD", 1ULL << 7}, {"ANNOUNCE", 1ULL << 8}, {"MODCHAT", 1ULL << 9}, - {"GM", 1ULL << 10}, {"SUPER", ~0ULL} }; diff --git a/src/commands.cpp b/src/commands.cpp index 8f7ad14..2cd968f 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -892,7 +892,7 @@ void AOClient::cmdM(int argc, QStringList argv) void AOClient::cmdGM(int argc, QStringList argv) { - if (checkAuth(ACLFlags.value("GM"))) { + if (checkAuth(ACLFlags.value("MODCHAT"))) { QString sender_name = ooc_name; QString sender_area = server->area_names.value(current_area); QString sender_message = argv.join(" "); From 834f908d841fe4271c13b06160563d2b353a675a Mon Sep 17 00:00:00 2001 From: Salanto Date: Fri, 12 Mar 2021 22:17:19 +0100 Subject: [PATCH 22/46] For real this time --- include/aoclient.h | 2 +- src/commands.cpp | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 6fbb981..4ff94c7 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -309,7 +309,7 @@ class AOClient : public QObject { {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}}, {"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}}, {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, - {"gm", {ACLFlags.value("GM"), 1, &AOClient::cmdGM}} + {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}} }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index 2cd968f..9d98004 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -892,18 +892,14 @@ void AOClient::cmdM(int argc, QStringList argv) void AOClient::cmdGM(int argc, QStringList argv) { - if (checkAuth(ACLFlags.value("MODCHAT"))) { - QString sender_name = ooc_name; - QString sender_area = server->area_names.value(current_area); - QString sender_message = argv.join(" "); - for (AOClient* client : server->clients) { - if (client->global_enabled) - client->sendPacket("CT", {"[G][" + sender_area + "]" + "["+sender_name+"][M]", sender_message}); + QString sender_name = ooc_name; + QString sender_area = server->area_names.value(current_area); + QString sender_message = argv.join(" "); + for (AOClient* client : server->clients) { + if (client->global_enabled) { + client->sendPacket("CT", {"[G][" + sender_area + "]" + "["+sender_name+"][M]", sender_message}); } } - else { - sendServerMessage("You do not have permission to use Global Mod Message."); - } } QStringList AOClient::buildAreaList(int area_idx) From dd7daa0c88380b039bc769b606c8d73cae19d0cb Mon Sep 17 00:00:00 2001 From: in1tiate Date: Fri, 12 Mar 2021 22:48:44 -0600 Subject: [PATCH 23/46] fix /mods --- src/commands.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands.cpp b/src/commands.cpp index 8b87a42..d4d3884 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -781,8 +781,8 @@ void AOClient::cmdMods(int argc, QStringList argv) if (client->authenticated) { entries << "---"; if (auth_type != "simple") - entries << "Moderator: " + moderator_name; - entries << "OOC name: " + ooc_name; + entries << "Moderator: " + client->moderator_name; + entries << "OOC name: " + client->ooc_name; entries << "ID: " + QString::number(client->id); entries << "Area: " + QString::number(client->current_area); entries << "Character: " + client->current_char; From 18f76d68eae2d889296027ede3039502b645d7be Mon Sep 17 00:00:00 2001 From: scatterflower Date: Sat, 13 Mar 2021 03:17:46 -0600 Subject: [PATCH 24/46] fix crash from old music packets --- src/packets.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/packets.cpp b/src/packets.cpp index 421688f..9cc9989 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -210,9 +210,14 @@ void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPack for (QString song : server->music_list) { if (song == argument || song == "~stop.mp3") { // ~stop.mp3 is a dummy track used by 2.9+ // We have a song here - AOPacket music_change("MC", {song, argv[1], argv[2], "1", "0", argv[3]}); + QString effects; + if (argc >= 4) + effects = argv[3]; + else + effects = "0"; + AOPacket music_change("MC", {song, argv[1], showname, "1", "0", effects}); area->current_music = song; - area->music_played_by = argv[2]; + area->music_played_by = showname; server->broadcast(music_change, current_area); return; } From f45099e47b9630b1d762d30521a6b234ff801fa4 Mon Sep 17 00:00:00 2001 From: scatterflower Date: Sat, 13 Mar 2021 05:10:36 -0600 Subject: [PATCH 25/46] implement tsu-like time parsing --- include/aoclient.h | 7 +++- src/commands.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 4ff94c7..0cbf476 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -240,11 +240,15 @@ class AOClient : public QObject { void cmdToggleGlobal(int argc, QStringList argv); void cmdPM(int argc, QStringList argv); + // DELETE THIS LATER MARISA + void cmdTestDateTime(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); + long long parseTime(QString input); // Command function global variables bool change_auth_started = false; @@ -309,7 +313,8 @@ class AOClient : public QObject { {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}}, {"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}}, {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, - {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}} + {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}}, + {"test", {ACLFlags.value("NONE"), 1, &AOClient::cmdTestDateTime}} }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index 04243a9..c0f2d18 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -89,19 +89,44 @@ void AOClient::cmdGetArea(int argc, QStringList argv) void AOClient::cmdBan(int argc, QStringList argv) { + QString args_str = argv[1]; + if (argc > 2) { + for (int i = 2; i < argc; i++) + args_str += " " + argv[i]; + } + + QRegularExpression quoteMatcher("['\"](.+?)[\"']"); + QRegularExpressionMatchIterator matches = quoteMatcher.globalMatch(args_str); + QList unquoted_args; + while (matches.hasNext()) { + QRegularExpressionMatch match = matches.next(); + unquoted_args.append(match.captured(1)); + } + + QString reason; + QString duration = "perma"; + + if (unquoted_args.length() < 1) { + sendServerMessage("Invalid syntax. Usage:\n/ban \"\" \"\""); + return; + } + + reason = unquoted_args.at(0); + if (unquoted_args.length() > 1) + duration = unquoted_args.at(1); + + + qDebug() << "Reason: " << reason; + qDebug() << "Duration: " << duration; + return; + QString target_ipid = argv[0]; QHostAddress ip; QString hdid; unsigned long time = QDateTime::currentDateTime().toTime_t(); - QString reason = argv[1]; + //QString reason = argv[1]; bool ban_logged = false; - if (argc > 2) { - for (int i = 2; i < argv.length(); i++) { - reason += " " + argv[i]; - } - } - for (AOClient* client : server->clients) { if (client->getIpid() == target_ipid) { if (!ban_logged) { @@ -1019,3 +1044,53 @@ QString AOClient::getAreaTimer(int area_idx, QTimer* timer) } } +void AOClient::cmdTestDateTime(int argc, QStringList argv) +{ + qDebug() << parseTime(argv[0]); +} + +long long AOClient::parseTime(QString input) +{ + QRegularExpression regex("(?:(?:(?.*?)y)*(?:(?.*?)w)*(?:(?.*?)d)*(?:(?
.*?)h)*(?:(?.*?)m)*(?:(?.*?)s)*)"); + QRegularExpressionMatch match = regex.match(input); + QString str_year, str_week, str_hour, str_day, str_minute, str_second; + int year, week, day, hour, minute, second; + + str_year = match.captured("year"); + str_week = match.captured("week"); + str_day = match.captured("day"); + str_hour = match.captured("hr"); + str_minute = match.captured("min"); + str_second = match.captured("sec"); + + qDebug() << str_year << "years," << str_week << "weeks," << str_day << "days," << str_hour << "hours," << str_minute << "minutes," << str_second << "seconds"; + + bool is_well_formed = false; + QString concat_str(str_year + str_week + str_day + str_hour + str_minute + str_second); + concat_str.toInt(&is_well_formed); + + if (!is_well_formed) { + qDebug() << "retard alert!"; + return -1; + } + + year = str_year.toInt(); + week = str_week.toInt(); + day = str_day.toInt(); + hour = str_hour.toInt(); + minute = str_minute.toInt(); + second = str_second.toInt(); + + long long total = 0; + total += 31622400 * year; + total += 604800 * week; + total += 86400 * day; + total += 3600 * hour; + total += 60 * minute; + total += second; + + if (total < 0) + return -1; + + return total; +} From 6a38e50c4f5a73ad14deaf14222078dd456fad5c Mon Sep 17 00:00:00 2001 From: scatterflower Date: Sat, 13 Mar 2021 13:25:09 -0600 Subject: [PATCH 26/46] add ban durations (only works for hdid atm) --- include/db_manager.h | 5 +++- src/commands.cpp | 19 ++++++++----- src/db_manager.cpp | 63 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/include/db_manager.h b/include/db_manager.h index 150d751..d18b87a 100644 --- a/include/db_manager.h +++ b/include/db_manager.h @@ -19,6 +19,7 @@ #define BAN_MANAGER_H #include +#include #include #include #include @@ -37,8 +38,10 @@ public: QString getBanReason(QHostAddress ip); QString getBanReason(QString hdid); + long long getBanDuration(QString hdid); + long long getBanDuration(QHostAddress hdid); - void addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason); + void addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason, long long duration); bool createUser(QString username, QString salt, QString password, unsigned long long acl); unsigned long long getACL(QString moderator_name); diff --git a/src/commands.cpp b/src/commands.cpp index c0f2d18..071ad85 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -115,16 +115,21 @@ void AOClient::cmdBan(int argc, QStringList argv) if (unquoted_args.length() > 1) duration = unquoted_args.at(1); + long long duration_seconds = 0; + if (duration == "perma") + duration_seconds = -2; + else + duration_seconds = parseTime(duration); - qDebug() << "Reason: " << reason; - qDebug() << "Duration: " << duration; - return; + if (duration_seconds == -1) { + sendServerMessage("Invalid time format. Format example: 1h30m"); + return; + } QString target_ipid = argv[0]; QHostAddress ip; QString hdid; - unsigned long time = QDateTime::currentDateTime().toTime_t(); - //QString reason = argv[1]; + unsigned long time = QDateTime::currentDateTime().toSecsSinceEpoch(); bool ban_logged = false; for (AOClient* client : server->clients) { @@ -132,8 +137,8 @@ void AOClient::cmdBan(int argc, QStringList argv) if (!ban_logged) { ip = client->remote_ip; hdid = client->hwid; - server->db_manager->addBan(target_ipid, ip, hdid, time, reason); - sendServerMessage("Banned user with ipid " + target_ipid + " for reason: " + reason); + server->db_manager->addBan(target_ipid, ip, hdid, time, reason, duration_seconds); + sendServerMessage("Banned user with ipid " + target_ipid + " for " + duration + ". Reason: " + reason); ban_logged = true; } client->sendPacket("KB", {reason}); diff --git a/src/db_manager.cpp b/src/db_manager.cpp index f23f20e..0ea610d 100644 --- a/src/db_manager.cpp +++ b/src/db_manager.cpp @@ -24,26 +24,46 @@ DBManager::DBManager() : db.setDatabaseName("config/akashi.db"); if (!db.open()) qCritical() << "Database Error:" << db.lastError(); - QSqlQuery create_ban_table("CREATE TABLE IF NOT EXISTS bans ('ID' INTEGER, 'IPID' TEXT, 'HDID' TEXT, 'IP' TEXT, 'TIME' INTEGER, 'REASON' TEXT, PRIMARY KEY('ID' AUTOINCREMENT))"); + QSqlQuery create_ban_table("CREATE TABLE IF NOT EXISTS bans ('ID' INTEGER, 'IPID' TEXT, 'HDID' TEXT, 'IP' TEXT, 'TIME' INTEGER, 'REASON' TEXT, 'DURATION' INTEGER, PRIMARY KEY('ID' AUTOINCREMENT))"); QSqlQuery create_user_table("CREATE TABLE IF NOT EXISTS users ('ID' INTEGER, 'USERNAME' TEXT, 'SALT' TEXT, 'PASSWORD' TEXT, 'ACL' TEXT, PRIMARY KEY('ID' AUTOINCREMENT))"); } bool DBManager::isIPBanned(QHostAddress ip) { QSqlQuery query; - query.prepare("SELECT ID FROM BANS WHERE IP = ?"); + query.prepare("SELECT DURATION FROM BANS WHERE IP = ? ORDER BY TIME DESC"); query.addBindValue(ip.toString()); query.exec(); - return query.first(); + if (query.first()) { + long long duration = getBanDuration(ip); + long long ban_time = query.value(0).toLongLong(); + if (duration == -2) + return true; + long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); + if (ban_time + duration > current_time) + return true; + else return false; + } + else return false; } bool DBManager::isHDIDBanned(QString hdid) { QSqlQuery query; - query.prepare("SELECT ID FROM BANS WHERE HDID = ?"); + query.prepare("SELECT TIME FROM BANS WHERE HDID = ? ORDER BY TIME DESC"); query.addBindValue(hdid); query.exec(); - return query.first(); + if (query.first()) { + long long duration = getBanDuration(hdid); + long long ban_time = query.value(0).toLongLong(); + if (duration == -2) + return true; + long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); + if (ban_time + duration > current_time) + return true; + else return false; + } + else return false; } QString DBManager::getBanReason(QHostAddress ip) @@ -74,15 +94,44 @@ QString DBManager::getBanReason(QString hdid) } } -void DBManager::addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason) +long long DBManager::getBanDuration(QString hdid) { QSqlQuery query; - query.prepare("INSERT INTO BANS(IPID, HDID, IP, TIME, REASON) VALUES(?, ?, ?, ?, ?)"); + query.prepare("SELECT DURATION FROM BANS WHERE HDID = ?"); + query.addBindValue(hdid); + query.exec(); + if (query.first()) { + return query.value(0).toLongLong(); + } + else { + return -1; + } +} + +long long DBManager::getBanDuration(QHostAddress ip) +{ + QSqlQuery query; + query.prepare("SELECT DURATION FROM BANS WHERE IP = ?"); + query.addBindValue(ip.toString()); + query.exec(); + if (query.first()) { + return query.value(0).toLongLong(); + } + else { + return -1; + } +} + +void DBManager::addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason, long long duration) +{ + QSqlQuery query; + query.prepare("INSERT INTO BANS(IPID, HDID, IP, TIME, REASON, DURATION) VALUES(?, ?, ?, ?, ?, ?)"); query.addBindValue(ipid); query.addBindValue(hdid); query.addBindValue(ip.toString()); query.addBindValue(QString::number(time)); query.addBindValue(reason); + query.addBindValue(duration); if (!query.exec()) qDebug() << "SQL Error:" << query.lastError().text(); } From fa72e87e34fcfa0012bffc0c9279b6a90658a2d4 Mon Sep 17 00:00:00 2001 From: scatterflower Date: Sat, 13 Mar 2021 13:33:47 -0600 Subject: [PATCH 27/46] fix ip bans and generally make it work correctly --- src/db_manager.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/db_manager.cpp b/src/db_manager.cpp index 0ea610d..cdd68c1 100644 --- a/src/db_manager.cpp +++ b/src/db_manager.cpp @@ -31,12 +31,13 @@ DBManager::DBManager() : bool DBManager::isIPBanned(QHostAddress ip) { QSqlQuery query; - query.prepare("SELECT DURATION FROM BANS WHERE IP = ? ORDER BY TIME DESC"); + query.prepare("SELECT TIME FROM BANS WHERE IP = ? ORDER BY TIME DESC"); query.addBindValue(ip.toString()); query.exec(); if (query.first()) { long long duration = getBanDuration(ip); long long ban_time = query.value(0).toLongLong(); + qDebug() << ban_time << "duration:" << duration; if (duration == -2) return true; long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); @@ -69,7 +70,7 @@ bool DBManager::isHDIDBanned(QString hdid) QString DBManager::getBanReason(QHostAddress ip) { QSqlQuery query; - query.prepare("SELECT REASON FROM BANS WHERE IP = ?"); + query.prepare("SELECT REASON FROM BANS WHERE IP = ? ORDER BY TIME DESC"); query.addBindValue(ip.toString()); query.exec(); if (query.first()) { @@ -83,7 +84,7 @@ QString DBManager::getBanReason(QHostAddress ip) QString DBManager::getBanReason(QString hdid) { QSqlQuery query; - query.prepare("SELECT REASON FROM BANS WHERE HDID = ?"); + query.prepare("SELECT REASON FROM BANS WHERE HDID = ? ORDER BY TIME DESC"); query.addBindValue(hdid); query.exec(); if (query.first()) { @@ -97,7 +98,7 @@ QString DBManager::getBanReason(QString hdid) long long DBManager::getBanDuration(QString hdid) { QSqlQuery query; - query.prepare("SELECT DURATION FROM BANS WHERE HDID = ?"); + query.prepare("SELECT DURATION FROM BANS WHERE HDID = ? ORDER BY TIME DESC"); query.addBindValue(hdid); query.exec(); if (query.first()) { @@ -111,7 +112,7 @@ long long DBManager::getBanDuration(QString hdid) long long DBManager::getBanDuration(QHostAddress ip) { QSqlQuery query; - query.prepare("SELECT DURATION FROM BANS WHERE IP = ?"); + query.prepare("SELECT DURATION FROM BANS WHERE IP = ? ORDER BY TIME DESC"); query.addBindValue(ip.toString()); query.exec(); if (query.first()) { From 5368601b6750df0ecb2c0c7fd35e5a5d424a719d Mon Sep 17 00:00:00 2001 From: scatterflower Date: Sat, 13 Mar 2021 13:40:37 -0600 Subject: [PATCH 28/46] remove desu --- include/aoclient.h | 6 +----- src/commands.cpp | 8 -------- src/db_manager.cpp | 1 - 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 0cbf476..061b193 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -240,9 +240,6 @@ class AOClient : public QObject { void cmdToggleGlobal(int argc, QStringList argv); void cmdPM(int argc, QStringList argv); - // DELETE THIS LATER MARISA - void cmdTestDateTime(int argc, QStringList argv); - // Command helper functions QString getAreaTimer(int area_idx, QTimer* timer); QStringList buildAreaList(int area_idx); @@ -313,8 +310,7 @@ class AOClient : public QObject { {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}}, {"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}}, {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, - {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}}, - {"test", {ACLFlags.value("NONE"), 1, &AOClient::cmdTestDateTime}} + {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}} }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index 071ad85..e290fe5 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1049,11 +1049,6 @@ QString AOClient::getAreaTimer(int area_idx, QTimer* timer) } } -void AOClient::cmdTestDateTime(int argc, QStringList argv) -{ - qDebug() << parseTime(argv[0]); -} - long long AOClient::parseTime(QString input) { QRegularExpression regex("(?:(?:(?.*?)y)*(?:(?.*?)w)*(?:(?.*?)d)*(?:(?
.*?)h)*(?:(?.*?)m)*(?:(?.*?)s)*)"); @@ -1068,14 +1063,11 @@ long long AOClient::parseTime(QString input) str_minute = match.captured("min"); str_second = match.captured("sec"); - qDebug() << str_year << "years," << str_week << "weeks," << str_day << "days," << str_hour << "hours," << str_minute << "minutes," << str_second << "seconds"; - bool is_well_formed = false; QString concat_str(str_year + str_week + str_day + str_hour + str_minute + str_second); concat_str.toInt(&is_well_formed); if (!is_well_formed) { - qDebug() << "retard alert!"; return -1; } diff --git a/src/db_manager.cpp b/src/db_manager.cpp index cdd68c1..6a0c0b7 100644 --- a/src/db_manager.cpp +++ b/src/db_manager.cpp @@ -37,7 +37,6 @@ bool DBManager::isIPBanned(QHostAddress ip) if (query.first()) { long long duration = getBanDuration(ip); long long ban_time = query.value(0).toLongLong(); - qDebug() << ban_time << "duration:" << duration; if (duration == -2) return true; long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); From 6f1d17f923e1ae544e403e1b26f51861379c14c6 Mon Sep 17 00:00:00 2001 From: scatterflower <2956568+scatterflower@users.noreply.github.com> Date: Sat, 13 Mar 2021 13:57:58 -0600 Subject: [PATCH 29/46] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3681abc..862d627 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,8 @@ Requires Qt >= 5.10, and Qt websockets make ``` -Copyright © scatterflower 2021 \ No newline at end of file +Copyright © scatterflower 2020-2021 + +Copyright © Salanto 2021 + +Copyright © in1tiate 2021 From c6733396533f8681f44972b1e41babafdaae6539 Mon Sep 17 00:00:00 2001 From: scatterflower Date: Sun, 14 Mar 2021 08:21:58 -0500 Subject: [PATCH 30/46] Add mute and unmute --- include/aoclient.h | 8 +++++++- src/commands.cpp | 32 ++++++++++++++++++++++++++++++++ src/packets.cpp | 5 +++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/aoclient.h b/include/aoclient.h index 061b193..2da1478 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -59,6 +59,7 @@ class AOClient : public QObject { QString ooc_name = ""; QString showname = ""; bool global_enabled = true; + bool is_muted = false; struct ClientVersion { QString string; int release = -1; @@ -79,6 +80,7 @@ class AOClient : public QObject { {"MOTD", 1ULL << 7}, {"ANNOUNCE", 1ULL << 8}, {"MODCHAT", 1ULL << 9}, + {"MUTE", 1ULL << 10}, {"SUPER", ~0ULL} }; @@ -221,6 +223,8 @@ class AOClient : public QObject { void cmdAnnounce(int argc, QStringList argv); void cmdM(int argc, QStringList argv); void cmdGM(int argc, QStringList argv); + void cmdMute(int argc, QStringList argv); + void cmdUnmute(int argc, QStringList argv); // Casing/RP void cmdPlay(int argc, QStringList argv); void cmdNeed(int argc, QStringList argv); @@ -310,7 +314,9 @@ class AOClient : public QObject { {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}}, {"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}}, {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, - {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}} + {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}}, + {"mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdMute}}, + {"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnmute}} }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index e290fe5..0a6df94 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -933,6 +933,38 @@ void AOClient::cmdGM(int argc, QStringList argv) } } +void AOClient::cmdMute(int argc, QStringList argv) +{ + bool conv_ok = false; + int uid = argv[0].toInt(&conv_ok); + if (!conv_ok) { + sendServerMessage("Invalid user ID."); + return; + } + + if (server->getClientByID(uid)->is_muted) + sendServerMessage("That player is already muted!"); + else + sendServerMessage("Muted player."); + server->getClientByID(uid)->is_muted = true; +} + +void AOClient::cmdUnmute(int argc, QStringList argv) +{ + bool conv_ok = false; + int uid = argv[0].toInt(&conv_ok); + if (!conv_ok) { + sendServerMessage("Invalid user ID."); + return; + } + + if (!server->getClientByID(uid)->is_muted) + sendServerMessage("That player is already unmuted!"); + else + sendServerMessage("Unmuted player."); + server->getClientByID(uid)->is_muted = false; +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; diff --git a/src/packets.cpp b/src/packets.cpp index 9cc9989..6dcd25f 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -154,6 +154,11 @@ void AOClient::pktSelectChar(AreaData* area, int argc, QStringList argv, AOPacke void AOClient::pktIcChat(AreaData* area, int argc, QStringList argv, AOPacket packet) { + if (is_muted) { + sendServerMessage("You cannot speak while muted."); + return; + } + AOPacket validated_packet = validateIcPacket(packet); if (validated_packet.header == "INVALID") return; From ae0d308ec786b51bf6ae88a4beff3e794bfaa261 Mon Sep 17 00:00:00 2001 From: scatterflower Date: Sun, 14 Mar 2021 12:01:27 -0500 Subject: [PATCH 31/46] apparently ipids are different --- include/aoclient.h | 5 ++--- src/aoclient.cpp | 16 ++++++---------- src/packets.cpp | 9 +++++---- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index 2da1478..1d663fe 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -42,10 +42,9 @@ class AOClient : public QObject { AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent = nullptr, int user_id = 0); ~AOClient(); - QString getHwid(); - QString getIpid(); Server* getServer(); - void setHwid(QString p_hwid); + QString getIpid(); + void calculateIpid(); int id; diff --git a/src/aoclient.cpp b/src/aoclient.cpp index 2d8f26c..10521af 100644 --- a/src/aoclient.cpp +++ b/src/aoclient.cpp @@ -28,6 +28,7 @@ AOClient::AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent, int current_area = 0; current_char = ""; remote_ip = p_socket->peerAddress(); + calculateIpid(); is_partial = false; last_wtce_time = 0; last_message = ""; @@ -274,22 +275,17 @@ void AOClient::sendPacket(QString header) sendPacket(AOPacket(header, {})); } -QString AOClient::getHwid() { return hwid; } - -void AOClient::setHwid(QString p_hwid) +void AOClient::calculateIpid() { - // TODO: add support for longer hwids? + // TODO: add support for longer ipids? // This reduces the (fairly high) chance of // birthday paradox issues arising. However, // typing more than 8 characters might be a // bit cumbersome. - hwid = p_hwid; - QCryptographicHash hash( - QCryptographicHash::Md5); // Don't need security, just - // hashing for uniqueness - QString concat_ip_id = remote_ip.toString() + p_hwid; - hash.addData(concat_ip_id.toUtf8()); + QCryptographicHash hash(QCryptographicHash::Md5); // Don't need security, just hashing for uniqueness + + hash.addData(remote_ip.toString().toUtf8()); ipid = hash.result().toHex().right(8); // Use the last 8 characters (4 bytes) } diff --git a/src/packets.cpp b/src/packets.cpp index 6dcd25f..9cfc22a 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -26,9 +26,9 @@ void AOClient::pktDefault(AreaData* area, int argc, QStringList argv, AOPacket p void AOClient::pktHardwareId(AreaData* area, int argc, QStringList argv, AOPacket packet) { - setHwid(argv[0]); - if(server->db_manager->isHDIDBanned(getHwid())) { - sendPacket("BD", {server->db_manager->getBanReason(getHwid())}); + hwid = argv[0]; + if(server->db_manager->isHDIDBanned(hwid)) { + sendPacket("BD", {server->db_manager->getBanReason(hwid)}); socket->close(); return; } @@ -88,7 +88,7 @@ void AOClient::pktRequestMusic(AreaData* area, int argc, QStringList argv, AOPac void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPacket packet) { - if (getHwid() == "") { + if (hwid == "") { // No early connecting! socket->close(); return; @@ -271,6 +271,7 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack qDebug() << "ws ip set to" << argv[0]; #endif remote_ip = QHostAddress(argv[0]); + calculateIpid(); } } From 2a8ed66c4f8dd23045780df340e1c1ed4a2531be Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 12:11:18 -0500 Subject: [PATCH 32/46] rework getClient into getClientsByIpid, alter /ban and /kick to report number of clients affected --- include/server.h | 2 +- src/commands.cpp | 40 ++++++++++++++++++++-------------------- src/server.cpp | 7 ++++--- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/include/server.h b/include/server.h index 14c4883..16f045a 100644 --- a/include/server.h +++ b/include/server.h @@ -46,7 +46,7 @@ class Server : public QObject { ~Server(); void start(); - AOClient* getClient(QString ipid); + QList getClientsByIpid(QString ipid); AOClient* getClientByID(int id); void updateCharsTaken(AreaData* area); void broadcast(AOPacket packet, int area_index); diff --git a/src/commands.cpp b/src/commands.cpp index 04243a9..6756859 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -95,6 +95,7 @@ void AOClient::cmdBan(int argc, QStringList argv) unsigned long time = QDateTime::currentDateTime().toTime_t(); QString reason = argv[1]; bool ban_logged = false; + int kick_counter = 0; if (argc > 2) { for (int i = 2; i < argv.length(); i++) { @@ -102,20 +103,21 @@ void AOClient::cmdBan(int argc, QStringList argv) } } - for (AOClient* client : server->clients) { - if (client->getIpid() == target_ipid) { - if (!ban_logged) { - ip = client->remote_ip; - hdid = client->hwid; - server->db_manager->addBan(target_ipid, ip, hdid, time, reason); - sendServerMessage("Banned user with ipid " + target_ipid + " for reason: " + reason); - ban_logged = true; - } - client->sendPacket("KB", {reason}); - client->socket->close(); + for (AOClient* client : server->getClientsByIpid(target_ipid)) { + if (!ban_logged) { + ip = client->remote_ip; + hdid = client->hwid; + server->db_manager->addBan(target_ipid, ip, hdid, time, reason); + sendServerMessage("Banned user with ipid " + target_ipid + " for reason: " + reason); + ban_logged = true; } + client->sendPacket("KB", {reason}); + client->socket->close(); + kick_counter++; } + if (kick_counter > 1) + sendServerMessage("Kicked " + QString::number(kick_counter) + " clients with matching ipids"); if (!ban_logged) sendServerMessage("User with ipid not found!"); } @@ -124,7 +126,7 @@ void AOClient::cmdKick(int argc, QStringList argv) { QString target_ipid = argv[0]; QString reason = argv[1]; - bool did_kick = false; + int kick_counter = 0; if (argc > 2) { for (int i = 2; i < argv.length(); i++) { @@ -132,16 +134,14 @@ void AOClient::cmdKick(int argc, QStringList argv) } } - for (AOClient* client : server->clients) { - if (client->getIpid() == target_ipid) { - client->sendPacket("KK", {reason}); - client->socket->close(); - did_kick = true; - } + for (AOClient* client : server->getClientsByIpid(target_ipid)) { + client->sendPacket("KK", {reason}); + client->socket->close(); + kick_counter++; } - if (did_kick) - sendServerMessage("Kicked user with ipid " + target_ipid + " for reason: " + reason); + if (kick_counter > 0) + sendServerMessage("Kicked " + QString::number(kick_counter) + " client(s) with ipid " + target_ipid + " for reason: " + reason); else sendServerMessage("User with ipid not found!"); } diff --git a/src/server.cpp b/src/server.cpp index 35d0281..17c6efc 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -185,13 +185,14 @@ int Server::getDiceValue(QString value_type) return value; } -AOClient* Server::getClient(QString ipid) +QList Server::getClientsByIpid(QString ipid) { + QList return_clients; for (AOClient* client : clients) { if (client->getIpid() == ipid) - return client; + return_clients.append(client); } - return nullptr; + return return_clients; } AOClient* Server::getClientByID(int id) From b5779b1aa5b60459dd2d8ff3366fe2eacf591106 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 13:13:26 -0500 Subject: [PATCH 33/46] add /bans --- include/aoclient.h | 4 +++- include/db_manager.h | 10 ++++++++++ src/commands.cpp | 16 ++++++++++++++++ src/db_manager.cpp | 21 +++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/aoclient.h b/include/aoclient.h index 1d663fe..48e9606 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -224,6 +224,7 @@ class AOClient : public QObject { void cmdGM(int argc, QStringList argv); void cmdMute(int argc, QStringList argv); void cmdUnmute(int argc, QStringList argv); + void cmdBans(int argc, QStringList argv); // Casing/RP void cmdPlay(int argc, QStringList argv); void cmdNeed(int argc, QStringList argv); @@ -315,7 +316,8 @@ class AOClient : public QObject { {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}}, {"mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdMute}}, - {"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnmute}} + {"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnmute}}, + {"bans", {ACLFlags.value("BAN"), 0, &AOClient::cmdBans}} }; QString partial_packet; diff --git a/include/db_manager.h b/include/db_manager.h index d18b87a..a93b7a4 100644 --- a/include/db_manager.h +++ b/include/db_manager.h @@ -41,6 +41,16 @@ public: long long getBanDuration(QString hdid); long long getBanDuration(QHostAddress hdid); + struct BanInfo { + QString ipid; + QHostAddress ip; + QString hdid; + unsigned long time; + QString reason; + long long duration; + }; + QList getRecentBans(); + void addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason, long long duration); bool createUser(QString username, QString salt, QString password, unsigned long long acl); diff --git a/src/commands.cpp b/src/commands.cpp index 033050b..3325a20 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -971,6 +971,22 @@ void AOClient::cmdUnmute(int argc, QStringList argv) server->getClientByID(uid)->is_muted = false; } +void AOClient::cmdBans(int argc, QStringList argv) +{ + QStringList recent_bans; + recent_bans << "Last 5 bans:"; + recent_bans << "-----"; + for (DBManager::BanInfo ban : server->db_manager->getRecentBans()) { + recent_bans << "Affected IPID: " + ban.ipid; + recent_bans << "Affected HDID: " + ban.hdid; + recent_bans << "Reason for ban: " + ban.reason; + recent_bans << "Date of ban: " + QDateTime::fromSecsSinceEpoch(ban.time).toString("dd.MM.yyyy, hh:mm"); + recent_bans << "Ban lasts until: " + QDateTime::fromSecsSinceEpoch(ban.time).addSecs(ban.duration).toString("dd.MM.yyyy, hh:mm"); + recent_bans << "-----"; + } + sendServerMessage(recent_bans.join("\n")); +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; diff --git a/src/db_manager.cpp b/src/db_manager.cpp index 6a0c0b7..e203fcc 100644 --- a/src/db_manager.cpp +++ b/src/db_manager.cpp @@ -122,6 +122,27 @@ long long DBManager::getBanDuration(QHostAddress ip) } } +QList DBManager::getRecentBans() +{ + QList return_list; + QSqlQuery query; + query.prepare("SELECT TOP(5) * FROM BANS ORDER BY TIME DESC"); + query.setForwardOnly(true); + query.exec(); + while (query.next()) { + BanInfo ban; + ban.ipid = query.value(0).toString(); + ban.hdid = query.value(1).toString(); + ban.ip = QHostAddress(query.value(2).toString()); + ban.time = static_cast(query.value(3).toULongLong()); + ban.reason = query.value(4).toString(); + ban.duration = query.value(5).toLongLong(); + return_list.append(ban); + } + std::reverse(return_list.begin(), return_list.end()); + return return_list; +} + void DBManager::addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason, long long duration) { QSqlQuery query; From b562b77be9fb9cc232eb79cacaa3b907d7586c7e Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 13:28:59 -0500 Subject: [PATCH 34/46] use BanInfo for inserting bans, send ban id and duration with KB packet --- include/db_manager.h | 6 ++++-- src/commands.cpp | 29 +++++++++++++++-------------- src/db_manager.cpp | 44 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/include/db_manager.h b/include/db_manager.h index a93b7a4..e99ca76 100644 --- a/include/db_manager.h +++ b/include/db_manager.h @@ -39,7 +39,9 @@ public: QString getBanReason(QHostAddress ip); QString getBanReason(QString hdid); long long getBanDuration(QString hdid); - long long getBanDuration(QHostAddress hdid); + long long getBanDuration(QHostAddress ip); + int getBanID(QString hdid); + int getBanID(QHostAddress ip); struct BanInfo { QString ipid; @@ -51,7 +53,7 @@ public: }; QList getRecentBans(); - void addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason, long long duration); + void addBan(BanInfo ban); bool createUser(QString username, QString salt, QString password, unsigned long long acl); unsigned long long getACL(QString moderator_name); diff --git a/src/commands.cpp b/src/commands.cpp index 3325a20..605f224 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -95,6 +95,8 @@ void AOClient::cmdBan(int argc, QStringList argv) args_str += " " + argv[i]; } + DBManager::BanInfo ban; + QRegularExpression quoteMatcher("['\"](.+?)[\"']"); QRegularExpressionMatchIterator matches = quoteMatcher.globalMatch(args_str); QList unquoted_args; @@ -103,7 +105,6 @@ void AOClient::cmdBan(int argc, QStringList argv) unquoted_args.append(match.captured(1)); } - QString reason; QString duration = "perma"; if (unquoted_args.length() < 1) { @@ -111,7 +112,7 @@ void AOClient::cmdBan(int argc, QStringList argv) return; } - reason = unquoted_args.at(0); + ban.reason = unquoted_args.at(0); if (unquoted_args.length() > 1) duration = unquoted_args.at(1); @@ -126,34 +127,34 @@ void AOClient::cmdBan(int argc, QStringList argv) return; } - QString target_ipid = argv[0]; - QHostAddress ip; - QString hdid; - unsigned long time = QDateTime::currentDateTime().toSecsSinceEpoch(); + ban.duration = duration_seconds; + + ban.ipid = argv[0]; + ban.time = QDateTime::currentDateTime().toSecsSinceEpoch(); bool ban_logged = false; int kick_counter = 0; if (argc > 2) { for (int i = 2; i < argv.length(); i++) { - reason += " " + argv[i]; + ban.reason += " " + argv[i]; } } - for (AOClient* client : server->getClientsByIpid(target_ipid)) { + for (AOClient* client : server->getClientsByIpid(ban.ipid)) { if (!ban_logged) { - ip = client->remote_ip; - hdid = client->hwid; - server->db_manager->addBan(target_ipid, ip, hdid, time, reason, duration_seconds); - sendServerMessage("Banned user with ipid " + target_ipid + " for reason: " + reason); + ban.ip = client->remote_ip; + ban.hdid = client->hwid; + server->db_manager->addBan(ban); + sendServerMessage("Banned user with ipid " + ban.ipid + " for reason: " + ban.reason); ban_logged = true; } - client->sendPacket("KB", {reason}); + client->sendPacket("KB", {ban.reason + "\nID: " + QString::number(server->db_manager->getBanID(ban.ip)) + "\nUntil: " + QDateTime::fromSecsSinceEpoch(ban.time).addSecs(ban.duration).toString("dd.MM.yyyy, hh:mm")}); client->socket->close(); kick_counter++; } if (kick_counter > 1) - sendServerMessage("Kicked " + QString::number(kick_counter) + " clients with matching ipids"); + sendServerMessage("Kicked " + QString::number(kick_counter) + " clients with matching ipids."); if (!ban_logged) sendServerMessage("User with ipid not found!"); } diff --git a/src/db_manager.cpp b/src/db_manager.cpp index e203fcc..335e10b 100644 --- a/src/db_manager.cpp +++ b/src/db_manager.cpp @@ -122,6 +122,36 @@ long long DBManager::getBanDuration(QHostAddress ip) } } + +int DBManager::getBanID(QString hdid) +{ + QSqlQuery query; + query.prepare("SELECT ID FROM BANS WHERE HDID = ?"); + query.addBindValue(hdid); + query.exec(); + if (query.first()) { + return query.value(0).toInt(); + } + else { + return -1; + } +} + + +int DBManager::getBanID(QHostAddress ip) +{ + QSqlQuery query; + query.prepare("SELECT ID FROM BANS WHERE IP = ?"); + query.addBindValue(ip.toString()); + query.exec(); + if (query.first()) { + return query.value(0).toInt(); + } + else { + return -1; + } +} + QList DBManager::getRecentBans() { QList return_list; @@ -143,16 +173,16 @@ QList DBManager::getRecentBans() return return_list; } -void DBManager::addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason, long long duration) +void DBManager::addBan(BanInfo ban) { QSqlQuery query; query.prepare("INSERT INTO BANS(IPID, HDID, IP, TIME, REASON, DURATION) VALUES(?, ?, ?, ?, ?, ?)"); - query.addBindValue(ipid); - query.addBindValue(hdid); - query.addBindValue(ip.toString()); - query.addBindValue(QString::number(time)); - query.addBindValue(reason); - query.addBindValue(duration); + query.addBindValue(ban.ipid); + query.addBindValue(ban.hdid); + query.addBindValue(ban.ip.toString()); + query.addBindValue(QString::number(ban.time)); + query.addBindValue(ban.reason); + query.addBindValue(ban.duration); if (!query.exec()) qDebug() << "SQL Error:" << query.lastError().text(); } From 9b32188cc6d93fdde631d2af4b65c19d27167ac0 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 13:44:12 -0500 Subject: [PATCH 35/46] add /unban and /removeuser --- include/aoclient.h | 7 ++++++- include/db_manager.h | 2 ++ src/commands.cpp | 22 ++++++++++++++++++++++ src/db_manager.cpp | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/include/aoclient.h b/include/aoclient.h index 48e9606..8370489 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -193,6 +193,7 @@ class AOClient : public QObject { void cmdChangeAuth(int argc, QStringList argv); void cmdSetRootPass(int argc, QStringList argv); void cmdAddUser(int argc, QStringList argv); + void cmdRemoveUser(int argc, QStringList argv); void cmdListPerms(int argc, QStringList argv); void cmdAddPerms(int argc, QStringList argv); void cmdRemovePerms(int argc, QStringList argv); @@ -218,6 +219,7 @@ class AOClient : public QObject { // Moderation void cmdMods(int argc, QStringList argv); void cmdBan(int argc, QStringList argv); + void cmdUnBan(int argc, QStringList argv); void cmdKick(int argc, QStringList argv); void cmdAnnounce(int argc, QStringList argv); void cmdM(int argc, QStringList argv); @@ -317,7 +319,10 @@ class AOClient : public QObject { {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}}, {"mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdMute}}, {"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnmute}}, - {"bans", {ACLFlags.value("BAN"), 0, &AOClient::cmdBans}} + {"bans", {ACLFlags.value("BAN"), 0, &AOClient::cmdBans}}, + {"unban", {ACLFlags.value("BAN"), 1, &AOClient::cmdUnBan}}, + {"removeuser", {ACLFlags.value("MODIFY_USERS"), 1, &AOClient::cmdRemoveUser}}, + }; QString partial_packet; diff --git a/include/db_manager.h b/include/db_manager.h index e99ca76..636f3f1 100644 --- a/include/db_manager.h +++ b/include/db_manager.h @@ -54,8 +54,10 @@ public: QList getRecentBans(); void addBan(BanInfo ban); + bool invalidateBan(int id); bool createUser(QString username, QString salt, QString password, unsigned long long acl); + bool deleteUser(QString username); unsigned long long getACL(QString moderator_name); bool authenticate(QString username, QString password); bool updateACL(QString username, unsigned long long acl, bool mode); diff --git a/src/commands.cpp b/src/commands.cpp index 605f224..8789554 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -269,6 +269,14 @@ void AOClient::cmdAddUser(int argc, QStringList argv) sendServerMessage("Unable to create user " + argv[0] + ".\nDoes a user with that name already exist?"); } +void AOClient::cmdRemoveUser(int argc, QStringList argv) +{ + if (server->db_manager->deleteUser(argv[0])) + sendServerMessage("Successfully removed user " + argv[0] + "."); + else + sendServerMessage("Unable to remove user " + argv[0] + ".\nDoes it exist?"); +} + void AOClient::cmdListPerms(int argc, QStringList argv) { unsigned long long user_acl = server->db_manager->getACL(moderator_name); @@ -988,6 +996,20 @@ void AOClient::cmdBans(int argc, QStringList argv) sendServerMessage(recent_bans.join("\n")); } +void AOClient::cmdUnBan(int argc, QStringList argv) +{ + bool ok; + int target_ban = argv[0].toInt(&ok); + if (!ok) { + sendServerMessage("Invalid ban ID."); + return; + } + else if (server->db_manager->invalidateBan(target_ban)) + sendServerMessage("Successfully invalidated ban " + argv[0] + "."); + else + sendServerMessage("Couldn't invalidate ban " + argv[0] + ", are you sure it exists?"); +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; diff --git a/src/db_manager.cpp b/src/db_manager.cpp index 335e10b..bd2ba32 100644 --- a/src/db_manager.cpp +++ b/src/db_manager.cpp @@ -187,6 +187,23 @@ void DBManager::addBan(BanInfo ban) qDebug() << "SQL Error:" << query.lastError().text(); } +bool DBManager::invalidateBan(int id) +{ + QSqlQuery ban_exists; + ban_exists.prepare("SELECT DURATION FROM bans WHERE ID = ?"); + ban_exists.addBindValue(id); + ban_exists.exec(); + + if (ban_exists.first()) + return false; + + QSqlQuery query; + query.prepare("UPDATE bans SET DURATION = 0 WHERE ID = ?"); + query.addBindValue(id); + query.exec(); + return true; +} + bool DBManager::createUser(QString username, QString salt, QString password, unsigned long long acl) { QSqlQuery username_exists; @@ -215,6 +232,23 @@ bool DBManager::createUser(QString username, QString salt, QString password, uns return true; } +bool DBManager::deleteUser(QString username) +{ + QSqlQuery username_exists; + username_exists.prepare("SELECT ACL FROM users WHERE USERNAME = ?"); + username_exists.addBindValue(username); + username_exists.exec(); + + if (username_exists.first()) + return false; + + QSqlQuery query; + query.prepare("DELETE FROM users WHERE USERNAME = ?"); + username_exists.addBindValue(username); + username_exists.exec(); + return true; +} + unsigned long long DBManager::getACL(QString moderator_name) { if (moderator_name == "") From 6b3bfb2fdac0090525c2e23e55db4a662336387e Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 13:49:55 -0500 Subject: [PATCH 36/46] add some cute flavor text for permanent bans --- src/commands.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/commands.cpp b/src/commands.cpp index 8789554..63e7a39 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -986,11 +986,16 @@ void AOClient::cmdBans(int argc, QStringList argv) recent_bans << "Last 5 bans:"; recent_bans << "-----"; for (DBManager::BanInfo ban : server->db_manager->getRecentBans()) { + QString banned_until; + if (ban.duration == -2) + banned_until = "The heat death of the universe"; + else + banned_until = QDateTime::fromSecsSinceEpoch(ban.time).addSecs(ban.duration).toString("dd.MM.yyyy, hh:mm"); recent_bans << "Affected IPID: " + ban.ipid; recent_bans << "Affected HDID: " + ban.hdid; recent_bans << "Reason for ban: " + ban.reason; recent_bans << "Date of ban: " + QDateTime::fromSecsSinceEpoch(ban.time).toString("dd.MM.yyyy, hh:mm"); - recent_bans << "Ban lasts until: " + QDateTime::fromSecsSinceEpoch(ban.time).addSecs(ban.duration).toString("dd.MM.yyyy, hh:mm"); + recent_bans << "Ban lasts until: " + banned_until; recent_bans << "-----"; } sendServerMessage(recent_bans.join("\n")); From 954744d86af2f6d332d508e649dee20cd3153be8 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 15:14:44 -0500 Subject: [PATCH 37/46] add /subtheme --- include/aoclient.h | 4 +++- src/commands.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/aoclient.h b/include/aoclient.h index 1d663fe..6bd2e77 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -234,6 +234,7 @@ class AOClient : public QObject { void cmdClearDoc(int argc, QStringList argv); void cmdTimer(int argc, QStringList argv); void cmdEvidenceMod(int argc, QStringList argv); + void cmdSubTheme(int argc, QStringList argv); // Messaging/Client void cmdPos(int argc, QStringList argv); void cmdForcePos(int argc, QStringList argv); @@ -315,7 +316,8 @@ class AOClient : public QObject { {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}}, {"mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdMute}}, - {"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnmute}} + {"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnmute}}, + {"subtheme", {ACLFlags.value("CM"), 1, &AOClient::cmdSubTheme}}, }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index 033050b..5a3c083 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -971,6 +971,16 @@ void AOClient::cmdUnmute(int argc, QStringList argv) server->getClientByID(uid)->is_muted = false; } +void AOClient::cmdSubTheme(int argc, QStringList argv) +{ + QString subtheme = argv.join(" "); + for (AOClient* client : server->clients) { + if (client->current_area == current_area) + client->sendPacket("ST", {subtheme}); + } + sendServerMessageArea("Subtheme was set to " + subtheme); +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; From 01f81c71074d87cbbb942ccf4fa05e0f1c86ec83 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 15:16:30 -0500 Subject: [PATCH 38/46] always reload theme on subtheme change --- src/commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands.cpp b/src/commands.cpp index 5a3c083..38f4915 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -976,7 +976,7 @@ void AOClient::cmdSubTheme(int argc, QStringList argv) QString subtheme = argv.join(" "); for (AOClient* client : server->clients) { if (client->current_area == current_area) - client->sendPacket("ST", {subtheme}); + client->sendPacket("ST", {subtheme, "1"}); } sendServerMessageArea("Subtheme was set to " + subtheme); } From cfc75798e7ac1c46a2951ddb33056ba058f5045e Mon Sep 17 00:00:00 2001 From: scatterflower Date: Sun, 14 Mar 2021 17:51:14 -0500 Subject: [PATCH 39/46] add /about and update version string --- include/aoclient.h | 2 ++ src/commands.cpp | 5 +++++ src/main.cpp | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/aoclient.h b/include/aoclient.h index 64edf16..bade278 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -188,6 +188,7 @@ class AOClient : public QObject { void cmdDefault(int argc, QStringList argv); void cmdHelp(int argc, QStringList argv); void cmdMOTD(int argc, QStringList argv); + void cmdAbout(int argc, QStringList argv); // Authentication void cmdLogin(int argc, QStringList argv); void cmdChangeAuth(int argc, QStringList argv); @@ -324,6 +325,7 @@ class AOClient : public QObject { {"unban", {ACLFlags.value("BAN"), 1, &AOClient::cmdUnBan}}, {"removeuser", {ACLFlags.value("MODIFY_USERS"), 1, &AOClient::cmdRemoveUser}}, {"subtheme", {ACLFlags.value("CM"), 1, &AOClient::cmdSubTheme}}, + {"about", {ACLFlags.value("NONE"), 0, &AOClient::cmdAbout}} }; QString partial_packet; diff --git a/src/commands.cpp b/src/commands.cpp index cca5b40..b387674 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1025,6 +1025,11 @@ void AOClient::cmdSubTheme(int argc, QStringList argv) sendServerMessageArea("Subtheme was set to " + subtheme); } +void AOClient::cmdAbout(int argc, QStringList argv) +{ + sendPacket("CT", {"The akashi dev team", "Thank you for using akashi! Made with love by scatterflower, with help from in1tiate and Salanto. akashi " + QCoreApplication::applicationVersion()}); +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; diff --git a/src/main.cpp b/src/main.cpp index da19865..d6d2582 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,7 +36,7 @@ int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationName("akashi"); - QCoreApplication::setApplicationVersion("1.0.0-alpha"); + QCoreApplication::setApplicationVersion("apricot r1"); std::atexit(cleanup); ConfigManager config_manager; From 82a53826a9aceb90bb64887938f6074761b69dd6 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 20:35:07 -0500 Subject: [PATCH 40/46] properly support music stopping --- src/packets.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/packets.cpp b/src/packets.cpp index 9cfc22a..b0cf50d 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -220,8 +220,13 @@ void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPack effects = argv[3]; else effects = "0"; - AOPacket music_change("MC", {song, argv[1], showname, "1", "0", effects}); - area->current_music = song; + QString final_song; + if (!argument.contains(".")) + final_song = "~stop.mp3"; + else + final_song = argument; + AOPacket music_change("MC", {final_song, argv[1], showname, "1", "0", effects}); + area->current_music = final_song; area->music_played_by = showname; server->broadcast(music_change, current_area); return; From 499765bfaacb4822f146b94945fbffabb87a7ab3 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Sun, 14 Mar 2021 20:37:25 -0500 Subject: [PATCH 41/46] update version string --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index d6d2582..8560141 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,7 +36,7 @@ int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationName("akashi"); - QCoreApplication::setApplicationVersion("apricot r1"); + QCoreApplication::setApplicationVersion("apricot r2 prerelease"); std::atexit(cleanup); ConfigManager config_manager; From 6de72085afcf86e1fb159d58cdbd6237c85b37ba Mon Sep 17 00:00:00 2001 From: Salanto Date: Mon, 15 Mar 2021 12:45:39 +0100 Subject: [PATCH 42/46] Prevent empty OOC name --- include/server.h | 1 - src/packets.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/server.h b/include/server.h index 16f045a..cac743e 100644 --- a/include/server.h +++ b/include/server.h @@ -52,7 +52,6 @@ class Server : public QObject { void broadcast(AOPacket packet, int area_index); void broadcast(AOPacket packet); QString getServerName(); - QString getMOTD(); int getDiceValue(QString value_type); int getCharID(QString char_name); diff --git a/src/packets.cpp b/src/packets.cpp index b0cf50d..dabfbba 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -174,7 +174,7 @@ void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket p { ooc_name = dezalgo(argv[0]).replace(QRegExp("\\[|\\]|\\{|\\}|\\#|\\$|\\%|\\&"), ""); // no fucky wucky shit here - if (ooc_name == server->getServerName()) // impersonation prevention + if (ooc_name == server->getServerName() || "") // impersonation & empty name protection return; QString message = dezalgo(argv[1]); From 6415732da3525f97d7d144ce6a32052a09b3e798 Mon Sep 17 00:00:00 2001 From: Salanto Date: Mon, 15 Mar 2021 16:38:37 +0100 Subject: [PATCH 43/46] Logic is hard, mkay? --- src/packets.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/packets.cpp b/src/packets.cpp index dabfbba..3bb681d 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -173,8 +173,7 @@ void AOClient::pktIcChat(AreaData* area, int argc, QStringList argv, AOPacket pa void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket packet) { ooc_name = dezalgo(argv[0]).replace(QRegExp("\\[|\\]|\\{|\\}|\\#|\\$|\\%|\\&"), ""); // no fucky wucky shit here - - if (ooc_name == server->getServerName() || "") // impersonation & empty name protection + if (ooc_name.isEmpty() || ooc_name == server->getServerName()) // impersonation & empty name protection return; QString message = dezalgo(argv[1]); From c11546c7a834a0beccb56acd10415266459472a5 Mon Sep 17 00:00:00 2001 From: scatterflower Date: Mon, 15 Mar 2021 18:04:20 -0500 Subject: [PATCH 44/46] make advertiser version string less stupid --- src/advertiser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advertiser.cpp b/src/advertiser.cpp index 31d2860..a45c33d 100644 --- a/src/advertiser.cpp +++ b/src/advertiser.cpp @@ -62,7 +62,7 @@ void Advertiser::socketConnected() AOPacket ao_packet("SCC", {concat_ports, name, description, - "akashi v" + QCoreApplication::applicationVersion()}); + "akashi " + QCoreApplication::applicationVersion()}); QByteArray data = ao_packet.toUtf8(); socket->write(data); From d6b41d00d528013189f74bb8edc335a6ade4f04e Mon Sep 17 00:00:00 2001 From: in1tiate Date: Mon, 15 Mar 2021 18:20:08 -0500 Subject: [PATCH 45/46] send hardcoded string only when client version is below 2.9.1 --- src/commands.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/commands.cpp b/src/commands.cpp index 5e778ee..1a4aa09 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -43,7 +43,7 @@ void AOClient::cmdLogin(int argc, QStringList argv) } else if(argv[0] == modpass) { sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button." - sendServerMessage("Logged in as a moderator."); // for old clients, this is hardcoded to display the mod UI + sendServerMessage("Logged in as a moderator."); // pre-2.9.1 clients are hardcoded to display the mod UI when this string is sent in OOC authenticated = true; } else { @@ -63,7 +63,8 @@ void AOClient::cmdLogin(int argc, QStringList argv) moderator_name = username; authenticated = true; sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button." - sendServerMessage("Logged in as a moderator."); // for old clients, this is hardcoded to display the mod UI + if (version.release <= 2 && version.major <= 9 && version.minor <= 0) + sendServerMessage("Logged in as a moderator."); // pre-2.9.1 clients are hardcoded to display the mod UI when this string is sent in OOC sendServerMessage("Welcome, " + username); } else { From 1636dd93ef60e5d4f782e1c23d03fdb171d3f22d Mon Sep 17 00:00:00 2001 From: scatterflower Date: Wed, 17 Mar 2021 05:52:04 -0500 Subject: [PATCH 46/46] extremely important commit --- src/commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands.cpp b/src/commands.cpp index 1a4aa09..2455016 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////////////// // akashi - a server for Attorney Online 2 // -// Copyright (C) 2020 scatterflower // +// Copyright (C) 2020 scatterflower // // // // This program is free software: you can redistribute it and/or modify // // it under the terms of the GNU Affero General Public License as //