Clang-format; Correctly add command discordrpc-reconnect; Check for doLanguageIcons config option

This commit is contained in:
Bytequill
2025-02-11 22:20:43 +01:00
parent fadb3b9879
commit 08e92db506
6 changed files with 551 additions and 527 deletions

View File

@@ -160,6 +160,8 @@ File path is: </string>
<string name="cut">Cut</string>
<string name="dark">Dark</string>
<string name="date">Date</string>
<string name="dc_editing">Editing %s, a %s file</string>
<string name="dc_workspace">Working on %s</string>
<string name="debug_draw_boxes">Draw Boxes</string>
<string name="debug_draw_boxes_toggle">Debug Draw Boxes Toggle</string>
<string name="debug_draw_debug_data">Debug Draw Debug Data</string>

View File

@@ -1,112 +1,110 @@
{
"config" : {
"appID": "1335730393948749898",
"doLanguageIcons": true,
"iconBindings": {
".htaccess": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
".ignore file": "https://github.com/vyfor/icons/raw/master/icons/onyx/git.png",
"[x]it!": "https://github.com/vyfor/icons/raw/master/icons/onyx/notes.png",
"ada": "https://github.com/vyfor/icons/raw/master/icons/pastel/ada.png",
"adept": "https://raw.github.com/AdeptLanguage/Adept/master/.github/README_logo.png",
"angelscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"awk script": "https://github.com/vyfor/icons/raw/master/icons/pastel/awk.png",
"bat": "https://github.com/vyfor/icons/raw/master/icons/onyx/shell.png",
"bazel": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Bazel_logo.svg/1024px-Bazel_logo.svg.png",
"bend": "https://avatars.githubusercontent.com/u/92327702",
"blueprint": "https://github.com/vyfor/icons/raw/master/icons/onyx/controller.png",
"brainfuck": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"buzz": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"c": "https://github.com/vyfor/icons/raw/master/icons/onyx/c.png",
"carbon": "https://upload.wikimedia.org/wikipedia/commons/e/e1/Carbon_logo.png",
"clojure": "https://github.com/vyfor/icons/raw/master/icons/onyx/clojure.png",
"cmake": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/CMake_logo.svg/1024px-CMake_logo.svg.png",
"cpp": "https://github.com/vyfor/icons/raw/master/icons/onyx/cpp.png",
"crystal": "https://github.com/vyfor/icons/raw/master/icons/onyx/crystal.png",
"csharp": "https://github.com/vyfor/icons/raw/master/icons/onyx/csharp.png",
"css": "https://github.com/vyfor/icons/raw/master/icons/onyx/css.png",
"d": "https://github.com/vyfor/icons/raw/master/icons/onyx/d.png",
"dart": "https://github.com/vyfor/icons/raw/master/icons/onyx/dart.png",
"diff": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
"dockerfile": "https://github.com/vyfor/icons/raw/master/icons/onyx/docker.png",
"elixir": "https://github.com/vyfor/icons/raw/master/icons/onyx/elixir.png",
"elm": "https://github.com/vyfor/icons/raw/master/icons/onyx/elm.png",
"environment file": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
"fantom": "https://avatars.githubusercontent.com/u/54911692",
"fortran": "https://github.com/vyfor/icons/raw/master/icons/onyx/fortran.png",
"fstab": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
"gdscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/godot.png",
"glsl": "https://github.com/vyfor/icons/raw/master/icons/onyx/opengl.png",
"go": "https://github.com/vyfor/icons/raw/master/icons/onyx/go.png",
"graphql": "https://github.com/vyfor/icons/raw/master/icons/onyx/graphql.png",
"groovy": "https://github.com/vyfor/icons/raw/master/icons/onyx/groovy.png",
"hare": "https://harelang.org/mascot.png",
"haskell": "https://github.com/vyfor/icons/raw/master/icons/onyx/haskell.png",
"haxe": "https://github.com/vyfor/icons/raw/master/icons/pastel/haxe.png",
"haxe compiler arguments": "https://github.com/vyfor/icons/raw/master/icons/onyx/haxe.png",
"hlsl": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
"html": "https://github.com/vyfor/icons/raw/master/icons/onyx/html.png",
"ini": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
"jai": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"java": "https://github.com/vyfor/icons/raw/master/icons/onyx/java.png",
"javascript": "https://github.com/vyfor/icons/raw/master/icons/onyx/javascript.png",
"javascriptreact": "https://github.com/vyfor/icons/raw/master/icons/onyx/react.png",
"json": "https://github.com/vyfor/icons/raw/master/icons/onyx/json.png",
"julia": "https://github.com/vyfor/icons/raw/master/icons/onyx/julia.png",
"kotlin": "https://github.com/vyfor/icons/raw/master/icons/onyx/kotlin.png",
"latex": "https://github.com/vyfor/icons/raw/master/icons/onyx/latex.png",
"lobster": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"lua": "https://github.com/vyfor/icons/raw/master/icons/onyx/latex.png",
"makefile": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
"markdown": "https://github.com/vyfor/icons/raw/master/icons/onyx/markdown.png",
"meson": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
"moonscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/lua.png",
"nelua": "https://nelua.io/assets/img/nelua-logo-64px.png",
"nim": "https://github.com/vyfor/icons/raw/master/icons/onyx/nim.png",
"objeck": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
"objective-c": "https://github.com/vyfor/icons/raw/master/icons/onyx/c.png",
"ocaml": "https://github.com/vyfor/icons/raw/master/icons/onyx/ocaml.png",
"odin": "https://github.com/vyfor/icons/raw/master/icons/onyx/odin.png",
"openscad": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/Openscad.svg/1024px-Openscad.svg.png",
"pascal": "https://github.com/vyfor/icons/raw/master/icons/onyx/pascal.png",
"perl": "https://github.com/vyfor/icons/raw/master/icons/onyx/perl.png",
"php": "https://github.com/vyfor/icons/raw/master/icons/onyx/php.png",
"pico-8": "https://www.lexaloffle.com/gfx/p8b_pico8.png",
"plaintext": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"po": "https://github.com/vyfor/icons/raw/master/icons/onyx/gnu.png",
"pony": "https://avatars.githubusercontent.com/u/12997238",
"postgresql": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Postgresql_elephant.svg/1024px-Postgresql_elephant.svg.png",
"powershell": "https://github.com/vyfor/icons/raw/master/icons/onyx/powershell.png",
"python": "https://github.com/vyfor/icons/raw/master/icons/onyx/python.png",
"r": "https://github.com/vyfor/icons/raw/master/icons/onyx/r.png",
"ring": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"ruby": "https://github.com/vyfor/icons/raw/master/icons/onyx/ruby.png",
"rust": "https://github.com/vyfor/icons/raw/master/icons/onyx/rust.png",
"sass": "https://github.com/vyfor/icons/raw/master/icons/onyx/scss.png",
"scala": "https://github.com/vyfor/icons/raw/master/icons/onyx/scala.png",
"shellscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/shell.png",
"smallbasic": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"solidity": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"sql": "https://github.com/vyfor/icons/raw/master/icons/onyx/sql.png",
"swift": "https://github.com/vyfor/icons/raw/master/icons/onyx/swift.png",
"tcl": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"teal": "https://avatars.githubusercontent.com/u/62526430",
"toml": "https://github.com/vyfor/icons/raw/master/icons/onyx/toml.png",
"typescript": "https://github.com/vyfor/icons/raw/master/icons/onyx/typescript.png",
"typescriptreact": "https://github.com/vyfor/icons/raw/master/icons/onyx/react.png",
"v": "https://github.com/vyfor/icons/raw/master/icons/onyx/v.png",
"vala": "https://github.com/vyfor/icons/raw/master/icons/onyx/vala.png",
"verilog": "https://github.com/vyfor/icons/raw/master/icons/onyx/assembly.png",
"visual basic": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/VB.NET_Logo.svg/1024px-VB.NET_Logo.svg.png",
"vue": "https://github.com/vyfor/icons/raw/master/icons/onyx/vue.png",
"wren": "https://avatars.githubusercontent.com/u/45213573",
"x86 assembly": "https://github.com/vyfor/icons/raw/master/icons/onyx/assembly.png",
"xml": "https://github.com/vyfor/icons/raw/master/icons/onyx/xml.png",
"xtend": "https://github.com/vyfor/icons/raw/master/icons/onyx/java.png",
"yaml": "https://github.com/vyfor/icons/raw/master/icons/onyx/yaml.png",
"zig": "https://github.com/vyfor/icons/raw/master/icons/onyx/zig.png"
}
},
"keybindings" : {
}
"config": {
"appID": "1335730393948749898",
"doLanguageIcons": true,
"iconBindings": {
".htaccess": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
".ignore file": "https://github.com/vyfor/icons/raw/master/icons/onyx/git.png",
"[x]it!": "https://github.com/vyfor/icons/raw/master/icons/onyx/notes.png",
"ada": "https://github.com/vyfor/icons/raw/master/icons/pastel/ada.png",
"adept": "https://raw.github.com/AdeptLanguage/Adept/master/.github/README_logo.png",
"angelscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"awk script": "https://github.com/vyfor/icons/raw/master/icons/pastel/awk.png",
"bat": "https://github.com/vyfor/icons/raw/master/icons/onyx/shell.png",
"bazel": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Bazel_logo.svg/1024px-Bazel_logo.svg.png",
"bend": "https://avatars.githubusercontent.com/u/92327702",
"blueprint": "https://github.com/vyfor/icons/raw/master/icons/onyx/controller.png",
"brainfuck": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"buzz": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"c": "https://github.com/vyfor/icons/raw/master/icons/onyx/c.png",
"carbon": "https://upload.wikimedia.org/wikipedia/commons/e/e1/Carbon_logo.png",
"clojure": "https://github.com/vyfor/icons/raw/master/icons/onyx/clojure.png",
"cmake": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/CMake_logo.svg/1024px-CMake_logo.svg.png",
"cpp": "https://github.com/vyfor/icons/raw/master/icons/onyx/cpp.png",
"crystal": "https://github.com/vyfor/icons/raw/master/icons/onyx/crystal.png",
"csharp": "https://github.com/vyfor/icons/raw/master/icons/onyx/csharp.png",
"css": "https://github.com/vyfor/icons/raw/master/icons/onyx/css.png",
"d": "https://github.com/vyfor/icons/raw/master/icons/onyx/d.png",
"dart": "https://github.com/vyfor/icons/raw/master/icons/onyx/dart.png",
"diff": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
"dockerfile": "https://github.com/vyfor/icons/raw/master/icons/onyx/docker.png",
"elixir": "https://github.com/vyfor/icons/raw/master/icons/onyx/elixir.png",
"elm": "https://github.com/vyfor/icons/raw/master/icons/onyx/elm.png",
"environment file": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
"fantom": "https://avatars.githubusercontent.com/u/54911692",
"fortran": "https://github.com/vyfor/icons/raw/master/icons/onyx/fortran.png",
"fstab": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
"gdscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/godot.png",
"glsl": "https://github.com/vyfor/icons/raw/master/icons/onyx/opengl.png",
"go": "https://github.com/vyfor/icons/raw/master/icons/onyx/go.png",
"graphql": "https://github.com/vyfor/icons/raw/master/icons/onyx/graphql.png",
"groovy": "https://github.com/vyfor/icons/raw/master/icons/onyx/groovy.png",
"hare": "https://harelang.org/mascot.png",
"haskell": "https://github.com/vyfor/icons/raw/master/icons/onyx/haskell.png",
"haxe": "https://github.com/vyfor/icons/raw/master/icons/pastel/haxe.png",
"haxe compiler arguments": "https://github.com/vyfor/icons/raw/master/icons/onyx/haxe.png",
"hlsl": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
"html": "https://github.com/vyfor/icons/raw/master/icons/onyx/html.png",
"ini": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
"jai": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"java": "https://github.com/vyfor/icons/raw/master/icons/onyx/java.png",
"javascript": "https://github.com/vyfor/icons/raw/master/icons/onyx/javascript.png",
"javascriptreact": "https://github.com/vyfor/icons/raw/master/icons/onyx/react.png",
"json": "https://github.com/vyfor/icons/raw/master/icons/onyx/json.png",
"julia": "https://github.com/vyfor/icons/raw/master/icons/onyx/julia.png",
"kotlin": "https://github.com/vyfor/icons/raw/master/icons/onyx/kotlin.png",
"latex": "https://github.com/vyfor/icons/raw/master/icons/onyx/latex.png",
"lobster": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"lua": "https://github.com/vyfor/icons/raw/master/icons/onyx/latex.png",
"makefile": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
"markdown": "https://github.com/vyfor/icons/raw/master/icons/onyx/markdown.png",
"meson": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
"moonscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/lua.png",
"nelua": "https://nelua.io/assets/img/nelua-logo-64px.png",
"nim": "https://github.com/vyfor/icons/raw/master/icons/onyx/nim.png",
"objeck": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
"objective-c": "https://github.com/vyfor/icons/raw/master/icons/onyx/c.png",
"ocaml": "https://github.com/vyfor/icons/raw/master/icons/onyx/ocaml.png",
"odin": "https://github.com/vyfor/icons/raw/master/icons/onyx/odin.png",
"openscad": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/Openscad.svg/1024px-Openscad.svg.png",
"pascal": "https://github.com/vyfor/icons/raw/master/icons/onyx/pascal.png",
"perl": "https://github.com/vyfor/icons/raw/master/icons/onyx/perl.png",
"php": "https://github.com/vyfor/icons/raw/master/icons/onyx/php.png",
"pico-8": "https://www.lexaloffle.com/gfx/p8b_pico8.png",
"plaintext": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"po": "https://github.com/vyfor/icons/raw/master/icons/onyx/gnu.png",
"pony": "https://avatars.githubusercontent.com/u/12997238",
"postgresql": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Postgresql_elephant.svg/1024px-Postgresql_elephant.svg.png",
"powershell": "https://github.com/vyfor/icons/raw/master/icons/onyx/powershell.png",
"python": "https://github.com/vyfor/icons/raw/master/icons/onyx/python.png",
"r": "https://github.com/vyfor/icons/raw/master/icons/onyx/r.png",
"ring": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"ruby": "https://github.com/vyfor/icons/raw/master/icons/onyx/ruby.png",
"rust": "https://github.com/vyfor/icons/raw/master/icons/onyx/rust.png",
"sass": "https://github.com/vyfor/icons/raw/master/icons/onyx/scss.png",
"scala": "https://github.com/vyfor/icons/raw/master/icons/onyx/scala.png",
"shellscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/shell.png",
"smallbasic": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"solidity": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"sql": "https://github.com/vyfor/icons/raw/master/icons/onyx/sql.png",
"swift": "https://github.com/vyfor/icons/raw/master/icons/onyx/swift.png",
"tcl": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
"teal": "https://avatars.githubusercontent.com/u/62526430",
"toml": "https://github.com/vyfor/icons/raw/master/icons/onyx/toml.png",
"typescript": "https://github.com/vyfor/icons/raw/master/icons/onyx/typescript.png",
"typescriptreact": "https://github.com/vyfor/icons/raw/master/icons/onyx/react.png",
"v": "https://github.com/vyfor/icons/raw/master/icons/onyx/v.png",
"vala": "https://github.com/vyfor/icons/raw/master/icons/onyx/vala.png",
"verilog": "https://github.com/vyfor/icons/raw/master/icons/onyx/assembly.png",
"visual basic": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/VB.NET_Logo.svg/1024px-VB.NET_Logo.svg.png",
"vue": "https://github.com/vyfor/icons/raw/master/icons/onyx/vue.png",
"wren": "https://avatars.githubusercontent.com/u/45213573",
"x86 assembly": "https://github.com/vyfor/icons/raw/master/icons/onyx/assembly.png",
"xml": "https://github.com/vyfor/icons/raw/master/icons/onyx/xml.png",
"xtend": "https://github.com/vyfor/icons/raw/master/icons/onyx/java.png",
"yaml": "https://github.com/vyfor/icons/raw/master/icons/onyx/yaml.png",
"zig": "https://github.com/vyfor/icons/raw/master/icons/onyx/zig.png"
}
},
"keybindings": {}
}

View File

@@ -1,7 +1,7 @@
#include "discordRPCplugin.hpp"
using json = nlohmann::json;
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined ( __EMSCRIPTEN_PTHREADS__ )
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ )
#define dcRPC_THREADED 1
#else
#define dcRPC_THREADED 0
@@ -9,11 +9,11 @@ using json = nlohmann::json;
namespace ecode {
Plugin* DiscordRPCplugin::New( PluginManager* pluginManager) {
Plugin* DiscordRPCplugin::New( PluginManager* pluginManager ) {
return eeNew( DiscordRPCplugin, ( pluginManager, false ) );
}
Plugin* DiscordRPCplugin::NewSync( PluginManager* pluginManager) {
Plugin* DiscordRPCplugin::NewSync( PluginManager* pluginManager ) {
return eeNew( DiscordRPCplugin, ( pluginManager, true ) );
}
@@ -33,28 +33,27 @@ DiscordRPCplugin::DiscordRPCplugin( PluginManager* pluginManager, bool sync ) :
DiscordRPCplugin::~DiscordRPCplugin() {
waitUntilLoaded();
mShuttingDown = true;
}
void DiscordRPCplugin::load( PluginManager* pluginManager ) {
Clock clock;
AtomicBoolScopedOp loading( mLoading, true );
pluginManager->subscribeMessages( this,
[this]( const auto& notification ) -> PluginRequestHandle {
return processMessage( notification );
} );
std::vector<std::string> paths;
std::string path( pluginManager->getResourcesPath() + "plugins/discordRPC.json" );
if ( FileSystem::fileExists( path ) )
paths.emplace_back( path );
path = pluginManager->getPluginsPath() + "discordRPC.json";
if ( FileSystem::fileExists( path ) ||
FileSystem::fileWrite(path, "{\n \"config\":{},\n \"keybindings\":{}\n}\n") ) {
mConfigPath = path;
paths.emplace_back( path );
}
std::string data;
FileSystem::fileWrite( path, "{\n \"config\":{},\n \"keybindings\":{}\n}\n" ) ) {
mConfigPath = path;
paths.emplace_back( path );
}
std::string data;
if ( !FileSystem::fileGet( path, data ) )
return;
mConfigHash = String::hash( data );
@@ -81,7 +80,12 @@ void DiscordRPCplugin::load( PluginManager* pluginManager ) {
mIPC.mcClientID = "1335730393948749898";
updateConfigFile = true;
}
if ( config.contains( "doLanguageIcons" ) ) {
mcDoLangIcon = config.value( "doLanguageIcons", true );
} else {
mIPC.mcClientID = true;
updateConfigFile = true;
}
}
if ( updateConfigFile ) {
@@ -91,13 +95,13 @@ void DiscordRPCplugin::load( PluginManager* pluginManager ) {
mConfigHash = String::hash( newData );
}
}
mIPC.tryConnect();
DiscordIPCActivity* a = mIPC.getActivity();
a->largeImage = DISCORDRPC_DEFAULT_ICON;
mIPC.setActivity(*a);
mIPC.setActivity( *a );
mReady = true;
fireReadyCbs();
setReady( clock.getElapsedTime() );
@@ -109,38 +113,45 @@ PluginRequestHandle DiscordRPCplugin::processMessage( const PluginMessage& msg )
std::string rpath = FileSystem::getRealPath( msg.asJSON()["folder"] );
FileSystem::dirAddSlashAtEnd( rpath );
mProjectName = FileSystem::fileNameFromPath( rpath );
Log::debug("Loaded new workspace: %s ; %s", rpath, mProjectName);
Log::debug( "Loaded new workspace: %s ; %s", rpath, mProjectName );
}
case PluginMessageType::UIReady: {
mIPC.mUIReady = true;
// Log::debug("dcPlugin: UI is ready!");
if (mIPC.mIsReconnectScheduled) {
Log::debug("Running scheduled reconnect");
// Log::debug("dcPlugin: UI is ready!");
if ( mIPC.mIsReconnectScheduled ) {
Log::debug( "Running scheduled reconnect" );
mIPC.tryConnect();
}
}
default:
break;
}
return PluginRequestHandle::empty();
}
void DiscordRPCplugin::onRegisterDocument( TextDocument* doc ){
doc->setCommand( "discordrpc-reconnect", [this] {
mIPC.reconnect();
} );
void DiscordRPCplugin::onRegisterEditor( UICodeEditor* editor ) {
editor->addUnlockedCommands( { "discordrpc-reconnect" } );
editor->getDocument().setCommand( "discordrpc-reconnect", [this] { mIPC.reconnect(); } );
PluginBase::onRegisterEditor( editor );
}
void DiscordRPCplugin::onUnregisterEditor( UICodeEditor* editor ) {
editor->removeUnlockedCommands( { "discordrpc-reconnect" } );
}
void DiscordRPCplugin::onRegisterListeners( UICodeEditor* editor, std::vector<Uint32>& listeners ) {
listeners.push_back( editor->on( Event::OnFocus, [this, editor]( const Event* ) {
// `this` in the scope of the lambda is the parent `DiscordRPCplugin`
auto& doc = editor->getDocument();
if (!doc.hasFilepath()) { return; }
if ( !doc.hasFilepath() ) {
return;
}
auto filename = doc.getFilename();
if ( filename != mLastFile ) {
this->mLastFile = filename;
@@ -149,27 +160,25 @@ void DiscordRPCplugin::onRegisterListeners( UICodeEditor* editor, std::vector<Ui
DiscordIPCActivity* a = this->mIPC.getActivity();
if (!mProjectName.empty())
a->details = String::format(i18n( "dc_workspace", "Working on %s" ).toUtf8(),
mProjectName);
a->state = String::format(i18n( "dc_editing", "Editing %s, a %s file" ).toUtf8(),
filename, doc.getSyntaxDefinition().getLanguageName() );
if ( !mProjectName.empty() )
a->details = String::format( i18n( "dc_workspace", "Working on %s" ).toUtf8(),
mProjectName );
a->state = String::format( i18n( "dc_editing", "Editing %s, a %s file" ).toUtf8(),
filename, doc.getSyntaxDefinition().getLanguageName() );
a->start = time( nullptr ); // Time spent in this specific file
// TODO: Implement github/gitlab remote button (integrate with git plugin)
// a->buttons[0].label = "Repository";
// a->buttons[0].url = "https://github.com/name/repo";
std::string name = doc.getSyntaxDefinition().getLSPName();
if (!name.empty()) {
a->largeImage = mcLangBindings.value(name, DISCORDRPC_DEFAULT_ICON);
if ( !name.empty() && mcDoLangIcon ) {
a->largeImage = mcLangBindings.value( name, DISCORDRPC_DEFAULT_ICON );
}
this->mIPC.setActivity( *a );
}
} ) );
}
} // namespace ecode

View File

@@ -4,10 +4,10 @@
#include "../plugin.hpp"
#include "../pluginmanager.hpp"
#include <eepp/system/threadpool.hpp>
#include <eepp/system/mutex.hpp>
#include <eepp/system/filesystem.hpp>
#include <eepp/system/mutex.hpp>
#include <eepp/system/scopedop.hpp>
#include <eepp/system/threadpool.hpp>
#include "sdk/ipc.hpp"
@@ -18,52 +18,53 @@ using namespace EE::System;
using namespace EE::UI;
using namespace EE::UI::Doc;
#define DISCORDRPC_DEFAULT_ICON "https://github.com/SpartanJ/eepp/blob/develop/bin/assets/icon/ecode.png?raw=true"
#define DISCORDRPC_DEFAULT_ICON \
"https://github.com/SpartanJ/eepp/blob/develop/bin/assets/icon/ecode.png?raw=true"
namespace ecode {
class DiscordRPCplugin : public PluginBase {
public:
static PluginDefinition Definition() {
return {
"discrdrpc",
"Discord Rich Presence",
"Show your friends what you are up to through the discord Rich Presence system",
DiscordRPCplugin::New,
{ 0, 0, 0 },
DiscordRPCplugin::NewSync };
}
static Plugin* New( PluginManager* pluginManager );
static Plugin* NewSync( PluginManager* pluginManager );
virtual ~DiscordRPCplugin() override;
std::string getId() override { return Definition().id; }
public:
static PluginDefinition Definition() {
return { "discrdrpc",
"Discord Rich Presence",
"Show your friends what you are up to through the discord Rich Presence system",
DiscordRPCplugin::New,
{ 0, 0, 0 },
DiscordRPCplugin::NewSync };
}
std::string getTitle() override { return Definition().name; }
std::string getDescription() override { return Definition().description; }
protected:
DiscordIPC mIPC;
std::string mLastFile;
std::string mProjectName;
nlohmann::json mcLangBindings;
void load ( PluginManager* pluginManager );
PluginRequestHandle processMessage( const PluginMessage& msg );
virtual void onRegisterListeners(UICodeEditor* editor, std::vector<Uint32>& listeners ) override;
virtual void onRegisterDocument( TextDocument* doc ) override;
DiscordRPCplugin( PluginManager* pluginManager, bool sync );
static Plugin* New( PluginManager* pluginManager );
static Plugin* NewSync( PluginManager* pluginManager );
virtual ~DiscordRPCplugin() override;
std::string getId() override { return Definition().id; }
std::string getTitle() override { return Definition().name; }
std::string getDescription() override { return Definition().description; }
protected:
DiscordIPC mIPC;
std::string mLastFile;
std::string mProjectName;
nlohmann::json mcLangBindings;
bool mcDoLangIcon;
void load( PluginManager* pluginManager );
PluginRequestHandle processMessage( const PluginMessage& msg );
virtual void onRegisterListeners( UICodeEditor* editor,
std::vector<Uint32>& listeners ) override;
virtual void onRegisterEditor( UICodeEditor* editor ) override;
virtual void onUnregisterEditor( UICodeEditor* editor ) override;
DiscordRPCplugin( PluginManager* pluginManager, bool sync );
};
} // namespace ecode
#endif // ECODE_DISCORDRPCPLUGIN_HPP

View File

@@ -3,19 +3,19 @@
#include <filesystem>
#include <vector>
#include <eepp/system/log.hpp>
#include <eepp/scene/scenemanager.hpp>
#include <eepp/system/log.hpp>
#include <eepp/ui/uiscenenode.hpp>
#if defined( EE_PLATFORM_POSIX )
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#if defined( EE_PLATFORM_POSIX )
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#elif EE_PLATFORM == EE_PLATFORM_WIN
#ifndef WIN32LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#ifndef WIN32LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif
using namespace EE::System;
@@ -27,303 +27,320 @@ DiscordIPC::DiscordIPC() {
}
bool DiscordIPC::tryConnect() {
#if EE_PLATFORM == EE_PLATFORM_WIN
std::string basePath = "\\\\.\\pipe\\";
for (int i = 0; i < 10; ++i) {
std::string ipcPath = basePath + "discord-ipc-" + std::to_string(i);
// Check if exists
DWORD attributes = GetFileAttributes(ipcPath.c_str());
if (attributes != INVALID_FILE_ATTRIBUTES) {
Log::debug("dcIPC: IPC path found! - %s", ipcPath);
mIpcPath = ipcPath;
mSocket = CreateFile(mIpcPath.c_str(), GENERIC_READ | GENERIC_WRITE,
0, nullptr, OPEN_EXISTING, 0, nullptr);
doHandshake();
return true;
}
#if EE_PLATFORM == EE_PLATFORM_WIN
std::string basePath = "\\\\.\\pipe\\";
for ( int i = 0; i < 10; ++i ) {
std::string ipcPath = basePath + "discord-ipc-" + std::to_string( i );
// Check if exists
DWORD attributes = GetFileAttributes( ipcPath.c_str() );
if ( attributes != INVALID_FILE_ATTRIBUTES ) {
Log::debug( "dcIPC: IPC path found! - %s", ipcPath );
mIpcPath = ipcPath;
mSocket = CreateFile( mIpcPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr,
OPEN_EXISTING, 0, nullptr );
doHandshake();
return true;
}
}
reconnect();
return false;
#elif defined( EE_PLATFORM_POSIX )
// Socket path can be in any of the following directories:
// * `XDG_RUNTIME_DIR`
// * `TMPDIR`
// * `TMP`
// * `TEMP`
// * `/tmp`
//
// Possibly Followed by:
// * `/app/com.discordapp.Discord` - for flatpak
// * `/.flatpak/dev.vencord.Vesktop/xdg-run` - Vesktop flatpak
// * `/snap.discord` - for snap
//
// Followed by:
// * `/discord-ipc-{i}` - where `i` is a number from 0 to 9
const std::string env[] = { "XDG_RUNTIME_DIR", "TMPDIR", "TMP", "TEMP" };
const std::vector<std::string> additionalPaths = {
"/app/com.discordapp.Discord",
"/.flatpak/dev.vencord.Vesktop/xdg-run",
"/snap.discord",
};
std::vector<std::string> validPaths;
for ( const auto& eVar : env ) {
const char* value = std::getenv( eVar.c_str() );
if ( !value ) {
continue;
}
if ( !std::filesystem::exists( value ) ) {
continue;
}
validPaths.push_back( value );
}
validPaths.push_back( "/tmp" ); // Hard coded fallback
std::vector<std::string> checkPaths;
for ( const auto& basePath : validPaths ) {
for ( const auto& additionalPath : additionalPaths ) {
std::string fullPath = basePath + additionalPath;
if ( std::filesystem::exists( fullPath ) ) {
checkPaths.push_back( fullPath );
}
}
}
checkPaths.insert( checkPaths.end(), validPaths.begin(), validPaths.end() );
for ( const auto& basePath : checkPaths ) {
if ( !std::filesystem::exists( basePath ) ) {
continue;
}
for ( int i = 0; i < 10; ++i ) {
std::string ipcPath = basePath + "/discord-ipc-" + std::to_string( i );
if ( std::filesystem::exists( ipcPath ) ) {
Log::debug( "dcIPC: IPC path found! - %s", ipcPath );
mIpcPath = ipcPath;
mSocket = socket( AF_UNIX, SOCK_STREAM, 0 );
if ( mSocket == -1 ) {
Log::error( "dcIPC: Discord IPC socket cold not be opened: %s", mIpcPath );
mIpcPath = "";
continue;
}
sockaddr_un serverAddr;
memset( &serverAddr, 0, sizeof( serverAddr ) );
serverAddr.sun_family = AF_UNIX;
mIpcPath.copy( serverAddr.sun_path, sizeof( serverAddr.sun_path ) - 1 );
serverAddr.sun_path[sizeof( serverAddr.sun_path ) - 1] =
'\0'; // Ensure null termination
if ( connect( mSocket, reinterpret_cast<struct sockaddr*>( &serverAddr ),
sizeof( serverAddr ) ) == -1 ) {
close( mSocket );
return false;
}
doHandshake();
return true;
}
}
reconnect();
return false;
#elif defined(EE_PLATFORM_POSIX)
// Socket path can be in any of the following directories:
// * `XDG_RUNTIME_DIR`
// * `TMPDIR`
// * `TMP`
// * `TEMP`
// * `/tmp`
//
// Possibly Followed by:
// * `/app/com.discordapp.Discord` - for flatpak
// * `/.flatpak/dev.vencord.Vesktop/xdg-run` - Vesktop flatpak
// * `/snap.discord` - for snap
//
// Followed by:
// * `/discord-ipc-{i}` - where `i` is a number from 0 to 9
const std::string env[] = {"XDG_RUNTIME_DIR", "TMPDIR", "TMP", "TEMP"};
const std::vector<std::string> additionalPaths = {
"/app/com.discordapp.Discord",
"/.flatpak/dev.vencord.Vesktop/xdg-run",
"/snap.discord",
};
std::vector<std::string> validPaths;
for ( const auto& eVar : env ){
const char* value = std::getenv(eVar.c_str());
if (!value) { continue; }
if (!std::filesystem::exists(value)) { continue; }
validPaths.push_back(value);
}
validPaths.push_back("/tmp"); // Hard coded fallback
std::vector<std::string> checkPaths;
for ( const auto& basePath : validPaths ) {
for (const auto& additionalPath : additionalPaths) {
std::string fullPath = basePath + additionalPath;
if (std::filesystem::exists(fullPath)) {
checkPaths.push_back(fullPath);
}
}
}
checkPaths.insert(checkPaths.end(), validPaths.begin(), validPaths.end());
for (const auto& basePath : checkPaths) {
if (!std::filesystem::exists(basePath)) { continue; }
for (int i = 0; i < 10; ++i) {
std::string ipcPath = basePath + "/discord-ipc-" + std::to_string(i);
if (std::filesystem::exists(ipcPath)) {
Log::debug("dcIPC: IPC path found! - %s", ipcPath);
mIpcPath = ipcPath;
mSocket = socket(AF_UNIX, SOCK_STREAM, 0);
if (mSocket == -1) {
Log::error("dcIPC: Discord IPC socket cold not be opened: %s", mIpcPath);
mIpcPath = "";
continue;
}
sockaddr_un serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sun_family = AF_UNIX;
mIpcPath.copy(serverAddr.sun_path, sizeof(serverAddr.sun_path) - 1);
serverAddr.sun_path[sizeof(serverAddr.sun_path) - 1] = '\0'; // Ensure null termination
if (connect(mSocket, reinterpret_cast<struct sockaddr*>(&serverAddr), sizeof(serverAddr)) == -1) {
close(mSocket);
return false;
}
doHandshake();
return true;
}
}
reconnect();
return false;
}
#endif
}
#endif
return false; // Discord not supported by other OS (if it is, TBA)
}
void DiscordIPC::doHandshake() {
json j = {
{"v", 1},
{"client_id", mcClientID}
};
sendPacket(DiscordIPCOpcodes::Handshake, j);
json j = { { "v", 1 }, { "client_id", mcClientID } };
sendPacket( DiscordIPCOpcodes::Handshake, j );
}
void DiscordIPC::clearActivity() {
json j = {
{"cmd", "SET_ACTIVITY"},
{"args", {
{"pid", 0},
{"activity", nullptr}
}},
{"nonce", "-"} // TODO: Null nonce for dev purposes, change to UUIDV4 in finished product
};
sendPacket(DiscordIPCOpcodes::Frame, j);
{ "cmd", "SET_ACTIVITY" },
{ "args", { { "pid", 0 }, { "activity", nullptr } } },
{ "nonce", "-" } // TODO: Null nonce for dev purposes, change to UUIDV4 in finished product
};
sendPacket( DiscordIPCOpcodes::Frame, j );
}
void DiscordIPC::setActivity( DiscordIPCActivity a ) {
json aj = {
{"type", static_cast<int>(a.type)},
{"instance", true},
};
if (!a.state.empty())
aj["state"] = a.state;
if (!a.details.empty())
aj["details"] = a.details;
{ "type", static_cast<int>( a.type ) },
{ "instance", true },
};
json as;
if (!a.largeImage.empty()) {
as["large_image"] = a.largeImage;
}
if (!a.largeText.empty()) {
as["large_text"] = a.largeText;
}
if (!a.smallImage.empty()) {
as["small_image"] = a.smallImage;
}
if (!a.smallText.empty()) {
as["small_text"] = a.smallText;
}
if (!as.empty()) {
aj["assets"] = as;
}
if ( !a.state.empty() )
aj["state"] = a.state;
if ( !a.details.empty() )
aj["details"] = a.details;
json as;
if ( !a.largeImage.empty() ) {
as["large_image"] = a.largeImage;
}
if ( !a.largeText.empty() ) {
as["large_text"] = a.largeText;
}
if ( !a.smallImage.empty() ) {
as["small_image"] = a.smallImage;
}
if ( !a.smallText.empty() ) {
as["small_text"] = a.smallText;
}
if ( !as.empty() ) {
aj["assets"] = as;
}
json t;
if ( a.start != 0 ) {
t["start"] = a.start;
}
if ( a.end != 0 ) {
t["end"] = a.end;
}
if ( !t.empty() ) {
aj["timestamps"] = t;
}
json t;
if (a.start != 0) {
t["start"] = a.start;
}
if (a.end != 0) {
t["end"] = a.end;
}
if (!t.empty()) {
aj["timestamps"] = t;
}
json b;
if (!a.buttons[0].url.empty()){
if ( !a.buttons[0].url.empty() ) {
b[0]["label"] = a.buttons[0].label;
b[0]["url"] = a.buttons[0].url;
}
if (!a.buttons[1].url.empty()){
}
if ( !a.buttons[1].url.empty() ) {
b[1]["label"] = a.buttons[1].label;
b[1]["url"] = a.buttons[1].url;
}
if (!b.empty()) {
aj["buttons"] = b;
}
json j{
{"cmd", "SET_ACTIVITY"},
{"args", {
{"pid", mPID},
{"activity", aj},
}},
{"nonce", "-"}
};
}
if ( !b.empty() ) {
aj["buttons"] = b;
}
json j{ { "cmd", "SET_ACTIVITY" },
{ "args",
{
{ "pid", mPID },
{ "activity", aj },
} },
{ "nonce", "-" } };
mActivity = a;
sendPacket(DiscordIPCOpcodes::Frame, j);
sendPacket( DiscordIPCOpcodes::Frame, j );
}
void DiscordIPC::sendPacket(DiscordIPCOpcodes opcode, json j) {
if (!std::filesystem::exists(mIpcPath)) { reconnect(); return; }
const std::string packet = j.dump();
std::vector<uint8_t> data;
void DiscordIPC::sendPacket( DiscordIPCOpcodes opcode, json j ) {
if ( !std::filesystem::exists( mIpcPath ) ) {
reconnect();
return;
}
const std::string packet = j.dump();
std::vector<uint8_t> data;
// Add correct ammount of padding for the protocol
union {
uint32_t value;
uint8_t bytes[4];
} bytes;
union {
uint32_t value;
uint8_t bytes[4];
} bytes;
bytes.value = opcode;
for (int i = 0; i <= 3; ++i) {
data.push_back(bytes.bytes[i]);
}
bytes.value = opcode;
for ( int i = 0; i <= 3; ++i ) {
data.push_back( bytes.bytes[i] );
}
bytes.value = packet.length();
for (int i = 0; i <= 3; ++i) {
data.push_back(bytes.bytes[i]);
}
bytes.value = packet.length();
for ( int i = 0; i <= 3; ++i ) {
data.push_back( bytes.bytes[i] );
}
for (char c : packet) {
data.push_back(static_cast<uint8_t>(c));
}
// Log::debug("Packet is: %s (%u)", j.dump(4), data.size());
// std::stringstream ss;
// for (uint8_t byte : data) {
// ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
// }
for ( char c : packet ) {
data.push_back( static_cast<uint8_t>( c ) );
}
// Log::debug(ss.str());
#if defined( EE_PLATFORM_POSIX )
ssize_t bytesSent = send(mSocket, data.data(), data.size(), 0);
if (bytesSent != data.size()) {
Log::error("dcIPC: Failed to send all data to Unix socket: %zu bytes sent, %zu bytes expected", bytesSent, data.size());
reconnect();
return;
}
// Log::debug("Packet is: %s (%u)", j.dump(4), data.size());
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 500000; // 0.5 seconds in microseconds
setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
char buffer[1024];
ssize_t bytesRead = recv(mSocket, buffer, sizeof(buffer), 0);
// Log::debug("dcIPC: RECV: %s", buffer);
// TODO: Implement nonce checking? (does it even really matter?)
//return bytesRead;
#elif EE_PLATFORM == EE_PLATFORM_WIN
DWORD bytesSent;
if ( !WriteFile(mSocket, data.data(), data.size(), &bytesSent, nullptr) ) {
Log::error("dcIPC: Error writing to pipe!!");
reconnect();
return;
} else if (bytesSent != data.size()) {
Log::error("dcIPC: Incorrect ammount of data written: %zu bytes sent, %zu bytes expected",
bytesSent, data.size());
reconnect();
return;
}
DWORD bytesRead;
char buffer[1024];
if ( !ReadFile(mSocket, buffer, 1024, &bytesRead, nullptr ) ) {
Log::error("dcIPC: Error reading pipe!!");
reconnect();
return;
}
// Log::debug("dcIPC: RECV: %s", buffer);
// std::stringstream ss;
// for (uint8_t byte : data) {
// ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
// }
#endif
// Log::debug(ss.str());
#if defined( EE_PLATFORM_POSIX )
ssize_t bytesSent = send( mSocket, data.data(), data.size(), 0 );
if ( bytesSent != data.size() ) {
Log::error(
"dcIPC: Failed to send all data to Unix socket: %zu bytes sent, %zu bytes expected",
bytesSent, data.size() );
reconnect();
return;
}
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 500000; // 0.5 seconds in microseconds
setsockopt( mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) );
char buffer[1024];
ssize_t bytesRead = recv( mSocket, buffer, sizeof( buffer ), 0 );
// Log::debug("dcIPC: RECV: %s", buffer);
// TODO: Implement nonce checking? (does it even really matter?)
// return bytesRead;
#elif EE_PLATFORM == EE_PLATFORM_WIN
DWORD bytesSent;
if ( !WriteFile( mSocket, data.data(), data.size(), &bytesSent, nullptr ) ) {
Log::error( "dcIPC: Error writing to pipe!!" );
reconnect();
return;
} else if ( bytesSent != data.size() ) {
Log::error( "dcIPC: Incorrect ammount of data written: %zu bytes sent, %zu bytes expected",
bytesSent, data.size() );
reconnect();
return;
}
DWORD bytesRead;
char buffer[1024];
if ( !ReadFile( mSocket, buffer, 1024, &bytesRead, nullptr ) ) {
Log::error( "dcIPC: Error reading pipe!!" );
reconnect();
return;
}
// Log::debug("dcIPC: RECV: %s", buffer);
#endif
}
void DiscordIPC::reconnect() {
if (mReconnectLock) {Log::warning("dcIPC: Tried to call reconnect while locked"); return;}
if (!mUIReady) { Log::debug("dcIPC: Scheduled a reconnect"); mIsReconnectScheduled = true; return; }
if (mBackoffIndex < DISCORDIPC_BACKOFF_MAX) { mBackoffIndex++; }
int delay = 5 + pow(2, mBackoffIndex);
if ( mReconnectLock ) {
Log::warning( "dcIPC: Tried to call reconnect while locked" );
return;
}
if ( !mUIReady ) {
Log::debug( "dcIPC: Scheduled a reconnect" );
mIsReconnectScheduled = true;
return;
}
if ( mBackoffIndex < DISCORDIPC_BACKOFF_MAX ) {
mBackoffIndex++;
}
int delay = 5 + pow( 2, mBackoffIndex );
mReconnectLock = true;
Log::warning("dcIPC: Waiting for reconnect delay of %us (%u/%u)", delay, mBackoffIndex, DISCORDIPC_BACKOFF_MAX);
EE::Scene::SceneManager::instance()->getUISceneNode()
->setTimeout( [this] {
EE::Scene::SceneManager::instance()->getUISceneNode()
->getThreadPool()->run( [this]{
Log::info("dcIPC: Reconnecting...");
mReconnectLock = false;
if(tryConnect()){ mBackoffIndex = 0; }
});
}, Seconds(delay));
Log::warning( "dcIPC: Waiting for reconnect delay of %us (%u/%u)", delay, mBackoffIndex,
DISCORDIPC_BACKOFF_MAX );
EE::Scene::SceneManager::instance()->getUISceneNode()->setTimeout(
[this] {
EE::Scene::SceneManager::instance()->getUISceneNode()->getThreadPool()->run( [this] {
Log::info( "dcIPC: Reconnecting..." );
mReconnectLock = false;
if ( tryConnect() ) {
mBackoffIndex = 0;
}
} );
},
Seconds( delay ) );
}
DiscordIPC::~DiscordIPC() {
#if defined( EE_PLATFORM_POSIX )
close(mSocket);
#elif EE_PLATFORM == EE_PLATFORM_WIN
CloseHandle(mSocket);
#endif
#if defined( EE_PLATFORM_POSIX )
close( mSocket );
#elif EE_PLATFORM == EE_PLATFORM_WIN
CloseHandle( mSocket );
#endif
}

View File

@@ -3,81 +3,78 @@
#include <nlohmann/json.hpp>
// 2^8 = 256s ~4.3min
#define DISCORDIPC_BACKOFF_MAX 8
#define DISCORDIPC_BACKOFF_MAX 8
enum DiscordIPCActivityTypes {
Playing = 0,
Listening = 2,
Watching = 3,
Competing = 5,
Playing = 0,
Listening = 2,
Watching = 3,
Competing = 5,
};
struct DiscordIPCActivityButton {
std::string label;
std::string url;
std::string label;
std::string url;
};
struct DiscordIPCActivity {
DiscordIPCActivityTypes type = DiscordIPCActivityTypes::Playing;
std::string state;
std::string details;
time_t start = 0;
time_t end = 0;
std::string largeImage;
std::string largeText;
std::string smallImage;
std::string smallText;
DiscordIPCActivityButton buttons[2];
DiscordIPCActivityTypes type = DiscordIPCActivityTypes::Playing;
std::string state;
std::string details;
time_t start = 0;
time_t end = 0;
std::string largeImage;
std::string largeText;
std::string smallImage;
std::string smallText;
// IMPORTANT: For some reason, you do not see the buttons of your own account on the discord
// client (intended discord behavior)
DiscordIPCActivityButton buttons[2];
};
enum DiscordIPCOpcodes {
Handshake = 0,
Frame,
Close,
Ping,
Pong
};
enum DiscordIPCOpcodes { Handshake = 0, Frame, Close, Ping, Pong };
class DiscordIPC {
public:
virtual ~DiscordIPC();
DiscordIPC();
public:
virtual ~DiscordIPC();
DiscordIPC();
// false - FileNotFound/OSNotSupported
// true - Success
bool tryConnect();
void reconnect();
void setActivity( DiscordIPCActivity a );
DiscordIPCActivity *getActivity() { return &mActivity; }
void clearActivity();
bool mUIReady;
bool mIsReconnectScheduled = false; // If we fail to load bofore UI initialises we call reconnect after init
//Configurables
std::string mcClientID;
protected:
std::string mIpcPath;
int mPID;
int mBackoffIndex;
int mReconnectLock = false; // Not quite a mutex because I want to lock any attempts if one is already waiting
DiscordIPCActivity mActivity;
#if defined( EE_PLATFORM_POSIX )
int mSocket;
#elif EE_PLATFORM == EE_PLATFORM_WIN
void* mSocket;
#endif
void doHandshake();
void sendPacket( DiscordIPCOpcodes opcode, nlohmann::json j );
// false - FileNotFound/OSNotSupported
// true - Success
bool tryConnect();
void reconnect();
void setActivity( DiscordIPCActivity a );
DiscordIPCActivity* getActivity() { return &mActivity; }
void clearActivity();
bool mUIReady;
bool mIsReconnectScheduled =
false; // If we fail to load bofore UI initialises we call reconnect after init
// Configurables
std::string mcClientID;
protected:
std::string mIpcPath;
int mPID;
int mBackoffIndex;
int mReconnectLock =
false; // Not quite a mutex because I want to lock any attempts if one is already waiting
DiscordIPCActivity mActivity;
#if defined( EE_PLATFORM_POSIX )
int mSocket;
#elif EE_PLATFORM == EE_PLATFORM_WIN
void* mSocket;
#endif
void doHandshake();
void sendPacket( DiscordIPCOpcodes opcode, nlohmann::json j );
};