diff --git a/core/include/area_data.h b/core/include/area_data.h index ca436e5..94bac98 100644 --- a/core/include/area_data.h +++ b/core/include/area_data.h @@ -696,7 +696,7 @@ class AreaData : public QObject { * * First, a `QStringList` that is the packet of the statement that was advanced to. * * Then, a `TestimonyProgress` value that describes how the advancement happened. */ - std::pair jumpToStatement(int f_position); + QPair jumpToStatement(int f_position); /** * @brief Returns a copy of the judgelog in the area. diff --git a/core/include/db_manager.h b/core/include/db_manager.h index 02c56e5..fcc5f4a 100644 --- a/core/include/db_manager.h +++ b/core/include/db_manager.h @@ -56,52 +56,26 @@ public: ~DBManager(); /** - * @brief Checks if there is a record in the Bans table with the given IP address. + * @brief Checks if there is a record in the Bans table with the given IPID. * - * @param ip The IP address to check if it is banned. + * @param ipid The IPID to check if it is banned. * - * @return True if the query could return at least one such record. + * @return A pair of values: + * * First, a `bool` that is true if the query could return at least one such record. + * * Then, a `QString` that is the reason for the ban. */ - bool isIPBanned(QHostAddress ip); + QPair isIPBanned(QString ipid); /** * @brief Checks if there is a record in the Bans table with the given hardware ID. * * @param hdid The hardware ID to check if it is banned. * - * @return True if the query could return at least one such record. + * @return A pair of values: + * * First, a `bool` that is true if the query could return at least one such record. + * * Then, a `QString` that is the reason for the ban. */ - bool isHDIDBanned(QString hdid); - - /** - * @brief Returns the reason the given IP address was banned with. - * - * @param ip The IP address whose ban reason needs to be returned. - * - * @return The ban reason if the IP address is actually banned, - * or `"Ban reason not found."` if the IP address is not actually banned. - */ - QString getBanReason(QHostAddress ip); - - /** - * @overload - */ - QString getBanReason(QString hdid); - - /** - * @brief Returns the reason the given IP address was banned with. - * - * @param ip The IP address whose ban duration to get. - * - * @return The ban duration if the IP address is actually banned, - * or `-1` if the IP address is not actually banned. - */ - long long getBanDuration(QHostAddress ip); - - /** - * @overload - */ - long long getBanDuration(QString hdid); + QPair isHDIDBanned(QString hdid); /** * @brief Gets the ID number of a given ban. diff --git a/core/src/area_data.cpp b/core/src/area_data.cpp index 38daf76..fdd7b16 100644 --- a/core/src/area_data.cpp +++ b/core/src/area_data.cpp @@ -403,7 +403,7 @@ void AreaData::removeStatement(int f_position) --m_statement; } -std::pair AreaData::jumpToStatement(int f_position) +QPair AreaData::jumpToStatement(int f_position) { m_statement = f_position; diff --git a/core/src/commands/moderation.cpp b/core/src/commands/moderation.cpp index 52f1474..1582151 100644 --- a/core/src/commands/moderation.cpp +++ b/core/src/commands/moderation.cpp @@ -79,8 +79,12 @@ void AOClient::cmdBan(int argc, QStringList argv) if (kick_counter > 1) sendServerMessage("Kicked " + QString::number(kick_counter) + " clients with matching ipids."); - if (!ban_logged) - sendServerMessage("User with ipid not found!"); + + // We're banning someone not connected. + if (!ban_logged) { + server->db_manager->addBan(ban); + sendServerMessage("Banned " + ban.ipid + " for reason: " + ban.reason); + } } void AOClient::cmdKick(int argc, QStringList argv) diff --git a/core/src/db_manager.cpp b/core/src/db_manager.cpp index 7a3ad16..d8e2ace 100644 --- a/core/src/db_manager.cpp +++ b/core/src/db_manager.cpp @@ -31,101 +31,46 @@ DBManager::DBManager() : updateDB(db_version); } -bool DBManager::isIPBanned(QHostAddress ip) +QPair DBManager::isIPBanned(QString ipid) { QSqlQuery query; - query.prepare("SELECT TIME FROM BANS WHERE IP = ? ORDER BY TIME DESC"); - query.addBindValue(ip.toString()); + query.prepare("SELECT TIME,REASON,DURATION FROM BANS WHERE IPID = ? ORDER BY TIME DESC"); + query.addBindValue(ipid); query.exec(); if (query.first()) { - long long duration = getBanDuration(ip); long long ban_time = query.value(0).toLongLong(); + QString reason = query.value(1).toString(); + long long duration = query.value(2).toLongLong(); if (duration == -2) - return true; + return {true, reason}; long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); if (ban_time + duration > current_time) - return true; - else return false; + return {true, reason}; + else return {false, nullptr}; } - else return false; + else return {false, nullptr}; } -bool DBManager::isHDIDBanned(QString hdid) +QPair DBManager::isHDIDBanned(QString hdid) { QSqlQuery query; - query.prepare("SELECT TIME FROM BANS WHERE HDID = ? ORDER BY TIME DESC"); + query.prepare("SELECT TIME,REASON,DURATION FROM BANS WHERE HDID = ? ORDER BY TIME DESC"); query.addBindValue(hdid); query.exec(); if (query.first()) { - long long duration = getBanDuration(hdid); long long ban_time = query.value(0).toLongLong(); + QString reason = query.value(1).toString(); + long long duration = query.value(2).toLongLong(); if (duration == -2) - return true; + return {true, reason}; long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); if (ban_time + duration > current_time) - return true; - else return false; + return {true, reason}; + else return {false, nullptr}; } - else return false; + else return {false, nullptr}; } -QString DBManager::getBanReason(QHostAddress ip) -{ - QSqlQuery query; - query.prepare("SELECT REASON FROM BANS WHERE IP = ? ORDER BY TIME DESC"); - query.addBindValue(ip.toString()); - query.exec(); - if (query.first()) { - return query.value(0).toString(); - } - else { - return "Ban reason not found."; - } -} - -QString DBManager::getBanReason(QString hdid) -{ - QSqlQuery query; - query.prepare("SELECT REASON FROM BANS WHERE HDID = ? ORDER BY TIME DESC"); - query.addBindValue(hdid); - query.exec(); - if (query.first()) { - return query.value(0).toString(); - } - else { - return "Ban reason not found."; - } -} - -long long DBManager::getBanDuration(QString hdid) -{ - QSqlQuery query; - query.prepare("SELECT DURATION FROM BANS WHERE HDID = ? ORDER BY TIME DESC"); - 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 = ? ORDER BY TIME DESC"); - query.addBindValue(ip.toString()); - query.exec(); - if (query.first()) { - return query.value(0).toLongLong(); - } - else { - return -1; - } -} - - int DBManager::getBanID(QString hdid) { QSqlQuery query; diff --git a/core/src/packets.cpp b/core/src/packets.cpp index f209ca3..20dd57d 100644 --- a/core/src/packets.cpp +++ b/core/src/packets.cpp @@ -27,8 +27,9 @@ void AOClient::pktDefault(AreaData* area, int argc, QStringList argv, AOPacket p void AOClient::pktHardwareId(AreaData* area, int argc, QStringList argv, AOPacket packet) { hwid = argv[0]; - if(server->db_manager->isHDIDBanned(hwid)) { - sendPacket("BD", {server->db_manager->getBanReason(hwid) + "\nBan ID: " + QString::number(server->db_manager->getBanID(hwid))}); + auto ban = server->db_manager->isHDIDBanned(hwid); + if (ban.first) { + sendPacket("BD", {ban.second + "\nBan ID: " + QString::number(server->db_manager->getBanID(hwid))}); socket->close(); return; } @@ -318,16 +319,17 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack // Special packet to set remote IP from the webao proxy // Only valid if from a local ip if (remote_ip.isLoopback()) { - if(server->db_manager->isIPBanned(QHostAddress(argv[0]))) { - sendPacket("BD", {server->db_manager->getBanReason(QHostAddress(argv[0]))}); - socket->close(); - return; - } #ifdef NET_DEBUG qDebug() << "ws ip set to" << argv[0]; #endif remote_ip = QHostAddress(argv[0]); calculateIpid(); + auto ban = server->db_manager->isIPBanned(ipid); + if (ban.first) { + sendPacket("BD", {ban.second}); + socket->close(); + return; + } int multiclient_count = 0; for (AOClient* joined_client : server->clients) { diff --git a/core/src/server.cpp b/core/src/server.cpp index a3a209e..635e0a9 100644 --- a/core/src/server.cpp +++ b/core/src/server.cpp @@ -121,7 +121,9 @@ void Server::clientConnected() int multiclient_count = 1; bool is_at_multiclient_limit = false; - bool is_banned = db_manager->isIPBanned(socket->peerAddress()); + client->calculateIpid(); + auto ban = db_manager->isIPBanned(client->getIpid()); + bool is_banned = ban.first; for (AOClient* joined_client : clients) { if (client->remote_ip.isEqual(joined_client->remote_ip)) multiclient_count++; @@ -131,7 +133,8 @@ void Server::clientConnected() is_at_multiclient_limit = true; if (is_banned) { - AOPacket ban_reason("BD", {db_manager->getBanReason(socket->peerAddress())}); + QString reason = ban.second; + AOPacket ban_reason("BD", {reason}); socket->write(ban_reason.toUtf8()); } if (is_banned || is_at_multiclient_limit) { @@ -154,7 +157,6 @@ void Server::clientConnected() // tsuserver4. It should disable fantacrypt // completely in any client 2.4.3 or newer client->sendPacket(decryptor); - client->calculateIpid(); #ifdef NET_DEBUG qDebug() << client->remote_ip.toString() << "connected"; #endif