Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Temporary "solution" for transferring players in 0.12.1

Comments in 'Resources' started by PEMapModder, Sep 30, 2015.

  1. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    As we all know, 0.12.1 has many issues, and one of the significant ones is the malfunctioning of the FastTransfer packet - 0x1b.
    The issue is that the client does not close the session after joining another server, and so the client continues to accept data from the server. And if you explicitly kick the player on the old server, you will find that the player quits the new server as well (at least visually).

    I have worked out a temporary "solution" to this problem:
    PHP:
    // SKIPPED: code to transfer player away by sending packet, i.e. calling the FastTransfer API function.

    // find out the RakLib interface, which is the network interface that MCPE players connect with
    foreach($server->getNetwork()->getInterfaces() as $interface){
      if(
    $interface instanceof RakLibInterface){
        
    $raklib $interface;
        break;
      }
    }
    if(!isset(
    $rakLib)){
      return;
    }

    // calculate the identifier for the player used by RakLib
    $identifier $player->getAddress() . ":" $player->getPort();

    // this method call is the most important one - it sends some signal to RakLib that makes it think that the client has clicked the "Quit to Title" button (or timed out). Some RakLib internal stuff will then tell PocketMine that the player has quitted.
    $rakLib->closeSession($identifier"transfer");
  2. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    Note that doing this has a lot of side effects.

    Technically: Players still connect to your server through an open socket, and they may still send data.

    This may let you understand more clearly: Every client you transfer will DoS you. Transferring many clients is equivalent to asking them to DDoS you.
  3. TryoneLegendZzz
    Offline

    TryoneLegendZzz Active Member

    Joined:
    May 31, 2015
    Posts:
    201
    Minecraft User:
    SavionLegendZzz
    so even ddos protection has 0% help?
  4. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    Do you know what DDoS means? DDoS means to have a large number of clients connecting to a server from different sources, making your server slow down and become almsot nonfunctional. How would those so-called DDoS protection services know if they are normal clients or attackers? They are not DDoS, but they still send a lot of useless data to the server, so it is semi DDoS.
    DunxandMinecraft likes this.
  5. shoghicp
    Offline

    shoghicp Staff Member PocketMine Team

    Joined:
    Aug 22, 2013
    Posts:
    433
    Plugins:
    14
    Minecraft User:
    shoghicp
    The problem itself is in the client, so all the people asking about other server software not being buggy on transfer don't understand the problem.

    Also remember that this method is hacky and might go away (that's why it's a plugin and not a core feature) so don't base your server around this!
  6. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    A simple word "DDoS" is enough to scare 99% people away :p
    archie426 and DunxandMinecraft like this.
  7. tigerza118
    Offline

    tigerza118 Active Member

    Joined:
    Jan 31, 2015
    Posts:
    100
    Minecraft User:
    tigerza117
    Not work LOL
  8. tigerza118
    Offline

    tigerza118 Active Member

    Joined:
    Jan 31, 2015
    Posts:
    100
    Minecraft User:
    tigerza117
    Help is Full code and Phar is Fix :D
  9. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    The code I posted was already full code. And I won't post any phars, because I don't really encourage you to use it unless you know very clearly the consequences of doing so, which you most likely don't if you are unable to apply the changes yourself.
    And again, this is a temporary "solution", not a fix. This only hides the problem from your eyes, but the 80% of the problem's negative effects still exists.

    And it works. I am using it on LegionPE. If you need proof:
    https://github.com/LegionPE/LegionPE-Theta-Base/blob/master/src/legionpe/theta/BasePlugin.php#L523
    However, my code is slightly different from what you will use, so don't copy it. You can copy it, but it will surely "not work" (it is too vague to say "not work"; it can mean many things). And I won't help you fix it if you just copy LegionPE-Theta-Base.
    Read the first line of my code: // SKIPPE:eek: code to transfer players away using FastTransfer API
    Ake likes this.
  10. tigerza118
    Offline

    tigerza118 Active Member

    Joined:
    Jan 31, 2015
    Posts:
    100
    Minecraft User:
    tigerza117
    HA HA HA Thx i am noobs sorry
  11. Brutus
    Offline

    Brutus New Member

    Joined:
    Aug 31, 2015
    Posts:
    21
    Do you have any practical idea of what the size of the "DDoS attack" is?

    You say they "may still send data", do you happen to know when and how much they send? Are they sending every packet to every server they have connected to, or just occasional packets, or are you just saying that they might theoretically sometimes do it, but generally stick with their current server?
  12. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    A small scale I suppose. Every client you send assume you are still connected, so they keep sending data they expect to send. According to @shoghicp, for reasons that I don't understand, clients sometimes think that they are servers and even send chunks packets. Although they are not connected and hence packets are internally ignored, they can still significantly affect server performance if the server-to-players ratio is not high enough.

    Moreover, as clients are temporarily connected to the old server, they cannot be transferred back according to testing.
    Brutus likes this.
  13. ManiakMCPE
    Offline

    ManiakMCPE New Member

    Joined:
    Feb 6, 2015
    Posts:
    20
    Minecraft User:
    ManiakMCPE
    How do I do this? I know almost nothing about coding.
  14. FuryTacticz
    Offline

    FuryTacticz New Member

    Joined:
    Aug 31, 2015
    Posts:
    23
    Minecraft User:
    FuryTacticz
    Has anyone got this to work?
    Not working for me :/
  15. Brutus
    Offline

    Brutus New Member

    Joined:
    Aug 31, 2015
    Posts:
    21
    It does work, with the caveats that @PEMapModder stated.
  16. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    Because you don't know how to use it? The implementation in LegionPE is acceptable.
  17. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    Say that next year. You should have emphasized that when you first introduced FastTransfer :/
  18. tigerza118
    Offline

    tigerza118 Active Member

    Joined:
    Jan 31, 2015
    Posts:
    100
    Minecraft User:
    tigerza117
    It Work
    PHP:
        private function transferPlayer0(Player $player$ip$port){
            
    $packet = new TransferPacket();
            
    $packet->address $this->getHostByName($ip);
            
    $packet->port $port;
            
    $player->dataPacket($packet);
            
    $this->removePlayer($player);
            
    $this->removeOnlinePlayer($player);
            
    $this->removePlayerListData($player->getUniqueId(), [$player]);
            
    $rakLib null;
            foreach(
    $this->getServer()->getNetwork()->getInterfaces() as $interface) {
                if(
    $interface instanceof RakLibInterface) {
                    
    $raklib $interface;
                    break;
                }
            }
            if(!isset(
    $rakLib)){
                return;
            }

            
    $identifier $player->getAddress () . ":" $player->getPort();
            
    $rakLib->closeSession($identifier"transfer");
            
    $this->getServer()->removeInterface($identifier);
        }

        public function 
    removePlayer(Player $player){
            if(isset(
    $this->identifiers[$hash spl_object_hash($player)])){
                
    $identifier $this->identifiers[$hash];
                unset(
    $this->players[$identifier]);
                unset(
    $this->identifiers[$hash]);
                return;
            }
            foreach(
    $this->players as $identifier => $p){
                if(
    $player === $p){
                    unset(
    $this->players[$identifier]);
                    unset(
    $this->identifiers[spl_object_hash($player)]);
                    break;
                }
            }
        }

        public function 
    removePlayerListData(UUID $uuid, array $players null){
            
    $pk = new PlayerListPacket();
            
    $pk->type PlayerListPacket::TYPE_REMOVE;
            
    $pk->entries[] = [$uuid];
            
    Server::broadcastPacket($players === null $this->playerList $players$pk);
        }

        public function 
    removeOnlinePlayer(Player $player){
            if(isset(
    $this->playerList[$player->getRawUniqueId()])){
                unset(
    $this->playerList[$player->getRawUniqueId()]);
                
    $pk = new PlayerListPacket();
                
    $pk->type PlayerListPacket::TYPE_REMOVE;
                
    $pk->entries[] = [$player->getUniqueId()];
                
    Server::broadcastPacket($this->playerList$pk);
            }
        }
    Cr.PEMapModder
    and Guillaume351
  19. FuryTacticz
    Offline

    FuryTacticz New Member

    Joined:
    Aug 31, 2015
    Posts:
    23
    Minecraft User:
    FuryTacticz
    Yeah thanks but I got it work shortly after i commented it doesnt work lol :p
  20. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    You don't need to remove player from player list. Closing the RakLib session already disconnects the player properly.

Share This Page

Advertisement