JnCrMx / discord-game-sdk4j

Java bindings for Discord's Game SDK
MIT License
123 stars 23 forks source link

Discord Game SDK fails to initialize when Discord is not installed #52

Open BullyWiiPlaza opened 2 years ago

BullyWiiPlaza commented 2 years ago

I tested this library on a machine which does not have Discord installed, it causes the following exception:

de.jcm.discordgamesdk.GameSDKException: Game SDK operation failed: INTERNAL_ERROR
    at de.jcm.discordgamesdk.Core.<init>(Core.java:439) ~[discord-game-sdk4j-v0.5.5.jar:?]
        ...

Is this the cause of not installing Discord? Since this error seems quite opaque, it would be great to know or maybe provide a static boolean isDiscordInstalled() so we can skip using the library entirely in this case.

JnCrMx commented 2 years ago

Sadly, I don't know of any good cross-platform way to check if a program is installed. Especially on Linux there is a huge variety of ways to install Discord (Snap, Flatpak, .deb, pacman as well as different AUR versions on Arch, etc.). It might be possible to check if a Discord process is running, but there is also no guarantee for a specific process name.

If you got any ideas, feel free to contribute them! But for now, the only good way I can imagine is simply catching any GameSDKException throw during initialization and the first Core#runCallbacks. You can also initialize the Core with the NoRequireDiscord flag, which will cause the exception to be thrown only when you try to use the SDK (and it might give a better error message).

BullyWiiPlaza commented 2 years ago

I actually had the same idea to check for a running Discord process. Since some of my apps happen to only run on Windows, I can easily just implement a native solution to check for running processes and call it a day. Maybe that would make more sense to implement, also for cross-platform functionality. We can assume Discord is using the default process name like Discord.exe on Windows, who even edits that on purpose?

Or, more cross-platform friendly might be to talk to some port Discord which might be listening on and sending a message to it and getting a response. In this case we can implement it with standard Java sockets or so. I don't know the exact details of what Discord exposes though.

JnCrMx commented 2 years ago

There is a cross-platform way of checking if a process exists, which I originally used to skip my tests automatically for CI builds (https://github.com/JnCrMx/discord-game-sdk4j/blob/master/src/test/java/de/jcm/discordgamesdk/DiscordTest.java#L30). But sadly, it does not work in Java 8…

Since the library already uses native code, it might be an idea to simply implement such a check in C and #ifdef our way around different platforms.

As for checking if the port is open… Currently, the library is basically just a wrapper around the C library provided by Discord. I don't want to rely on any “under the hood”-behavior of it. For the future, it might be interesting to entirely re-implement the protocol used for communication in pure Java (which would also avoid any proprietary libraries or native code), but I sadly don't have enough time for that.