diff --git a/akashi.pro b/akashi.pro index 42a09d1..4c4b6e4 100644 --- a/akashi.pro +++ b/akashi.pro @@ -26,6 +26,7 @@ SOURCES += src/advertiser.cpp \ src/aopacket.cpp \ src/area_data.cpp \ src/ban_manager.cpp \ + src/commands.cpp \ src/config_manager.cpp \ src/icchatpacket.cpp \ src/main.cpp \ diff --git a/include/aoclient.h b/include/aoclient.h index f5a73cc..24ffe07 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -46,6 +46,8 @@ class AOClient : public QObject { bool joined; int current_area; QString current_char; + bool authenticated = false; + QString ooc_name = ""; public slots: void clientDisconnected(); @@ -54,7 +56,6 @@ class AOClient : public QObject { void sendPacket(QString header, QStringList contents); void sendPacket(QString header); - private: Server* server; QTcpSocket* socket; @@ -66,19 +67,6 @@ class AOClient : public QObject { LOCKED }; - struct CommandInfo { - bool privileged; - int minArgs; - }; - - const QMap commands { - {"login", {false, 1}}, - {"getareas", {false, 0 }}, - {"getarea", {false, 0}}, - {"ban", {true, 2}}, - {"kick", {true, 2}} - }; - void handlePacket(AOPacket packet); void handleCommand(QString command, int argc, QStringList argv); void changeArea(int new_area); @@ -86,6 +74,31 @@ class AOClient : public QObject { void fullArup(); void sendServerMessage(QString message); + // Commands + void cmdDefault(int argc, QStringList argv); + void cmdLogin(int argc, QStringList argv); + void cmdGetAreas(int argc, QStringList argv); + void cmdGetArea(int argc, QStringList argv); + void cmdBan(int argc, QStringList argv); + void cmdKick(int argc, QStringList argv); + + // Command helper functions + QStringList buildAreaList(int area_idx); + + struct CommandInfo { + bool privileged; + int minArgs; + void (AOClient::*action)(int, QStringList); + }; + + const QMap commands { + {"login", {false, 1, &AOClient::cmdLogin}}, + {"getareas", {false, 0 , &AOClient::cmdGetAreas}}, + {"getarea", {false, 0, &AOClient::cmdGetArea}}, + {"ban", {true, 2, &AOClient::cmdBan}}, + {"kick", {true, 2, &AOClient::cmdKick}} + }; + QString partial_packet; bool is_partial; @@ -93,9 +106,6 @@ class AOClient : public QObject { QString ipid; long last_wtce_time; QString last_message; - - bool authenticated = false; - QString ooc_name = ""; }; #endif // AOCLIENT_H diff --git a/src/aoclient.cpp b/src/aoclient.cpp index 90d0204..d5c5afe 100644 --- a/src/aoclient.cpp +++ b/src/aoclient.cpp @@ -283,13 +283,7 @@ void AOClient::changeArea(int new_area) void AOClient::handleCommand(QString command, int argc, QStringList argv) { - // Be sure to register the command in the header before adding it here! - CommandInfo info = commands.value(command, {false, -1}); - - if (info.minArgs == -1) { - sendServerMessage("Invalid command."); - return; - } + CommandInfo info = commands.value(command, {false, -1, &AOClient::cmdDefault}); if (info.privileged && !authenticated) { sendServerMessage("You do not have permission to use that command."); @@ -301,110 +295,7 @@ void AOClient::handleCommand(QString command, int argc, QStringList argv) return; } - if (command == "login") { - QSettings config("config/config.ini", QSettings::IniFormat); - config.beginGroup("Options"); - QString modpass = config.value("modpass", "default").toString();; - // TODO: tell the user if no modpass is set - if(argv[0] == modpass) { - sendServerMessage("Logged in as a moderator."); // This string has to be exactly this, because it is hardcoded in the client - authenticated = true; - } else { - sendServerMessage("Incorrect password."); - return; - } - } - else if (command == "getareas") { - QStringList entries; - entries.append("== Area List =="); - for (int i = 0; i < server->area_names.length(); i++) { - QString area_name = server->area_names[i]; - AreaData* area = server->areas[i]; - entries.append("=== " + area_name + " ==="); - entries.append("[" + QString::number(area->player_count) + " users][" + area->status + "]"); - for (AOClient* client : server->clients) { - if (client->current_area == i) { - QString char_entry = client->current_char; - if (authenticated) - char_entry += " (" + client->getIpid() + "): " + ooc_name; - entries.append(char_entry); - } - } - } - sendServerMessage(entries.join("\n")); - } - else if (command == "getarea") { - // TODO: get rid of copy-pasted code - QStringList entries; - QString area_name = server->area_names[current_area]; - AreaData* area = server->areas[current_area]; - entries.append("=== " + area_name + " ==="); - entries.append("[" + QString::number(area->player_count) + " users][" + area->status + "]"); - for (AOClient* client : server->clients) { - if (client->current_area == current_area) { - QString char_entry = client->current_char; - if (authenticated) - char_entry += " (" + client->getIpid() + "): " + ooc_name; - entries.append(char_entry); - } - } - sendServerMessage(entries.join("\n")); - } - else if (command == "ban") { - QString target_ipid = argv[0]; - QHostAddress ip; - QString hdid; - unsigned long time = QDateTime::currentDateTime().toTime_t(); - 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) { - ip = client->remote_ip; - hdid = client->hwid; - server->ban_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(); - } - } - - if (!ban_logged) - sendServerMessage("User with ipid not found!"); - } - else if (command == "kick") { - QString target_ipid = argv[0]; - QString reason = argv[1]; - bool did_kick = 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) { - client->sendPacket("KK", {reason}); - client->socket->close(); - did_kick = true; - } - } - - if (did_kick) - sendServerMessage("Banned user with ipid " + target_ipid + " for reason: " + reason); - else - sendServerMessage("User with ipid not found!"); - } + (this->*(info.action))(argc, argv); } void AOClient::arup(ARUPType type, bool broadcast) diff --git a/src/commands.cpp b/src/commands.cpp new file mode 100644 index 0000000..89f8658 --- /dev/null +++ b/src/commands.cpp @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////////////////// +// akashi - a server for Attorney Online 2 // +// 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 // +// published by the Free Software Foundation, either version 3 of the // +// License, or (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU Affero General Public License for more details. // +// // +// You should have received a copy of the GNU Affero General Public License // +// along with this program. If not, see . // +////////////////////////////////////////////////////////////////////////////////////// +#include "include/aoclient.h" + +// Be sure to register the command in the header before adding it here! + +void AOClient::cmdDefault(int argc, QStringList argv) +{ + sendServerMessage("Invalid command."); + return; +} + +void AOClient::cmdLogin(int argc, QStringList argv) +{ + QSettings config("config/config.ini", QSettings::IniFormat); + config.beginGroup("Options"); + QString modpass = config.value("modpass", "default").toString();; + // TODO: tell the user if no modpass is set + if(argv[0] == modpass) { + sendServerMessage("Logged in as a moderator."); // This string has to be exactly this, because it is hardcoded in the client + authenticated = true; + } else { + sendServerMessage("Incorrect password."); + return; + } +} + +void AOClient::cmdGetAreas(int argc, QStringList argv) +{ + QStringList entries; + entries.append("== Area List =="); + for (int i = 0; i < server->area_names.length(); i++) { + QStringList cur_area_lines = buildAreaList(i); + entries.append(cur_area_lines); + } + sendServerMessage(entries.join("\n")); +} + +void AOClient::cmdGetArea(int argc, QStringList argv) +{ + QStringList entries = buildAreaList(current_area); + sendServerMessage(entries.join("\n")); +} + +void AOClient::cmdBan(int argc, QStringList argv) +{ + QString target_ipid = argv[0]; + QHostAddress ip; + QString hdid; + unsigned long time = QDateTime::currentDateTime().toTime_t(); + 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) { + ip = client->remote_ip; + hdid = client->hwid; + server->ban_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(); + } + } + + if (!ban_logged) + sendServerMessage("User with ipid not found!"); +} + +void AOClient::cmdKick(int argc, QStringList argv) +{ + QString target_ipid = argv[0]; + QString reason = argv[1]; + bool did_kick = 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) { + client->sendPacket("KK", {reason}); + client->socket->close(); + did_kick = true; + } + } + + if (did_kick) + sendServerMessage("Banned user with ipid " + target_ipid + " for reason: " + reason); + else + sendServerMessage("User with ipid not found!"); +} + +QStringList AOClient::buildAreaList(int area_idx) +{ + QStringList entries; + QString area_name = server->area_names[area_idx]; + AreaData* area = server->areas[area_idx]; + entries.append("=== " + area_name + " ==="); + entries.append("[" + QString::number(area->player_count) + " users][" + area->status + "]"); + for (AOClient* client : server->clients) { + if (client->current_area == area_idx) { + QString char_entry = client->current_char; + if (authenticated) + char_entry += " (" + client->getIpid() + "): " + ooc_name; + entries.append(char_entry); + } + } + return entries; +}