diff --git a/.gitignore b/.gitignore index fedd458..3186dab 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,7 @@ src/test/* out/* build/* .idea/* +.classpath +.settings/* +bin/* +.project diff --git a/README.md b/README.md index 24434b7..08fc74e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,16 @@ [ ![jitpack](https://jitpack.io/v/MinnDevelopment/Java-DiscordRPC.svg) ](https://jitpack.io/#MinnDevelopment/Java-DiscordRPC) # Java-DiscordRPC -This library contains Java bindings for [Discord's official RPC SDK](https://github.com/discordapp/discord-rpc) using JNA. +This library contains Java bindings for [Discord's official RPC SDK](https://github.com/discordapp/discord-rpc) using JNA. This project provides binaries for `linux-x86-64`, `win32-x86-64` and `darwin`. -If, on macOS, you get the following message: -``` -Error in LSRegisterURL: -10811 -``` -it can safely be ignored. +If, on macOS, you get the following message which can be ignored: `Error in LSRegisterURL: -10811` + +## Documentation + +You can see the official discord documentation in the [API Documentation](https://discordapp.com/developers/docs/rich-presence/how-to). +
Alternatively you may visist the javadoc at [jitpack](https://jitpack.io/com/github/MinnDevelopment/Java-DiscordRPC/master-SNAPSHOT/javadoc/index.html). ## Examples @@ -17,7 +18,6 @@ it can safely be ignored. import club.minnced.discord.rpc.*; public class Main { - public static void main(String[] args) { DiscordRPC lib = DiscordRPC.INSTANCE; String applicationId = ""; @@ -39,12 +39,15 @@ public class Main { } }, "RPC-Callback-Handler").start(); } - } ``` +> Note: To reveal this presence you have to start a window for your application. + ## License + Java-DiscordRPC is licensed under the Apache 2.0 License. The base DiscordRPC is licensed under the MIT license. ## Contributing + Find something that is lacking? Fork the project and pull request! diff --git a/build.gradle b/build.gradle index b0a065e..00538e4 100644 --- a/build.gradle +++ b/build.gradle @@ -15,14 +15,15 @@ */ plugins { id 'com.github.johnrengelman.shadow' version '2.0.1' + id 'maven-publish' } group 'club.minnced' -version '1.0-SNAPSHOT' +version '1.2' apply plugin: 'java' -build.dependsOn shadowJar + sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -34,3 +35,72 @@ repositories { dependencies { compile 'net.java.dev.jna:jna:4.4.0' } + +wrapper { + gradleVersion = '4.2.1' +} + +// Publishing + +task sources(type: Copy) { + from 'src/main/java' + into "$buildDir/sources" +} + +classes.dependsOn sources + +jar { + baseName = project.name + manifest { + attributes 'Implementation-Version': version + attributes 'Target-Platforms': 'win32-x86-64, linux-x86-64, darwin' + } + + dependsOn sources +} + +javadoc { + failOnError = false + options.encoding = 'UTF-8' + options.addStringOption('-html5') // jdk-9 docs + + dependsOn sources + source = sources.destinationDir +} + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from "$buildDir/sources" +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +publishing { + publications { + MavenProject(MavenPublication) { + from components.java + groupId group + artifactId archivesBaseName + version version + + artifact javadocJar + artifact sourcesJar + } + } +} + +build { + dependsOn clean + dependsOn jar + dependsOn javadocJar + dependsOn sourcesJar + dependsOn shadowJar + + jar.mustRunAfter clean + javadocJar.mustRunAfter jar + sourcesJar.mustRunAfter javadocJar + shadowJar.mustRunAfter sourcesJar +} diff --git a/src/main/java/club/minnced/discord/rpc/DiscordEventHandlers.java b/src/main/java/club/minnced/discord/rpc/DiscordEventHandlers.java index a2b5455..c5eedc1 100644 --- a/src/main/java/club/minnced/discord/rpc/DiscordEventHandlers.java +++ b/src/main/java/club/minnced/discord/rpc/DiscordEventHandlers.java @@ -33,24 +33,39 @@ void (*joinRequest)(const DiscordJoinRequest* request); } DiscordEventHandlers; */ - +/** + * Struct containing handlers for RPC events + *
Provided handlers can be null. + */ public class DiscordEventHandlers extends Structure { + /** + * Handler function for the ready event + */ public interface OnReady extends Callback { void accept(); } + /** + * Handler function for the exceptional events (error, disconnect) + */ public interface OnStatus extends Callback { void accept(int errorCode, String message); } + /** + * Handler function for game update events (joinGame, spectateGame) + */ public interface OnGameUpdate extends Callback { void accept(String secret); } + /** + * Handler function for user join requests + */ public interface OnJoinRequest extends Callback { void accept(DiscordJoinRequest request); @@ -65,11 +80,29 @@ public interface OnJoinRequest extends Callback "joinRequest" )); + /** + * Called when the RPC connection has been established + */ public OnReady ready; + /** + * Called when the RPC connection has been severed + */ public OnStatus disconnected; + /** + * Called when an internal error is caught within the SDK + */ public OnStatus errored; + /** + * Called when the logged in user joined a game + */ public OnGameUpdate joinGame; + /** + * Called when the logged in user joined to spectate a game + */ public OnGameUpdate spectateGame; + /** + * Called when another discord user wants to join the game of the logged in user + */ public OnJoinRequest joinRequest; @Override diff --git a/src/main/java/club/minnced/discord/rpc/DiscordJoinRequest.java b/src/main/java/club/minnced/discord/rpc/DiscordJoinRequest.java index 7806175..bdd32cb 100644 --- a/src/main/java/club/minnced/discord/rpc/DiscordJoinRequest.java +++ b/src/main/java/club/minnced/discord/rpc/DiscordJoinRequest.java @@ -29,7 +29,9 @@ const char* avatar; } DiscordJoinRequest; */ - +/** + * Struct binding for a discord join request. + */ public class DiscordJoinRequest extends Structure { private static final List FIELD_ORDER = Collections.unmodifiableList(Arrays.asList( @@ -38,8 +40,17 @@ public class DiscordJoinRequest extends Structure "avatar" )); + /** + * The userId for the user that requests to join + */ public String userId; + /** + * The username of the user that requests to join + */ public String username; + /** + * The avatar of the user that requests to join + */ public String avatar; @Override diff --git a/src/main/java/club/minnced/discord/rpc/DiscordRPC.java b/src/main/java/club/minnced/discord/rpc/DiscordRPC.java index 2ec562b..e1e0ed7 100644 --- a/src/main/java/club/minnced/discord/rpc/DiscordRPC.java +++ b/src/main/java/club/minnced/discord/rpc/DiscordRPC.java @@ -19,23 +19,134 @@ import com.sun.jna.Library; import com.sun.jna.Native; +/** + * Core library binding for the official Discord RPC SDK. + *
Use {@link #INSTANCE} to access this library. + * + *

Supported Architectures

+ * + */ public interface DiscordRPC extends Library { + /** + * Library instance. + */ DiscordRPC INSTANCE = Native.loadLibrary("discord-rpc", DiscordRPC.class); + /** + * Used to decline a request via {@link #Discord_Respond(String, int)} + * @see #DISCORD_REPLY_YES + */ int DISCORD_REPLY_NO = 0; + /** + * Used to accept a request via {@link #Discord_Respond(String, int)} + * @see #DISCORD_REPLY_NO + */ int DISCORD_REPLY_YES = 1; + /** + * Currently unsused response, treated like NO. + * Used with {@link #Discord_Respond(String, int)} + * @see #DISCORD_REPLY_NO + */ int DISCORD_REPLY_IGNORE = 2; + /** + * Initializes the library, supply with application details and event handlers. + * Handlers are only called when the {@link #Discord_RunCallbacks()} method is invoked! + *
Before closing the application it is recommended to call {@link #Discord_Shutdown()} + * + * @param applicationId + * The ID for this RPC application, + * retrieved from the developer dashboard + * @param handlers + * Nullable instance of {@link club.minnced.discord.rpc.DiscordEventHandlers} + * @param autoRegister + * {@code true} to automatically call {@link #Discord_RegisterSteamGame(String, String)} or {@link #Discord_Register(String, String)} + * @param steamId + * Possible steam ID of the running game + */ void Discord_Initialize(String applicationId, DiscordEventHandlers handlers, boolean autoRegister, String steamId); + + /** + * Shuts the RPC connection down. + * If not currently connected, this does nothing. + */ void Discord_Shutdown(); + /** + * Executes the registered handlers for currently queued events. + *
If this is not called the handlers will not receive any events! + * + *

It is recommended to call this in a 2 second interval + */ void Discord_RunCallbacks(); + + /** + * Polls events from the RPC pipe and pushes the currently queued presence. + *
This will be performed automatically if the attached binary + * has an enabled IO thread (default) + * + *

If the IO-Thread has been enabled this will not be supported! + */ void Discord_UpdateConnection(); + /** + * Updates the currently set presence of the logged in user. + *
Note that the client only updates its presence every 15 seconds + * and queues all additional presence updates. + * + * @param struct + * The new presence to use, or null to reset + * + * @see club.minnced.discord.rpc.DiscordRichPresence + */ void Discord_UpdatePresence(DiscordRichPresence struct); + + /** + * Responds to the given user with the specified reply type. + * + *

Possible Replies

+ * + * + * @param userid + * The id of the user to respond to + * @param reply + * The reply type + * + * @see club.minnced.discord.rpc.DiscordJoinRequest#userId DiscordJoinRequest.userId + */ void Discord_Respond(String userid, int reply); + + /** + * Registers the given application so it can be run by the discord client. {@code discord-://} + * + * @param applicationId + * The ID of the application to register + * @param command + * The command for the application startup, or {@code null} to use the + * current executable's path + */ + void Discord_Register(String applicationId, String command); + + /** + * Similar to {@link #Discord_Register(String, String)} but uses the steam + * game's installation path. + * + * @param applicationId + * The ID of the application to register + * @param steamId + * The steam ID for the game + */ + void Discord_RegisterSteamGame(String applicationId, String steamId); } diff --git a/src/main/java/club/minnced/discord/rpc/DiscordRichPresence.java b/src/main/java/club/minnced/discord/rpc/DiscordRichPresence.java index dc317ac..18dcd00 100644 --- a/src/main/java/club/minnced/discord/rpc/DiscordRichPresence.java +++ b/src/main/java/club/minnced/discord/rpc/DiscordRichPresence.java @@ -41,7 +41,9 @@ int8_t instance; } DiscordRichPresence; */ - +/** + * Struct binding for a RichPresence + */ public class DiscordRichPresence extends Structure { private static final List FIELD_ORDER = Collections.unmodifiableList(Arrays.asList( @@ -62,20 +64,118 @@ public class DiscordRichPresence extends Structure "instance" )); + /** + * The user's current party status. + *
Example: "Looking to Play", "Playing Solo", "In a Group" + * + *

Maximum: 128 characters + */ public String state; + + /** + * What the player is currently doing. + *
Example: "Competitive - Captain's Mode", "In Queue", "Unranked PvP" + * + *

Maximum: 128 characters + */ public String details; + + /** + * Unix timestamp (seconds) for the start of the game. + *
Example: 1507665886 + */ public long startTimestamp; + + /** + * Unix timestamp (seconds) for the start of the game. + *
Example: 1507665886 + */ public long endTimestamp; + + /** + * Name of the uploaded image for the large profile artwork. + *
Example: "default" + * + *

Maximum: 32 characters + */ public String largeImageKey; + + /** + * Tooltip for the largeImageKey. + *
Example: "Blade's Edge Arena", "Numbani", "Danger Zone" + * + *

Maximum: 128 characters + */ public String largeImageText; + + /** + * Name of the uploaded image for the small profile artwork. + *
Example: "rogue" + * + *

Maximum: 32 characters + */ public String smallImageKey; + + /** + * Tooltip for the smallImageKey. + *
Example: "Rogue - Level 100" + * + *

Maximum: 128 characters + */ public String smallImageText; + + /** + * ID of the player's party, lobby, or group. + *
Example: "ae488379-351d-4a4f-ad32-2b9b01c91657" + * + *

Maximum: 128 characters + */ public String partyId; + + /** + * Current size of the player's party, lobby, or group. + *
Example: 1 + */ public int partySize; + + /** + * Maximum size of the player's party, lobby, or group. + *
Example: 5 + */ public int partyMax; + + /** + * Unique hashed string for Spectate and Join. + * Required to enable match interactive buttons in the user's presence. + *
Example: "MmhuZToxMjMxMjM6cWl3amR3MWlqZA==" + * + *

Maximum: 128 characters + */ public String matchSecret; + + /** + * Unique hashed string for Spectate button. + * This will enable the "Spectate" button on the user's presence if whitelisted. + *
Example: "MTIzNDV8MTIzNDV8MTMyNDU0" + * + *

Maximum: 128 characters + */ public String joinSecret; + + /** + * Unique hashed string for chat invitations and Ask to Join. + * This will enable the "Ask to Join" button on the user's presence if whitelisted. + *
Example: "MTI4NzM0OjFpMmhuZToxMjMxMjM=" + * + *

Maximum: 128 characters + */ public String spectateSecret; + + /** + * Marks the matchSecret as a game session with a specific beginning and end. + * Boolean value of 0 or 1. + *
Example: 1 + */ public byte instance; @Override diff --git a/src/main/java/club/minnced/discord/rpc/package-info.java b/src/main/java/club/minnced/discord/rpc/package-info.java new file mode 100644 index 0000000..1405955 --- /dev/null +++ b/src/main/java/club/minnced/discord/rpc/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016 - 2017 Florian Spieß + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Java bindings for the official Discord RPC SDK. + */ +package club.minnced.discord.rpc;