1 | #include <base/system.h> |
2 | #include <engine/discord.h> |
3 | |
4 | // Hack for universal binary builds on macOS: Ignore arm64 until Discord |
5 | // releases a native arm64 SDK for macOS. |
6 | |
7 | #if defined(CONF_DISCORD) && !(defined(CONF_ARCH_ARM64) && defined(CONF_PLATFORM_MACOS)) |
8 | #include <discord_game_sdk.h> |
9 | |
10 | typedef enum EDiscordResult DISCORD_API (*FDiscordCreate)(DiscordVersion, struct DiscordCreateParams *, struct IDiscordCore **); |
11 | |
12 | #if defined(CONF_DISCORD_DYNAMIC) |
13 | #include <dlfcn.h> |
14 | FDiscordCreate GetDiscordCreate() |
15 | { |
16 | void *pSdk = dlopen("discord_game_sdk.so" , RTLD_NOW); |
17 | if(!pSdk) |
18 | { |
19 | return nullptr; |
20 | } |
21 | return (FDiscordCreate)dlsym(pSdk, "DiscordCreate" ); |
22 | } |
23 | #else |
24 | FDiscordCreate GetDiscordCreate() |
25 | { |
26 | return DiscordCreate; |
27 | } |
28 | #endif |
29 | |
30 | class CDiscord : public IDiscord |
31 | { |
32 | IDiscordCore *m_pCore; |
33 | IDiscordActivityEvents m_ActivityEvents; |
34 | IDiscordActivityManager *m_pActivityManager; |
35 | |
36 | public: |
37 | bool Init(FDiscordCreate pfnDiscordCreate) |
38 | { |
39 | m_pCore = 0; |
40 | mem_zero(&m_ActivityEvents, sizeof(m_ActivityEvents)); |
41 | m_pActivityManager = 0; |
42 | |
43 | DiscordCreateParams Params; |
44 | DiscordCreateParamsSetDefault(&Params); |
45 | |
46 | Params.client_id = 752165779117441075; // DDNet |
47 | Params.flags = EDiscordCreateFlags::DiscordCreateFlags_NoRequireDiscord; |
48 | Params.event_data = this; |
49 | Params.activity_events = &m_ActivityEvents; |
50 | int Error = pfnDiscordCreate(DISCORD_VERSION, &Params, &m_pCore); |
51 | if(Error != DiscordResult_Ok) |
52 | { |
53 | dbg_msg("discord" , "error initializing discord instance, error=%d" , Error); |
54 | return true; |
55 | } |
56 | |
57 | m_pActivityManager = m_pCore->get_activity_manager(m_pCore); |
58 | ClearGameInfo(); |
59 | return false; |
60 | } |
61 | void Update() override |
62 | { |
63 | m_pCore->run_callbacks(m_pCore); |
64 | } |
65 | void ClearGameInfo() override |
66 | { |
67 | DiscordActivity Activity; |
68 | mem_zero(&Activity, sizeof(DiscordActivity)); |
69 | str_copy(Activity.assets.large_image, "ddnet_logo" , sizeof(Activity.assets.large_image)); |
70 | str_copy(Activity.assets.large_text, "DDNet logo" , sizeof(Activity.assets.large_text)); |
71 | Activity.timestamps.start = time_timestamp(); |
72 | str_copy(Activity.details, "Offline" , sizeof(Activity.details)); |
73 | m_pActivityManager->update_activity(m_pActivityManager, &Activity, 0, 0); |
74 | } |
75 | void SetGameInfo(const NETADDR &ServerAddr, const char *pMapName, bool AnnounceAddr) override |
76 | { |
77 | DiscordActivity Activity; |
78 | mem_zero(&Activity, sizeof(DiscordActivity)); |
79 | str_copy(Activity.assets.large_image, "ddnet_logo" , sizeof(Activity.assets.large_image)); |
80 | str_copy(Activity.assets.large_text, "DDNet logo" , sizeof(Activity.assets.large_text)); |
81 | Activity.timestamps.start = time_timestamp(); |
82 | str_copy(Activity.details, "Online" , sizeof(Activity.details)); |
83 | str_copy(Activity.state, pMapName, sizeof(Activity.state)); |
84 | m_pActivityManager->update_activity(m_pActivityManager, &Activity, 0, 0); |
85 | } |
86 | }; |
87 | |
88 | IDiscord *CreateDiscordImpl() |
89 | { |
90 | FDiscordCreate pfnDiscordCreate = GetDiscordCreate(); |
91 | if(!pfnDiscordCreate) |
92 | { |
93 | return 0; |
94 | } |
95 | CDiscord *pDiscord = new CDiscord(); |
96 | if(pDiscord->Init(pfnDiscordCreate)) |
97 | { |
98 | delete pDiscord; |
99 | return 0; |
100 | } |
101 | return pDiscord; |
102 | } |
103 | #else |
104 | IDiscord *CreateDiscordImpl() |
105 | { |
106 | return 0; |
107 | } |
108 | #endif |
109 | |
110 | class CDiscordStub : public IDiscord |
111 | { |
112 | void Update() override {} |
113 | void ClearGameInfo() override {} |
114 | void SetGameInfo(const NETADDR &ServerAddr, const char *pMapName, bool AnnounceAddr) override {} |
115 | }; |
116 | |
117 | IDiscord *CreateDiscord() |
118 | { |
119 | IDiscord *pDiscord = CreateDiscordImpl(); |
120 | if(pDiscord) |
121 | { |
122 | return pDiscord; |
123 | } |
124 | return new CDiscordStub(); |
125 | } |
126 | |