Skip to content

Commit 8de7214

Browse files
committed
- add ability to add activities to discord
- fixed a few discord bugs, some of them were really bogus, but the discord sdk isn't that stable (the c lib and the cpp wrapper)
1 parent bccb137 commit 8de7214

File tree

3 files changed

+165
-6
lines changed

3 files changed

+165
-6
lines changed

src/application.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "application.hpp"
2+
#include "discord/core.hpp"
23
#include "helper/sleep.hpp"
34
#include "platform/capabilities.hpp"
45
#include "scenes/scene.hpp"
6+
#include "types.h"
57

68
#include <ranges>
79

@@ -56,6 +58,12 @@ void Application::run() {
5658
spdlog::warn("Error initializing the discord instance, it might not be running: {}", discord_instance.error());
5759
} else {
5860
m_discord_instance = std::move(discord_instance.value());
61+
m_discord_instance->after_setup();
62+
63+
m_discord_instance->set_activity(
64+
DiscordActivityWrapper("Selecting playmode", discord::ActivityType::Playing)
65+
.add_large_image("Playing OOPetris", constants::discord::ArtAsset::logo)
66+
);
5967
}
6068

6169
#endif
@@ -211,6 +219,14 @@ void Application::update() {
211219
break;
212220
}
213221
}
222+
223+
#if defined(_HAVE_DISCORD_SDK)
224+
225+
if (m_discord_instance.has_value()) {
226+
m_discord_instance->update();
227+
}
228+
229+
#endif
214230
}
215231

216232
void Application::render() const {

src/discord/core.cpp

Lines changed: 115 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,46 @@
22

33
#include "core.hpp"
44
#include "helper/magic_enum_wrapper.hpp"
5+
#include "helper/utils.hpp"
56
#include "types.h"
67

78
#include <fmt/format.h>
89
#include <spdlog/spdlog.h>
910

10-
DiscordInstance::DiscordInstance(discord::Core* core) : m_core{ core }, m_current_user{} {
1111

12+
[[nodiscard]] std::string constants::discord ::get_asset_key(constants::discord::ArtAsset asset) {
1213

14+
switch (asset) {
15+
case ArtAsset::logo:
16+
return "logo";
17+
default:
18+
utils::unreachable();
19+
}
20+
}
21+
22+
DiscordInstance::DiscordInstance(discord::Core* core) : m_core{ core }, m_current_user{ nullptr } { }
23+
24+
void DiscordInstance::after_setup() {
1325
m_core->UserManager().OnCurrentUserUpdate.Connect([this]() {
14-
this->m_current_user = std::make_unique<discord::User>();
15-
this->m_core->UserManager().GetCurrentUser(this->m_current_user.get());
26+
auto* user = new discord::User; // NOLINT(cppcoreguidelines-owning-memory)
27+
this->m_core->UserManager().GetCurrentUser(user);
28+
this->m_current_user.reset(user);
29+
spdlog::info(
30+
"Current user updated: {}#{}", this->m_current_user->GetUsername(),
31+
this->m_current_user->GetDiscriminator()
32+
);
1633
});
1734

18-
19-
m_core->ActivityManager().RegisterCommand(constants::discord::platform_dependent_launch_arguments);
35+
auto result = m_core->ActivityManager().RegisterCommand(constants::discord::platform_dependent_launch_arguments);
36+
if (result != discord::Result::Ok) {
37+
spdlog::warn("ActivityManager: Failed to RegisterCommand: {}", magic_enum::enum_name(result));
38+
};
2039
}
2140

2241
[[nodiscard]] helper::expected<DiscordInstance, std::string> DiscordInstance::initialize() {
2342

2443
discord::Core* core{};
25-
auto result = discord::Core::Create(constants::discord::client_id, DiscordCreateFlags_NoRequireDiscord, &core);
44+
auto result = discord::Core::Create(constants::discord::client_id, DiscordCreateFlags_Default, &core);
2645
if (core == nullptr) {
2746
return helper::unexpected<std::string>{
2847
fmt::format("Failed to instantiate discord core: {}", magic_enum::enum_name(result))
@@ -59,6 +78,96 @@ DiscordInstance::DiscordInstance(discord::Core* core) : m_core{ core }, m_curren
5978
}
6079

6180

81+
DiscordInstance::DiscordInstance(DiscordInstance&& old) noexcept
82+
: m_core{ std::move(old.m_core) },
83+
m_current_user{ std::move(old.m_current_user) } {
84+
old.m_core = nullptr;
85+
old.m_current_user = nullptr;
86+
}
87+
88+
89+
DiscordInstance& DiscordInstance::operator=(DiscordInstance&& other) noexcept {
90+
if (this != &other) {
91+
92+
m_core = std::move(other.m_core);
93+
m_current_user = std::move(other.m_current_user);
94+
95+
other.m_core = nullptr;
96+
other.m_current_user = nullptr;
97+
}
98+
return *this;
99+
};
100+
101+
DiscordInstance::~DiscordInstance() {
102+
if (m_core != nullptr) {
103+
clear_activity();
104+
}
105+
}
106+
62107
void DiscordInstance::update() {
63108
m_core->RunCallbacks();
64109
}
110+
111+
112+
void DiscordInstance::set_activity(const DiscordActivityWrapper& activity) {
113+
114+
m_core->ActivityManager().UpdateActivity(activity.get_raw(), [](discord::Result result) {
115+
spdlog::info("Result to UpdateActivity: {}", magic_enum::enum_name(result));
116+
});
117+
}
118+
119+
120+
void DiscordInstance::clear_activity(bool wait) {
121+
bool received_callback = false;
122+
m_core->ActivityManager().ClearActivity([&received_callback](discord::Result result) {
123+
spdlog::info("Result to ClearActivity: {}", magic_enum::enum_name(result));
124+
received_callback = true;
125+
});
126+
127+
if (wait) {
128+
while (not received_callback) {
129+
this->update();
130+
std::this_thread::sleep_for(std::chrono::milliseconds(1));
131+
}
132+
}
133+
}
134+
135+
136+
DiscordActivityWrapper::DiscordActivityWrapper(const std::string& details, discord::ActivityType type) {
137+
138+
139+
m_activity.SetDetails(details.c_str());
140+
m_activity.SetType(type);
141+
}
142+
143+
144+
DiscordActivityWrapper&
145+
DiscordActivityWrapper::add_large_image(const std::string& text, constants::discord::ArtAsset asset) {
146+
m_activity.GetAssets().SetLargeText(text.c_str());
147+
148+
const auto asset_key = constants::discord::get_asset_key(asset);
149+
m_activity.GetAssets().SetLargeImage(asset_key.c_str());
150+
151+
return *this;
152+
}
153+
154+
155+
DiscordActivityWrapper&
156+
DiscordActivityWrapper::add_small_image(const std::string& text, constants::discord::ArtAsset asset) {
157+
m_activity.GetAssets().SetSmallText(text.c_str());
158+
159+
const auto asset_key = constants::discord::get_asset_key(asset);
160+
m_activity.GetAssets().SetSmallImage(asset_key.c_str());
161+
return *this;
162+
}
163+
164+
DiscordActivityWrapper& DiscordActivityWrapper::set_details(const std::string& text) {
165+
m_activity.SetState(text.c_str());
166+
167+
return *this;
168+
}
169+
170+
171+
[[nodiscard]] const discord::Activity& DiscordActivityWrapper::get_raw() const {
172+
return m_activity;
173+
}

src/discord/core.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,31 @@ namespace constants::discord {
2828
#error "Unsupported platform"
2929
#endif
3030

31+
// manually synchronized to https://discord.com/developers/applications/1220147916371394650/rich-presence/assets
32+
enum class ArtAsset { logo };
33+
34+
[[nodiscard]] std::string get_asset_key(ArtAsset asset);
35+
36+
3137
} // namespace constants::discord
3238

39+
40+
struct DiscordActivityWrapper {
41+
private:
42+
discord::Activity m_activity{};
43+
44+
public:
45+
//TODO: Add support for party and invites / join / invitations / spectate
46+
47+
DiscordActivityWrapper(const std::string& details, discord::ActivityType type);
48+
49+
DiscordActivityWrapper& add_large_image(const std::string& text, constants::discord::ArtAsset asset);
50+
DiscordActivityWrapper& add_small_image(const std::string& text, constants::discord::ArtAsset asset);
51+
DiscordActivityWrapper& set_details(const std::string& text);
52+
53+
[[nodiscard]] const discord::Activity& get_raw() const;
54+
};
55+
3356
struct DiscordInstance {
3457
private:
3558
std::unique_ptr<discord::Core> m_core;
@@ -40,5 +63,16 @@ struct DiscordInstance {
4063
public:
4164
[[nodiscard]] static helper::expected<DiscordInstance, std::string> initialize();
4265

66+
void after_setup();
67+
68+
DiscordInstance(DiscordInstance&& old) noexcept;
69+
DiscordInstance& operator=(DiscordInstance&& other) noexcept;
70+
71+
~DiscordInstance();
72+
4373
void update();
74+
void set_activity(const DiscordActivityWrapper& activity);
75+
76+
private:
77+
void clear_activity(bool wait = true);
4478
};

0 commit comments

Comments
 (0)