Skip to content

Commit a77eb29

Browse files
committed
Replace Discord.cpp with DiscordHook
1 parent 032db2d commit a77eb29

19 files changed

+193
-443
lines changed

CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ qt_add_executable(akashi
9797
src/data_types.h
9898
src/db_manager.cpp
9999
src/db_manager.h
100-
src/discord.cpp
101-
src/discord.h
102100
src/main.cpp
103101
src/medieval_parser.cpp
104102
src/medieval_parser.h

library/include/discordhook.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class AKASHI_ADDON_EXPORT DiscordMessage : public DiscordMessageCommon
3838
DiscordMessage &setEmbedTitle(const QString &title);
3939
DiscordMessage &setEmbedDescription(const QString &description);
4040
DiscordMessage &setEmbedUrl(const QString &url);
41-
DiscordMessage &setEmbedColor(int color);
41+
DiscordMessage &setEmbedColor(QString color);
4242
DiscordMessage &setEmbedTimestamp(const QString &timestamp);
4343
DiscordMessage &setEmbedFooter(const QString &text, const QString &icon_url = "");
4444
DiscordMessage &setEmbedImage(const QString &url);
@@ -82,9 +82,9 @@ class AKASHI_ADDON_EXPORT DiscordMultipartMessage : public DiscordMessageCommon
8282
~DiscordMultipartMessage() = default;
8383

8484
template <typename T>
85-
DiscordMultipartMessage &addPart(T data, QString name, QString filename = "")
85+
DiscordMultipartMessage &addPart(T data, QString name, QString filename = "", QString mime_type = "", QString charset = "")
8686
{
87-
m_parts.append(DiscordMultipart(std::move(data), std::move(name), std::move(filename)));
87+
m_parts.append(DiscordMultipart(std::move(data), std::move(name), std::move(filename), std::move(mime_type), std::move(charset)));
8888
return *this;
8989
}
9090

@@ -101,6 +101,7 @@ class AKASHI_ADDON_EXPORT DiscordMultipartMessage : public DiscordMessageCommon
101101
QJsonObject m_payload_json;
102102
};
103103

104+
Q_DECLARE_EXPORTED_LOGGING_CATEGORY(akashiDiscordHook, AKASHI_ADDON_EXPORT)
104105
class AKASHI_ADDON_EXPORT DiscordHook : public Service
105106
{
106107
Q_OBJECT
@@ -109,7 +110,10 @@ class AKASHI_ADDON_EXPORT DiscordHook : public Service
109110
DiscordHook(QObject *parent = nullptr);
110111
~DiscordHook() = default;
111112

112-
void setServiceRegistry(ServiceRegistry *f_registry = nullptr) override;
113+
inline const static QString SERVICE_ID = "akashi.addon.discordook";
114+
115+
void
116+
setServiceRegistry(ServiceRegistry *f_registry = nullptr) override;
113117

114118
void
115119
post(const DiscordMessage &message);

library/include/service.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
#include "akashi_addon_global.h"
44

5+
#include <QLoggingCategory>
56
#include <QMap>
67
#include <QObject>
78
#include <QVariant>
8-
#include <QVersionNumber>
99

1010
class ServiceRegistry;
1111

12+
Q_DECLARE_EXPORTED_LOGGING_CATEGORY(akashiService, AKASHI_ADDON_EXPORT)
1213
class AKASHI_ADDON_EXPORT Service : public QObject
1314
{
1415
Q_OBJECT
@@ -25,13 +26,11 @@ class AKASHI_ADDON_EXPORT Service : public QObject
2526
Service(QObject *parent = nullptr) : QObject{parent} {};
2627
~Service() = default;
2728

28-
virtual void setServiceRegistry(ServiceRegistry *f_registry = nullptr) {};
29-
Service::State getState() { return m_state; };
29+
virtual void setServiceRegistry(ServiceRegistry *f_registry = nullptr);
30+
void setState(Service::State f_state);
31+
Service::State getState();
3032

31-
QString getServiceProperty(QString f_key) const
32-
{
33-
return m_service_properties.value(f_key, {});
34-
}
33+
QString getServiceProperty(QString f_key) const;
3534

3635
protected:
3736
Service::State m_state = State::PENDING;

library/include/serviceregistry.h

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
#include "akashi_addon_global.h"
66
#include "servicewrapper.h"
77

8+
#include <QLoggingCategory>
89
#include <QMap>
910
#include <QObject>
1011

1112
class Service;
1213

14+
Q_DECLARE_EXPORTED_LOGGING_CATEGORY(akashiServiceRegistry, AKASHI_ADDON_EXPORT)
15+
1316
// Services are commonly owned by the ServiceRegistry.
1417
// Why? Because I say so. - Salanto
1518

@@ -19,14 +22,15 @@ class AKASHI_ADDON_EXPORT ServiceRegistry : public QObject
1922

2023
public:
2124
ServiceRegistry(QObject *parent = nullptr);
25+
~ServiceRegistry();
2226

2327
template <class T>
2428
requires std::is_base_of_v<Service, T>
2529
inline void create()
2630
{
2731
T *l_ptr = new T(this);
2832
l_ptr->setServiceRegistry(this);
29-
insertService(l_ptr);
33+
insertService<T>(l_ptr);
3034
}
3135

3236
template <class T>
@@ -36,31 +40,60 @@ class AKASHI_ADDON_EXPORT ServiceRegistry : public QObject
3640
{
3741
T *l_ptr = new T(this);
3842
ServiceWrapper<T> *l_wrapper = new ServiceWrapper<T>(l_ptr, f_identifier, f_version, f_author, this);
39-
insertService(l_wrapper);
43+
insertService<ServiceWrapper<T>>(l_wrapper);
4044
}
4145

4246
template <class T>
4347
requires std::is_base_of_v<Service, T>
4448
inline std::optional<T *> get(const QString f_identifier)
4549
{
4650
if (!m_services.contains(f_identifier)) {
47-
qCritical() << "Unable to get service with identifier" << f_identifier;
51+
qCCritical(akashiServiceRegistry) << qUtf8Printable(QString("Unable to get service with identifier %1").arg(f_identifier));
4852
return std::nullopt;
4953
}
5054

5155
Service *l_service = m_services.value(f_identifier);
5256

5357
const Service::State l_service_state = l_service->getState();
5458
if (l_service_state != Service::OK) {
55-
qCritical() << "Unable to get service with identifier" << f_identifier << "due to state:" << l_service_state;
59+
qCCritical(akashiServiceRegistry) << qUtf8Printable(QString("Unable to get service with identifier %1 due to state: %2").arg(f_identifier).arg(l_service_state));
5660
return std::nullopt;
5761
}
5862

5963
return std::make_optional<T *>(static_cast<T *>(l_service));
6064
}
6165

66+
inline bool exists(const QString &f_identifier)
67+
{
68+
return m_services.contains(f_identifier);
69+
}
70+
6271
private:
63-
void insertService(Service *f_ptr);
72+
template <class T>
73+
requires std::is_base_of_v<Service, T>
74+
void insertService(T *f_ptr)
75+
{
76+
std::unique_ptr<T> l_ptr_scoped(f_ptr);
77+
const QString l_identifier = l_ptr_scoped->getServiceProperty("identifier");
78+
const QString l_version = l_ptr_scoped->getServiceProperty("version");
79+
const QString l_author = l_ptr_scoped->getServiceProperty("author");
80+
81+
if (l_identifier.isEmpty()) {
82+
qCCritical(akashiServiceRegistry) << "Unable to register service: Service identifier is empty.";
83+
return;
84+
}
85+
86+
if (m_services.contains(l_identifier)) {
87+
qCCritical(akashiServiceRegistry) << "Unable to register service: Service identifier is already taken.";
88+
return;
89+
}
90+
91+
// We are out of the hot path. We can now safely remove ourselves from this equation.
92+
T *l_ptr = l_ptr_scoped.release();
93+
m_services.insert(l_identifier, l_ptr);
94+
95+
qCInfo(akashiServiceRegistry) << qUtf8Printable(QString("Adding Service: %1:%2:%3").arg(l_identifier, l_version, l_author));
96+
}
6497

6598
QMap<QString, Service *> m_services;
6699
};

library/include/servicewrapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
// This is a non-owning wrapper. Because I say so. - Salanto
99

10+
Q_DECLARE_EXPORTED_LOGGING_CATEGORY(akashiServiceWrapper, AKASHI_ADDON_EXPORT)
11+
1012
template <class T>
1113
requires std::is_base_of_v<QObject, T>
1214
class ServiceWrapper : public Service

library/src/discordhook.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <QNetworkReply>
1212
#include <QNetworkRequest>
1313

14+
Q_LOGGING_CATEGORY(akashiDiscordHook, "akashi.addon.discordhook")
15+
1416
DiscordMessage &DiscordMessage::setRequestUrl(const QString &url)
1517
{
1618
m_request_url = url;
@@ -75,7 +77,7 @@ DiscordMessage &DiscordMessage::setEmbedUrl(const QString &url)
7577
return *this;
7678
}
7779

78-
DiscordMessage &DiscordMessage::setEmbedColor(int color)
80+
DiscordMessage &DiscordMessage::setEmbedColor(QString color)
7981
{
8082
if (m_building_embed) {
8183
m_current_embed["color"] = color;
@@ -238,7 +240,7 @@ DiscordHook::DiscordHook(QObject *parent) : Service{parent}
238240
{
239241
m_service_properties = {{"author", "Salanto"},
240242
{"version", "1.0.0"},
241-
{"identifier", "akashi.network.discordhook"}};
243+
{"identifier", SERVICE_ID}};
242244
}
243245

244246
void DiscordHook::setServiceRegistry(ServiceRegistry *f_registry)
@@ -247,23 +249,23 @@ void DiscordHook::setServiceRegistry(ServiceRegistry *f_registry)
247249

248250
auto l_service = m_registry->get<ServiceWrapper<QNetworkAccessManager>>("qt.network.manager");
249251
if (!l_service.has_value()) {
250-
m_state = FAILED;
252+
setState(State::FAILED);
251253
}
252254

253-
m_state = OK;
255+
setState(State::OK);
254256
m_network_manager = l_service.value()->get();
255257
}
256258

257259
void DiscordHook::post(const DiscordMessage &message)
258260
{
259261
if (!m_network_manager) {
260-
qWarning() << "Cannot post DiscordMessage: QNetworkAccessManager not installed";
262+
qCWarning(akashiDiscordHook) << "Cannot post DiscordMessage: QNetworkAccessManager not installed";
261263
return;
262264
}
263265

264266
QUrl url(message.requestUrl());
265267
if (!url.isValid()) {
266-
qWarning() << "Failed to post DiscordMessage: Invalid URL" << message.requestUrl();
268+
qCWarning(akashiDiscordHook) << "Failed to post DiscordMessage: Invalid URL" << qUtf8Printable(message.requestUrl());
267269
return;
268270
}
269271

@@ -280,27 +282,14 @@ void DiscordHook::post(const DiscordMessage &message)
280282

281283
void DiscordHook::post(const DiscordMultipartMessage &message)
282284
{
283-
if (!m_network_manager) {
284-
qWarning() << "Cannot post DiscordMultipartMessage: QNetworkAccessManager not installed";
285-
return;
286-
}
287-
288285
QUrl url(message.requestUrl());
289286
if (!url.isValid()) {
290-
qWarning() << "Failed to post DiscordMultipartMessage: Invalid URL" << message.requestUrl();
287+
qCWarning(akashiDiscordHook) << "Failed to post DiscordMultipartMessage: Invalid URL" << qUtf8Printable(message.requestUrl());
291288
return;
292289
}
293290

294291
auto *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
295292

296-
if (!message.payloadJson().isEmpty()) {
297-
QHttpPart json_part;
298-
json_part.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"payload_json\"");
299-
json_part.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
300-
json_part.setBody(QJsonDocument(message.payloadJson()).toJson(QJsonDocument::Compact));
301-
multipart->append(json_part);
302-
}
303-
304293
for (int i = 0; i < message.size(); ++i) {
305294
const DiscordMultipart &part_data = message.partAt(i);
306295

@@ -324,6 +313,14 @@ void DiscordHook::post(const DiscordMultipartMessage &message)
324313
multipart->append(http_part);
325314
}
326315

316+
if (!message.payloadJson().isEmpty()) {
317+
QHttpPart json_part;
318+
json_part.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"payload_json\"");
319+
json_part.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
320+
json_part.setBody(QJsonDocument(message.payloadJson()).toJson(QJsonDocument::Compact));
321+
multipart->append(json_part);
322+
}
323+
327324
QNetworkRequest request(url);
328325

329326
QNetworkReply *reply = m_network_manager->post(request, multipart);
@@ -339,8 +336,8 @@ void DiscordHook::onDiscordResponse(QNetworkReply *reply)
339336
reply->deleteLater();
340337

341338
if (reply->error() != QNetworkReply::NoError) {
342-
qWarning() << "Discord webhook failed:" << reply->errorString();
343-
qWarning() << "Response body:" << reply->readAll();
339+
qCWarning(akashiDiscordHook) << "Discord webhook failed:" << qUtf8Printable(reply->errorString());
340+
qCWarning(akashiDiscordHook) << "Response body:" << reply->readAll();
344341
return;
345342
}
346343
}

library/src/service.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,28 @@
11
#include "service.h"
2+
3+
#include <QDebug>
4+
5+
Q_LOGGING_CATEGORY(akashiService, "akashi.addon.service")
6+
7+
void Service::setServiceRegistry(ServiceRegistry *f_registry)
8+
{
9+
qCDebug(akashiService) << "Called dummy implementation of" << Q_FUNC_INFO;
10+
qCDebug(akashiService) << "This is likely not what is being intended.";
11+
}
12+
13+
void Service::setState(State f_state)
14+
{
15+
m_state = f_state;
16+
qCDebug(akashiService) << "ServiceState of" << getServiceProperty("identifier") << "is set to" << m_state;
17+
}
18+
19+
Service::State Service::getState()
20+
{
21+
qCDebug(akashiService) << "ServiceState of" << getServiceProperty("identifier") << "is" << m_state;
22+
return m_state;
23+
}
24+
25+
QString Service::getServiceProperty(QString f_key) const
26+
{
27+
return m_service_properties.value(f_key, {});
28+
}

library/src/serviceregistry.cpp

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,13 @@
11
#include "serviceregistry.h"
22
#include "service.h"
3-
#include "servicewrapper.h"
43

54
#include <QDebug>
65

6+
Q_LOGGING_CATEGORY(akashiServiceRegistry, "akashi.addon.serviceregistry")
7+
78
ServiceRegistry::ServiceRegistry(QObject *parent) : QObject{parent}
89
{
9-
qInfo() << "Creating new service registry instance at" << this;
10+
qCDebug(akashiServiceRegistry) << "Created at" << this;
1011
}
1112

12-
void ServiceRegistry::insertService(Service *f_ptr)
13-
{
14-
std::unique_ptr<Service> l_ptr_scoped(f_ptr);
15-
const QString l_identifier = l_ptr_scoped->getServiceProperty("identifier");
16-
const QString l_version = l_ptr_scoped->getServiceProperty("version");
17-
const QString l_author = l_ptr_scoped->getServiceProperty("author");
18-
19-
if (l_identifier.isEmpty()) {
20-
qCritical() << "Unable to register service: Service identifier is empty.";
21-
return;
22-
}
23-
24-
if (m_services.contains(l_identifier)) {
25-
qCritical() << "Unable to register service: Service identifier is already taken.";
26-
return;
27-
}
28-
29-
// We are out of the hot path. We can now safely remove ourselves from this equation.
30-
Service *l_ptr = l_ptr_scoped.release();
31-
m_services.insert(l_identifier, l_ptr);
32-
33-
qInfo() << QString("Adding Service: %1:%2:%3").arg(l_identifier, l_version, l_author);
34-
}
13+
ServiceRegistry::~ServiceRegistry() {}

library/src/servicewrapper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
#include "servicewrapper.h"
2+
3+
Q_LOGGING_CATEGORY(akashiServiceWrapper, "akashi.addon.servicewrapper")

src/aoclient.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,13 +607,14 @@ void AOClient::onAfkTimeout()
607607
m_is_afk = true;
608608
}
609609

610-
AOClient::AOClient(Server *p_server, NetworkSocket *socket, QObject *parent, int user_id, MusicManager *p_manager) :
610+
AOClient::AOClient(Server *p_server, NetworkSocket *socket, QObject *parent, int user_id, MusicManager *p_manager, ServiceRegistry *f_registry) :
611611
QObject(parent),
612612
m_remote_ip(socket->peerAddress()),
613613
m_password(""),
614614
m_joined(false),
615615
m_socket(socket),
616616
m_music_manager(p_manager),
617+
m_service_registry(f_registry),
617618
m_last_wtce_time(0),
618619
m_id(user_id),
619620
m_current_area(0),

0 commit comments

Comments
 (0)