diff --git a/core/include/db_manager.h b/core/include/db_manager.h index 02c56e5..1f340ee 100644 --- a/core/include/db_manager.h +++ b/core/include/db_manager.h @@ -56,13 +56,15 @@ 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); + std::pair isIPBanned(QString ipid); /** * @brief Checks if there is a record in the Bans table with the given hardware ID. diff --git a/core/src/commands/moderation.cpp b/core/src/commands/moderation.cpp index 43c7f89..ebad420 100644 --- a/core/src/commands/moderation.cpp +++ b/core/src/commands/moderation.cpp @@ -82,8 +82,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..3cd4fd7 100644 --- a/core/src/db_manager.cpp +++ b/core/src/db_manager.cpp @@ -31,23 +31,24 @@ DBManager::DBManager() : updateDB(db_version); } -bool DBManager::isIPBanned(QHostAddress ip) +std::pair 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 * 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(); + long long ban_time = query.value(4).toLongLong(); + QString reason = query.value(5).toString(); + long long duration = query.value(6).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) diff --git a/core/src/packets.cpp b/core/src/packets.cpp index 4c4e0d0..0f62caa 100644 --- a/core/src/packets.cpp +++ b/core/src/packets.cpp @@ -315,9 +315,13 @@ 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 + calculateIpid(); if (remote_ip.isLoopback()) { - if(server->db_manager->isIPBanned(QHostAddress(argv[0]))) { - sendPacket("BD", {server->db_manager->getBanReason(QHostAddress(argv[0]))}); + auto ban = server->db_manager->isIPBanned(ipid); + bool is_banned = ban.first; + if(is_banned) { + QString reason = ban.second; + sendPacket("BD", {reason}); socket->close(); return; } @@ -325,7 +329,6 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack qDebug() << "ws ip set to" << argv[0]; #endif remote_ip = QHostAddress(argv[0]); - calculateIpid(); int multiclient_count = 0; for (AOClient* joined_client : server->clients) { diff --git a/core/src/server.cpp b/core/src/server.cpp index 5462609..87fe428 100644 --- a/core/src/server.cpp +++ b/core/src/server.cpp @@ -125,7 +125,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++; @@ -135,7 +137,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) { @@ -158,7 +161,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