diff --git a/projectfiles/VC12/wesnoth.vcxproj b/projectfiles/VC12/wesnoth.vcxproj
index 363e138146526..2f04bd785ed3a 100644
--- a/projectfiles/VC12/wesnoth.vcxproj
+++ b/projectfiles/VC12/wesnoth.vcxproj
@@ -137,7 +137,7 @@
/SAFESEH:NO %(AdditionalOptions)
- SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)
+ SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;discord-rpc.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)
..\..\..\external\lib;%(AdditionalLibraryDirectories)
MSVCR90;MSVCRT;%(IgnoreSpecificDefaultLibraries)
true
@@ -177,7 +177,7 @@
true
- SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)
+ SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;discord-rpc.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)
..\..\..\external\lib;%(AdditionalLibraryDirectories)
false
Windows
@@ -751,6 +751,13 @@
$(IntDir)Desktop\
$(IntDir)Desktop\
+
+ $(IntDir)Desktop\
+ $(IntDir)Desktop\
+ $(IntDir)Desktop\
+ $(IntDir)Desktop\
+ $(IntDir)Desktop\
+
$(IntDir)Desktop\
$(IntDir)Desktop\
@@ -3582,6 +3589,7 @@
+
diff --git a/projectfiles/VC12/wesnoth.vcxproj.filters b/projectfiles/VC12/wesnoth.vcxproj.filters
index da66d1c506277..4b893f67e53d2 100644
--- a/projectfiles/VC12/wesnoth.vcxproj.filters
+++ b/projectfiles/VC12/wesnoth.vcxproj.filters
@@ -1558,6 +1558,9 @@
Gui\Dialogs\Multiplayer
+
+ Desktop
+
@@ -3025,6 +3028,9 @@
Gui\Dialogs\Multiplayer
+
+ Desktop
+
diff --git a/source_lists/wesnoth b/source_lists/wesnoth
index acf6835c503d9..575e5e47cf98e 100644
--- a/source_lists/wesnoth
+++ b/source_lists/wesnoth
@@ -66,6 +66,7 @@ commandline_options.cpp
config_cache.cpp
controller_base.cpp
countdown_clock.cpp
+desktop/discord_rich_presence.cpp
desktop/notifications.cpp
desktop/open.cpp
desktop/paths.cpp
diff --git a/src/desktop/discord_rich_presence.cpp b/src/desktop/discord_rich_presence.cpp
new file mode 100644
index 0000000000000..4e469b755685d
--- /dev/null
+++ b/src/desktop/discord_rich_presence.cpp
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2018 by the Battle for Wesnoth Project http://www.wesnoth.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.
+
+ See the COPYING file for more details.
+*/
+
+#include "desktop/discord_rich_presence.hpp"
+
+#include
+
+#include
+#include
+
+namespace desktop
+{
+namespace
+{
+const char* DISCORD_APP_ID = "407478227485982720";
+const char* STEAM_APP_ID = "599390";
+
+void callback_disconnected(int errorCode, const char* message)
+{
+
+}
+
+} // end anon namespace
+
+rich_presence_manager::rich_presence_manager()
+{
+ DiscordEventHandlers handlers;
+ std::memset(&handlers, 0, sizeof(handlers));
+
+ // FIXME
+ handlers.ready = nullptr;
+ handlers.errored = nullptr;
+ handlers.disconnected = &callback_disconnected;
+
+ // TODO: we might want to add the ability to join/observe games directly from
+ // discord in the future, but that requires special approval by Discord. Leaving
+ // these callbacks null for now.
+ handlers.joinGame = nullptr;
+ handlers.spectateGame = nullptr;
+ handlers.joinRequest = nullptr;
+
+ Discord_Initialize(DISCORD_APP_ID, &handlers, 1, STEAM_APP_ID);
+}
+
+rich_presence_manager::~rich_presence_manager()
+{
+ Discord_Shutdown();
+}
+
+void rich_presence_manager::update_presence(
+ const std::string state,
+ const std::string details,
+ const unsigned party_size,
+ const unsigned party_max) const
+{
+ DiscordRichPresence data;
+ std::memset(&data, 0, sizeof(data));
+
+ data.state = state.c_str();
+ data.details = details.c_str();
+ data.largeImageKey = "weslogo";
+ data.partySize = party_size;
+ data.partyMax = party_max;
+
+ Discord_UpdatePresence(&data);
+}
+
+} // namespace desktop1
diff --git a/src/desktop/discord_rich_presence.hpp b/src/desktop/discord_rich_presence.hpp
new file mode 100644
index 0000000000000..d172159bf601d
--- /dev/null
+++ b/src/desktop/discord_rich_presence.hpp
@@ -0,0 +1,35 @@
+/*
+ Copyright (C) 2018 by the Battle for Wesnoth Project http://www.wesnoth.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.
+
+ See the COPYING file for more details.
+*/
+
+#pragma once
+
+#include
+
+namespace desktop
+{
+class rich_presence_manager
+{
+public:
+ rich_presence_manager();
+ ~rich_presence_manager();
+
+ void update_presence(
+ const std::string state,
+ const std::string details,
+ const unsigned party_size = 0,
+ const unsigned party_max = 0) const;
+
+private:
+};
+
+} // namespace desktop
diff --git a/src/game_initialization/multiplayer.cpp b/src/game_initialization/multiplayer.cpp
index c0e5c74747276..3035bdc9709a1 100644
--- a/src/game_initialization/multiplayer.cpp
+++ b/src/game_initialization/multiplayer.cpp
@@ -15,6 +15,7 @@
#include "game_initialization/multiplayer.hpp"
#include "addon/manager.hpp" // for installed_addons
+#include "desktop/discord_rich_presence.hpp"
#include "events.hpp"
#include "formula/string_utils.hpp"
#include "game_config_manager.hpp"
@@ -371,6 +372,7 @@ struct mp_workflow_helper
, state(state)
, connection(connection)
, lobby_info(li)
+ , rp_manager()
{}
const config& game_config;
@@ -380,6 +382,8 @@ struct mp_workflow_helper
wesnothd_connection* connection;
mp::lobby_info* lobby_info;
+
+ desktop::rich_presence_manager rp_manager;
};
using mp_workflow_helper_ptr = std::shared_ptr;
@@ -499,6 +503,8 @@ bool enter_lobby_mode(mp_workflow_helper_ptr helper, const std::vectorconnection);
+ helper->rp_manager.update_presence("In Lobby", "Looking for Game");
+
// We use a loop here to allow returning to the lobby if you, say, cancel game creation.
while(true) {
if(const config& cfg = helper->game_config.child("lobby_music")) {
@@ -577,7 +583,7 @@ bool enter_lobby_mode(mp_workflow_helper_ptr helper, const std::vector