mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-06-01 11:06:30 +03:00
Clang-format; Correctly add command discordrpc-reconnect; Check for doLanguageIcons config option
This commit is contained in:
@@ -160,6 +160,8 @@ File path is: </string>
|
|||||||
<string name="cut">Cut</string>
|
<string name="cut">Cut</string>
|
||||||
<string name="dark">Dark</string>
|
<string name="dark">Dark</string>
|
||||||
<string name="date">Date</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">Draw Boxes</string>
|
||||||
<string name="debug_draw_boxes_toggle">Debug Draw Boxes Toggle</string>
|
<string name="debug_draw_boxes_toggle">Debug Draw Boxes Toggle</string>
|
||||||
<string name="debug_draw_debug_data">Debug Draw Debug Data</string>
|
<string name="debug_draw_debug_data">Debug Draw Debug Data</string>
|
||||||
|
|||||||
@@ -1,112 +1,110 @@
|
|||||||
{
|
{
|
||||||
"config" : {
|
"config": {
|
||||||
"appID": "1335730393948749898",
|
"appID": "1335730393948749898",
|
||||||
"doLanguageIcons": true,
|
"doLanguageIcons": true,
|
||||||
"iconBindings": {
|
"iconBindings": {
|
||||||
".htaccess": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
|
".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",
|
".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",
|
"[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",
|
"ada": "https://github.com/vyfor/icons/raw/master/icons/pastel/ada.png",
|
||||||
"adept": "https://raw.github.com/AdeptLanguage/Adept/master/.github/README_logo.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",
|
"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",
|
"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",
|
"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",
|
"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",
|
"bend": "https://avatars.githubusercontent.com/u/92327702",
|
||||||
"blueprint": "https://github.com/vyfor/icons/raw/master/icons/onyx/controller.png",
|
"blueprint": "https://github.com/vyfor/icons/raw/master/icons/onyx/controller.png",
|
||||||
"brainfuck": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.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",
|
"buzz": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
|
||||||
"c": "https://github.com/vyfor/icons/raw/master/icons/onyx/c.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",
|
"carbon": "https://upload.wikimedia.org/wikipedia/commons/e/e1/Carbon_logo.png",
|
||||||
"clojure": "https://github.com/vyfor/icons/raw/master/icons/onyx/clojure.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",
|
"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",
|
"cpp": "https://github.com/vyfor/icons/raw/master/icons/onyx/cpp.png",
|
||||||
"crystal": "https://github.com/vyfor/icons/raw/master/icons/onyx/crystal.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",
|
"csharp": "https://github.com/vyfor/icons/raw/master/icons/onyx/csharp.png",
|
||||||
"css": "https://github.com/vyfor/icons/raw/master/icons/onyx/css.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",
|
"d": "https://github.com/vyfor/icons/raw/master/icons/onyx/d.png",
|
||||||
"dart": "https://github.com/vyfor/icons/raw/master/icons/onyx/dart.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",
|
"diff": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
|
||||||
"dockerfile": "https://github.com/vyfor/icons/raw/master/icons/onyx/docker.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",
|
"elixir": "https://github.com/vyfor/icons/raw/master/icons/onyx/elixir.png",
|
||||||
"elm": "https://github.com/vyfor/icons/raw/master/icons/onyx/elm.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",
|
"environment file": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
|
||||||
"fantom": "https://avatars.githubusercontent.com/u/54911692",
|
"fantom": "https://avatars.githubusercontent.com/u/54911692",
|
||||||
"fortran": "https://github.com/vyfor/icons/raw/master/icons/onyx/fortran.png",
|
"fortran": "https://github.com/vyfor/icons/raw/master/icons/onyx/fortran.png",
|
||||||
"fstab": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.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",
|
"gdscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/godot.png",
|
||||||
"glsl": "https://github.com/vyfor/icons/raw/master/icons/onyx/opengl.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",
|
"go": "https://github.com/vyfor/icons/raw/master/icons/onyx/go.png",
|
||||||
"graphql": "https://github.com/vyfor/icons/raw/master/icons/onyx/graphql.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",
|
"groovy": "https://github.com/vyfor/icons/raw/master/icons/onyx/groovy.png",
|
||||||
"hare": "https://harelang.org/mascot.png",
|
"hare": "https://harelang.org/mascot.png",
|
||||||
"haskell": "https://github.com/vyfor/icons/raw/master/icons/onyx/haskell.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": "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",
|
"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",
|
"hlsl": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.png",
|
||||||
"html": "https://github.com/vyfor/icons/raw/master/icons/onyx/html.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",
|
"ini": "https://github.com/vyfor/icons/raw/master/icons/onyx/gear.png",
|
||||||
"jai": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.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",
|
"java": "https://github.com/vyfor/icons/raw/master/icons/onyx/java.png",
|
||||||
"javascript": "https://github.com/vyfor/icons/raw/master/icons/onyx/javascript.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",
|
"javascriptreact": "https://github.com/vyfor/icons/raw/master/icons/onyx/react.png",
|
||||||
"json": "https://github.com/vyfor/icons/raw/master/icons/onyx/json.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",
|
"julia": "https://github.com/vyfor/icons/raw/master/icons/onyx/julia.png",
|
||||||
"kotlin": "https://github.com/vyfor/icons/raw/master/icons/onyx/kotlin.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",
|
"latex": "https://github.com/vyfor/icons/raw/master/icons/onyx/latex.png",
|
||||||
"lobster": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.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",
|
"lua": "https://github.com/vyfor/icons/raw/master/icons/onyx/latex.png",
|
||||||
"makefile": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.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",
|
"markdown": "https://github.com/vyfor/icons/raw/master/icons/onyx/markdown.png",
|
||||||
"meson": "https://github.com/vyfor/icons/raw/master/icons/onyx/diagnostics.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",
|
"moonscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/lua.png",
|
||||||
"nelua": "https://nelua.io/assets/img/nelua-logo-64px.png",
|
"nelua": "https://nelua.io/assets/img/nelua-logo-64px.png",
|
||||||
"nim": "https://github.com/vyfor/icons/raw/master/icons/onyx/nim.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",
|
"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",
|
"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",
|
"ocaml": "https://github.com/vyfor/icons/raw/master/icons/onyx/ocaml.png",
|
||||||
"odin": "https://github.com/vyfor/icons/raw/master/icons/onyx/odin.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",
|
"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",
|
"pascal": "https://github.com/vyfor/icons/raw/master/icons/onyx/pascal.png",
|
||||||
"perl": "https://github.com/vyfor/icons/raw/master/icons/onyx/perl.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",
|
"php": "https://github.com/vyfor/icons/raw/master/icons/onyx/php.png",
|
||||||
"pico-8": "https://www.lexaloffle.com/gfx/p8b_pico8.png",
|
"pico-8": "https://www.lexaloffle.com/gfx/p8b_pico8.png",
|
||||||
"plaintext": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.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",
|
"po": "https://github.com/vyfor/icons/raw/master/icons/onyx/gnu.png",
|
||||||
"pony": "https://avatars.githubusercontent.com/u/12997238",
|
"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",
|
"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",
|
"powershell": "https://github.com/vyfor/icons/raw/master/icons/onyx/powershell.png",
|
||||||
"python": "https://github.com/vyfor/icons/raw/master/icons/onyx/python.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",
|
"r": "https://github.com/vyfor/icons/raw/master/icons/onyx/r.png",
|
||||||
"ring": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.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",
|
"ruby": "https://github.com/vyfor/icons/raw/master/icons/onyx/ruby.png",
|
||||||
"rust": "https://github.com/vyfor/icons/raw/master/icons/onyx/rust.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",
|
"sass": "https://github.com/vyfor/icons/raw/master/icons/onyx/scss.png",
|
||||||
"scala": "https://github.com/vyfor/icons/raw/master/icons/onyx/scala.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",
|
"shellscript": "https://github.com/vyfor/icons/raw/master/icons/onyx/shell.png",
|
||||||
"smallbasic": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.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",
|
"solidity": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
|
||||||
"sql": "https://github.com/vyfor/icons/raw/master/icons/onyx/sql.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",
|
"swift": "https://github.com/vyfor/icons/raw/master/icons/onyx/swift.png",
|
||||||
"tcl": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
|
"tcl": "https://github.com/vyfor/icons/raw/master/icons/onyx/text.png",
|
||||||
"teal": "https://avatars.githubusercontent.com/u/62526430",
|
"teal": "https://avatars.githubusercontent.com/u/62526430",
|
||||||
"toml": "https://github.com/vyfor/icons/raw/master/icons/onyx/toml.png",
|
"toml": "https://github.com/vyfor/icons/raw/master/icons/onyx/toml.png",
|
||||||
"typescript": "https://github.com/vyfor/icons/raw/master/icons/onyx/typescript.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",
|
"typescriptreact": "https://github.com/vyfor/icons/raw/master/icons/onyx/react.png",
|
||||||
"v": "https://github.com/vyfor/icons/raw/master/icons/onyx/v.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",
|
"vala": "https://github.com/vyfor/icons/raw/master/icons/onyx/vala.png",
|
||||||
"verilog": "https://github.com/vyfor/icons/raw/master/icons/onyx/assembly.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",
|
"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",
|
"vue": "https://github.com/vyfor/icons/raw/master/icons/onyx/vue.png",
|
||||||
"wren": "https://avatars.githubusercontent.com/u/45213573",
|
"wren": "https://avatars.githubusercontent.com/u/45213573",
|
||||||
"x86 assembly": "https://github.com/vyfor/icons/raw/master/icons/onyx/assembly.png",
|
"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",
|
"xml": "https://github.com/vyfor/icons/raw/master/icons/onyx/xml.png",
|
||||||
"xtend": "https://github.com/vyfor/icons/raw/master/icons/onyx/java.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",
|
"yaml": "https://github.com/vyfor/icons/raw/master/icons/onyx/yaml.png",
|
||||||
"zig": "https://github.com/vyfor/icons/raw/master/icons/onyx/zig.png"
|
"zig": "https://github.com/vyfor/icons/raw/master/icons/onyx/zig.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keybindings" : {
|
"keybindings": {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "discordRPCplugin.hpp"
|
#include "discordRPCplugin.hpp"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
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
|
#define dcRPC_THREADED 1
|
||||||
#else
|
#else
|
||||||
#define dcRPC_THREADED 0
|
#define dcRPC_THREADED 0
|
||||||
@@ -9,11 +9,11 @@ using json = nlohmann::json;
|
|||||||
|
|
||||||
namespace ecode {
|
namespace ecode {
|
||||||
|
|
||||||
Plugin* DiscordRPCplugin::New( PluginManager* pluginManager) {
|
Plugin* DiscordRPCplugin::New( PluginManager* pluginManager ) {
|
||||||
return eeNew( DiscordRPCplugin, ( pluginManager, false ) );
|
return eeNew( DiscordRPCplugin, ( pluginManager, false ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin* DiscordRPCplugin::NewSync( PluginManager* pluginManager) {
|
Plugin* DiscordRPCplugin::NewSync( PluginManager* pluginManager ) {
|
||||||
return eeNew( DiscordRPCplugin, ( pluginManager, true ) );
|
return eeNew( DiscordRPCplugin, ( pluginManager, true ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,28 +33,27 @@ DiscordRPCplugin::DiscordRPCplugin( PluginManager* pluginManager, bool sync ) :
|
|||||||
DiscordRPCplugin::~DiscordRPCplugin() {
|
DiscordRPCplugin::~DiscordRPCplugin() {
|
||||||
waitUntilLoaded();
|
waitUntilLoaded();
|
||||||
mShuttingDown = true;
|
mShuttingDown = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
void DiscordRPCplugin::load( PluginManager* pluginManager ) {
|
void DiscordRPCplugin::load( PluginManager* pluginManager ) {
|
||||||
Clock clock;
|
Clock clock;
|
||||||
AtomicBoolScopedOp loading( mLoading, true );
|
AtomicBoolScopedOp loading( mLoading, true );
|
||||||
|
|
||||||
pluginManager->subscribeMessages( this,
|
pluginManager->subscribeMessages( this,
|
||||||
[this]( const auto& notification ) -> PluginRequestHandle {
|
[this]( const auto& notification ) -> PluginRequestHandle {
|
||||||
return processMessage( notification );
|
return processMessage( notification );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
std::vector<std::string> paths;
|
std::vector<std::string> paths;
|
||||||
std::string path( pluginManager->getResourcesPath() + "plugins/discordRPC.json" );
|
std::string path( pluginManager->getResourcesPath() + "plugins/discordRPC.json" );
|
||||||
if ( FileSystem::fileExists( path ) )
|
if ( FileSystem::fileExists( path ) )
|
||||||
paths.emplace_back( path );
|
paths.emplace_back( path );
|
||||||
path = pluginManager->getPluginsPath() + "discordRPC.json";
|
path = pluginManager->getPluginsPath() + "discordRPC.json";
|
||||||
if ( FileSystem::fileExists( path ) ||
|
if ( FileSystem::fileExists( path ) ||
|
||||||
FileSystem::fileWrite(path, "{\n \"config\":{},\n \"keybindings\":{}\n}\n") ) {
|
FileSystem::fileWrite( path, "{\n \"config\":{},\n \"keybindings\":{}\n}\n" ) ) {
|
||||||
mConfigPath = path;
|
mConfigPath = path;
|
||||||
paths.emplace_back( path );
|
paths.emplace_back( path );
|
||||||
}
|
}
|
||||||
std::string data;
|
std::string data;
|
||||||
if ( !FileSystem::fileGet( path, data ) )
|
if ( !FileSystem::fileGet( path, data ) )
|
||||||
return;
|
return;
|
||||||
mConfigHash = String::hash( data );
|
mConfigHash = String::hash( data );
|
||||||
@@ -81,7 +80,12 @@ void DiscordRPCplugin::load( PluginManager* pluginManager ) {
|
|||||||
mIPC.mcClientID = "1335730393948749898";
|
mIPC.mcClientID = "1335730393948749898";
|
||||||
updateConfigFile = true;
|
updateConfigFile = true;
|
||||||
}
|
}
|
||||||
|
if ( config.contains( "doLanguageIcons" ) ) {
|
||||||
|
mcDoLangIcon = config.value( "doLanguageIcons", true );
|
||||||
|
} else {
|
||||||
|
mIPC.mcClientID = true;
|
||||||
|
updateConfigFile = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( updateConfigFile ) {
|
if ( updateConfigFile ) {
|
||||||
@@ -91,13 +95,13 @@ void DiscordRPCplugin::load( PluginManager* pluginManager ) {
|
|||||||
mConfigHash = String::hash( newData );
|
mConfigHash = String::hash( newData );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mIPC.tryConnect();
|
mIPC.tryConnect();
|
||||||
DiscordIPCActivity* a = mIPC.getActivity();
|
DiscordIPCActivity* a = mIPC.getActivity();
|
||||||
a->largeImage = DISCORDRPC_DEFAULT_ICON;
|
a->largeImage = DISCORDRPC_DEFAULT_ICON;
|
||||||
|
|
||||||
mIPC.setActivity(*a);
|
mIPC.setActivity( *a );
|
||||||
|
|
||||||
mReady = true;
|
mReady = true;
|
||||||
fireReadyCbs();
|
fireReadyCbs();
|
||||||
setReady( clock.getElapsedTime() );
|
setReady( clock.getElapsedTime() );
|
||||||
@@ -109,38 +113,45 @@ PluginRequestHandle DiscordRPCplugin::processMessage( const PluginMessage& msg )
|
|||||||
std::string rpath = FileSystem::getRealPath( msg.asJSON()["folder"] );
|
std::string rpath = FileSystem::getRealPath( msg.asJSON()["folder"] );
|
||||||
FileSystem::dirAddSlashAtEnd( rpath );
|
FileSystem::dirAddSlashAtEnd( rpath );
|
||||||
mProjectName = FileSystem::fileNameFromPath( 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: {
|
case PluginMessageType::UIReady: {
|
||||||
mIPC.mUIReady = true;
|
mIPC.mUIReady = true;
|
||||||
// Log::debug("dcPlugin: UI is ready!");
|
// Log::debug("dcPlugin: UI is ready!");
|
||||||
if (mIPC.mIsReconnectScheduled) {
|
if ( mIPC.mIsReconnectScheduled ) {
|
||||||
Log::debug("Running scheduled reconnect");
|
Log::debug( "Running scheduled reconnect" );
|
||||||
mIPC.tryConnect();
|
mIPC.tryConnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PluginRequestHandle::empty();
|
return PluginRequestHandle::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiscordRPCplugin::onRegisterDocument( TextDocument* doc ){
|
void DiscordRPCplugin::onRegisterEditor( UICodeEditor* editor ) {
|
||||||
doc->setCommand( "discordrpc-reconnect", [this] {
|
editor->addUnlockedCommands( { "discordrpc-reconnect" } );
|
||||||
mIPC.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 ) {
|
void DiscordRPCplugin::onRegisterListeners( UICodeEditor* editor, std::vector<Uint32>& listeners ) {
|
||||||
listeners.push_back( editor->on( Event::OnFocus, [this, editor]( const Event* ) {
|
listeners.push_back( editor->on( Event::OnFocus, [this, editor]( const Event* ) {
|
||||||
// `this` in the scope of the lambda is the parent `DiscordRPCplugin`
|
// `this` in the scope of the lambda is the parent `DiscordRPCplugin`
|
||||||
|
|
||||||
auto& doc = editor->getDocument();
|
auto& doc = editor->getDocument();
|
||||||
if (!doc.hasFilepath()) { return; }
|
if ( !doc.hasFilepath() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto filename = doc.getFilename();
|
auto filename = doc.getFilename();
|
||||||
|
|
||||||
if ( filename != mLastFile ) {
|
if ( filename != mLastFile ) {
|
||||||
this->mLastFile = filename;
|
this->mLastFile = filename;
|
||||||
|
|
||||||
@@ -149,27 +160,25 @@ void DiscordRPCplugin::onRegisterListeners( UICodeEditor* editor, std::vector<Ui
|
|||||||
|
|
||||||
DiscordIPCActivity* a = this->mIPC.getActivity();
|
DiscordIPCActivity* a = this->mIPC.getActivity();
|
||||||
|
|
||||||
if (!mProjectName.empty())
|
if ( !mProjectName.empty() )
|
||||||
a->details = String::format(i18n( "dc_workspace", "Working on %s" ).toUtf8(),
|
a->details = String::format( i18n( "dc_workspace", "Working on %s" ).toUtf8(),
|
||||||
mProjectName);
|
mProjectName );
|
||||||
a->state = String::format(i18n( "dc_editing", "Editing %s, a %s file" ).toUtf8(),
|
a->state = String::format( i18n( "dc_editing", "Editing %s, a %s file" ).toUtf8(),
|
||||||
filename, doc.getSyntaxDefinition().getLanguageName() );
|
filename, doc.getSyntaxDefinition().getLanguageName() );
|
||||||
a->start = time( nullptr ); // Time spent in this specific file
|
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();
|
std::string name = doc.getSyntaxDefinition().getLSPName();
|
||||||
if (!name.empty()) {
|
if ( !name.empty() && mcDoLangIcon ) {
|
||||||
a->largeImage = mcLangBindings.value(name, DISCORDRPC_DEFAULT_ICON);
|
a->largeImage = mcLangBindings.value( name, DISCORDRPC_DEFAULT_ICON );
|
||||||
}
|
}
|
||||||
|
|
||||||
this->mIPC.setActivity( *a );
|
this->mIPC.setActivity( *a );
|
||||||
}
|
}
|
||||||
|
|
||||||
} ) );
|
} ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace ecode
|
} // namespace ecode
|
||||||
@@ -4,10 +4,10 @@
|
|||||||
#include "../plugin.hpp"
|
#include "../plugin.hpp"
|
||||||
#include "../pluginmanager.hpp"
|
#include "../pluginmanager.hpp"
|
||||||
|
|
||||||
#include <eepp/system/threadpool.hpp>
|
|
||||||
#include <eepp/system/mutex.hpp>
|
|
||||||
#include <eepp/system/filesystem.hpp>
|
#include <eepp/system/filesystem.hpp>
|
||||||
|
#include <eepp/system/mutex.hpp>
|
||||||
#include <eepp/system/scopedop.hpp>
|
#include <eepp/system/scopedop.hpp>
|
||||||
|
#include <eepp/system/threadpool.hpp>
|
||||||
|
|
||||||
#include "sdk/ipc.hpp"
|
#include "sdk/ipc.hpp"
|
||||||
|
|
||||||
@@ -18,52 +18,53 @@ using namespace EE::System;
|
|||||||
using namespace EE::UI;
|
using namespace EE::UI;
|
||||||
using namespace EE::UI::Doc;
|
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 {
|
namespace ecode {
|
||||||
|
|
||||||
class DiscordRPCplugin : public PluginBase {
|
class DiscordRPCplugin : public PluginBase {
|
||||||
public:
|
public:
|
||||||
static PluginDefinition Definition() {
|
static PluginDefinition Definition() {
|
||||||
return {
|
return { "discrdrpc",
|
||||||
"discrdrpc",
|
"Discord Rich Presence",
|
||||||
"Discord Rich Presence",
|
"Show your friends what you are up to through the discord Rich Presence system",
|
||||||
"Show your friends what you are up to through the discord Rich Presence system",
|
DiscordRPCplugin::New,
|
||||||
DiscordRPCplugin::New,
|
{ 0, 0, 0 },
|
||||||
{ 0, 0, 0 },
|
DiscordRPCplugin::NewSync };
|
||||||
DiscordRPCplugin::NewSync };
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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; }
|
static Plugin* New( PluginManager* pluginManager );
|
||||||
|
|
||||||
std::string getDescription() override { return Definition().description; }
|
static Plugin* NewSync( PluginManager* pluginManager );
|
||||||
|
|
||||||
protected:
|
virtual ~DiscordRPCplugin() override;
|
||||||
DiscordIPC mIPC;
|
|
||||||
std::string mLastFile;
|
std::string getId() override { return Definition().id; }
|
||||||
std::string mProjectName;
|
|
||||||
nlohmann::json mcLangBindings;
|
std::string getTitle() override { return Definition().name; }
|
||||||
|
|
||||||
void load ( PluginManager* pluginManager );
|
std::string getDescription() override { return Definition().description; }
|
||||||
|
|
||||||
PluginRequestHandle processMessage( const PluginMessage& msg );
|
protected:
|
||||||
|
DiscordIPC mIPC;
|
||||||
virtual void onRegisterListeners(UICodeEditor* editor, std::vector<Uint32>& listeners ) override;
|
std::string mLastFile;
|
||||||
virtual void onRegisterDocument( TextDocument* doc ) override;
|
std::string mProjectName;
|
||||||
|
nlohmann::json mcLangBindings;
|
||||||
|
bool mcDoLangIcon;
|
||||||
DiscordRPCplugin( PluginManager* pluginManager, bool sync );
|
|
||||||
|
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
|
} // namespace ecode
|
||||||
|
|
||||||
#endif // ECODE_DISCORDRPCPLUGIN_HPP
|
#endif // ECODE_DISCORDRPCPLUGIN_HPP
|
||||||
@@ -3,19 +3,19 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <eepp/system/log.hpp>
|
|
||||||
#include <eepp/scene/scenemanager.hpp>
|
#include <eepp/scene/scenemanager.hpp>
|
||||||
|
#include <eepp/system/log.hpp>
|
||||||
#include <eepp/ui/uiscenenode.hpp>
|
#include <eepp/ui/uiscenenode.hpp>
|
||||||
|
|
||||||
#if defined( EE_PLATFORM_POSIX )
|
#if defined( EE_PLATFORM_POSIX )
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#elif EE_PLATFORM == EE_PLATFORM_WIN
|
#elif EE_PLATFORM == EE_PLATFORM_WIN
|
||||||
#ifndef WIN32LEAN_AND_MEAN
|
#ifndef WIN32LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace EE::System;
|
using namespace EE::System;
|
||||||
@@ -27,303 +27,320 @@ DiscordIPC::DiscordIPC() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DiscordIPC::tryConnect() {
|
bool DiscordIPC::tryConnect() {
|
||||||
#if EE_PLATFORM == EE_PLATFORM_WIN
|
#if EE_PLATFORM == EE_PLATFORM_WIN
|
||||||
std::string basePath = "\\\\.\\pipe\\";
|
std::string basePath = "\\\\.\\pipe\\";
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
for ( int i = 0; i < 10; ++i ) {
|
||||||
std::string ipcPath = basePath + "discord-ipc-" + std::to_string(i);
|
std::string ipcPath = basePath + "discord-ipc-" + std::to_string( i );
|
||||||
|
|
||||||
// Check if exists
|
// Check if exists
|
||||||
DWORD attributes = GetFileAttributes(ipcPath.c_str());
|
DWORD attributes = GetFileAttributes( ipcPath.c_str() );
|
||||||
if (attributes != INVALID_FILE_ATTRIBUTES) {
|
if ( attributes != INVALID_FILE_ATTRIBUTES ) {
|
||||||
Log::debug("dcIPC: IPC path found! - %s", ipcPath);
|
Log::debug( "dcIPC: IPC path found! - %s", ipcPath );
|
||||||
mIpcPath = ipcPath;
|
mIpcPath = ipcPath;
|
||||||
|
|
||||||
mSocket = CreateFile(mIpcPath.c_str(), GENERIC_READ | GENERIC_WRITE,
|
mSocket = CreateFile( mIpcPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr,
|
||||||
0, nullptr, OPEN_EXISTING, 0, nullptr);
|
OPEN_EXISTING, 0, nullptr );
|
||||||
|
|
||||||
doHandshake();
|
doHandshake();
|
||||||
return true;
|
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();
|
reconnect();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
#elif defined(EE_PLATFORM_POSIX)
|
#endif
|
||||||
// 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
|
|
||||||
return false; // Discord not supported by other OS (if it is, TBA)
|
return false; // Discord not supported by other OS (if it is, TBA)
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiscordIPC::doHandshake() {
|
void DiscordIPC::doHandshake() {
|
||||||
json j = {
|
json j = { { "v", 1 }, { "client_id", mcClientID } };
|
||||||
{"v", 1},
|
|
||||||
{"client_id", mcClientID}
|
sendPacket( DiscordIPCOpcodes::Handshake, j );
|
||||||
};
|
|
||||||
|
|
||||||
sendPacket(DiscordIPCOpcodes::Handshake, j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiscordIPC::clearActivity() {
|
void DiscordIPC::clearActivity() {
|
||||||
json j = {
|
json j = {
|
||||||
{"cmd", "SET_ACTIVITY"},
|
{ "cmd", "SET_ACTIVITY" },
|
||||||
{"args", {
|
{ "args", { { "pid", 0 }, { "activity", nullptr } } },
|
||||||
{"pid", 0},
|
{ "nonce", "-" } // TODO: Null nonce for dev purposes, change to UUIDV4 in finished product
|
||||||
{"activity", nullptr}
|
};
|
||||||
}},
|
sendPacket( DiscordIPCOpcodes::Frame, j );
|
||||||
{"nonce", "-"} // TODO: Null nonce for dev purposes, change to UUIDV4 in finished product
|
|
||||||
};
|
|
||||||
sendPacket(DiscordIPCOpcodes::Frame, j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiscordIPC::setActivity( DiscordIPCActivity a ) {
|
void DiscordIPC::setActivity( DiscordIPCActivity a ) {
|
||||||
json aj = {
|
json aj = {
|
||||||
{"type", static_cast<int>(a.type)},
|
{ "type", static_cast<int>( a.type ) },
|
||||||
{"instance", true},
|
{ "instance", true },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!a.state.empty())
|
|
||||||
aj["state"] = a.state;
|
|
||||||
if (!a.details.empty())
|
|
||||||
aj["details"] = a.details;
|
|
||||||
|
|
||||||
json as;
|
if ( !a.state.empty() )
|
||||||
if (!a.largeImage.empty()) {
|
aj["state"] = a.state;
|
||||||
as["large_image"] = a.largeImage;
|
if ( !a.details.empty() )
|
||||||
}
|
aj["details"] = a.details;
|
||||||
if (!a.largeText.empty()) {
|
|
||||||
as["large_text"] = a.largeText;
|
json as;
|
||||||
}
|
if ( !a.largeImage.empty() ) {
|
||||||
if (!a.smallImage.empty()) {
|
as["large_image"] = a.largeImage;
|
||||||
as["small_image"] = a.smallImage;
|
}
|
||||||
}
|
if ( !a.largeText.empty() ) {
|
||||||
if (!a.smallText.empty()) {
|
as["large_text"] = a.largeText;
|
||||||
as["small_text"] = a.smallText;
|
}
|
||||||
}
|
if ( !a.smallImage.empty() ) {
|
||||||
if (!as.empty()) {
|
as["small_image"] = a.smallImage;
|
||||||
aj["assets"] = as;
|
}
|
||||||
}
|
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;
|
json b;
|
||||||
if (!a.buttons[0].url.empty()){
|
if ( !a.buttons[0].url.empty() ) {
|
||||||
b[0]["label"] = a.buttons[0].label;
|
b[0]["label"] = a.buttons[0].label;
|
||||||
b[0]["url"] = a.buttons[0].url;
|
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]["label"] = a.buttons[1].label;
|
||||||
b[1]["url"] = a.buttons[1].url;
|
b[1]["url"] = a.buttons[1].url;
|
||||||
}
|
}
|
||||||
if (!b.empty()) {
|
if ( !b.empty() ) {
|
||||||
aj["buttons"] = b;
|
aj["buttons"] = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
json j{
|
json j{ { "cmd", "SET_ACTIVITY" },
|
||||||
{"cmd", "SET_ACTIVITY"},
|
{ "args",
|
||||||
{"args", {
|
{
|
||||||
{"pid", mPID},
|
{ "pid", mPID },
|
||||||
{"activity", aj},
|
{ "activity", aj },
|
||||||
}},
|
} },
|
||||||
{"nonce", "-"}
|
{ "nonce", "-" } };
|
||||||
};
|
|
||||||
|
|
||||||
mActivity = a;
|
mActivity = a;
|
||||||
sendPacket(DiscordIPCOpcodes::Frame, j);
|
sendPacket( DiscordIPCOpcodes::Frame, j );
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiscordIPC::sendPacket(DiscordIPCOpcodes opcode, json j) {
|
void DiscordIPC::sendPacket( DiscordIPCOpcodes opcode, json j ) {
|
||||||
if (!std::filesystem::exists(mIpcPath)) { reconnect(); return; }
|
if ( !std::filesystem::exists( mIpcPath ) ) {
|
||||||
|
reconnect();
|
||||||
const std::string packet = j.dump();
|
return;
|
||||||
std::vector<uint8_t> data;
|
}
|
||||||
|
|
||||||
|
const std::string packet = j.dump();
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
|
||||||
// Add correct ammount of padding for the protocol
|
// Add correct ammount of padding for the protocol
|
||||||
union {
|
union {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
uint8_t bytes[4];
|
uint8_t bytes[4];
|
||||||
} bytes;
|
} bytes;
|
||||||
|
|
||||||
bytes.value = opcode;
|
bytes.value = opcode;
|
||||||
for (int i = 0; i <= 3; ++i) {
|
for ( int i = 0; i <= 3; ++i ) {
|
||||||
data.push_back(bytes.bytes[i]);
|
data.push_back( bytes.bytes[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes.value = packet.length();
|
bytes.value = packet.length();
|
||||||
for (int i = 0; i <= 3; ++i) {
|
for ( int i = 0; i <= 3; ++i ) {
|
||||||
data.push_back(bytes.bytes[i]);
|
data.push_back( bytes.bytes[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
for (char c : packet) {
|
for ( char c : packet ) {
|
||||||
data.push_back(static_cast<uint8_t>(c));
|
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) << " ";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Log::debug(ss.str());
|
// Log::debug("Packet is: %s (%u)", j.dump(4), data.size());
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// std::stringstream ss;
|
||||||
struct timeval tv;
|
// for (uint8_t byte : data) {
|
||||||
tv.tv_sec = 0;
|
// ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
|
||||||
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
|
// 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() {
|
void DiscordIPC::reconnect() {
|
||||||
if (mReconnectLock) {Log::warning("dcIPC: Tried to call reconnect while locked"); return;}
|
if ( mReconnectLock ) {
|
||||||
if (!mUIReady) { Log::debug("dcIPC: Scheduled a reconnect"); mIsReconnectScheduled = true; return; }
|
Log::warning( "dcIPC: Tried to call reconnect while locked" );
|
||||||
if (mBackoffIndex < DISCORDIPC_BACKOFF_MAX) { mBackoffIndex++; }
|
return;
|
||||||
int delay = 5 + pow(2, mBackoffIndex);
|
}
|
||||||
|
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;
|
mReconnectLock = true;
|
||||||
|
|
||||||
Log::warning("dcIPC: Waiting for reconnect delay of %us (%u/%u)", delay, mBackoffIndex, DISCORDIPC_BACKOFF_MAX);
|
Log::warning( "dcIPC: Waiting for reconnect delay of %us (%u/%u)", delay, mBackoffIndex,
|
||||||
EE::Scene::SceneManager::instance()->getUISceneNode()
|
DISCORDIPC_BACKOFF_MAX );
|
||||||
->setTimeout( [this] {
|
EE::Scene::SceneManager::instance()->getUISceneNode()->setTimeout(
|
||||||
EE::Scene::SceneManager::instance()->getUISceneNode()
|
[this] {
|
||||||
->getThreadPool()->run( [this]{
|
EE::Scene::SceneManager::instance()->getUISceneNode()->getThreadPool()->run( [this] {
|
||||||
Log::info("dcIPC: Reconnecting...");
|
Log::info( "dcIPC: Reconnecting..." );
|
||||||
mReconnectLock = false;
|
mReconnectLock = false;
|
||||||
if(tryConnect()){ mBackoffIndex = 0; }
|
if ( tryConnect() ) {
|
||||||
});
|
mBackoffIndex = 0;
|
||||||
}, Seconds(delay));
|
}
|
||||||
|
} );
|
||||||
|
},
|
||||||
|
Seconds( delay ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscordIPC::~DiscordIPC() {
|
DiscordIPC::~DiscordIPC() {
|
||||||
#if defined( EE_PLATFORM_POSIX )
|
#if defined( EE_PLATFORM_POSIX )
|
||||||
close(mSocket);
|
close( mSocket );
|
||||||
#elif EE_PLATFORM == EE_PLATFORM_WIN
|
#elif EE_PLATFORM == EE_PLATFORM_WIN
|
||||||
CloseHandle(mSocket);
|
CloseHandle( mSocket );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -3,81 +3,78 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
// 2^8 = 256s ~4.3min
|
// 2^8 = 256s ~4.3min
|
||||||
#define DISCORDIPC_BACKOFF_MAX 8
|
#define DISCORDIPC_BACKOFF_MAX 8
|
||||||
|
|
||||||
enum DiscordIPCActivityTypes {
|
enum DiscordIPCActivityTypes {
|
||||||
Playing = 0,
|
Playing = 0,
|
||||||
Listening = 2,
|
Listening = 2,
|
||||||
Watching = 3,
|
Watching = 3,
|
||||||
Competing = 5,
|
Competing = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DiscordIPCActivityButton {
|
struct DiscordIPCActivityButton {
|
||||||
std::string label;
|
std::string label;
|
||||||
std::string url;
|
std::string url;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DiscordIPCActivity {
|
struct DiscordIPCActivity {
|
||||||
DiscordIPCActivityTypes type = DiscordIPCActivityTypes::Playing;
|
DiscordIPCActivityTypes type = DiscordIPCActivityTypes::Playing;
|
||||||
std::string state;
|
std::string state;
|
||||||
std::string details;
|
std::string details;
|
||||||
|
|
||||||
time_t start = 0;
|
time_t start = 0;
|
||||||
time_t end = 0;
|
time_t end = 0;
|
||||||
|
|
||||||
std::string largeImage;
|
std::string largeImage;
|
||||||
std::string largeText;
|
std::string largeText;
|
||||||
std::string smallImage;
|
std::string smallImage;
|
||||||
std::string smallText;
|
std::string smallText;
|
||||||
|
|
||||||
DiscordIPCActivityButton buttons[2];
|
// 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 {
|
enum DiscordIPCOpcodes { Handshake = 0, Frame, Close, Ping, Pong };
|
||||||
Handshake = 0,
|
|
||||||
Frame,
|
|
||||||
Close,
|
|
||||||
Ping,
|
|
||||||
Pong
|
|
||||||
};
|
|
||||||
|
|
||||||
class DiscordIPC {
|
class DiscordIPC {
|
||||||
public:
|
public:
|
||||||
|
virtual ~DiscordIPC();
|
||||||
virtual ~DiscordIPC();
|
DiscordIPC();
|
||||||
DiscordIPC();
|
|
||||||
|
|
||||||
// false - FileNotFound/OSNotSupported
|
// false - FileNotFound/OSNotSupported
|
||||||
// true - Success
|
// true - Success
|
||||||
bool tryConnect();
|
bool tryConnect();
|
||||||
void reconnect();
|
void reconnect();
|
||||||
|
|
||||||
void setActivity( DiscordIPCActivity a );
|
void setActivity( DiscordIPCActivity a );
|
||||||
DiscordIPCActivity *getActivity() { return &mActivity; }
|
DiscordIPCActivity* getActivity() { return &mActivity; }
|
||||||
void clearActivity();
|
void clearActivity();
|
||||||
|
|
||||||
bool mUIReady;
|
bool mUIReady;
|
||||||
bool mIsReconnectScheduled = false; // If we fail to load bofore UI initialises we call reconnect after init
|
bool mIsReconnectScheduled =
|
||||||
|
false; // If we fail to load bofore UI initialises we call reconnect after init
|
||||||
//Configurables
|
|
||||||
std::string mcClientID;
|
// Configurables
|
||||||
protected:
|
std::string mcClientID;
|
||||||
std::string mIpcPath;
|
|
||||||
int mPID;
|
protected:
|
||||||
|
std::string mIpcPath;
|
||||||
int mBackoffIndex;
|
int mPID;
|
||||||
int mReconnectLock = false; // Not quite a mutex because I want to lock any attempts if one is already waiting
|
|
||||||
|
int mBackoffIndex;
|
||||||
DiscordIPCActivity mActivity;
|
int mReconnectLock =
|
||||||
|
false; // Not quite a mutex because I want to lock any attempts if one is already waiting
|
||||||
|
|
||||||
#if defined( EE_PLATFORM_POSIX )
|
DiscordIPCActivity mActivity;
|
||||||
int mSocket;
|
|
||||||
#elif EE_PLATFORM == EE_PLATFORM_WIN
|
#if defined( EE_PLATFORM_POSIX )
|
||||||
void* mSocket;
|
int mSocket;
|
||||||
#endif
|
#elif EE_PLATFORM == EE_PLATFORM_WIN
|
||||||
|
void* mSocket;
|
||||||
void doHandshake();
|
#endif
|
||||||
|
|
||||||
void sendPacket( DiscordIPCOpcodes opcode, nlohmann::json j );
|
void doHandshake();
|
||||||
|
|
||||||
|
void sendPacket( DiscordIPCOpcodes opcode, nlohmann::json j );
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user