Skip to content

Commit 4899e96

Browse files
committed
feat: implement the discord workflows using the new SDK
use the new social sdk, to implement the needed things this is still WIP and untested
1 parent 4f240f4 commit 4899e96

File tree

9 files changed

+203
-150
lines changed

9 files changed

+203
-150
lines changed

src/discord/core.cpp

Lines changed: 139 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11

2-
#include <core/helper/magic_enum_wrapper.hpp>
32
#include <core/helper/utils.hpp>
43

54
#include "./core.hpp"
@@ -18,165 +17,219 @@
1817
}
1918
}
2019

21-
DiscordInstance::DiscordInstance(discord::Core* core) : m_core{ core }, m_current_user{ nullptr } { }
22-
23-
void DiscordInstance::after_setup() {
24-
m_core->UserManager().OnCurrentUserUpdate.Connect([this]() {
25-
auto* user = new discord::User; // NOLINT(cppcoreguidelines-owning-memory)
26-
this->m_core->UserManager().GetCurrentUser(user);
27-
this->m_current_user.reset(user);
28-
spdlog::info(
29-
"Current user updated: {}#{}", this->m_current_user->GetUsername(),
30-
this->m_current_user->GetDiscriminator()
31-
);
32-
});
33-
34-
auto result = m_core->ActivityManager().RegisterCommand(constants::discord::platform_dependent_launch_arguments);
35-
if (result != discord::Result::Ok) {
36-
spdlog::warn("ActivityManager: Failed to RegisterCommand: {}", magic_enum::enum_name(result));
37-
};
38-
}
39-
40-
[[nodiscard]] helper::expected<DiscordInstance, std::string> DiscordInstance::initialize() {
20+
DiscordInstance::DiscordInstance()
21+
: m_client{},
22+
m_current_user{ std::move(discordpp::UserHandle::nullobj) },
23+
m_status{ DiscordStatus::Starting } {
4124

42-
discord::Core* core{};
43-
auto result = discord::Core::Create(constants::discord::client_id, DiscordCreateFlags_Default, &core);
44-
if (core == nullptr) {
45-
return helper::unexpected<std::string>{
46-
fmt::format("Failed to instantiate discord core: {}", magic_enum::enum_name(result))
47-
};
48-
}
49-
50-
51-
core->SetLogHook(
52-
#if !defined(NDEBUG)
53-
discord::LogLevel::Debug
54-
#else
55-
discord::LogLevel::Error
56-
#endif
57-
,
58-
[](discord::LogLevel level, const char* message) {
59-
switch (level) {
60-
case discord::LogLevel::Error:
25+
m_client.AddLogCallback(
26+
[](std::string message, discordpp::LoggingSeverity severity) -> void {
27+
switch (severity) {
28+
case discordpp::LoggingSeverity::Error:
6129
spdlog::error("DISCORD SDK: {}", message);
6230
break;
63-
case discord::LogLevel::Warn:
31+
case discordpp::LoggingSeverity::Warning:
6432
spdlog::warn("DISCORD SDK: {}", message);
6533
break;
66-
case discord::LogLevel::Info:
34+
case discordpp::LoggingSeverity::Info:
6735
spdlog::info("DISCORD SDK: {}", message);
6836
break;
69-
case discord::LogLevel::Debug:
37+
case discordpp::LoggingSeverity::Verbose:
7038
spdlog::debug("DISCORD SDK: {}", message);
7139
break;
40+
case discordpp::LoggingSeverity::None:
41+
break;
42+
}
43+
},
44+
#if !defined(NDEBUG)
45+
discordpp::LoggingSeverity::Verbose
46+
#else
47+
discordpp::LoggingSeverity::Error
48+
#endif
49+
);
50+
51+
52+
m_client.SetStatusChangedCallback(
53+
[this](discordpp::Client::Status status, discordpp::Client::Error error, int32_t errorDetail) -> void {
54+
if (error != discordpp::Client::Error::None) {
55+
this->m_status = DiscordStatus::Error;
56+
spdlog::error(
57+
"Connection Error: {} - Details: {}", discordpp::Client::ErrorToString(error), errorDetail
58+
);
59+
return;
60+
}
61+
62+
if (status == discordpp::Client::Status::Ready) {
63+
this->m_status = DiscordStatus::Ok;
64+
this->after_ready();
65+
return;
7266
}
7367
}
7468
);
7569

76-
return DiscordInstance{ core };
70+
m_client.SetApplicationId(constants::discord::application_id);
71+
72+
m_client.Connect();
73+
}
74+
75+
void DiscordInstance::after_ready() {
76+
77+
this->m_client.GetDiscordClientConnectedUser(
78+
constants::discord::application_id,
79+
[this](discordpp::ClientResult result, std::optional<discordpp::UserHandle> user) -> void {
80+
if (result.Successful() and user.has_value()) {
81+
82+
auto user_handle = m_client.GetUser(user->Id());
83+
if (not user_handle.has_value()) {
84+
spdlog::error("Current Connected User Error: Can't get userhandle from id: {}", user->Id());
85+
86+
return;
87+
}
88+
89+
this->m_current_user = user_handle.value();
90+
spdlog::info("Current user updated: {}", user_handle->Username());
91+
92+
return;
93+
}
94+
95+
spdlog::error("Current Connected User Error: {}", result.ToString());
96+
}
97+
);
7798
}
7899

79100

80101
DiscordInstance::DiscordInstance(DiscordInstance&& old) noexcept
81-
: m_core{ std::move(old.m_core) },
82-
m_current_user{ std::move(old.m_current_user) } {
83-
old.m_core = nullptr;
84-
old.m_current_user = nullptr;
102+
: m_client{ std::move(old.m_client) },
103+
m_current_user{ std::move(old.m_current_user) },
104+
m_status{ old.m_status } {
105+
old.m_client = discordpp::Client{};
106+
old.m_current_user = discordpp::UserHandle::nullobj;
107+
old.m_status = DiscordStatus::Error;
85108
}
86109

87110

88111
DiscordInstance& DiscordInstance::operator=(DiscordInstance&& other) noexcept {
89112
if (this != &other) {
90113

91-
m_core = std::move(other.m_core);
114+
m_client = std::move(other.m_client);
92115
m_current_user = std::move(other.m_current_user);
116+
m_status = other.m_status;
93117

94-
other.m_core = nullptr;
95-
other.m_current_user = nullptr;
118+
other.m_client = discordpp::Client{};
119+
other.m_current_user = discordpp::UserHandle::nullobj;
120+
other.m_status = DiscordStatus::Error;
96121
}
97122
return *this;
98123
};
99124

100125
DiscordInstance::~DiscordInstance() {
101-
if (m_core != nullptr) {
126+
if (m_client.operator bool()) {
102127
clear_activity();
128+
m_client.Disconnect();
103129
}
104130
}
105131

106132
void DiscordInstance::update() {
107-
m_core->RunCallbacks();
133+
discordpp::RunCallbacks();
108134
}
109135

110136

111137
void DiscordInstance::set_activity(const DiscordActivityWrapper& activity) {
112138

113-
m_core->ActivityManager().UpdateActivity(activity.get_raw(), [](discord::Result result) {
114-
spdlog::info("Result to UpdateActivity: {}", magic_enum::enum_name(result));
115-
});
116-
}
139+
auto raw_activity = activity.get_raw();
117140

141+
if (not raw_activity.operator bool()) {
142+
spdlog::error("Tried to set an invalid Discord Activity!");
143+
return;
144+
}
118145

119-
void DiscordInstance::clear_activity(bool wait) {
120-
bool received_callback = false;
121-
m_core->ActivityManager().ClearActivity([&received_callback](discord::Result result) {
122-
spdlog::info("Result to ClearActivity: {}", magic_enum::enum_name(result));
123-
received_callback = true;
146+
// Update rich presence
147+
m_client.UpdateRichPresence(raw_activity, [](discordpp::ClientResult result) {
148+
if (result.Successful()) {
149+
spdlog::info("Rich Presence updated successfully");
150+
} else {
151+
spdlog::error("Rich Presence update failed: {}", result.ToString());
152+
}
124153
});
154+
}
125155

126-
using namespace std::chrono_literals;
127-
128-
if (wait) {
129-
130-
constexpr auto max_waittime = 1s;
131-
132-
const auto start_time = std::chrono::steady_clock::now();
133156

134-
while (not received_callback) {
135-
this->update();
136-
std::this_thread::sleep_for(1ms);
137-
const auto now = std::chrono::steady_clock::now();
138-
if (now - start_time >= max_waittime) {
139-
break;
140-
}
141-
}
142-
}
157+
void DiscordInstance::clear_activity() {
158+
m_client.ClearRichPresence();
143159
}
144160

145161

146-
DiscordActivityWrapper::DiscordActivityWrapper(const std::string& details, discord::ActivityType type) {
147-
m_activity.SetDetails(details.c_str());
162+
DiscordActivityWrapper::DiscordActivityWrapper(const std::string& details, discordpp::ActivityTypes type) {
163+
// NOTE: this are partial fields, that are set by the final call, do not set them manually
164+
// https://discord.com/developers/docs/rich-presence/using-with-the-game-sdk#partial-activity-struct
165+
// m_activity.SetName(constants::program_name);
166+
// m_activity.SetApplicationId(constants::application_id);
167+
168+
m_activity.SetDetails(details);
148169
m_activity.SetType(type);
149170
m_activity.SetSupportedPlatforms(constants::discord::supported_platforms);
150171
}
151172

152173

153174
DiscordActivityWrapper&
154175
DiscordActivityWrapper::set_large_image(const std::string& text, constants::discord::ArtAsset asset) {
155-
m_activity.GetAssets().SetLargeText(text.c_str());
176+
auto assets = this->get_assets();
156177

157178
const auto asset_key = constants::discord::get_asset_key(asset);
158-
m_activity.GetAssets().SetLargeImage(asset_key.c_str());
179+
180+
assets.SetLargeImage(asset_key);
181+
assets.SetLargeText(text);
182+
183+
m_activity.SetAssets(assets);
159184

160185
return *this;
161186
}
162187

163188

164189
DiscordActivityWrapper&
165190
DiscordActivityWrapper::set_small_image(const std::string& text, constants::discord::ArtAsset asset) {
166-
m_activity.GetAssets().SetSmallText(text.c_str());
191+
auto assets = this->get_assets();
167192

168193
const auto asset_key = constants::discord::get_asset_key(asset);
169-
m_activity.GetAssets().SetSmallImage(asset_key.c_str());
194+
195+
assets.SetSmallImage(asset_key);
196+
assets.SetSmallText(text);
197+
198+
m_activity.SetAssets(assets);
199+
170200
return *this;
171201
}
172202

173203
DiscordActivityWrapper& DiscordActivityWrapper::set_details(const std::string& text) {
174-
m_activity.SetState(text.c_str());
204+
m_activity.SetState(text);
175205

176206
return *this;
177207
}
178208

179209

180-
[[nodiscard]] const discord::Activity& DiscordActivityWrapper::get_raw() const {
210+
[[nodiscard]] const discordpp::Activity& DiscordActivityWrapper::get_raw() const {
181211
return m_activity;
182212
}
213+
214+
215+
discordpp::ActivityTimestamps DiscordActivityWrapper::get_timestamps() {
216+
217+
std::optional<discordpp::ActivityTimestamps> timestamps = m_activity.Timestamps();
218+
219+
if (timestamps.has_value()) {
220+
return timestamps.value();
221+
}
222+
223+
return discordpp::ActivityTimestamps::nullobj;
224+
}
225+
226+
227+
[[nodiscard]] discordpp::ActivityAssets DiscordActivityWrapper::get_assets() {
228+
std::optional<discordpp::ActivityAssets> assets = m_activity.Assets();
229+
230+
if (assets.has_value()) {
231+
return assets.value();
232+
}
233+
234+
return discordpp::ActivityAssets::nullobj;
235+
}

0 commit comments

Comments
 (0)