Disconnect Players before connecting them to other servers.

Discussion in 'BungeeCord Help' started by Explode, Jun 30, 2016.

  1. Hey there!

    For example I have the servers 'Lobby' and 'PVP' and I like to save the player's stats in a database when the player connects back to the Lobby BEFORE my Lobby-Plugin attempts to fetch the player's stats from the database.

    But in the end that process is reversed and the Lobby-Plugin fetches the old data from the database (at the Join Event) before the PVP Plugin saves the new data in the database (at the Quit Event).

    Is there any way to fix that problem?
    Thank you in advance
     
  2. Bump, also having the same issue, I already tried disconnecting the player from the previous server before connecting it to the new server in the ServerConnectEvent, but it kicks the player with "[Proxy] Lost connection to the server", kicking in the ServerConnectedEvent doesn't change anything because the player is already connected to the new server.

    I think the only way is by moving the player to another temp server before moving to the new one.
     
  3. Oh, okay, I found a (very hacky) solution!

    You need to override the player DownstreamBridge and add a check to not kick the player when the old server is obsolete.

    Code (Text):
        @EventHandler
        public void onSwitch1(ServerConnectEvent e) {
            System.out.println("Overriding Downstream #2");
            ProxyServer bungee = getProxy();
            UserConnection user = (UserConnection) e.getPlayer();
            ServerConnection server = user.getServer();
            ChannelWrapper ch = server.getCh();

            CustomBridge bridge = new CustomBridge(bungee, user, server);
            ch.getHandle().pipeline().get(HandlerBoss.class).setHandler(bridge);
         
            System.out.println("Dropping connection NOW");
            e.getPlayer().getServer().disconnect("TempKick");
            System.out.println("small delay because why not");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    Code (Text):
    package com.mrpowergamerbr.bungeetest.net;

    import net.md_5.bungee.ServerConnection;
    import net.md_5.bungee.UserConnection;
    import net.md_5.bungee.api.ProxyServer;
    import net.md_5.bungee.api.event.ServerDisconnectEvent;
    import net.md_5.bungee.connection.DownstreamBridge;
    import net.md_5.bungee.netty.ChannelWrapper;

    public class CustomBridge extends DownstreamBridge {

        private final ProxyServer bungee;
        private final UserConnection user;
        private final ServerConnection server;

        public CustomBridge(ProxyServer bungee, UserConnection user, ServerConnection server) {
            super(bungee, user, server);
            this.bungee = bungee;
            this.user = user;
            this.server = server;
        }

        @Override
        public void disconnected(ChannelWrapper channel) throws Exception
        {
            // We lost connection to the server
            /* server.getInfo().removePlayer( user );
            if ( bungee.getReconnectHandler() != null )
            {
                bungee.getReconnectHandler().setServer( user );
            }

            if ( !server.isObsolete() )
            {
                user.disconnect( bungee.getTranslation( "lost_connection" ) );
            } */

            ServerDisconnectEvent serverDisconnectEvent = new ServerDisconnectEvent( user, server.getInfo() );
            bungee.getPluginManager().callEvent( serverDisconnectEvent );
        }
    }
     
    However yes, this is hacky, it just waits 100 millis before connecting to the new server, you probably shouldn't do this... at all.
     
  4. Bump. I also have this problem
     
  5. You can't do too much to be honest.

    You have some solutions:

    1. On join, make the server send to BungeeCord "hey BungeeCord, when this player switches server, please set up a database lock for me?", and when the player leaves the server, BungeeCord automatically sets a "isLocked = true" for that player before connecting to the server, and, when the player connects to the new server, your code waits the lock to be free (because the old server will remove the lock on quit) and then proceeds to load the data from the database. I'm doing this way.

    2. On join, make the server send to BungeeCord "hey BungeeCord, when this player switches server, wait until I say "ok" to you", and when the player leaves the server, a "while (condition) { Thread.sleep(50); }" happens until the old server sends "okay, now you can switch the player". You will need to edit the DownstreamBridge to remove the "[Proxy] Lost connection to server" kick.

    3. On join, create a arbitrary delay on server switch, this has a race condition but doesn't require any set ups on the servers. You will need to edit the DownstreamBridge to remove the "[Proxy] Lost connection to server" kick.