Skip to content

Commit 8c6c859

Browse files
committed
Add helper, fix noisy console output
1 parent 985b257 commit 8c6c859

File tree

11 files changed

+156
-131
lines changed

11 files changed

+156
-131
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ qt_add_executable(akashi
111111
src/serverpublisher.h
112112
src/testimony_recorder.cpp
113113
src/typedefs.h
114+
src/discordmessagehelper.h
114115
)
115116

116117
target_link_libraries(akashi PRIVATE

bin/config_sample/qtlogging.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[Rules]
2+
*.debug=false

library/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ add_library(akashi_addon SHARED
44
include/serviceregistry.h src/serviceregistry.cpp
55
include/servicewrapper.h src/servicewrapper.cpp
66
include/discordhook.h src/discordhook.cpp
7+
include/discordtypes.h
78
)
89
add_library(akashi::Addon ALIAS akashi_addon)
910

library/include/discordhook.h

Lines changed: 1 addition & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,12 @@
11
#pragma once
22

33
#include "akashi_addon_global.h"
4+
#include "discordtypes.h"
45
#include "service.h"
56

6-
#include <QByteArray>
7-
#include <QJsonObject>
8-
#include <QMap>
9-
#include <QString>
10-
#include <QVector>
11-
#include <concepts>
12-
137
class QNetworkAccessManager;
148
class QNetworkReply;
159

16-
class DiscordMessageCommon
17-
{
18-
public:
19-
const QString &requestUrl() const { return m_request_url; }
20-
21-
protected:
22-
QString m_request_url;
23-
};
24-
25-
class AKASHI_ADDON_EXPORT DiscordMessage : public DiscordMessageCommon
26-
{
27-
public:
28-
DiscordMessage() = default;
29-
~DiscordMessage() = default;
30-
31-
DiscordMessage &setRequestUrl(const QString &url);
32-
DiscordMessage &setContent(const QString &content);
33-
DiscordMessage &setUsername(const QString &username);
34-
DiscordMessage &setAvatarUrl(const QString &avatar_url);
35-
DiscordMessage &setTts(bool tts);
36-
37-
DiscordMessage &beginEmbed();
38-
DiscordMessage &setEmbedTitle(const QString &title);
39-
DiscordMessage &setEmbedDescription(const QString &description);
40-
DiscordMessage &setEmbedUrl(const QString &url);
41-
DiscordMessage &setEmbedColor(QString color);
42-
DiscordMessage &setEmbedTimestamp(const QString &timestamp);
43-
DiscordMessage &setEmbedFooter(const QString &text, const QString &icon_url = "");
44-
DiscordMessage &setEmbedImage(const QString &url);
45-
DiscordMessage &setEmbedThumbnail(const QString &url);
46-
DiscordMessage &setEmbedAuthor(const QString &name, const QString &url = "", const QString &icon_url = "");
47-
DiscordMessage &addEmbedField(const QString &name, const QString &value, bool inline_field = false);
48-
DiscordMessage &endEmbed();
49-
50-
QJsonObject toJson() const;
51-
52-
private:
53-
QMap<QString, QString> m_fields;
54-
QVector<QVariantMap> m_embeds;
55-
QVariantMap m_current_embed;
56-
bool m_building_embed = false;
57-
};
58-
59-
struct DiscordMultipart
60-
{
61-
QByteArray data;
62-
QString name;
63-
QString filename;
64-
QString mime_type;
65-
QString charset;
66-
67-
template <typename T>
68-
requires std::convertible_to<T, QByteArray>
69-
DiscordMultipart(T data, QString name, QString filename = "",
70-
QString mime_type = "", QString charset = "") : data(std::move(data)),
71-
name(std::move(name)),
72-
filename(std::move(filename)),
73-
mime_type(std::move(mime_type)),
74-
charset(std::move(charset))
75-
{}
76-
};
77-
78-
class AKASHI_ADDON_EXPORT DiscordMultipartMessage : public DiscordMessageCommon
79-
{
80-
public:
81-
DiscordMultipartMessage() = default;
82-
~DiscordMultipartMessage() = default;
83-
84-
template <typename T>
85-
DiscordMultipartMessage &addPart(T data, QString name, QString filename = "", QString mime_type = "", QString charset = "")
86-
{
87-
m_parts.append(DiscordMultipart(std::move(data), std::move(name), std::move(filename), std::move(mime_type), std::move(charset)));
88-
return *this;
89-
}
90-
91-
DiscordMultipartMessage &setRequestUrl(const QString &url);
92-
DiscordMultipartMessage &setPayloadJson(const QJsonObject &payload);
93-
94-
int size() const { return m_parts.size(); }
95-
const DiscordMultipart &partAt(int index) const { return m_parts.at(index); }
96-
const QVector<DiscordMultipart> &parts() const { return m_parts; }
97-
const QJsonObject &payloadJson() const { return m_payload_json; }
98-
99-
private:
100-
QVector<DiscordMultipart> m_parts;
101-
QJsonObject m_payload_json;
102-
};
103-
10410
Q_DECLARE_EXPORTED_LOGGING_CATEGORY(akashiDiscordHook, AKASHI_ADDON_EXPORT)
10511
class AKASHI_ADDON_EXPORT DiscordHook : public Service
10612
{

library/include/discordtypes.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#pragma once
2+
3+
#include "akashi_addon_global.h"
4+
5+
#include <QByteArray>
6+
#include <QJsonObject>
7+
#include <QMap>
8+
#include <QString>
9+
#include <QVector>
10+
#include <concepts>
11+
12+
class DiscordMessageCommon
13+
{
14+
public:
15+
const QString &requestUrl() const { return m_request_url; }
16+
17+
protected:
18+
QString m_request_url;
19+
};
20+
21+
class AKASHI_ADDON_EXPORT DiscordMessage : public DiscordMessageCommon
22+
{
23+
public:
24+
DiscordMessage &setRequestUrl(const QString &url);
25+
DiscordMessage &setContent(const QString &content);
26+
DiscordMessage &setUsername(const QString &username);
27+
DiscordMessage &setAvatarUrl(const QString &avatar_url);
28+
DiscordMessage &setTts(bool tts);
29+
30+
DiscordMessage &beginEmbed();
31+
DiscordMessage &setEmbedTitle(const QString &title);
32+
DiscordMessage &setEmbedDescription(const QString &description);
33+
DiscordMessage &setEmbedUrl(const QString &url);
34+
DiscordMessage &setEmbedColor(QString color);
35+
DiscordMessage &setEmbedTimestamp(const QString &timestamp);
36+
DiscordMessage &setEmbedFooter(const QString &text, const QString &icon_url = "");
37+
DiscordMessage &setEmbedImage(const QString &url);
38+
DiscordMessage &setEmbedThumbnail(const QString &url);
39+
DiscordMessage &setEmbedAuthor(const QString &name, const QString &url = "", const QString &icon_url = "");
40+
DiscordMessage &addEmbedField(const QString &name, const QString &value, bool inline_field = false);
41+
DiscordMessage &endEmbed();
42+
43+
QJsonObject toJson() const;
44+
45+
private:
46+
QMap<QString, QString> m_fields;
47+
QVector<QVariantMap> m_embeds;
48+
QVariantMap m_current_embed;
49+
bool m_building_embed = false;
50+
};
51+
52+
struct DiscordMultipart
53+
{
54+
QByteArray data;
55+
QString name;
56+
QString filename;
57+
QString mime_type;
58+
QString charset;
59+
60+
template <typename T>
61+
requires std::convertible_to<T, QByteArray>
62+
DiscordMultipart(T data, QString name, QString filename = "",
63+
QString mime_type = "", QString charset = "") : data(std::move(data)),
64+
name(std::move(name)),
65+
filename(std::move(filename)),
66+
mime_type(std::move(mime_type)),
67+
charset(std::move(charset))
68+
{}
69+
};
70+
71+
class AKASHI_ADDON_EXPORT DiscordMultipartMessage : public DiscordMessageCommon
72+
{
73+
public:
74+
template <typename T>
75+
DiscordMultipartMessage &addPart(T data, QString name, QString filename = "", QString mime_type = "", QString charset = "")
76+
{
77+
m_parts.append(DiscordMultipart(std::move(data), std::move(name), std::move(filename), std::move(mime_type), std::move(charset)));
78+
return *this;
79+
}
80+
81+
DiscordMultipartMessage &setRequestUrl(const QString &url);
82+
DiscordMultipartMessage &setPayloadJson(const QJsonObject &payload);
83+
84+
int size() const { return m_parts.size(); }
85+
const DiscordMultipart &partAt(int index) const { return m_parts.at(index); }
86+
const QVector<DiscordMultipart> &parts() const { return m_parts; }
87+
const QJsonObject &payloadJson() const { return m_payload_json; }
88+
89+
private:
90+
QVector<DiscordMultipart> m_parts;
91+
QJsonObject m_payload_json;
92+
};

library/src/service.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ void Service::setServiceRegistry(ServiceRegistry *f_registry)
1313
void Service::setState(State f_state)
1414
{
1515
m_state = f_state;
16-
qCDebug(akashiService) << "ServiceState of" << getServiceProperty("identifier") << "is set to" << m_state;
16+
qCDebug(akashiService) << "Status of" << getServiceProperty("identifier") << "is set to" << m_state;
1717
}
1818

1919
Service::State Service::getState()
2020
{
21-
qCDebug(akashiService) << "ServiceState of" << getServiceProperty("identifier") << "is" << m_state;
21+
qCDebug(akashiService) << "Status of" << getServiceProperty("identifier") << "is" << m_state;
2222
return m_state;
2323
}
2424

src/commands/moderation.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "config_manager.h"
2323
#include "db_manager.h"
2424
#include "discordhook.h"
25+
#include "discordmessagehelper.h"
2526
#include "server.h"
2627
#include "serviceregistry.h"
2728

@@ -88,14 +89,10 @@ void AOClient::cmdBan(int argc, QStringList argv)
8889

8990
emit logBan(l_ban.moderator, l_ban.ipid, l_ban_duration, l_ban.reason);
9091
if (ConfigManager::discordBanWebhookEnabled() && m_service_registry->exists(DiscordHook::SERVICE_ID)) {
91-
DiscordMessage l_message;
92-
l_message.setRequestUrl(ConfigManager::discordBanWebhookUrl())
93-
.beginEmbed()
94-
.setEmbedColor(ConfigManager::discordWebhookColor())
95-
.setEmbedTitle("Ban issued by " + l_ban.moderator)
96-
.setEmbedDescription("Client IPID : " + l_ban.ipid + "\nBan ID: " + QString::number(l_ban.id) + "\nBan reason : " + l_ban.reason + "\nBanned until : " + QString::number(l_ban.duration))
97-
.endEmbed();
98-
m_service_registry->get<DiscordHook>(DiscordHook::SERVICE_ID).value()->post(l_message);
92+
DiscordMessage l_message = DiscordMessageHelper::banMessage(l_ban.ipid, l_ban.moderator, l_ban_duration, l_ban.reason, l_ban_id);
93+
if (std::optional<DiscordHook *> l_hook = m_service_registry->get<DiscordHook>(DiscordHook::SERVICE_ID); l_hook.has_value()) {
94+
l_hook.value()->post(l_message);
95+
}
9996
}
10097
}
10198

src/discordmessagehelper.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#pragma once
2+
3+
#include "config_manager.h"
4+
#include "discordtypes.h"
5+
6+
#include <QQueue>
7+
8+
/**
9+
* @brief DiscordMessageHelper contains an assortment of helper function to create specific Webhook messages.
10+
*/
11+
namespace DiscordMessageHelper {
12+
13+
inline const DiscordMessage banMessage(const QString &f_ipid, const QString &f_moderator, const QString &f_duration, const QString &f_reason, const int &f_banID)
14+
{
15+
DiscordMessage l_message;
16+
17+
return l_message;
18+
}
19+
20+
inline const DiscordMultipartMessage modcallMessage(const QString &f_name, const QString &f_area, const QString &f_reason, const QQueue<QString> &f_buffer)
21+
{
22+
DiscordMultipartMessage l_multi_message;
23+
24+
DiscordMessage l_message;
25+
l_message.setContent(ConfigManager::discordModcallWebhookContent())
26+
.beginEmbed()
27+
.setEmbedColor(ConfigManager::discordWebhookColor())
28+
.setEmbedTitle(f_name + " filed a modcall in " + f_area)
29+
.setEmbedDescription(f_reason)
30+
.endEmbed();
31+
32+
QString l_log;
33+
for (const QString &l_entry : f_buffer) {
34+
l_log.append(l_entry);
35+
}
36+
l_multi_message.setRequestUrl(ConfigManager::discordModcallWebhookUrl());
37+
l_multi_message.addPart(l_log.toUtf8(), "file", "log.txt", "text/plain", "utf-8").setPayloadJson(l_message.toJson());
38+
39+
return l_multi_message;
40+
}
41+
42+
}

src/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
int main(int argc, char *argv[])
2828
{
29+
qputenv("QT_LOGGING_CONF", "config/qtlogging.ini");
2930
QCoreApplication app(argc, argv);
3031
QCoreApplication::setApplicationName("akashi");
3132
QCoreApplication::setApplicationVersion("jackfruit (1.9)");

src/packet/packet_ma.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "config_manager.h"
44
#include "db_manager.h"
55
#include "discordhook.h"
6+
#include "discordmessagehelper.h"
67
#include "server.h"
78
#include "serviceregistry.h"
89

@@ -106,14 +107,10 @@ void PacketMA::handlePacket(AreaData *area, AOClient &client) const
106107

107108
int ban_id = client.getServer()->getDatabaseManager()->getBanID(ban.ip);
108109
if (ConfigManager::discordBanWebhookEnabled() && client.m_service_registry->exists(DiscordHook::SERVICE_ID)) {
109-
DiscordMessage l_message;
110-
l_message.setRequestUrl(ConfigManager::discordBanWebhookUrl())
111-
.beginEmbed()
112-
.setEmbedColor(ConfigManager::discordWebhookColor())
113-
.setEmbedTitle("Ban issued by " + ban.moderator)
114-
.setEmbedDescription("Client IPID : " + ban.ipid + "\nBan ID: " + QString::number(ban_id) + "\nBan reason : " + ban.reason + "\nBanned until : " + QString::number(ban.duration))
115-
.endEmbed();
116-
client.m_service_registry->get<DiscordHook>(DiscordHook::SERVICE_ID).value()->post(l_message);
110+
DiscordMessage l_message = DiscordMessageHelper::banMessage(ban.ipid, ban.moderator, timestamp, ban.reason, ban_id);
111+
if (std::optional<DiscordHook *> l_hook = client.m_service_registry->get<DiscordHook>(DiscordHook::SERVICE_ID); l_hook.has_value()) {
112+
l_hook.value()->post(l_message);
113+
}
117114
}
118115
}
119116
}

0 commit comments

Comments
 (0)