Merge remote-tracking branch 'upstream/master' into discord

This commit is contained in:
Salanto 2021-04-27 23:42:14 +02:00
commit 32e88d6be1
13 changed files with 60 additions and 8 deletions

View File

@ -18,6 +18,7 @@ logbuffer=500
logging=modcall logging=modcall
maximum_statements=10 maximum_statements=10
multiclient_limit=15 multiclient_limit=15
maximum_characters=256
[Dice] [Dice]
max_value=100 max_value=100

View File

@ -2049,6 +2049,11 @@ class AOClient : public QObject {
* @param incoming_message QString to be decoded. * @param incoming_message QString to be decoded.
*/ */
QString decodeMessage(QString incoming_message); QString decodeMessage(QString incoming_message);
/**
* @brief The size, in bytes, of the last data the client sent to the server.
*/
int last_read;
}; };
#endif // AOCLIENT_H #endif // AOCLIENT_H

View File

@ -303,6 +303,11 @@ class Server : public QObject {
*/ */
int multiclient_limit; int multiclient_limit;
/**
* @brief Integer representing the maximum amount of characters an IC or OOC message can contain.
*/
int max_chars;
public slots: public slots:
/** /**
* @brief Handles a new connection. * @brief Handles a new connection.

View File

@ -19,7 +19,12 @@
void AOClient::clientData() void AOClient::clientData()
{ {
if (last_read + socket->bytesAvailable() > 30720) { // Client can send a max of 30KB to the server over two sequential reads
socket->close();
}
QString data = QString::fromUtf8(socket->readAll()); QString data = QString::fromUtf8(socket->readAll());
last_read = data.size();
if (is_partial) { if (is_partial) {
data = partial_packet + data; data = partial_packet + data;
@ -73,6 +78,10 @@ void AOClient::handlePacket(AOPacket packet)
AreaData* area = server->areas[current_area]; AreaData* area = server->areas[current_area];
PacketInfo info = packets.value(packet.header, {false, 0, &AOClient::pktDefault}); PacketInfo info = packets.value(packet.header, {false, 0, &AOClient::pktDefault});
if (packet.contents.join("").size() > 16384) {
return;
}
if (!checkAuth(info.acl_mask)) { if (!checkAuth(info.acl_mask)) {
return; return;
} }

View File

@ -25,6 +25,9 @@ AOPacket::AOPacket(QString p_header, QStringList p_contents)
AOPacket::AOPacket(QString p_packet) AOPacket::AOPacket(QString p_packet)
{ {
if (p_packet.isEmpty())
return;
QStringList packet_contents = p_packet.split("#"); QStringList packet_contents = p_packet.split("#");
if (p_packet.at(0) == '#') { if (p_packet.at(0) == '#') {
// The header is encrypted with FantaCrypt // The header is encrypted with FantaCrypt

View File

@ -32,6 +32,7 @@ AreaData::AreaData(QString p_name, int p_index) :
name_split.removeFirst(); name_split.removeFirst();
name = name_split.join(":"); name = name_split.join(":");
QSettings areas_ini("config/areas.ini", QSettings::IniFormat); QSettings areas_ini("config/areas.ini", QSettings::IniFormat);
areas_ini.setIniCodec("UTF-8");
areas_ini.beginGroup(p_name); areas_ini.beginGroup(p_name);
background = areas_ini.value("background", "gs4").toString(); background = areas_ini.value("background", "gs4").toString();
is_protected = areas_ini.value("protected_area", "false").toBool(); is_protected = areas_ini.value("protected_area", "false").toBool();
@ -41,8 +42,10 @@ AreaData::AreaData(QString p_name, int p_index) :
blankposting_allowed = areas_ini.value("blankposting_allowed","true").toBool(); blankposting_allowed = areas_ini.value("blankposting_allowed","true").toBool();
force_immediate = areas_ini.value("force_immediate", "false").toBool(); force_immediate = areas_ini.value("force_immediate", "false").toBool();
toggle_music = areas_ini.value("toggle_music", "true").toBool(); toggle_music = areas_ini.value("toggle_music", "true").toBool();
showname_allowed = areas_ini.value("shownames_allowed", "true").toBool();
areas_ini.endGroup(); areas_ini.endGroup();
QSettings config_ini("config/config.ini", QSettings::IniFormat); QSettings config_ini("config/config.ini", QSettings::IniFormat);
config_ini.setIniCodec("UTF-8");
config_ini.beginGroup("Options"); config_ini.beginGroup("Options");
int log_size = config_ini.value("logbuffer", 50).toInt(); int log_size = config_ini.value("logbuffer", 50).toInt();
log_type = config_ini.value("logger","modcall").toString(); log_type = config_ini.value("logger","modcall").toString();

View File

@ -291,6 +291,7 @@ void AOClient::cmdStatus(int argc, QStringList argv)
return; return;
} }
arup(ARUPType::STATUS, true); arup(ARUPType::STATUS, true);
sendServerMessageArea(ooc_name + " changed status to " + arg);
} }
void AOClient::cmdJudgeLog(int argc, QStringList argv) void AOClient::cmdJudgeLog(int argc, QStringList argv)

View File

@ -107,7 +107,6 @@ void AOClient::cmdTestify(int argc, QStringList argv)
} }
else { else {
clearTestimony(); clearTestimony();
area->statement = 0;
area->test_rec = AreaData::TestimonyRecording::RECORDING; area->test_rec = AreaData::TestimonyRecording::RECORDING;
sendServerMessage("Started testimony recording."); sendServerMessage("Started testimony recording.");
} }
@ -157,6 +156,7 @@ void AOClient::cmdDeleteStatement(int argc, QStringList argv)
} }
if (c_statement > 0 && area->testimony.size() > 2) { if (c_statement > 0 && area->testimony.size() > 2) {
area->testimony.remove(c_statement); area->testimony.remove(c_statement);
area->statement = c_statement - 1;
sendServerMessage("The statement with id " + QString::number(c_statement) + " has been deleted from the testimony."); sendServerMessage("The statement with id " + QString::number(c_statement) + " has been deleted from the testimony.");
} }
} }

View File

@ -21,6 +21,7 @@
bool ConfigManager::initConfig() bool ConfigManager::initConfig()
{ {
QSettings config("config/config.ini", QSettings::IniFormat); QSettings config("config/config.ini", QSettings::IniFormat);
config.setIniCodec("UTF-8");
QFileInfo config_dir_info("config/"); QFileInfo config_dir_info("config/");
if (!config_dir_info.exists() || !config_dir_info.isDir()) { if (!config_dir_info.exists() || !config_dir_info.isDir()) {
qCritical() << "Config directory doesn't exist!"; qCritical() << "Config directory doesn't exist!";
@ -39,6 +40,7 @@ bool ConfigManager::initConfig()
} }
else { else {
QSettings areas_ini("config/areas.ini", QSettings::IniFormat); QSettings areas_ini("config/areas.ini", QSettings::IniFormat);
areas_ini.setIniCodec("UTF-8");
if (areas_ini.childGroups().length() < 1) { if (areas_ini.childGroups().length() < 1) {
qCritical() << "areas.ini is invalid!"; qCritical() << "areas.ini is invalid!";
return false; return false;
@ -105,6 +107,7 @@ bool ConfigManager::initConfig()
bool ConfigManager::updateConfig(int current_version) bool ConfigManager::updateConfig(int current_version)
{ {
QSettings config("config/config.ini", QSettings::IniFormat); QSettings config("config/config.ini", QSettings::IniFormat);
config.setIniCodec("UTF-8");
if (current_version > CONFIG_VERSION) { if (current_version > CONFIG_VERSION) {
// Config version is newer than the latest version, and the config is // Config version is newer than the latest version, and the config is
// invalid This could also mean the server is out of date, and the user // invalid This could also mean the server is out of date, and the user
@ -137,6 +140,7 @@ bool ConfigManager::updateConfig(int current_version)
bool ConfigManager::loadServerSettings(server_settings* settings) bool ConfigManager::loadServerSettings(server_settings* settings)
{ {
QSettings config("config/config.ini", QSettings::IniFormat); QSettings config("config/config.ini", QSettings::IniFormat);
config.setIniCodec("UTF-8");
bool port_conversion_success; bool port_conversion_success;
bool ws_port_conversion_success; bool ws_port_conversion_success;
bool local_port_conversion_success; bool local_port_conversion_success;

View File

@ -36,7 +36,7 @@ int main(int argc, char* argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName("akashi"); QCoreApplication::setApplicationName("akashi");
QCoreApplication::setApplicationVersion("apricot r3 prerelease"); QCoreApplication::setApplicationVersion("banana");
std::atexit(cleanup); std::atexit(cleanup);
ConfigManager config_manager; ConfigManager config_manager;

View File

@ -180,9 +180,14 @@ void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket p
ooc_name = dezalgo(argv[0]).replace(QRegExp("\\[|\\]|\\{|\\}|\\#|\\$|\\%|\\&"), ""); // no fucky wucky shit here ooc_name = dezalgo(argv[0]).replace(QRegExp("\\[|\\]|\\{|\\}|\\#|\\$|\\%|\\&"), ""); // no fucky wucky shit here
if (ooc_name.isEmpty() || ooc_name == server->server_name) // impersonation & empty name protection if (ooc_name.isEmpty() || ooc_name == server->server_name) // impersonation & empty name protection
return; return;
if (ooc_name.length() > 30) {
sendServerMessage("Your name is too long! Please limit it to under 30 characters.");
return;
}
QString message = dezalgo(argv[1]); QString message = dezalgo(argv[1]);
if (message.length() == 0) if (message.length() == 0 || message.length() > server->max_chars)
return; return;
AOPacket final_packet("CT", {ooc_name, message, "0"}); AOPacket final_packet("CT", {ooc_name, message, "0"});
if(message.at(0) == '/') { if(message.at(0) == '/') {
@ -464,7 +469,6 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
// and outgoing packets are different. Just RTFM. // and outgoing packets are different. Just RTFM.
AOPacket invalid("INVALID", {}); AOPacket invalid("INVALID", {});
QStringList args; QStringList args;
if (current_char == "" || !joined) if (current_char == "" || !joined)
// Spectators cannot use IC // Spectators cannot use IC
@ -509,6 +513,9 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
args.append(emote); args.append(emote);
// message text // message text
if (incoming_args[4].toString().size() > server->max_chars)
return invalid;
QString incoming_msg = dezalgo(incoming_args[4].toString().trimmed()); QString incoming_msg = dezalgo(incoming_args[4].toString().trimmed());
if (!area->last_ic_message.isEmpty() if (!area->last_ic_message.isEmpty()
&& incoming_msg == area->last_ic_message[4] && incoming_msg == area->last_ic_message[4]
@ -615,6 +622,15 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
if (incoming_args.length() > 15) { if (incoming_args.length() > 15) {
// showname // showname
QString incoming_showname = dezalgo(incoming_args[15].toString().trimmed()); QString incoming_showname = dezalgo(incoming_args[15].toString().trimmed());
if (!(incoming_showname == current_char || incoming_showname.isEmpty()) && !area->showname_allowed) {
sendServerMessage("Shownames are not allowed in this area!");
return invalid;
}
if (incoming_showname.length() > 30) {
sendServerMessage("Your showname is too long! Please limit it to under 30 characters");
return invalid;
}
// if the raw input is not empty but the trimmed input is, use a single space // if the raw input is not empty but the trimmed input is, use a single space
if (incoming_showname.isEmpty() && !incoming_args[15].toString().isEmpty()) if (incoming_showname.isEmpty() && !incoming_args[15].toString().isEmpty())
incoming_showname = " "; incoming_showname = " ";
@ -726,7 +742,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
if (args[5] != "wit") if (args[5] != "wit")
return AOPacket("MS", args); return AOPacket("MS", args);
if (area->statement == 0) { if (area->statement == -1) {
args[4] = "~~\\n-- " + args[4] + " --"; args[4] = "~~\\n-- " + args[4] + " --";
args[14] = "3"; args[14] = "3";
server->broadcast(AOPacket("RT",{"testimony1"}), current_area); server->broadcast(AOPacket("RT",{"testimony1"}), current_area);

View File

@ -290,6 +290,10 @@ void Server::loadServerConfig()
multiclient_limit = config.value("multiclient_limit", "15").toInt(&multiclient_limit_conversion_success); multiclient_limit = config.value("multiclient_limit", "15").toInt(&multiclient_limit_conversion_success);
if (!multiclient_limit_conversion_success) if (!multiclient_limit_conversion_success)
multiclient_limit = 15; multiclient_limit = 15;
bool max_char_conversion_success;
max_chars = config.value("maximum_characters", "256").toInt(&max_char_conversion_success);
if (!max_char_conversion_success)
max_chars = 256;
config.endGroup(); config.endGroup();
//Load dice values //Load dice values

View File

@ -23,15 +23,15 @@ void AOClient::addStatement(QStringList packet)
{ {
AreaData* area = server->areas[current_area]; AreaData* area = server->areas[current_area];
int c_statement = area->statement; int c_statement = area->statement;
if (c_statement >= 0) { if (c_statement >= -1) {
if (area->test_rec == AreaData::TestimonyRecording::RECORDING) { if (area->test_rec == AreaData::TestimonyRecording::RECORDING) {
if (c_statement <= server->maximum_statements) { if (c_statement <= server->maximum_statements) {
if (c_statement == 0) if (c_statement == -1)
packet[14] = "3"; packet[14] = "3";
else else
packet[14] = "1"; packet[14] = "1";
area->testimony.append(packet);
area->statement = c_statement + 1; area->statement = c_statement + 1;
area->testimony.append(packet);
return; return;
} }
else { else {
@ -70,6 +70,7 @@ void AOClient::clearTestimony()
{ {
AreaData* area = server->areas[current_area]; AreaData* area = server->areas[current_area];
area->test_rec = AreaData::TestimonyRecording::STOPPED; area->test_rec = AreaData::TestimonyRecording::STOPPED;
area->statement = -1;
area->testimony.clear(); //!< Empty out the QVector area->testimony.clear(); //!< Empty out the QVector
area->testimony.squeeze(); //!< Release memory. Good idea? God knows, I do not. area->testimony.squeeze(); //!< Release memory. Good idea? God knows, I do not.
} }