discord / discord-rpc

https://discordapp.com/developers
MIT License
1.06k stars 329 forks source link

My RPC disappears after an hour #121

Closed LaxZ closed 6 years ago

LaxZ commented 6 years ago

Hello,

I have a problem with the discord rich presence.

So, i created a timer to update every 20 seconds the rich presence. (To show ingame data like remaining distance etc. of an Truck game). But now the problem: My RPC disappears after exactly an hour, like in this GIF: https://gyazo.com/f606bf1ffb1d2190f1a13aef41e5cf7a - When i tab out of game, my RPC is back... but sometimes, it works fine: http://prntscr.com/ib6l8a

Is something wrong with my code? Or isn't it my problem?

It's a C# WinForm Application using the RPC C# Wrapper.

msciotti commented 6 years ago

That's a very odd issue. I can't say that others have had this problem, but that may not mean it's specific to you. Could you post a snippet of the code your running for Rich Presence related stuff?

LaxZ commented 6 years ago

Sure:

private DiscordRpc.RichPresence presence;
private DiscordRpc.EventHandlers handlers;

void MainForm_Load(object sender, EventArgs e)
        {
            InitializeDiscord();
        }

void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            _server?.Dispose();
            trayIcon.Visible = false;

            Properties.Settings.Default.token = tokenBox.Text;
            Properties.Settings.Default.Save();

            DiscordRpc.Shutdown();
        }

private void InitializeDiscord()
        {
            handlers = new DiscordRpc.EventHandlers();

            handlers.readyCallback = ReadyCallback;
            handlers.disconnectedCallback += DisconnectedCallback;
            handlers.errorCallback += ErrorCallback;
            handlers.joinCallback += JoinCallback;
            handlers.requestCallback += RequestCallback;
            handlers.spectateCallback += SpectateCallback;

            DiscordRpc.Initialize(clientId, ref handlers, true, null);

            Log.Info("Discord Rich Presence intialized.");

            System.DateTime epoch = new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
            long cur_time = (long)(System.DateTime.UtcNow - epoch).TotalSeconds;

            presence.startTimestamp = cur_time;
            presence.largeImageKey = "large_logo";

            UpdatePresence();
        }

private void UpdatePresence()
        {
            try
            {
                json.RunJsonAsync();
            }
            catch (Exception e)
            {
                MessageBox.Show("Whoops... That shouldn't be right. Please report this message to LaxZ! Exception: \n\n" + e.Message, "VIVA Telemetry Server - WebException", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            if (Ets2ProcessHelper.IsEts2Running && Ets2TelemetryDataReader.Instance.IsConnected)
            {
                if (json.getPausedStatus() == true)
                {
                    presence.details = "Game Paused";
                    presence.smallImageKey = "";
                    presence.smallImageText = "";
                }
                else
                {
                    if (json.getTrailerAttached() == false)
                    {
                        presence.details = "No Job | Free as the wind";
                        presence.smallImageKey = "";
                        presence.smallImageText = "";
                    }
                    else
                    {
                        presence.details = "Delivering " + json.getCargo() + " \nfrom " + json.getSourceCity() + " to " + json.getDestinationCity();
                        presence.smallImageKey = "small_logo";
                        presence.smallImageText = "Remaining Distance: " + json.getEstimatedDistanceKm() + " KM";
                    }
                }

                presence.largeImageText = "Playing " + Ets2ProcessHelper.LastRunningGameName;
                presence.state = "Truck: " + json.getTruckName() + " " + json.getTruckModel();
            }
            else
            {
                presence.details = "Game not running | Idling";
                presence.state = "Version: " + AssemblyHelper.Version;
                presence.smallImageKey = "";
                presence.smallImageText = "";
                presence.largeImageText = "Idling";
            }
        }

private void discordTimer_Tick(object sender, EventArgs e)
        {
            UpdatePresence();

            DiscordRpc.UpdatePresence(ref presence);

            Log.Info("Updated Discord Rich Presence.");
        }

If you need more, i can upload the sourcecode to a new repo. (Not the best code, ikr)

C# Wrapper is from the button clicker example.

Edit: Its working again for 1 hour, when i restart my telemetry. But yea, as i said, only for one hour. then it disappears.

msciotti commented 6 years ago

No I think that's fine code-wise, thank you! So, when you boot up ETS2, you already have your RP app running. Couple questions:

  1. Does ETS2 take over your presence when you start it? Or does your RP still show?
  2. When you tab out, you get RP back. If you tab back in, does it disappear again? Or does it last for another hour?
LaxZ commented 6 years ago
  1. No, it shows the RP. But as I said, for one hour. Another video from a friend (You see the timestamp; i call it when I run the telemetry): https://youtu.be/iy_OZBHbmFA

  2. Yes, if I tab back in, it disappear.

But it shows the RP again, when I restart the telemetry. But only for one hour. Then its the same problem.

Also I can't remove ETS2 from discord, since its a verified game.

msciotti commented 6 years ago

Yeah you shouldn't need to (and, can't) remove ETS2. The priority of presence should always be RP > normal game, even if verified. Especially if you're updating every 20 seconds, it's not like your presence should "expire" or anything like that.

I'm interested in you tabbing out, getting RP again, tabbing back in, and then losing it. Could you reproduce that with your Discord console open (control + shift + i) and see if there's any errors? There should be some events around a RunningGamesStore call, which changes when games are added/removed (in this case, when your RP app is reconnected/disconnected).

LaxZ commented 6 years ago

There are no errors. Just the RPC and RunningGameStore events.

After one hour: When i'm tabbed in game: http://prntscr.com/ibm1wj

When i'm tabbed out: http://prntscr.com/ibm2b8

Maybe helpful?: http://prntscr.com/ibm5vs

LaxZ commented 6 years ago

So i got it working for longer than one hour. I created a another timer which clears the presence every 30 mins. But now it disappear after one hour and 30 minutes. Wtf?

private void clearPresenceTimer_Tick(object sender, EventArgs e)
        {
            DiscordRpc.ClearPresence();

            UpdatePresence();
        }

I don't know how to fix this....

msciotti commented 6 years ago

There shouldn't be any significance to it disappearing after an hour, or an hour and 30 mins, etc. We don't have a timeout like that, especially if you're continuously pushing presence updates every 20 seconds.

My advice would be to try and cut down to the least amount of code possible to test this. Something like:

private void discordTimer_Tick(object sender, EventArgs e)
{
        DiscordRpc.RichPresence presence;
        presence.details = "Look I pinged again!';
        DiscordRpc.UpdatePresence(ref presence);
        Log.Info("Updated Discord Rich Presence.");
}

I'm not sure of the logic of stuff like json.RunJsonAsync() or what it might do to a timer loop like this, so my first step would be to cut out the data tied to ETS2 and see if it still shows the same behavior.

LaxZ commented 6 years ago

Ok, i'll try this.

json.RunJsonAsync() catches the data from a api: https://pastebin.com/YdevuD8t

LaxZ commented 6 years ago

Ok, so i tried it just with your example. Same problem. My Telemetry RP got overlapped by ETS2 after exactly an hour. But this time there was a error when I tabbed out: https://gyazo.com/c2dae9654f9354770d3619a04b5438f4

msciotti commented 6 years ago

At this point, the best thing would probably be to upload the source somewhere where I can run it and see for myself, if that's appropriate for the project. Always easier to debug locally when I can.

LaxZ commented 6 years ago

Sure. Can i send you a pm via discord or somewhere else with the source file?

msciotti commented 6 years ago

No problem. Mason#1337

msciotti commented 6 years ago

Implementation issue solved offline.

AleksaDjordjic commented 5 years ago

Can we know how .... i have a similar problem with the same game (ETS 2). I can see the custom RPC from our program on my screen and its working fine , but everyone else sees me playing ETS 2

msciotti commented 5 years ago

Oh man. I lost the DM thread. Perhaps @LaxZ would be able to remind us?

AleksaDjordjic commented 5 years ago

The only way we know of fixing this is to launch ETS 2 first , then our app , but that isnt a long term solution in our case ..... something better would be nice

LaxZ commented 5 years ago

@msciotti It got server-side fixed about a while ago. See #181 for more.

Maybe @AleksaDjrodjic could show his code for the discord rpc implementation.

AleksaDjordjic commented 5 years ago

Its a bit long .... : `public DiscordRpc.EventHandlers discordHandlers; public Thread discordThread;

    void InitializeDiscord()
    {
        discordHandlers = new DiscordRpc.EventHandlers();

        DiscordRpc.Initialize("OUR_APPID", ref discordHandlers, true, null);

        discordThread = new Thread(() => 
        {
            while (true)
            {
                this.Dispatcher.Invoke(() => { DiscordUpdatePresence(); });
                Thread.Sleep(1000);
            }
        });

        discordThread.Start();
    }

    long startTimeLong;
    void DiscordUpdatePresence()
    {
        DiscordRpc.RichPresence discordPresence = new DiscordRpc.RichPresence();

        if (onJob == true)
        {
            string text = "🚚 " + sourceCity + " to " + destinationCity + " | " + cargo;
            discordPresence.details = text;

            discordPresence.state = "📝 " + (int)speed + "KM/h | " + (int)(leftJobDistance / 1000) + "KM Left";
        }
        else
        {
            discordPresence.details = "🚚 Free As The Wind !";
            discordPresence.state = "Crusing At " + (int)speed + "KM/h";
        }

        discordPresence.startTimestamp = startTimeLong;
        discordPresence.largeImageKey = "logo";
        DiscordRpc.UpdatePresence(discordPresence);
    }`

And yeah , we dont really have a problem that you had , its a bit different , as i said in the last comment : "The only way we know of fixing this is to launch ETS 2 first , then our app" but sometimes even that isnt required as Rich Presence of our app takes over .... idk , its weird , sometimes it prioritizes ETS2 over our app , sometimes its the other way ...

we will have to do some testing on our end to see if this is still happening to us... but thanks for the link to the other 'issue'