work on rpc and add real rpc sources

This commit is contained in:
S-B99 2019-10-28 18:22:00 -04:00
parent 4b737aa1b8
commit 3095ad7cdf
7 changed files with 812 additions and 16 deletions

View File

@ -0,0 +1,136 @@
/*
* Copyright 2016 - 2019 Florian Spieß and the java-discord-rpc contributors
*
* 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.
*/
package club.minnced.discord.rpc;
import com.sun.jna.Callback;
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/*
typedef struct DiscordEventHandlers {
void (*ready)(DiscordUser*);
void (*disconnected)(int errorCode, const char* message);
void (*errored)(int errorCode, const char* message);
void (*joinGame)(const char* joinSecret);
void (*spectateGame)(const char* spectateSecret);
void (*joinRequest)(const DiscordUser* request);
} DiscordEventHandlers;
*/
/**
* Struct containing handlers for RPC events
* <br>Provided handlers can be null.
*/
public class DiscordEventHandlers extends Structure
{
/**
* Handler function for the ready event
*/
public interface OnReady extends Callback
{
void accept(DiscordUser user);
}
/**
* 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(DiscordUser request);
}
private static final List<String> FIELD_ORDER = Collections.unmodifiableList(Arrays.asList(
"ready",
"disconnected",
"errored",
"joinGame",
"spectateGame",
"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
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof DiscordEventHandlers))
return false;
DiscordEventHandlers that = (DiscordEventHandlers) o;
return Objects.equals(ready, that.ready)
&& Objects.equals(disconnected, that.disconnected)
&& Objects.equals(errored, that.errored)
&& Objects.equals(joinGame, that.joinGame)
&& Objects.equals(spectateGame, that.spectateGame)
&& Objects.equals(joinRequest, that.joinRequest);
}
@Override
public int hashCode()
{
return Objects.hash(ready, disconnected, errored, joinGame, spectateGame, joinRequest);
}
@Override
protected List<String> getFieldOrder()
{
return FIELD_ORDER;
}
}

View File

@ -0,0 +1,169 @@
/*
* Copyright 2016 - 2019 Florian Spieß and the java-discord-rpc contributors
*
* 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.
*/
package club.minnced.discord.rpc;
import com.sun.jna.Library;
import com.sun.jna.Native;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Core library binding for the official <a href="https://github.com/discordapp/discord-rpc" target="_blank">Discord RPC SDK</a>.
* <br>Use {@link #INSTANCE} to access this library.
*
* <h1>Supported Architectures</h1>
* <ul>
* <li>Windows x86</li>
* <li>Windows x86-64</li>
* <li>Linux x86-64</li>
* <li>Darwin</li>
* </ul>
*/
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!
* <br><b>Before closing the application it is recommended to call {@link #Discord_Shutdown()}</b>
*
* @param applicationId
* The ID for this RPC application,
* retrieved from the <a href="https://discordappc.com/developers/applications/me" target="_blank">developer dashboard</a>
* @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(@Nonnull String applicationId,
@Nullable DiscordEventHandlers handlers,
boolean autoRegister,
@Nullable 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.
* <br>If this is not called the handlers will not receive any events!
*
* <p>It is recommended to call this in a <u>2 second interval</u>
*/
void Discord_RunCallbacks();
/**
* Polls events from the RPC pipe and pushes the currently queued presence.
* <br>This will be performed automatically if the attached binary
* has an enabled IO thread (default)
*
* <p><b>If the IO-Thread has been enabled this will not be supported!</b>
*/
void Discord_UpdateConnection();
/**
* Updates the currently set presence of the logged in user.
* <br>Note that the client only updates its presence every <b>15 seconds</b>
* and queues all additional presence updates.
*
* @param struct
* The new presence to use
*
* @see club.minnced.discord.rpc.DiscordRichPresence
*/
void Discord_UpdatePresence(@Nullable DiscordRichPresence struct);
/**
* Clears the currently set presence.
*/
void Discord_ClearPresence();
/**
* Responds to the given user with the specified reply type.
*
* <h1>Possible Replies</h1>
* <ul>
* <li>{@link #DISCORD_REPLY_NO}</li>
* <li>{@link #DISCORD_REPLY_YES}</li>
* <li>{@link #DISCORD_REPLY_IGNORE}</li>
* </ul>
*
* @param userid
* The id of the user to respond to
* @param reply
* The reply type
*
* @see club.minnced.discord.rpc.DiscordUser#userId DiscordUser.userId
*/
void Discord_Respond(@Nonnull String userid, int reply);
/**
* Updates the registered event handlers to the provided struct.
*
* @param handlers
* The handlers to update to, or null
*/
void Discord_UpdateHandlers(@Nullable DiscordEventHandlers handlers);
/**
* Registers the given application so it can be run by the discord client. {@code discord-<appid>://}
*
* @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);
}

View File

@ -0,0 +1,229 @@
/*
* Copyright 2016 - 2019 Florian Spieß and the java-discord-rpc contributors
*
* 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.
*/
package club.minnced.discord.rpc;
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/*
typedef struct DiscordRichPresence {
const char* state; // max 128 bytes
const char* details; // max 128 bytes
int64_t startTimestamp;
int64_t endTimestamp;
const char* largeImageKey; // max 32 bytes
const char* largeImageText; // max 128 bytes
const char* smallImageKey; // max 32 bytes
const char* smallImageText; // max 128 bytes
const char* partyId; // max 128 bytes
int partySize;
int partyMax;
const char* matchSecret; // max 128 bytes
const char* joinSecret; // max 128 bytes
const char* spectateSecret; // max 128 bytes
int8_t instance;
} DiscordRichPresence;
*/
/**
* Struct binding for a RichPresence
*/
public class DiscordRichPresence extends Structure
{
private static final List<String> FIELD_ORDER = Collections.unmodifiableList(Arrays.asList(
"state",
"details",
"startTimestamp",
"endTimestamp",
"largeImageKey",
"largeImageText",
"smallImageKey",
"smallImageText",
"partyId",
"partySize",
"partyMax",
"matchSecret",
"joinSecret",
"spectateSecret",
"instance"
));
public DiscordRichPresence(String encoding) {
super();
setStringEncoding(encoding);
}
public DiscordRichPresence() {
this("UTF-8");
}
/**
* The user's current party status.
* <br>Example: "Looking to Play", "Playing Solo", "In a Group"
*
* <p><b>Maximum: 128 characters</b>
*/
public String state;
/**
* What the player is currently doing.
* <br>Example: "Competitive - Captain's Mode", "In Queue", "Unranked PvP"
*
* <p><b>Maximum: 128 characters</b>
*/
public String details;
/**
* Unix timestamp (seconds) for the start of the game.
* <br>Example: 1507665886
*/
public long startTimestamp;
/**
* Unix timestamp (seconds) for the start of the game.
* <br>Example: 1507665886
*/
public long endTimestamp;
/**
* Name of the uploaded image for the large profile artwork.
* <br>Example: "default"
*
* <p><b>Maximum: 32 characters</b>
*/
public String largeImageKey;
/**
* Tooltip for the largeImageKey.
* <br>Example: "Blade's Edge Arena", "Numbani", "Danger Zone"
*
* <p><b>Maximum: 128 characters</b>
*/
public String largeImageText;
/**
* Name of the uploaded image for the small profile artwork.
* <br>Example: "rogue"
*
* <p><b>Maximum: 32 characters</b>
*/
public String smallImageKey;
/**
* Tooltip for the smallImageKey.
* <br>Example: "Rogue - Level 100"
*
* <p><b>Maximum: 128 characters</b>
*/
public String smallImageText;
/**
* ID of the player's party, lobby, or group.
* <br>Example: "ae488379-351d-4a4f-ad32-2b9b01c91657"
*
* <p><b>Maximum: 128 characters</b>
*/
public String partyId;
/**
* Current size of the player's party, lobby, or group.
* <br>Example: 1
*/
public int partySize;
/**
* Maximum size of the player's party, lobby, or group.
* <br>Example: 5
*/
public int partyMax;
/**
* Unique hashed string for Spectate and Join.
* Required to enable match interactive buttons in the user's presence.
* <br>Example: "MmhuZToxMjMxMjM6cWl3amR3MWlqZA=="
*
* <p><b>Maximum: 128 characters</b>
*/
public String matchSecret;
/**
* Unique hashed string for Spectate button.
* This will enable the "Spectate" button on the user's presence if whitelisted.
* <br>Example: "MTIzNDV8MTIzNDV8MTMyNDU0"
*
* <p><b>Maximum: 128 characters</b>
*/
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.
* <br>Example: "MTI4NzM0OjFpMmhuZToxMjMxMjM="
*
* <p><b>Maximum: 128 characters</b>
*/
public String spectateSecret;
/**
* Marks the matchSecret as a game session with a specific beginning and end.
* Boolean value of 0 or 1.
* <br>Example: 1
*/
public byte instance;
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof DiscordRichPresence))
return false;
DiscordRichPresence presence = (DiscordRichPresence) o;
return startTimestamp == presence.startTimestamp
&& endTimestamp == presence.endTimestamp
&& partySize == presence.partySize
&& partyMax == presence.partyMax
&& instance == presence.instance
&& Objects.equals(state, presence.state)
&& Objects.equals(details, presence.details)
&& Objects.equals(largeImageKey, presence.largeImageKey)
&& Objects.equals(largeImageText, presence.largeImageText)
&& Objects.equals(smallImageKey, presence.smallImageKey)
&& Objects.equals(smallImageText, presence.smallImageText)
&& Objects.equals(partyId, presence.partyId)
&& Objects.equals(matchSecret, presence.matchSecret)
&& Objects.equals(joinSecret, presence.joinSecret)
&& Objects.equals(spectateSecret, presence.spectateSecret);
}
@Override
public int hashCode()
{
return Objects.hash(state, details, startTimestamp, endTimestamp, largeImageKey, largeImageText, smallImageKey,
smallImageText, partyId, partySize, partyMax, matchSecret, joinSecret, spectateSecret, instance);
}
@Override
protected List<String> getFieldOrder()
{
return FIELD_ORDER;
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright 2016 - 2019 Florian Spieß and the java-discord-rpc contributors
*
* 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.
*/
package club.minnced.discord.rpc;
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/*
typedef struct DiscordUser {
const char* userId;
const char* username;
const char* discriminator;
const char* avatar;
} DiscordUser;
*/
/**
* Struct binding for a discord join request.
*/
public class DiscordUser extends Structure
{
private static final List<String> FIELD_ORDER = Collections.unmodifiableList(Arrays.asList(
"userId",
"username",
"discriminator",
"avatar"
));
public DiscordUser(String encoding) {
super();
setStringEncoding(encoding);
}
public DiscordUser() {
this("UTF-8");
}
/**
* 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 discriminator of the user that requests to join
*/
public String discriminator;
/**
* The avatar of the user that requests to join
*/
public String avatar;
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof DiscordUser))
return false;
DiscordUser that = (DiscordUser) o;
return Objects.equals(userId, that.userId)
&& Objects.equals(username, that.username)
&& Objects.equals(discriminator, that.discriminator)
&& Objects.equals(avatar, that.avatar);
}
@Override
public int hashCode()
{
return Objects.hash(userId, username, discriminator, avatar);
}
@Override
protected List<String> getFieldOrder()
{
return FIELD_ORDER;
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2016 - 2019 Florian Spieß and the java-discord-rpc contributors
*
* 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;

View File

@ -0,0 +1,157 @@
package me.sdashb.kamiblue;
import me.zeroeightsix.kami.module.Module;
import me.zeroeightsix.kami.module.ModuleManager;
import me.zeroeightsix.kami.setting.Setting;
import me.zeroeightsix.kami.setting.Settings;
// discord imports
import club.minnced.discord.rpc.*;
import com.google.common.hash.Hashing;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraftforge.fml.common.FMLLog;
import java.nio.charset.StandardCharsets;
import java.util.Random;
/**
* @author cookiedragon234
* Updated by S-B99 on 28/10/19
*/
@Module.Info(name = "DiscordRPC", category = Module.Category.MISC, description = "Discord Rich Presence")
public class DiscordKBlueRPC extends Module {
//1//protected void onEnable() {
//1//
//1// if (isDisabled()) {
//1// this.disable();
//1// return;
//1// }
//1//}
private static final String APP_ID = "638403216278683661";
private static final DiscordKBlueRPC rpc = DiscordKBlueRPC.INSTANCE;
private static DiscordRichPresence presence = new DiscordRichPresence();
private static boolean hasStarted = false;
public static boolean start()
{
FMLLog.log.info("Starting Discord RPC");
if(hasStarted) return false;
hasStarted = true;
DiscordEventHandlers handlers = new DiscordEventHandlers();
handlers.disconnected = (int var1, String var2) ->
{
System.out.println("Discord RPC disconnected, var1: " + String.valueOf(var1) + ", var2: " + var2);
};
rpc.Discord_Initialize(APP_ID, handlers, true, "");
presence.startTimestamp = System.currentTimeMillis() / 1000;
presence.details = "Main Menu";
presence.state = "discord.gg/ncQkFKU";
//presence.smallImageKey = "backdoored_logo";
presence.largeImageKey = "backdoored_logo";
//presence.spectateSecret = String.valueOf(new Random().nextInt((9000000 - 100000) + 1) + 100000);
//presence.joinSecret = String.valueOf(new Random().nextInt((9000000 - 100000) + 1) + 100000);
rpc.Discord_UpdatePresence(presence);
new Thread(() ->
{
while(!Thread.currentThread().isInterrupted())
{
try
{
// Run callbacks
rpc.Discord_RunCallbacks();
String details = "";
String state = "";
int players = 0;
int maxPlayers = 0;
// If we're in singleplayer
if (Globals.mc.isIntegratedServerRunning())
{
details = "Singleplayer";
}
else
{
if (Globals.mc.getCurrentServerData() != null)
{
ServerData svr = Globals.mc.getCurrentServerData();
if (!svr.serverIP.equals(""))
{
// If we're on multiplayer
details = "Multiplayer";
state = svr.serverIP;
if(svr.populationInfo != null)
{
String[] popInfo = svr.populationInfo.split("/");
if(popInfo.length > 2)
{
players = Integer.valueOf(popInfo[0]);
maxPlayers = Integer.valueOf(popInfo[1]);
}
}
if(state.contains("2b2t.org"))
{
try
{
if(Backdoored.lastChat.startsWith("Position in queue: "))
{
state = state + " " + Integer.parseInt(Backdoored.lastChat.substring(19)) + " in queue";
}
} catch(Throwable e){ e.printStackTrace(); }
}
}
}
// If we're in the main menu
else
{
details = "Main Menu";
state = "discord.gg/ncQkFKU";
}
}
if(!details.equals(presence.details) || !state.equals(presence.state))
{
presence.startTimestamp = System.currentTimeMillis() / 1000;
}
presence.details = details;
presence.state = state;
//presence.partySize = players;
//presence.partyMax = maxPlayers;
/*if(players > 0)
{
presence.partyId = String.valueOf(new Random().nextInt((9000000 - 100000) + 1) + 100000);
}*/
rpc.Discord_UpdatePresence(presence);
} catch(Exception e){e.printStackTrace();}
try
{
Thread.sleep(5000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}, "Discord-RPC-Callback-Handler").start();
FMLLog.log.info("Discord RPC initialised succesfully");
return true;
}
}

View File

@ -1,16 +0,0 @@
package me.sdashb.kamiblue;
import me.zeroeightsix.kami.module.Module;
import me.zeroeightsix.kami.setting.Setting;
import me.zeroeightsix.kami.setting.Settings;
//import club.minnced.discord.rpc.*;
/**
* @author 086
* Updated by S-B99 on 27/10/19
*/
@Module.Info(name = "DiscordRPC", category = Module.Category.PLAYER, description = "Discord Rich Presence")
public class DiscordRPC extends Module {
}