Merge branch 'master' into config-loading

This commit is contained in:
MangosArentLiterature 2021-04-13 15:53:24 -05:00
commit c2d1286e27
7 changed files with 289 additions and 104 deletions

View File

@ -53,7 +53,7 @@ class AOClient : public QObject {
AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent = nullptr, int user_id = 0) AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent = nullptr, int user_id = 0)
: QObject(parent), id(user_id), remote_ip(p_socket->peerAddress()), password(""), : QObject(parent), id(user_id), remote_ip(p_socket->peerAddress()), password(""),
joined(false), current_area(0), current_char(""), socket(p_socket), server(p_server), joined(false), current_area(0), current_char(""), socket(p_socket), server(p_server),
is_partial(false), last_wtce_time(0), last_message("") {}; is_partial(false), last_wtce_time(0) {};
/** /**
* @brief Destructor for the AOClient instance. * @brief Destructor for the AOClient instance.
@ -1403,9 +1403,32 @@ class AOClient : public QObject {
* @brief Reloads all server configuration files. * @brief Reloads all server configuration files.
* *
* @details No arguments. * @details No arguments.
*
* @iscommand
*/ */
void cmdReload(int argc, QStringList argv); void cmdReload(int argc, QStringList argv);
/**
* @brief Sends an out-of-character message with the judgelog of an area.
*
* @details No arguments.
*
* @iscommand
*/
void cmdJudgeLog(int argc, QStringList argv);
/**
* @brief Looks up info on a ban.
*
* @details If it is called with **one argument**, that argument is the ban ID to look up.
*
* If it is called with **two arguments**, then the first argument is either a ban ID, an IPID,
* or an HDID, and the the second argument specifies the ID type.
*
* @iscommand
*/
void cmdBanInfo(int argc, QStringList argv);
///@} ///@}
/** /**
@ -1421,12 +1444,12 @@ class AOClient : public QObject {
* @brief Returns a textual representation of the time left in an area's Timer. * @brief Returns a textual representation of the time left in an area's Timer.
* *
* @param area_idx The ID of the area whose timer to grab. * @param area_idx The ID of the area whose timer to grab.
* @param timer The pointer to the area's timer. * @param timer_idx The ID of the timer to grab
* *
* @return A textual representation of the time left over on the Timer, * @return A textual representation of the time left over on the Timer,
* or `"Timer is inactive"` if the timer wasn't started. * or `"Timer is inactive"` if the timer wasn't started.
*/ */
QString getAreaTimer(int area_idx, QTimer* timer); QString getAreaTimer(int area_idx, int timer_idx);
/** /**
* @brief Generates a tsuserver3-style area list to be displayed to the user in the out-of-character chat. * @brief Generates a tsuserver3-style area list to be displayed to the user in the out-of-character chat.
@ -1530,76 +1553,78 @@ class AOClient : public QObject {
* See @ref CommandInfo "the type's documentation" for more details. * See @ref CommandInfo "the type's documentation" for more details.
*/ */
const QMap<QString, CommandInfo> commands { const QMap<QString, CommandInfo> commands {
{"login", {ACLFlags.value("NONE"), 1, &AOClient::cmdLogin}}, {"login", {ACLFlags.value("NONE"), 1, &AOClient::cmdLogin}},
{"getareas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}}, {"getareas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}},
{"getarea", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetArea}}, {"getarea", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetArea}},
{"ban", {ACLFlags.value("BAN"), 2, &AOClient::cmdBan}}, {"ban", {ACLFlags.value("BAN"), 2, &AOClient::cmdBan}},
{"kick", {ACLFlags.value("KICK"), 2, &AOClient::cmdKick}}, {"kick", {ACLFlags.value("KICK"), 2, &AOClient::cmdKick}},
{"changeauth", {ACLFlags.value("SUPER"), 0, &AOClient::cmdChangeAuth}}, {"changeauth", {ACLFlags.value("SUPER"), 0, &AOClient::cmdChangeAuth}},
{"rootpass", {ACLFlags.value("SUPER"), 1, &AOClient::cmdSetRootPass}}, {"rootpass", {ACLFlags.value("SUPER"), 1, &AOClient::cmdSetRootPass}},
{"background", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}}, {"background", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}},
{"bg", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}}, {"bg", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}},
{"bglock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgLock}}, {"bglock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgLock}},
{"bgunlock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgUnlock}}, {"bgunlock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgUnlock}},
{"adduser", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddUser}}, {"adduser", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddUser}},
{"listperms", {ACLFlags.value("NONE"), 0, &AOClient::cmdListPerms}}, {"listperms", {ACLFlags.value("NONE"), 0, &AOClient::cmdListPerms}},
{"addperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddPerms}}, {"addperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddPerms}},
{"removeperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdRemovePerms}}, {"removeperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdRemovePerms}},
{"listusers", {ACLFlags.value("MODIFY_USERS"), 0, &AOClient::cmdListUsers}}, {"listusers", {ACLFlags.value("MODIFY_USERS"), 0, &AOClient::cmdListUsers}},
{"logout", {ACLFlags.value("NONE"), 0, &AOClient::cmdLogout}}, {"logout", {ACLFlags.value("NONE"), 0, &AOClient::cmdLogout}},
{"pos", {ACLFlags.value("NONE"), 1, &AOClient::cmdPos}}, {"pos", {ACLFlags.value("NONE"), 1, &AOClient::cmdPos}},
{"g", {ACLFlags.value("NONE"), 1, &AOClient::cmdG}}, {"g", {ACLFlags.value("NONE"), 1, &AOClient::cmdG}},
{"need", {ACLFlags.value("NONE"), 1, &AOClient::cmdNeed}}, {"need", {ACLFlags.value("NONE"), 1, &AOClient::cmdNeed}},
{"coinflip", {ACLFlags.value("NONE"), 0, &AOClient::cmdFlip}}, {"coinflip", {ACLFlags.value("NONE"), 0, &AOClient::cmdFlip}},
{"roll", {ACLFlags.value("NONE"), 0, &AOClient::cmdRoll}}, {"roll", {ACLFlags.value("NONE"), 0, &AOClient::cmdRoll}},
{"rollp", {ACLFlags.value("NONE"), 0, &AOClient::cmdRollP}}, {"rollp", {ACLFlags.value("NONE"), 0, &AOClient::cmdRollP}},
{"doc", {ACLFlags.value("NONE"), 0, &AOClient::cmdDoc}}, {"doc", {ACLFlags.value("NONE"), 0, &AOClient::cmdDoc}},
{"cleardoc", {ACLFlags.value("NONE"), 0, &AOClient::cmdClearDoc}}, {"cleardoc", {ACLFlags.value("NONE"), 0, &AOClient::cmdClearDoc}},
{"cm", {ACLFlags.value("NONE"), 0, &AOClient::cmdCM}}, {"cm", {ACLFlags.value("NONE"), 0, &AOClient::cmdCM}},
{"uncm", {ACLFlags.value("CM"), 0, &AOClient::cmdUnCM}}, {"uncm", {ACLFlags.value("CM"), 0, &AOClient::cmdUnCM}},
{"invite", {ACLFlags.value("CM"), 1, &AOClient::cmdInvite}}, {"invite", {ACLFlags.value("CM"), 1, &AOClient::cmdInvite}},
{"uninvite", {ACLFlags.value("CM"), 1, &AOClient::cmdUnInvite}}, {"uninvite", {ACLFlags.value("CM"), 1, &AOClient::cmdUnInvite}},
{"lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}}, {"lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}},
{"area_lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}}, {"area_lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}},
{"spectatable", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}}, {"spectatable", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}},
{"area_spectate", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}}, {"area_spectate", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}},
{"unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}}, {"unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}},
{"area_unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}}, {"area_unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}},
{"timer", {ACLFlags.value("CM"), 0, &AOClient::cmdTimer}}, {"timer", {ACLFlags.value("CM"), 0, &AOClient::cmdTimer}},
{"area", {ACLFlags.value("NONE"), 1, &AOClient::cmdArea}}, {"area", {ACLFlags.value("NONE"), 1, &AOClient::cmdArea}},
{"play", {ACLFlags.value("CM"), 1, &AOClient::cmdPlay}}, {"play", {ACLFlags.value("CM"), 1, &AOClient::cmdPlay}},
{"areakick", {ACLFlags.value("CM"), 1, &AOClient::cmdAreaKick}}, {"areakick", {ACLFlags.value("CM"), 1, &AOClient::cmdAreaKick}},
{"area_kick", {ACLFlags.value("CM"), 1, &AOClient::cmdAreaKick}}, {"area_kick", {ACLFlags.value("CM"), 1, &AOClient::cmdAreaKick}},
{"randomchar", {ACLFlags.value("NONE"), 0, &AOClient::cmdRandomChar}}, {"randomchar", {ACLFlags.value("NONE"), 0, &AOClient::cmdRandomChar}},
{"switch", {ACLFlags.value("NONE"), 1, &AOClient::cmdSwitch}}, {"switch", {ACLFlags.value("NONE"), 1, &AOClient::cmdSwitch}},
{"toggleglobal", {ACLFlags.value("NONE"), 0, &AOClient::cmdToggleGlobal}}, {"toggleglobal", {ACLFlags.value("NONE"), 0, &AOClient::cmdToggleGlobal}},
{"mods", {ACLFlags.value("NONE"), 0, &AOClient::cmdMods}}, {"mods", {ACLFlags.value("NONE"), 0, &AOClient::cmdMods}},
{"help", {ACLFlags.value("NONE"), 0, &AOClient::cmdHelp}}, {"help", {ACLFlags.value("NONE"), 0, &AOClient::cmdHelp}},
{"status", {ACLFlags.value("NONE"), 1, &AOClient::cmdStatus}}, {"status", {ACLFlags.value("NONE"), 1, &AOClient::cmdStatus}},
{"forcepos", {ACLFlags.value("CM"), 2, &AOClient::cmdForcePos}}, {"forcepos", {ACLFlags.value("CM"), 2, &AOClient::cmdForcePos}},
{"currentmusic", {ACLFlags.value("NONE"), 0, &AOClient::cmdCurrentMusic}}, {"currentmusic", {ACLFlags.value("NONE"), 0, &AOClient::cmdCurrentMusic}},
{"pm", {ACLFlags.value("NONE"), 2, &AOClient::cmdPM}}, {"pm", {ACLFlags.value("NONE"), 2, &AOClient::cmdPM}},
{"evidence_mod", {ACLFlags.value("EVI_MOD"), 1, &AOClient::cmdEvidenceMod}}, {"evidence_mod", {ACLFlags.value("EVI_MOD"), 1, &AOClient::cmdEvidenceMod}},
{"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}}, {"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}},
{"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}}, {"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}},
{"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}}, {"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}},
{"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}}, {"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}},
{"mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdMute}}, {"mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdMute}},
{"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnMute}}, {"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnMute}},
{"bans", {ACLFlags.value("BAN"), 0, &AOClient::cmdBans}}, {"bans", {ACLFlags.value("BAN"), 0, &AOClient::cmdBans}},
{"unban", {ACLFlags.value("BAN"), 1, &AOClient::cmdUnBan}}, {"unban", {ACLFlags.value("BAN"), 1, &AOClient::cmdUnBan}},
{"removeuser", {ACLFlags.value("MODIFY_USERS"), 1, &AOClient::cmdRemoveUser}}, {"removeuser", {ACLFlags.value("MODIFY_USERS"), 1, &AOClient::cmdRemoveUser}},
{"subtheme", {ACLFlags.value("CM"), 1, &AOClient::cmdSubTheme}}, {"subtheme", {ACLFlags.value("CM"), 1, &AOClient::cmdSubTheme}},
{"about", {ACLFlags.value("NONE"), 0, &AOClient::cmdAbout}}, {"about", {ACLFlags.value("NONE"), 0, &AOClient::cmdAbout}},
{"evidence_swap", {ACLFlags.value("CM"), 2, &AOClient::cmdEvidence_Swap}}, {"evidence_swap", {ACLFlags.value("CM"), 2, &AOClient::cmdEvidence_Swap}},
{"notecard", {ACLFlags.value("NONE"), 1, &AOClient::cmdNoteCard}}, {"notecard", {ACLFlags.value("NONE"), 1, &AOClient::cmdNoteCard}},
{"notecardreveal", {ACLFlags.value("CM"), 0, &AOClient::cmdNoteCardReveal}}, {"notecardreveal", {ACLFlags.value("CM"), 0, &AOClient::cmdNoteCardReveal}},
{"notecard_reveal", {ACLFlags.value("CM"), 0, &AOClient::cmdNoteCardReveal}}, {"notecard_reveal", {ACLFlags.value("CM"), 0, &AOClient::cmdNoteCardReveal}},
{"notecardclear", {ACLFlags.value("NONE"), 0, &AOClient::cmdNoteCardClear}}, {"notecardclear", {ACLFlags.value("NONE"), 0, &AOClient::cmdNoteCardClear}},
{"notecard_clear", {ACLFlags.value("NONE"), 0, &AOClient::cmdNoteCardClear}}, {"notecard_clear", {ACLFlags.value("NONE"), 0, &AOClient::cmdNoteCardClear}},
{"8ball", {ACLFlags.value("NONE"), 1, &AOClient::cmd8Ball}}, {"8ball", {ACLFlags.value("NONE"), 1, &AOClient::cmd8Ball}},
{"lm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdLM}}, {"lm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdLM}},
{"judgelog", {ACLFlags.value("CM"), 0, &AOClient::cmdJudgeLog}},
{"allow_blankposting", {ACLFlags.value("MODCHAT"), 0, &AOClient::cmdAllow_Blankposting}}, {"allow_blankposting", {ACLFlags.value("MODCHAT"), 0, &AOClient::cmdAllow_Blankposting}},
{"baninfo", {ACLFlags.value("BAN"), 1, &AOClient::cmdBanInfo}},
}; };
/** /**
@ -1647,6 +1672,17 @@ class AOClient : public QObject {
* @details Used to determine if the incoming message is a duplicate. * @details Used to determine if the incoming message is a duplicate.
*/ */
QString last_message; QString last_message;
/**
* @brief A helper function to add recorded packets to an area's judgelog.
*
* @param area Pointer to the area where the packet was sent.
*
* @param client Pointer to the client that sent the packet.
*
* @param action String containing the info that is being recorded.
*/
void updateJudgeLog(AreaData* area, AOClient* client, QString action);
}; };
#endif // AOCLIENT_H #endif // AOCLIENT_H

View File

@ -278,6 +278,13 @@ class AreaData : public QObject {
EvidenceMod evi_mod; EvidenceMod evi_mod;
QMap<QString, QString> notecards; QMap<QString, QString> notecards;
/**
* @brief The judgelog of an area.
*
* @details This list contains up to 10 recorded packets of the most recent judge actions (WT/CE or penalty updates) in an area.
*/
QStringList judgelog;
/** /**
* @brief The last IC packet sent in an area. * @brief The last IC packet sent in an area.
*/ */

View File

@ -239,6 +239,15 @@ public:
*/ */
QStringList getUsers(); QStringList getUsers();
/**
* @brief Gets information on a ban.
*
* @param lookup_type The type of ID to search
*
* @param id A Ban ID, IPID, or HDID to search for
*/
QList<BanInfo> getBanInfo(QString lookup_type, QString id);
private: private:
/** /**
* @brief The name of the database connection driver. * @brief The name of the database connection driver.

View File

@ -25,6 +25,7 @@ AreaData::AreaData(QString p_name, int p_index) :
document("No document."), document("No document."),
def_hp(10), def_hp(10),
pro_hp(10), pro_hp(10),
judgelog(),
last_ic_message() last_ic_message()
{ {
QStringList name_split = p_name.split(":"); QStringList name_split = p_name.split(":");

View File

@ -656,20 +656,19 @@ void AOClient::cmdTimer(int argc, QStringList argv)
{ {
AreaData* area = server->areas[current_area]; AreaData* area = server->areas[current_area];
// Called without arguments
// Shows a brief of all timers
if (argc == 0) { if (argc == 0) {
QStringList timers; QStringList timers;
timers.append("Currently active timers:"); timers.append("Currently active timers:");
QTimer* global_timer = server->timer; for (int i = 0; i <= 4; i++) {
if (global_timer->isActive()) { timers.append(getAreaTimer(area->index, i));
QTime current_time = QTime(0,0).addMSecs(global_timer->remainingTime());
timers.append("Global timer is at " + current_time.toString("hh:mm:ss.zzz"));
}
for (QTimer* timer : area->timers) {
timers.append(getAreaTimer(area->index, timer));
} }
sendServerMessage(timers.join("\n")); sendServerMessage(timers.join("\n"));
return; return;
} }
// Called with more than one argument
bool ok; bool ok;
int timer_id = argv[0].toInt(&ok); int timer_id = argv[0].toInt(&ok);
if (!ok || timer_id < 0 || timer_id > 4) { if (!ok || timer_id < 0 || timer_id > 4) {
@ -677,22 +676,18 @@ void AOClient::cmdTimer(int argc, QStringList argv)
return; return;
} }
// Called with one argument
// Shows the status of one timer
if (argc == 1) { if (argc == 1) {
if (timer_id == 0) { sendServerMessage(getAreaTimer(area->index, timer_id));
QTimer* global_timer = server->timer; return;
if (global_timer->isActive()) {
QTime current_time = QTime(0, 0, 0, global_timer->remainingTime());
sendServerMessage("Global timer is at " + current_time.toString("hh:mm:ss.zzz"));
return;
}
}
else {
QTimer* timer = area->timers[timer_id - 1];
sendServerMessage(getAreaTimer(area->index, timer));
return;
}
} }
// Called with more than one argument
// Updates the state of a timer
// Select the proper timer
// Check against permissions if global timer is selected
QTimer* requested_timer; QTimer* requested_timer;
if (timer_id == 0) { if (timer_id == 0) {
if (!checkAuth(ACLFlags.value("GLOBAL_TIMER"))) { if (!checkAuth(ACLFlags.value("GLOBAL_TIMER"))) {
@ -703,33 +698,45 @@ void AOClient::cmdTimer(int argc, QStringList argv)
} }
else else
requested_timer = area->timers[timer_id - 1]; requested_timer = area->timers[timer_id - 1];
AOPacket show_timer("TI", {QString::number(timer_id), "2"});
AOPacket hide_timer("TI", {QString::number(timer_id), "3"});
bool is_global = timer_id == 0;
// Set the timer's time remaining if the second
// argument is a valid time
QTime requested_time = QTime::fromString(argv[1], "hh:mm:ss"); QTime requested_time = QTime::fromString(argv[1], "hh:mm:ss");
if (requested_time.isValid()) { if (requested_time.isValid()) {
requested_timer->setInterval(QTime(0,0).msecsTo(requested_time)); requested_timer->setInterval(QTime(0,0).msecsTo(requested_time));
requested_timer->start(); requested_timer->start();
sendServerMessage("Set timer " + QString::number(timer_id) + " to " + argv[1] + "."); sendServerMessage("Set timer " + QString::number(timer_id) + " to " + argv[1] + ".");
sendPacket("TI", {QString::number(timer_id), "2"}); // Show the timer AOPacket update_timer("TI", {QString::number(timer_id), "0", QString::number(QTime(0,0).msecsTo(requested_time))});
sendPacket("TI", {QString::number(timer_id), "0", QString::number(QTime(0,0).msecsTo(requested_time))}); is_global ? server->broadcast(show_timer) : server->broadcast(show_timer, current_area); // Show the timer
is_global ? server->broadcast(update_timer) : server->broadcast(update_timer, current_area);
return; return;
} }
// Otherwise, update the state of the timer
else { else {
if (argv[1] == "start") { if (argv[1] == "start") {
requested_timer->start(); requested_timer->start();
sendServerMessage("Started timer " + QString::number(timer_id) + "."); sendServerMessage("Started timer " + QString::number(timer_id) + ".");
sendPacket("TI", {QString::number(timer_id), "2"}); // Show the timer AOPacket update_timer("TI", {QString::number(timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(requested_timer->remainingTime())))});
sendPacket("TI", {QString::number(timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(requested_timer->remainingTime())))}); is_global ? server->broadcast(show_timer) : server->broadcast(show_timer, current_area);
is_global ? server->broadcast(update_timer) : server->broadcast(update_timer, current_area);
} }
else if (argv[1] == "pause" || argv[1] == "stop") { else if (argv[1] == "pause" || argv[1] == "stop") {
requested_timer->setInterval(requested_timer->remainingTime()); requested_timer->setInterval(requested_timer->remainingTime());
requested_timer->stop(); requested_timer->stop();
sendServerMessage("Stopped timer " + QString::number(timer_id) + "."); sendServerMessage("Stopped timer " + QString::number(timer_id) + ".");
sendPacket("TI", {QString::number(timer_id), "1", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(requested_timer->interval())))}); AOPacket update_timer("TI", {QString::number(timer_id), "1", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(requested_timer->interval())))});
is_global ? server->broadcast(update_timer) : server->broadcast(update_timer, current_area);
} }
else if (argv[1] == "hide" || argv[1] == "unset") { else if (argv[1] == "hide" || argv[1] == "unset") {
requested_timer->setInterval(0); requested_timer->setInterval(0);
requested_timer->stop(); requested_timer->stop();
sendServerMessage("Hid timer " + QString::number(timer_id) + "."); sendServerMessage("Hid timer " + QString::number(timer_id) + ".");
sendPacket("TI", {QString::number(timer_id), "3"}); // Hide the timer // Hide the timer
is_global ? server->broadcast(hide_timer) : server->broadcast(hide_timer, current_area);
} }
} }
} }
@ -1252,6 +1259,24 @@ void AOClient::cmd8Ball(int argc, QStringList argv)
} }
} }
void AOClient::cmdJudgeLog(int argc, QStringList argv)
{
AreaData* area = server->areas[current_area];
if (area->judgelog.isEmpty()) {
sendServerMessage("There have been no judge actions in this area.");
return;
}
QString message = area->judgelog.join("\n");
//Judgelog contains an IPID, so we shouldn't send that unless the caller has appropriate permissions
if (checkAuth(ACLFlags.value("KICK")) == 1 || checkAuth(ACLFlags.value("BAN")) == 1) {
sendServerMessage(message);
}
else {
QString filteredmessage = message.remove(QRegularExpression("[(].*[)]")); //Filter out anything between two parentheses. This should only ever be the IPID
sendServerMessage(filteredmessage);
}
}
void AOClient::cmdAllow_Blankposting(int argc, QStringList argv) void AOClient::cmdAllow_Blankposting(int argc, QStringList argv)
{ {
QString sender_name = ooc_name; QString sender_name = ooc_name;
@ -1265,6 +1290,44 @@ void AOClient::cmdAllow_Blankposting(int argc, QStringList argv)
} }
} }
void AOClient::cmdBanInfo(int argc, QStringList argv)
{
QStringList ban_info;
ban_info << ("Ban Info for " + argv[0]);
ban_info << "-----";
QString lookup_type;
if (argc == 1) {
lookup_type = "banid";
}
else if (argc == 2) {
lookup_type = argv[1];
if (!((lookup_type == "banid") || (lookup_type == "ipid") || (lookup_type == "hdid"))) {
sendServerMessage("Invalid ID type.");
return;
}
}
else {
sendServerMessage("Invalid command.");
return;
}
QString id = argv[0];
for (DBManager::BanInfo ban : server->db_manager->getBanInfo(lookup_type, id)) {
QString banned_until;
if (ban.duration == -2)
banned_until = "The heat death of the universe";
else
banned_until = QDateTime::fromSecsSinceEpoch(ban.time).addSecs(ban.duration).toString("dd.MM.yyyy, hh:mm");
ban_info << "Affected IPID: " + ban.ipid;
ban_info << "Affected HDID: " + ban.hdid;
ban_info << "Reason for ban: " + ban.reason;
ban_info << "Date of ban: " + QDateTime::fromSecsSinceEpoch(ban.time).toString("dd.MM.yyyy, hh:mm");
ban_info << "Ban lasts until: " + banned_until;
ban_info << "-----";
}
sendServerMessage(ban_info.join("\n"));
}
QStringList AOClient::buildAreaList(int area_idx) QStringList AOClient::buildAreaList(int area_idx)
{ {
QStringList entries; QStringList entries;
@ -1369,15 +1432,26 @@ void AOClient::diceThrower(int argc, QStringList argv, RollType type)
} }
} }
QString AOClient::getAreaTimer(int area_idx, QTimer* timer) QString AOClient::getAreaTimer(int area_idx, int timer_idx)
{ {
AreaData* area = server->areas[area_idx]; AreaData* area = server->areas[area_idx];
QTimer* timer;
QString timer_name = (timer_idx == 0) ? "Global timer" : "Timer " + QString::number(timer_idx);
if (timer_idx == 0)
timer = server->timer;
else if (timer_idx > 0 && timer_idx <= 4)
timer = area->timers[timer_idx - 1];
else
return "Invalid timer ID.";
if (timer->isActive()) { if (timer->isActive()) {
QTime current_time = QTime(0,0).addMSecs(timer->remainingTime()); QTime current_time = QTime(0,0).addMSecs(timer->remainingTime());
return "Timer " + QString::number(area->timers.indexOf(timer) + 1) + " is at " + current_time.toString("hh:mm:ss.zzz");
return timer_name + " is at " + current_time.toString("hh:mm:ss.zzz");
} }
else { else {
return "Timer " + QString::number(area->timers.indexOf(timer) + 1) + " is inactive."; return timer_name + " is inactive.";
} }
} }

View File

@ -325,6 +325,42 @@ QStringList DBManager::getUsers()
return users; return users;
} }
QList<DBManager::BanInfo> DBManager::getBanInfo(QString lookup_type, QString id)
{
QList<BanInfo> return_list;
QSqlQuery query;
QList<BanInfo> invalid;
if (lookup_type == "banid") {
query.prepare("SELECT * FROM BANS WHERE ID = ?");
}
else if (lookup_type == "hdid") {
query.prepare("SELECT * FROM BANS WHERE HDID = ?");
}
else if (lookup_type == "ipid") {
query.prepare("SELECT * FROM BANS WHERE IPID = ?");
}
else {
qCritical("Invalid ban lookup type!");
return invalid;
}
query.addBindValue(id);
query.setForwardOnly(true);
query.exec();
while (query.next()) {
BanInfo ban;
ban.ipid = query.value(0).toString();
ban.hdid = query.value(1).toString();
ban.ip = QHostAddress(query.value(2).toString());
ban.time = static_cast<unsigned long>(query.value(3).toULongLong());
ban.reason = query.value(4).toString();
ban.duration = query.value(5).toLongLong();
return_list.append(ban);
}
std::reverse(return_list.begin(), return_list.end());
return return_list;
}
DBManager::~DBManager() DBManager::~DBManager()
{ {
db.close(); db.close();

View File

@ -182,6 +182,8 @@ void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket p
return; return;
QString message = dezalgo(argv[1]); QString message = dezalgo(argv[1]);
if (message.length() == 0)
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) == '/') {
QStringList cmd_argv = message.split(" ", QString::SplitBehavior::SkipEmptyParts); QStringList cmd_argv = message.split(" ", QString::SplitBehavior::SkipEmptyParts);
@ -260,6 +262,7 @@ void AOClient::pktWtCe(AreaData* area, int argc, QStringList argv, AOPacket pack
return; return;
last_wtce_time = QDateTime::currentDateTime().toSecsSinceEpoch(); last_wtce_time = QDateTime::currentDateTime().toSecsSinceEpoch();
server->broadcast(packet, current_area); server->broadcast(packet, current_area);
updateJudgeLog(area, this, "WT/CE");
} }
void AOClient::pktHpBar(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktHpBar(AreaData* area, int argc, QStringList argv, AOPacket packet)
@ -276,6 +279,7 @@ void AOClient::pktHpBar(AreaData* area, int argc, QStringList argv, AOPacket pac
} }
server->broadcast(AOPacket("HP", {"1", QString::number(area->def_hp)}), area->index); server->broadcast(AOPacket("HP", {"1", QString::number(area->def_hp)}), area->index);
server->broadcast(AOPacket("HP", {"2", QString::number(area->pro_hp)}), area->index); server->broadcast(AOPacket("HP", {"2", QString::number(area->pro_hp)}), area->index);
updateJudgeLog(area, this, "updated the penalties");
} }
void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPacket packet)
@ -430,15 +434,15 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
// message text // message text
QString incoming_msg = dezalgo(incoming_args[4].toString().trimmed()); QString incoming_msg = dezalgo(incoming_args[4].toString().trimmed());
if (incoming_msg == last_message) if (!area->last_ic_message.isEmpty()
&& incoming_msg == area->last_ic_message[4]
&& incoming_msg != "")
return invalid; return invalid;
if (incoming_msg == "" && area->blankposting_allowed == false) { if (incoming_msg == "" && area->blankposting_allowed == false) {
sendServerMessage("Blankposting has been forbidden in this area."); sendServerMessage("Blankposting has been forbidden in this area.");
return invalid; return invalid;
} }
last_message = incoming_msg;
args.append(incoming_msg); args.append(incoming_msg);
// side // side
@ -645,3 +649,21 @@ bool AOClient::checkEvidenceAccess(AreaData *area)
return false; return false;
} }
} }
void AOClient::updateJudgeLog(AreaData* area, AOClient* client, QString action)
{
QString timestamp = QTime::currentTime().toString("hh:mm:ss");
QString uid = QString::number(client->id);
QString char_name = client->current_char;
QString ipid = client->getIpid();
QString message = action;
QString logmessage = QString("[%1]: [%2] %3 (%4) %5").arg(timestamp, uid, char_name, ipid, message);
int size = area->judgelog.size();
if (size == 10) {
area->judgelog.removeFirst();
area->judgelog.append(logmessage);
}
else area->judgelog.append(logmessage);
}