JnCrMx / discord-game-sdk4j

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

Discord occasionally fails to send invite #35

Open CamperSamu opened 3 years ago

CamperSamu commented 3 years ago

I don't know what's causing it, I have no clue if it's me or some weird syncing issue, but sometimes the SDK or the RPC server fails to process an invite.

When I try to invite someone in an activity I occasionally get a Unknown or Internal error from both the SDK and the RPC server + a Invalid Activity Action error with code 50039 on the Discord app's console.

Discord console error:

97e6fa2….js:136 POST https://ptb.discord.com/api/v9/channels/579002871647830026/messages 400
97e6fa2….js:137 [RPCServer:IPC] Socket Emit: 160 
{cmd: "ACTIVITY_INVITE_USER", data: {…}, evt: "ERROR", nonce: "78"}
cmd: "ACTIVITY_INVITE_USER"
data:
code: 1000
message: "Unknown Error"
__proto__: Object
evt: "ERROR"
nonce: "78"
__proto__: Object
9b2b7f0….js:348 Uncaught (in promise) 
{ok: false, headers: {…}, body: {…}, text: "{\"message\": \"Invalid Activity Action\", \"code\": 50039}", status: 400}
body: {message: "Invalid Activity Action", code: 50039}
headers:
access-control-allow-credentials: "true"
access-control-allow-headers: "Content-Type, Authorization, X-Audit-Log-Reason, X-Track, X-Super-Properties, X-Context-Properties, X-Failed-Requests, X-Fingerprint, X-RPC-Proxy, X-Debug-Options, x-client-trace-id, If-None-Match, Range, X-RateLimit-Precision"
access-control-allow-methods: "POST, GET, PUT, PATCH, DELETE"
access-control-allow-origin: "https://ptb.discord.com"
alt-svc: "h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400, h3-28=\":443\"; ma=86400, h3-27=\":443\"; ma=86400"
cf-cache-status: "DYNAMIC"
cf-ray: "69140de86fda0e1a-MXP"
content-length: "53"
content-type: "application/json"
date: "Sun, 19 Sep 2021 16:05:13 GMT"
expect-ct: "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\""
nel: "{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}"
report-to: "{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=rXwBkjxOpAAeSBdAIPkjXI0TrKYEggqB1dE7KcQ18nru%2Bfgi0LwmECstr%2FCJYQUELAL%2BwGAFdWABgxcW7XINKQW9oxLtNt9i1t6R0J23%2B3JIxb%2F%2B6pqRKbFU4btME5Yabg%3D%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}"
server: "cloudflare"
strict-transport-security: "max-age=31536000; includeSubDomains; preload"
via: "1.1 google"
x-content-type-options: "nosniff"
x-envoy-upstream-service-time: "39"
__proto__: Object
ok: false
status: 400
text: "{\"message\": \"Invalid Activity Action\", \"code\": 50039}"
__proto__: Object

GameSDK Exception:

[de.jcm.discordgamesdk.Core] [ERROR] ResponseError { code: UnknownError, message: "Unknown Error" }
[STDERR]: de.jcm.discordgamesdk.GameSDKException: Game SDK operation failed: INTERNAL_ERROR
[STDERR]:   at de.jcm.discordgamesdk.Core.lambda$static$0(Core.java:130)
[STDERR]:   at de.jcm.discordgamesdk.Core.runCallbacks(Native Method)
[STDERR]:   at de.jcm.discordgamesdk.Core.lambda$runCallbacks$2(Core.java:330)
[STDERR]:   at de.jcm.discordgamesdk.Core.lambda$execute$4(Core.java:385)
[STDERR]:   at de.jcm.discordgamesdk.Core.execute(Core.java:398)
[STDERR]:   at de.jcm.discordgamesdk.Core.execute(Core.java:383)
[STDERR]:   at de.jcm.discordgamesdk.Core.runCallbacks(Core.java:330)

Discord Rich Presence Activity Payload:

RichPresence[largeImageID=the_crown, largeImageText=The Crown, smallImageID=verified_icon, smallImageText=, details=Playing on The Crown, state=in the Hub, currentPlayers=1, maxPlayers=500, partyID=testIdk, joinSecret=[there's a numeric ip + port here that I have to censor]-test, spectateSecret=spec:[there's a numeric ip + port here that I have to censor]-test, matchSecret=, inInstance=true]

(the party ID is not the issue, I tried with a UUID before that)

I'm trying to make a Minecraft Discord Integration if more context is needed.

Thanks in advance!

JnCrMx commented 3 years ago

Could you please share the piece of code you use to send the invites? I'm having trouble replicating the error. Are you sending join or spectate invites?

Also, how frequent does it occur? The only way I could get an error is by spamming invites, but it doesn't sound like that is what you are doing.

CamperSamu commented 3 years ago

Hi and thanks for the reply; sorry if I'm replying so late but I took a pause from the project I was working on I haven't checked my inbox in a while.

By playing around with the code a couple of weeks ago I somehow alleviated the issue by putting everything on a separate thread instead of updating everything on the main thread like Discord suggested, now it happens less but it's still an issue.

The way I handle Rich Presence and Invites is through a Record:

public record RichPresence(
        String largeImageID,
        String largeImageText,
        String smallImageID,
        String smallImageText,
        String details,
        String state,
        int currentPlayers,
        int maxPlayers,
        String partyID,
        String joinSecret,
        String spectateSecret,
        String matchSecret,
        boolean inInstance
)

//A RP status looks like this: RichPresence[largeImageID=the_crown, largeImageText=King's Client, smallImageID=crown_icon_black, smallImageText=, details=Playing on IglesiasCraft, state=IP: mc.iglesiascraft.it, currentPlayers=3, maxPlayers=420, partyID=5c6da8a2-d9a4-4e57-9be2-ac3ab0a55d80, joinSecret=mc.iglesiascraft.it, spectateSecret=spec:mc.iglesiascraft.it, matchSecret=, inInstance=true]
//This works, the status is displayed and the invite works too, sometimes it bugs out even if the invite and all is the exact same.

I then have on a separate thread a "manager" that runs the callbacks every 16ms.

I update Rich Presence with this method in the Manager:

    public void setRichPresence(@NotNull RichPresence richPresence) {
        core.activityManager().updateActivity(richPresence.getActivity());
//        System.out.println(richPresence);     //debug message to see what's the RPstatus contents
    }

And this is the thread run method contents:

    @Override
    public void run() {
        init();
        while (true) {
            try {
                if (running) {     //this is a boolean that I use to make sure that everything is up and running, otherwise players can attempt to join before the game is even running
                    core.runCallbacks();
                    InvitesManager.tick();     //This just manages the ingame join and quit action + popup notificaiton, has nothing to do with the issue as i tried with and without it
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                sleep(16);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

Edit: The issue occurs occasionally when switching servers and it fixes itself occasionally, IDK why and how tho since I only update the RP once except when I join (my) server where I have a plugin telling the client what to put on RP (check the 1st post for an example of the server's custom RP status), and even there it reads everything fine, the RP status is displayed, the secrets are there and there's a pause between one status and another, it's not instantaneous (I even tried to clear the status before setting it)