discord.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // SuperTux
  2. // Copyright (C) 2020 A. Semphris <semphris@protonmail.com>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #include "config.h"
  17. #ifdef ENABLE_DISCORD
  18. #include "sdk/discord.hpp"
  19. #include <iostream>
  20. #include <stdint.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <time.h>
  24. #include <discord_rpc.h>
  25. #include "supertux/gameconfig.hpp"
  26. #include "supertux/globals.hpp"
  27. #include "util/log.hpp"
  28. extern "C" {
  29. static void handleDiscordReady(const DiscordUser* connectedUser)
  30. {
  31. printf("\nDiscord: connected to user %s#%s - %s\n",
  32. connectedUser->username,
  33. connectedUser->discriminator,
  34. connectedUser->userId);
  35. }
  36. static void handleDiscordDisconnected(int errcode, const char* message)
  37. {
  38. printf("\nDiscord: disconnected (%d: %s)\n", errcode, message);
  39. }
  40. static void handleDiscordError(int errcode, const char* message)
  41. {
  42. printf("\nDiscord: error (%d: %s)\n", errcode, message);
  43. }
  44. static void handleDiscordJoin(const char* secret)
  45. {
  46. printf("\nDiscord: join (%s)\n", secret);
  47. }
  48. static void handleDiscordSpectate(const char* secret)
  49. {
  50. printf("\nDiscord: spectate (%s)\n", secret);
  51. }
  52. static void handleDiscordJoinRequest(const DiscordUser* request)
  53. {
  54. int response = -1;
  55. printf("\nDiscord: join request from %s#%s - %s\n",
  56. request->username,
  57. request->discriminator,
  58. request->userId);
  59. response = false ? DISCORD_REPLY_YES : DISCORD_REPLY_NO;
  60. if (response != -1) {
  61. Discord_Respond(request->userId, response);
  62. }
  63. }
  64. } // extern "C"
  65. DiscordIntegration* DiscordIntegration::driver;
  66. DiscordIntegration::DiscordIntegration() :
  67. Integration(),
  68. m_enabled(false)
  69. {
  70. }
  71. DiscordIntegration::~DiscordIntegration()
  72. {
  73. // It shouldn't get here, but just in case.
  74. close();
  75. }
  76. DiscordIntegration*
  77. DiscordIntegration::getDriver()
  78. {
  79. if (!driver)
  80. {
  81. driver = new DiscordIntegration();
  82. }
  83. return driver;
  84. }
  85. void
  86. DiscordIntegration::init()
  87. {
  88. if (m_enabled || !g_config->enable_discord) return;
  89. DiscordEventHandlers handlers;
  90. memset(&handlers, 0, sizeof(handlers));
  91. handlers.ready = handleDiscordReady;
  92. handlers.disconnected = handleDiscordDisconnected;
  93. handlers.errored = handleDiscordError;
  94. handlers.joinGame = handleDiscordJoin;
  95. handlers.spectateGame = handleDiscordSpectate;
  96. handlers.joinRequest = handleDiscordJoinRequest;
  97. Discord_Initialize("733576109744062537", &handlers, 1, nullptr);
  98. log_info << "[Discord] Started" << std::endl;
  99. m_enabled = true;
  100. }
  101. void
  102. DiscordIntegration::update()
  103. {
  104. if (!m_enabled) return;
  105. #ifdef DISCORD_DISABLE_IO_THREAD
  106. Discord_UpdateConnection();
  107. #endif
  108. Discord_RunCallbacks();
  109. }
  110. void
  111. DiscordIntegration::close()
  112. {
  113. if (!m_enabled) return;
  114. Discord_ClearPresence();
  115. Discord_Shutdown();
  116. log_info << "[Discord] Closed" << std::endl;
  117. m_enabled = false;
  118. }
  119. void
  120. DiscordIntegration::update_status(IntegrationStatus status)
  121. {
  122. if (!m_enabled) return;
  123. DiscordRichPresence discordPresence;
  124. memset(&discordPresence, 0, sizeof(discordPresence));
  125. /*
  126. * Possible keys :
  127. * state
  128. * details
  129. * startTimestamp
  130. * endTimestamp
  131. * largeImageKey
  132. * smallImageKey
  133. * partyId
  134. * partySize
  135. * partyMax
  136. * matchSecret
  137. * joinSecret
  138. * spectateSecret
  139. * instance
  140. */
  141. if (status.m_details.size() >= 1)
  142. discordPresence.state = status.m_details.begin()->c_str();
  143. if (status.m_details.size() >= 2)
  144. discordPresence.details = (status.m_details.begin() + 1)->c_str();
  145. if (status.m_timestamp != 0) {
  146. if (status.m_timestamp > time(nullptr)) {
  147. discordPresence.endTimestamp = status.m_timestamp;
  148. } else {
  149. discordPresence.startTimestamp = status.m_timestamp;
  150. }
  151. }
  152. // TODO: Manage parties and all.
  153. discordPresence.largeImageKey = "supertux_logo";
  154. Discord_UpdatePresence(&discordPresence);
  155. }
  156. #endif
  157. /* EOF */