Detect other player has QUIT the application, not just disconnected

Options
Hello,

I'm trying to implement a reconnect feature to our game. It's a 1v1 game so have 2 players in a room. So far, I can detect when the player gets disconnected due to a network issue using OnDisconnected() and OnPlayerLeftRoom(), and display a dialog while waiting for the other player to reconnect. However, I want to detect when the other player actually quits the application, and have the remaining player win immediately. Currently, I don't know of a way to distinguish whether the other player just got disconnected or has actually quit the application. Because of this, when the other player quits the application, the remaining player gets the waiting to reconnect dialog instead of winning immediately. I thought of implementing OnApplicationQuit(), thinking I would send an event to the remaining player before the application is closed, but more often than not by the time OnApplicationQuit() is called, Photon has already been disconnected, so I can't send events anymore. What should be the right approach to this? Thanks

Comments

  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @dango528,

    Thank you for choosing Photon!

    It depends on what you mean by quit:

    1. if you mean the player closed the app (or moved it to the background): you need a special event yes
    void OnApplicationQuit() 
    {
        this.SendQuitEvent();
    }
    
    // optional
    void OnApplicationPause(bool paused)
    {
        if (paused)
        {
             this.SendQuitEvent();
        }
    }
    
    // optional
    void OnApplicationFocus(bool focused)
    {
        if (!focused)
        {
             this.SendQuitEvent();
        }
    }
    
    void SendQuitEvent()
    {
        // send event, add your code here
        PhotonNetwork.SendAllOutgoingCommands(); // send it right now
    }
    2. if you use PlayerTTL and you have a game logic for abandoning the game: PhotonNetwork.LeaveRoom(roomName, false) vs. leaving temporarily PhotonNetwork.LeaveRoom(roomName, true) or unexepected disconnects, then you get separate callbacks for this or you can check IsInactive property of the player who disconnected.
  • dango528
    dango528
    edited February 2019
    Options
    Hi JohnTube,

    Thanks for the reply. I tried out #1, but it doesn't work because I am trying to send an event by PhotonNetwork.RaiseEvent() to the other player and by the time I try to do that Photon has already been disconnected and the player has left the room. It gives a warning
    "Your event is not being sent! Check if you are in a Room and the eventCode must be less than 200"
    , and my eventCode is definitely way less than 200. I even implemented OnDisconnected() and the logs indicate that I got disconnected by DisconnectByClientLogic before I can RaiseEvent().

    As for #2, I don't have a logic for leaving the room manually.

    What are my options?
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited February 2019
    Options
    Hi @dango528,

    by the time I try to do that Photon has already been disconnected and the player has left the room
    the logs indicate that I got disconnected by DisconnectByClientLogic
    You should call RaiseEvent() before calling Disconnect(). The player is quitting the room because a call to Disconnect() is made somewhere in the code. Look in your own code for all calls to Disconnect() first and put RaiseEvent() call before it.
  • dango528
    Options
    Hi @JohnTube ,

    Sorry I must have lacked some key information. I am not calling Disconnect() manually through code, instead, it gets called automatically when I force quit the app through my device (mobile - closing the app instance) or in Unity (stopping the game in Editor). I see how if I quit the game through some exit mechanism, like an exit button or so, then I can handle the cases as usual, but that is not the case. I've also tried commenting out the this.Client.Disconnect(); line in Photon's ConnectionStatusHandler#OnApplicationQuit() to see if anything changes, but to no avail.

    Thanks!
  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    I see.
    This is rather a timing issue, a race condition of sort, or rather "script execution order" as Unity calls it.
    You can try to delay PUN scripts or make your own script run first.
    Then I invite @Tobias to give us his opinion about this.
    How can we raise an event when the application is quitting before PUN automatically calls Disconnect.
  • dango528
    Options
    Thanks for the responses @JohnTube , looking forward to Tobias' opinions :smile:
  • Tobias
    Options
    Tricky.
    We disconnect on Quit, because otherwise the Unity Editor freezes. A built client typically doesn't freeze but the disconnect makes sure that anyone in a room knows quickly that this client left.
    So, we want to disconnect on quit. On disconnect, the client discards any locally queued commands and sends only the disconnect on it's own.
    So, to send anything briefly before this happens, you have to make sure your script runs earlier than ours. Set this up with the execution order in Unity. Also, you have to write the message (RPC or RaiseEvent) and send it right away. For the latter, use `SendAllOutgoingCommands()`.
    This should work in most cases. Why just most? Because the client is still shutting down and if the message should get lost, then nobody is around to repeat it. This can't be avoided technically, unless you would wait for this message to be acknowledged (by the server, who is the receiver in this case).

    Hope that helps.


  • dango528
    Options
    Hi @Tobias ,

    I'll see what I can come up with then. For now I guess I'm stuck for a while...
    Thanks for the input!
  • dango528
    Options
    Hi @Tobias ,

    When you say make sure my script runs earlier than yours, what script specifically are you talking about? Since I saw the Client.Disconnect(); in Connection in Photon.Realtime.ConnectionHandler, I'm assuming it's that. I set the script execution order to make my script go before ConnectionHandler, but the Disconnect is still happening before OnApplicationQuit()
  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @dango528,

    In PUN2 PhotonHandler is used which extends ConnectionHandler.
  • dango528
    Options
    Hi @JohnTube , @Tobias

    I've set my Script Execution Order to this setting
    • MyScript: -90
    • Photon.Pun.PhotonHandler: 50 (Default Time)
    But I still get disconnected first before I can send an event in MyScript
    For now I guess I can set this as a limitation...

    Thanks!
  • Oddreams
    Options
    Hi @Tobias , @JohnTube
    Currently we are having this limitation and our game needs it badly. We have PlayerTTL greater than 0 and have custom disconnection management where we give the player an amount of time to reconnect.
    However we want to call OpleaveRoom with inactive false OnApplicationQuit.
    Is there a workaround for that?
  • Tobias
    Options
    OnApplicationQuit, you can't do all that much, as the process stops more or less right away.
    What you can do is to call OnLeaveRoom(false) and then SendOutgoingCommands(). Unless you have a long send queue, this will send the leave right away. But: As the app closes, there will not be a repeat should this one message get lost.