From ddff99b26048d22f49dfdbfc6180c103dc11ec50 Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Fri, 5 Jul 2024 13:47:41 +0200 Subject: [PATCH 1/6] Dropped Qt5, ... Resolve #360, resolve #361 * Dropped Qt5 * Now targets Qt6.5 * Dropped backward compatibility/feature list --- core.pro | 1 + src/acl_roles_handler.cpp | 2 - src/akashidefs.cpp | 8 ++ src/akashidefs.h | 8 +- src/aoclient.h | 7 +- src/area_data.cpp | 6 - src/command_extension.cpp | 1 - src/commands/casing.cpp | 2 - src/commands/command_helper.cpp | 7 -- src/config_manager.cpp | 1 - src/data_types.h | 1 + src/packet/packet_casea.cpp | 11 +- src/packet/packet_ct.cpp | 6 +- src/packet/packet_hi.cpp | 10 +- src/packet/packet_id.cpp | 49 ++------- src/packet/packet_ms.cpp | 189 ++++++++++++++++++-------------- src/packets.cpp | 9 +- src/server.cpp | 7 +- 18 files changed, 157 insertions(+), 168 deletions(-) create mode 100644 src/akashidefs.cpp diff --git a/core.pro b/core.pro index 127946ee..366a2117 100644 --- a/core.pro +++ b/core.pro @@ -31,6 +31,7 @@ INCLUDEPATH += src SOURCES += \ src/acl_roles_handler.cpp \ + src/akashidefs.cpp \ src/aoclient.cpp \ src/network/aopacket.cpp \ src/network/network_socket.cpp \ diff --git a/src/acl_roles_handler.cpp b/src/acl_roles_handler.cpp index e55ac3b9..852c25e9 100644 --- a/src/acl_roles_handler.cpp +++ b/src/acl_roles_handler.cpp @@ -176,7 +176,6 @@ void ACLRolesHandler::clearRoles() bool ACLRolesHandler::loadFile(QString f_file_name) { QSettings l_settings(f_file_name, QSettings::IniFormat); - l_settings.setIniCodec("UTF-8"); if (!checkPermissionsIni(&l_settings)) { return false; } @@ -218,7 +217,6 @@ bool ACLRolesHandler::loadFile(QString f_file_name) bool ACLRolesHandler::saveFile(QString f_file_name) { QSettings l_settings(f_file_name, QSettings::IniFormat); - l_settings.setIniCodec("UTF-8"); if (!checkPermissionsIni(&l_settings)) { return false; } diff --git a/src/akashidefs.cpp b/src/akashidefs.cpp new file mode 100644 index 00000000..5d8686cd --- /dev/null +++ b/src/akashidefs.cpp @@ -0,0 +1,8 @@ +#include "akashidefs.h" + +namespace akashi { +QString get_protocol_version_string() +{ + return QString::number(PROTOCOL_MAJOR_VERSION) + "." + QString::number(PROTOCOL_MINOR_VERSION) + "." + QString::number(PROTOCOL_PATCH_VERSION); +} +} diff --git a/src/akashidefs.h b/src/akashidefs.h index a4e1753c..67edda1d 100644 --- a/src/akashidefs.h +++ b/src/akashidefs.h @@ -2,7 +2,6 @@ #define AKASHIDEFS_H #include -#include namespace akashi { #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) @@ -12,6 +11,11 @@ using SplitBehavior = Qt::SplitBehaviorFlags; #endif const SplitBehavior KeepEmptyParts = SplitBehavior::KeepEmptyParts; const SplitBehavior SkipEmptyParts = SplitBehavior::SkipEmptyParts; -} +QString get_protocol_version_string(); + +const int PROTOCOL_MAJOR_VERSION = 1; +const int PROTOCOL_MINOR_VERSION = 0; +const int PROTOCOL_PATCH_VERSION = 0; +} #endif // AKASHIDEFS_H diff --git a/src/aoclient.h b/src/aoclient.h index 258c26cf..60c40098 100644 --- a/src/aoclient.h +++ b/src/aoclient.h @@ -240,10 +240,9 @@ class AOClient : public QObject */ struct ClientVersion { - QString string; //!< The name of the client software, for example, `AO2`. - int release = -1; //!< The 'release' part of the version number. In Attorney Online's case, this is fixed at `2`. - int major = -1; //!< The 'major' part of the version number. In Attorney Online's case, this increases when a new feature is introduced (generally). - int minor = -1; //!< The 'minor' part of the version number. In Attorney Online's case, this increases for bugfix releases (generally). + int major = -1; + int minor = -1; + int patch = -1; }; /** diff --git a/src/area_data.cpp b/src/area_data.cpp index 5ed48857..c904e023 100644 --- a/src/area_data.cpp +++ b/src/area_data.cpp @@ -45,7 +45,6 @@ AreaData::AreaData(QString p_name, int p_index, MusicManager *p_music_manager = name_split.removeFirst(); m_name = name_split.join(":"); QSettings *areas_ini = ConfigManager::areaData(); - areas_ini->setIniCodec("UTF-8"); areas_ini->beginGroup(p_name); m_background = areas_ini->value("background", "gs4").toString(); m_isProtected = areas_ini->value("protected_area", "false").toBool(); @@ -262,12 +261,7 @@ QList AreaData::evidence() const void AreaData::swapEvidence(int f_eviId1, int f_eviId2) { -#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0) - // swapItemsAt does not exist in Qt older than 5.13 - m_evidence.swap(f_eviId1, f_eviId2); -#else m_evidence.swapItemsAt(f_eviId1, f_eviId2); -#endif } void AreaData::appendEvidence(const AreaData::Evidence &f_evi_r) diff --git a/src/command_extension.cpp b/src/command_extension.cpp index 27e001aa..7ae302c3 100644 --- a/src/command_extension.cpp +++ b/src/command_extension.cpp @@ -112,7 +112,6 @@ CommandExtension CommandExtensionCollection::getExtension(QString f_command_name bool CommandExtensionCollection::loadFile(QString f_filename) { QSettings l_settings(f_filename, QSettings::IniFormat); - l_settings.setIniCodec("UTF-8"); if (l_settings.status() != QSettings::NoError) { qWarning() << "[Command Extension Collection]" << "error: failed to load file" << f_filename << "; aborting"; diff --git a/src/commands/casing.cpp b/src/commands/casing.cpp index 982d399f..059746ff 100644 --- a/src/commands/casing.cpp +++ b/src/commands/casing.cpp @@ -240,7 +240,6 @@ void AOClient::cmdSaveTestimony(int argc, QStringList argv) } QTextStream l_out(&l_file); - l_out.setCodec("UTF-8"); if (l_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { for (int i = 0; i <= l_area->testimony().size() - 1; i++) { l_out << l_area->testimony().at(i).join("#") << "\n"; @@ -280,7 +279,6 @@ void AOClient::cmdLoadTestimony(int argc, QStringList argv) clearTestimony(); int l_testimony_lines = 0; QTextStream l_in(&l_file); - l_in.setCodec("UTF-8"); while (!l_in.atEnd()) { if (l_testimony_lines <= ConfigManager::maxStatements()) { QString line = l_in.readLine(); diff --git a/src/commands/command_helper.cpp b/src/commands/command_helper.cpp index 13715edf..e0e8c36f 100644 --- a/src/commands/command_helper.cpp +++ b/src/commands/command_helper.cpp @@ -74,14 +74,7 @@ QStringList AOClient::buildAreaList(int area_idx) int AOClient::genRand(int min, int max) { -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) - qsrand(QDateTime::currentMSecsSinceEpoch()); - quint32 random_number = (qrand() % (max - min + 1)) + min; - return random_number; - -#else return QRandomGenerator::system()->bounded(min, max + 1); -#endif } void AOClient::diceThrower(int sides, int dice, bool p_roll, int roll_modifier) diff --git a/src/config_manager.cpp b/src/config_manager.cpp index c65a46cd..d5d16c1e 100644 --- a/src/config_manager.cpp +++ b/src/config_manager.cpp @@ -54,7 +54,6 @@ bool ConfigManager::verifyServerConfig() // Verify areas QSettings l_areas_ini("config/areas.ini", QSettings::IniFormat); - l_areas_ini.setIniCodec("UTF-8"); if (l_areas_ini.childGroups().length() < 1) { qCritical() << "areas.ini is invalid!"; return false; diff --git a/src/data_types.h b/src/data_types.h index e1348832..14419d44 100644 --- a/src/data_types.h +++ b/src/data_types.h @@ -19,6 +19,7 @@ #define DATA_TYPES_H #include +#include /** * @brief A class for handling several custom data types. diff --git a/src/packet/packet_casea.cpp b/src/packet/packet_casea.cpp index a0835129..50298ace 100644 --- a/src/packet/packet_casea.cpp +++ b/src/packet/packet_casea.cpp @@ -44,20 +44,13 @@ void PacketCasea::handlePacket(AreaData *area, AOClient &client) const QString l_message = "=== Case Announcement ===\r\n" + (client.name() == "" ? client.character() : client.name()) + " needs " + l_needed_roles.join(", ") + " for " + (l_case_title == "" ? "a case" : l_case_title) + "!"; QList l_clients_to_alert; - // here lies morton, RIP -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QSet l_needs_set(l_needs_list.begin(), l_needs_list.end()); -#else - QSet l_needs_set = l_needs_list.toSet(); -#endif + const QVector l_clients = client.getServer()->getClients(); for (AOClient *l_client : l_clients) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QSet l_matches(l_client->m_casing_preferences.begin(), l_client->m_casing_preferences.end()); l_matches.intersect(l_needs_set); -#else - QSet l_matches = l_client->m_casing_preferences.toSet().intersect(l_needs_set); -#endif + if (!l_matches.isEmpty() && !l_clients_to_alert.contains(l_client)) l_clients_to_alert.append(l_client); } diff --git a/src/packet/packet_ct.cpp b/src/packet/packet_ct.cpp index f08137f1..43d68a97 100644 --- a/src/packet/packet_ct.cpp +++ b/src/packet/packet_ct.cpp @@ -1,10 +1,12 @@ #include "packet/packet_ct.h" + #include "akashidefs.h" #include "config_manager.h" #include "packet/packet_factory.h" #include "server.h" #include +#include PacketCT::PacketCT(QStringList &contents) : AOPacket(contents) @@ -27,8 +29,8 @@ void PacketCT::handlePacket(AreaData *area, AOClient &client) const return; } - client.setName(client.dezalgo(m_content[0]).replace(QRegExp("\\[|\\]|\\{|\\}|\\#|\\$|\\%|\\&"), "")); // no fucky wucky shit here - if (client.name().isEmpty() || client.name() == ConfigManager::serverName()) // impersonation & empty name protection + client.setName(client.dezalgo(m_content[0]).replace(QRegularExpression("\\[|\\]|\\{|\\}|\\#|\\$|\\%|\\&"), "")); // no fucky wucky shit here + if (client.name().isEmpty() || client.name() == ConfigManager::serverName()) // impersonation & empty name protection return; if (client.name().length() > 30) { diff --git a/src/packet/packet_hi.cpp b/src/packet/packet_hi.cpp index 5c7a2c4a..e5e00dc6 100644 --- a/src/packet/packet_hi.cpp +++ b/src/packet/packet_hi.cpp @@ -1,5 +1,6 @@ #include "packet/packet_hi.h" -#include "akashiutils.h" + +#include "config_manager.h" #include "db_manager.h" #include "server.h" @@ -47,5 +48,10 @@ void PacketHI::handlePacket(AreaData *area, AOClient &client) const return; } - client.sendPacket("ID", {QString::number(client.clientId()), "akashi", QCoreApplication::applicationVersion()}); + client.sendPacket("PN", {QString::number(client.getServer()->getPlayerCount()), QString::number(ConfigManager::maxPlayers()), ConfigManager::serverDescription()}); + + if (ConfigManager::assetUrl().isValid()) { + QByteArray l_asset_url = ConfigManager::assetUrl().toEncoded(QUrl::EncodeSpaces); + client.sendPacket("ASS", {l_asset_url}); + } } diff --git a/src/packet/packet_id.cpp b/src/packet/packet_id.cpp index 30b1bbdb..f272219e 100644 --- a/src/packet/packet_id.cpp +++ b/src/packet/packet_id.cpp @@ -1,5 +1,6 @@ #include "packet/packet_id.h" -#include "config_manager.h" + +#include "akashidefs.h" #include "server.h" #include @@ -13,7 +14,7 @@ PacketInfo PacketID::getPacketInfo() const { PacketInfo info{ .acl_permission = ACLRole::Permission::NONE, - .min_args = 2, + .min_args = 3, .header = "ID"}; return info; } @@ -22,50 +23,24 @@ void PacketID::handlePacket(AreaData *area, AOClient &client) const { Q_UNUSED(area) - if (client.m_version.major == 2) { + if (client.m_version.major == akashi::PROTOCOL_MAJOR_VERSION) { // No double sending of the ID packet! client.sendPacket("BD", {"A protocol error has been encountered. Packet : ID"}); client.m_socket->close(); return; } - // Full feature list as of AO 2.8.5 - // The only ones that are critical to ensuring the server works are - // "noencryption" and "fastloading" - QStringList l_feature_list = { - "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", "custom_blips"}; - - client.m_version.string = m_content[1]; - QRegularExpression rx("\\b(\\d+)\\.(\\d+)\\.(\\d+)\\b"); // matches X.X.X (e.g. 2.9.0, 2.4.10, etc.) - QRegularExpressionMatch l_match = rx.match(client.m_version.string); - if (l_match.hasMatch()) { - client.m_version.release = l_match.captured(1).toInt(); - client.m_version.major = l_match.captured(2).toInt(); - client.m_version.minor = l_match.captured(3).toInt(); - } - if (m_content[0] == "webAO") { - client.m_version.release = 2; - client.m_version.major = 10; - client.m_version.minor = 0; + AOClient::ClientVersion version; + if (m_content[0] == akashi::get_protocol_version_string()) { + version.major = akashi::PROTOCOL_MAJOR_VERSION; + version.minor = akashi::PROTOCOL_MINOR_VERSION; + version.patch = akashi::PROTOCOL_PATCH_VERSION; } - - if (client.m_version.release != 2) { - // No valid ID packet resolution. - client.sendPacket("BD", {"A protocol error has been encountered. Packet : ID\nMajor version not recognised."}); + else { + client.sendPacket("BD", {"A protocol error has been encountered. Packet : ID\nProtocol version not supported."}); client.m_socket->close(); return; } - client.sendPacket("PN", {QString::number(client.getServer()->getPlayerCount()), QString::number(ConfigManager::maxPlayers()), ConfigManager::serverDescription()}); - client.sendPacket("FL", l_feature_list); - - if (ConfigManager::assetUrl().isValid()) { - QByteArray l_asset_url = ConfigManager::assetUrl().toEncoded(QUrl::EncodeSpaces); - client.sendPacket("ASS", {l_asset_url}); - } + client.sendPacket("ID", {QString::number(client.clientId()), "akashi", QCoreApplication::applicationVersion()}); } diff --git a/src/packet/packet_ms.cpp b/src/packet/packet_ms.cpp index f0a060b7..518a020e 100644 --- a/src/packet/packet_ms.cpp +++ b/src/packet/packet_ms.cpp @@ -4,6 +4,39 @@ #include "server.h" #include +#include + +enum CHAT_MESSAGE +{ + DESK_MOD, + PRE_EMOTE, + CHAR_NAME, + EMOTE, + MESSAGE, + SIDE, + SFX_NAME, + EMOTE_MOD, + CHAR_ID, + SFX_DELAY, + OBJECTION_MOD, + EVIDENCE_ID, + FLIP, + REALIZATION, + TEXT_COLOR, + SHOWNAME, + OTHER_CHARID, + SELF_OFFSET, + IMMEDIATE, + LOOPING_SFX, + SCREENSHAKE, + FRAME_SCREENSHAKE, + FRAME_REALIZATION, + FRAME_SFX, + ADDITIVE, + EFFECTS, + BLIPNAME, + SLIDE, +}; PacketMS::PacketMS(QStringList &contents) : AOPacket(contents) @@ -81,7 +114,7 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const << "3" << "4" << "5"; - QString l_incoming_deskmod = l_incoming_args[0].toString(); + QString l_incoming_deskmod = l_incoming_args[DESK_MOD].toString(); if (allowed_desk_mods.contains(l_incoming_deskmod)) { // **WARNING : THIS IS A HACK!** // A proper solution would be to deprecate chat as an argument on the clientside @@ -90,41 +123,41 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const l_args.append("1"); } else { - l_args.append(l_incoming_args[0].toString()); + l_args.append(l_incoming_args[DESK_MOD].toString()); } } else return l_invalid; // preanim - l_args.append(l_incoming_args[1].toString()); + l_args.append(l_incoming_args[PRE_EMOTE].toString()); // char name - if (client.character().toLower() != l_incoming_args[2].toString().toLower()) { + if (client.character().toLower() != l_incoming_args[CHAR_NAME].toString().toLower()) { // Selected char is different from supplied folder name // This means the user is INI-swapped if (!area->iniswapAllowed()) { - QStringList l_character_split = l_incoming_args[2].toString().split("/"); + QStringList l_character_split = l_incoming_args[CHAR_NAME].toString().split("/"); if (!client.getServer()->getCharacters().contains(l_character_split.at(0), Qt::CaseInsensitive) || l_character_split.contains("..")) return l_invalid; } qDebug() << "INI swap detected from " << client.getIpid(); } - client.m_current_iniswap = l_incoming_args[2].toString(); - l_args.append(l_incoming_args[2].toString()); + client.m_current_iniswap = l_incoming_args[CHAR_NAME].toString(); + l_args.append(l_incoming_args[CHAR_NAME].toString()); // emote - client.m_emote = l_incoming_args[3].toString(); + client.m_emote = l_incoming_args[EMOTE].toString(); if (client.m_first_person) client.m_emote = ""; l_args.append(client.m_emote); // message text - if (l_incoming_args[4].toString().size() > ConfigManager::maxCharacters()) + if (l_incoming_args[MESSAGE].toString().size() > ConfigManager::maxCharacters()) return l_invalid; // Doublepost prevention. Has to ignore blankposts and testimony commands. - QString l_incoming_msg = client.dezalgo(l_incoming_args[4].toString().trimmed()); + QString l_incoming_msg = client.dezalgo(l_incoming_args[MESSAGE].toString().trimmed()); QRegularExpressionMatch match = isTestimonyJumpCommand(client.decodeMessage(l_incoming_msg)); bool msg_is_testimony_cmd = (match.hasMatch() || l_incoming_msg == ">" || l_incoming_msg == "<"); if (!client.m_last_message.isEmpty() // If the last message you sent isn't empty, @@ -153,7 +186,7 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const } if (client.m_is_disemvoweled) { - QString l_disemvoweled_message = l_incoming_msg.remove(QRegExp("[AEIOUaeiou]")); + QString l_disemvoweled_message = l_incoming_msg.remove(QRegularExpression("[AEIOUaeiou]")); l_incoming_msg = l_disemvoweled_message; } @@ -162,15 +195,15 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const // side // this is validated clientside so w/e - l_args.append(l_incoming_args[5].toString()); - if (client.m_pos != l_incoming_args[5].toString()) { - client.m_pos = l_incoming_args[5].toString(); + l_args.append(l_incoming_args[SIDE].toString()); + if (client.m_pos != l_incoming_args[SIDE].toString()) { + client.m_pos = l_incoming_args[SIDE].toString(); client.m_pos.replace("../", "").replace("..\\", ""); client.updateEvidenceList(client.getServer()->getAreaById(client.areaId())); } // sfx name - l_args.append(l_incoming_args[6].toString()); + l_args.append(l_incoming_args[SFX_NAME].toString()); // emote modifier // Now, gather round, y'all. Here is a story that is truly a microcosm of the AO dev experience. @@ -180,7 +213,7 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const // This would crash everyone else's client, and the feature had to be disabled // But, for some reason, nobody traced the cause of this issue for many many years. // The serverside fix is needed to ensure invalid values are not sent, because the client sucks - int emote_mod = l_incoming_args[7].toInt(); + int emote_mod = l_incoming_args[EMOTE_MOD].toInt(); if (emote_mod == 4) emote_mod = 6; @@ -189,21 +222,21 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const l_args.append(QString::number(emote_mod)); // char id - if (l_incoming_args[8].toInt() != client.m_char_id) + if (l_incoming_args[CHAR_ID].toInt() != client.m_char_id) return l_invalid; - l_args.append(l_incoming_args[8].toString()); + l_args.append(l_incoming_args[CHAR_ID].toString()); // sfx delay - l_args.append(l_incoming_args[9].toString()); + l_args.append(l_incoming_args[SFX_DELAY].toString()); // objection modifier if (area->isShoutAllowed()) { - if (l_incoming_args[10].toString().contains("4")) { + if (l_incoming_args[OBJECTION_MOD].toString().contains("4")) { // custom shout includes text metadata - l_args.append(l_incoming_args[10].toString()); + l_args.append(l_incoming_args[OBJECTION_MOD].toString()); } else { - int l_obj_mod = l_incoming_args[10].toInt(); + int l_obj_mod = l_incoming_args[OBJECTION_MOD].toInt(); if ((l_obj_mod < 0) || (l_obj_mod > 4)) { return l_invalid; } @@ -211,33 +244,33 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const } } else { - if (l_incoming_args[10].toString() != "0") { + if (l_incoming_args[OBJECTION_MOD].toString() != "0") { client.sendServerMessage("Shouts have been disabled in this area."); } l_args.append("0"); } // evidence - int evi_idx = l_incoming_args[11].toInt(); + int evi_idx = l_incoming_args[EVIDENCE_ID].toInt(); if (evi_idx > area->evidence().length()) return l_invalid; l_args.append(QString::number(evi_idx)); // flipping - int l_flip = l_incoming_args[12].toInt(); + int l_flip = l_incoming_args[FLIP].toInt(); if (l_flip != 0 && l_flip != 1) return l_invalid; client.m_flipping = QString::number(l_flip); l_args.append(client.m_flipping); // realization - int realization = l_incoming_args[13].toInt(); + int realization = l_incoming_args[REALIZATION].toInt(); if (realization != 0 && realization != 1) return l_invalid; l_args.append(QString::number(realization)); // text color - int text_color = l_incoming_args[14].toInt(); + int text_color = l_incoming_args[TEXT_COLOR].toInt(); if (text_color < 0 || text_color > 11) return l_invalid; l_args.append(QString::number(text_color)); @@ -245,7 +278,7 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const // 2.6 packet extensions if (l_incoming_args.length() >= 19) { // showname - QString l_incoming_showname = client.dezalgo(l_incoming_args[15].toString().trimmed()); + QString l_incoming_showname = client.dezalgo(l_incoming_args[SHOWNAME].toString().trimmed()); if (!(l_incoming_showname == client.character() || l_incoming_showname.isEmpty()) && !area->shownameAllowed()) { client.sendServerMessage("Shownames are not allowed in this area!"); return l_invalid; @@ -256,7 +289,7 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const } // if the raw input is not empty but the trimmed input is, use a single space - if (l_incoming_showname.isEmpty() && !l_incoming_args[15].toString().isEmpty()) + if (l_incoming_showname.isEmpty() && !l_incoming_args[SHOWNAME].toString().isEmpty()) l_incoming_showname = " "; l_args.append(l_incoming_showname); client.setCharacterName(l_incoming_showname); @@ -264,7 +297,7 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const // other char id // things get a bit hairy here // don't ask me how this works, because i don't know either - QStringList l_pair_data = l_incoming_args[16].toString().split("^"); + QStringList l_pair_data = l_incoming_args[OTHER_CHARID].toString().split("^"); client.m_pairing_with = l_pair_data[0].toInt(); QString l_front_back = ""; if (l_pair_data.length() > 1) @@ -294,22 +327,15 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const l_args.append(l_other_emote); // self offset - client.m_offset = l_incoming_args[17].toString(); - // versions 2.6-2.8 cannot validate y-offset so we send them just the x-offset - if ((client.m_version.release == 2) && (client.m_version.major == 6 || client.m_version.major == 7 || client.m_version.major == 8)) { - QString l_x_offset = client.m_offset.split("&")[0]; - l_args.append(l_x_offset); - QString l_other_x_offset = l_other_offset.split("&")[0]; - l_args.append(l_other_x_offset); - } - else { - l_args.append(client.m_offset); - l_args.append(l_other_offset); - } + client.m_offset = l_incoming_args[SELF_OFFSET].toString(); + l_args.append(client.m_offset); + l_args.append(l_other_offset); + + // other flip l_args.append(l_other_flip); // immediate text processing - int l_immediate = l_incoming_args[18].toInt(); + int l_immediate = l_incoming_args[IMMEDIATE].toInt(); if (area->forceImmediate()) { if (l_args[7] == "1" || l_args[7] == "2") { l_args[7] = "0"; @@ -325,55 +351,50 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const l_args.append(QString::number(l_immediate)); } - // 2.8 packet extensions - if (l_incoming_args.length() >= 26) { - // sfx looping - int l_sfx_loop = l_incoming_args[19].toInt(); - if (l_sfx_loop != 0 && l_sfx_loop != 1) - return l_invalid; - l_args.append(QString::number(l_sfx_loop)); - - // screenshake - int l_screenshake = l_incoming_args[20].toInt(); - if (l_screenshake != 0 && l_screenshake != 1) - return l_invalid; - l_args.append(QString::number(l_screenshake)); + // sfx looping + int l_sfx_loop = l_incoming_args[LOOPING_SFX].toInt(); + if (l_sfx_loop != 0 && l_sfx_loop != 1) + return l_invalid; + l_args.append(QString::number(l_sfx_loop)); - // frames shake - l_args.append(l_incoming_args[21].toString()); + // screenshake + int l_screenshake = l_incoming_args[SCREENSHAKE].toInt(); + if (l_screenshake != 0 && l_screenshake != 1) + return l_invalid; + l_args.append(QString::number(l_screenshake)); - // frames realization - l_args.append(l_incoming_args[22].toString()); + // frames shake + l_args.append(l_incoming_args[FRAME_SCREENSHAKE].toString()); - // frames sfx - l_args.append(l_incoming_args[23].toString()); + // frames realization + l_args.append(l_incoming_args[FRAME_REALIZATION].toString()); - // additive - int l_additive = l_incoming_args[24].toInt(); - if (l_additive != 0 && l_additive != 1) - return l_invalid; - else if (area->lastICMessage().isEmpty()) { - l_additive = 0; - } - else if (!(client.m_char_id == area->lastICMessage()[8].toInt())) { - l_additive = 0; - } - else if (l_additive == 1) { - l_args[4].insert(0, " "); - } - l_args.append(QString::number(l_additive)); + // frames sfx + l_args.append(l_incoming_args[FRAME_SFX].toString()); - // effect - l_args.append(l_incoming_args[25].toString()); + // additive + int l_additive = l_incoming_args[ADDITIVE].toInt(); + if (l_additive != 0 && l_additive != 1) + return l_invalid; + else if (area->lastICMessage().isEmpty()) { + l_additive = 0; } - if (l_incoming_args.size() >= 27) { - // blips - l_args.append(l_incoming_args[26].toString()); + else if (!(client.m_char_id == area->lastICMessage()[8].toInt())) { + l_additive = 0; } - if (l_incoming_args.size() >= 28) { - // slide toggle - l_args.append(l_incoming_args[27].toString()); + else if (l_additive == 1) { + l_args[4].insert(0, " "); } + l_args.append(QString::number(l_additive)); + + // effect + l_args.append(l_incoming_args[EFFECTS].toString()); + + // blips + l_args.append(l_incoming_args[BLIPNAME].toString()); + + // slide toggle + l_args.append(l_incoming_args[SLIDE].toString()); // Testimony playback QString client_name = client.name(); diff --git a/src/packets.cpp b/src/packets.cpp index e7a433e7..a04b2efc 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -107,8 +107,7 @@ void AOClient::loginAttempt(QString message) switch (ConfigManager::authType()) { case DataTypes::AuthType::SIMPLE: if (message == ConfigManager::modpass()) { - sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button." - 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 + sendPacket("AUTH", {"1"}); m_authenticated = true; m_acl_role_id = ACLRolesHandler::SUPER_ID; } @@ -133,13 +132,11 @@ void AOClient::loginAttempt(QString message) m_authenticated = true; m_acl_role_id = server->getDatabaseManager()->getACL(username); m_moderator_name = username; - sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button." - if (m_version.release <= 2 && m_version.major <= 9 && m_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 + sendPacket("AUTH", {"1"}); sendServerMessage("Welcome, " + username); } else { - sendPacket("AUTH", {"0"}); // Client: "Login unsuccessful." + sendPacket("AUTH", {"0"}); sendServerMessage("Incorrect password."); } emit logLogin((character() + " " + characterName()), name(), username, m_ipid, diff --git a/src/server.cpp b/src/server.cpp index 9eeead7f..f626b3e6 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -519,11 +519,12 @@ QString Server::getCharacterById(int f_chr_id) int Server::getCharID(QString char_name) { - for (const QString &character : qAsConst(m_characters)) { - if (character.toLower() == char_name.toLower()) { - return m_characters.indexOf(QRegExp(character, Qt::CaseInsensitive, QRegExp::FixedString)); + for (int i = 0; i < m_characters.length(); i++) { + if (m_characters[i].toLower() == char_name.toLower()) { + return i; } } + return -1; // character does not exist } From 62575e1677c1eaf1d9451665643680daa8ca37a2 Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Sat, 6 Jul 2024 17:14:44 +0200 Subject: [PATCH 2/6] Updated AOPacket tests --- tests/unittest_aopacket/tst_unittest_aopacket.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/unittest_aopacket/tst_unittest_aopacket.cpp b/tests/unittest_aopacket/tst_unittest_aopacket.cpp index dceea969..9722b57c 100644 --- a/tests/unittest_aopacket/tst_unittest_aopacket.cpp +++ b/tests/unittest_aopacket/tst_unittest_aopacket.cpp @@ -1,6 +1,7 @@ #include #include +#include "akashidefs.h" #include "network/aopacket.h" #include "packet/packet_factory.h" @@ -86,7 +87,7 @@ void Packet::createPacketSubclass_data() << 2; QTest::newRow("ID") << "ID#" << "ID" - << 2; + << 3; QTest::newRow("MC") << "MC#" << "MC" << 2; @@ -147,9 +148,9 @@ void Packet::createPacketFromString_data() << "HI" << QStringList{"1234"}; - QTest::newRow("Multiple fields") << "ID#34#Akashi#" + QTest::newRow("Multiple fields") << "ID#34#Akashi#5.0.0#" << "ID" - << QStringList{"34", "Akashi"}; + << QStringList{"34", "Akashi", "5.0.0"}; QTest::newRow("Encoded fields") << "MC#[TT]Objection.opus#0#oldmud0#-1#0#0#" << "MC" From ad8221b83ec5166e83056916032f59b5689184f5 Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Thu, 11 Jul 2024 07:39:54 +0200 Subject: [PATCH 3/6] Update RT to guarantee two parameters --- src/packet/packet_rt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packet/packet_rt.cpp b/src/packet/packet_rt.cpp index 98eb5dab..26dfbe97 100644 --- a/src/packet/packet_rt.cpp +++ b/src/packet/packet_rt.cpp @@ -13,7 +13,7 @@ PacketInfo PacketRT::getPacketInfo() const { PacketInfo info{ .acl_permission = ACLRole::Permission::NONE, - .min_args = 1, + .min_args = 2, .header = "RT"}; return info; } From 83b8e31cc362ba422fb82cc1a2192cf4ebbd9760 Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Sun, 14 Jul 2024 13:11:22 +0200 Subject: [PATCH 4/6] Format changes --- src/packet/packet_id.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packet/packet_id.cpp b/src/packet/packet_id.cpp index 0268f341..156fa736 100644 --- a/src/packet/packet_id.cpp +++ b/src/packet/packet_id.cpp @@ -29,7 +29,7 @@ void PacketID::handlePacket(AreaData *area, AOClient &client) const client.m_socket->close(); return; } - + if (!ConfigManager::webaoEnabled() && m_content[0] == "webAO") { client.sendPacket("BD", {"WebAO is disabled on this server."}); client.m_socket->close(); From cc30b2c4de194aca258bafce4e988606b067acf9 Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Sun, 14 Jul 2024 13:18:23 +0200 Subject: [PATCH 5/6] Missing include --- src/packet/packet_id.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packet/packet_id.cpp b/src/packet/packet_id.cpp index 156fa736..b34f8e8c 100644 --- a/src/packet/packet_id.cpp +++ b/src/packet/packet_id.cpp @@ -1,6 +1,7 @@ #include "packet/packet_id.h" #include "akashidefs.h" +#include "config_manager.h" #include "server.h" #include From 9ef93e6f058c45ea5afc16d5f538e36a59589ad0 Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Sun, 14 Jul 2024 14:59:45 +0200 Subject: [PATCH 6/6] Resolved failed RT packet test --- tests/unittest_aopacket/tst_unittest_aopacket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unittest_aopacket/tst_unittest_aopacket.cpp b/tests/unittest_aopacket/tst_unittest_aopacket.cpp index 9722b57c..4d0b224c 100644 --- a/tests/unittest_aopacket/tst_unittest_aopacket.cpp +++ b/tests/unittest_aopacket/tst_unittest_aopacket.cpp @@ -111,7 +111,7 @@ void Packet::createPacketSubclass_data() << 0; QTest::newRow("RT") << "RT#" << "RT" - << 1; + << 2; QTest::newRow("SETCASE") << "SETCASE#" << "SETCASE" << 7;