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

Best method to set online players in multiple servers

Comments in 'Plugin Development' started by AndrewBit, Jul 10, 2016.

  1. AndrewBit
    Offline

    AndrewBit Notable Member

    Joined:
    Jun 18, 2015
    Posts:
    435
    Minecraft User:
    AndrewBit4
    What's the best method to get online players in other server?
    I was thinking in use MySQL to store online players in all servers, but Idk if this is a good idea...
  2. Tim // robske Büba
    Offline

    Tim // robske Büba Notable Member

    Joined:
    Feb 26, 2014
    Posts:
    606
    Minecraft User:
    robske_110
    apart from saving the player stats the only way i know is suing the query like my banner:
    http://robskebueba.no-ip.biz/Banner...=robskebueba.no-ip.biz&port=3114&name=Offline
    Whatever, you have to use a async task if you don't want 500ms lag spikes on the main thread:
    This is code i have written for server signs wich displayed some stats: (Lol private plugin i don't care)
    ServerSignStats AsyncTask:
    PHP:
    class SSSAsyncTaskCaller extends PluginTask{
       public function 
    __construct(Main $main$parent){
         
    parent::__construct($main);
         
    $this->server $parent->server;
         
    $this->SSS $parent;
       }
      
       public function 
    onRun($currentTick){
         
    $this->server->SSS $this->SSS;
         
    $this->server->getScheduler()->scheduleAsyncTask(new SSSAsyncTask($this->SSS->doCheckServers$this->SSS->debug));
       }
    }

    class 
    SSSAsyncTask extends AsyncTask{
      private 
    $serverFINALdata;
      private 
    $doCheckServer;

      public function 
    __construct($doCheckServers$debug){
        
    $this->doCheckServer $doCheckServers;
        
    $this->debug $debug;
      }

      private function 
    doQuery($ip$port){
        echo(
    "doQuery:\n");
      
    $sock = @fsockopen("udp://".$ip,$port);
      if(!
    $sock){return [-1NULL];}
      
    socket_set_timeout($sock0500000);
      if([email protected]
    fwrite($sock"\xFE\xFD\x09\x10\x20\x30\x40\xFF\xFF\xFF\x01")){return [0NULL];}
      
    $challenge fread($sock1400);
      if(!
    $challenge){return [0NULL];}
      
    $challenge substr(preg_replace("/[^0-9\-]/si"""$challenge ), 1);
      
    $query sprintf(
      
    "\xFE\xFD\x00\x10\x20\x30\x40%c%c%c%c\xFF\xFF\xFF\x01",
      (
    $challenge >> 24),
      (
    $challenge >> 16),
      (
    $challenge >> 8),
      (
    $challenge >> 0)
      );
      if([email protected]
    fwrite($sock$query)){return [0NULL];}
      
    $response = array();
      for(
    $x 0$x 2$x++){
      
    $response[] = @fread($sock,2048);
      }
        if(
    $this->debug){
        
    var_dump($response);#
      
    }
      
    $response implode($response);
      
    $response substr($response,16);
      
    $response explode("\0",$response);
        if(
    $this->debug){
            
    var_dump($response);#
        
    }
      
    array_pop($response);
      
    array_pop($response);
      
    array_pop($response);
      
    array_pop($response);
      
    $return = [];
      
    $type 0;
        if(
    $this->debug){
          
    var_dump($response);#
      
    }
      foreach (
    $response as $key){
      if (
    $type == 0$val $key;
      if (
    $type == 1$return[$val] = $key;
      
    $type == $type $type 0;
        }  
          return [
    1$return];
        echo(
    "DoQueryEnd\n");
      }

      public function 
    onRun(){
        echo(
    "DoCheckServer:\n");
        if(
    $this->debug){
          
    var_dump($this->doCheckServer);#
          
    }
        foreach(
    $this->doCheckServer as $server){
          
    $doCheck $server[1];
          if(
    $doCheck){
            
    $ip $server[0];
            
    $deParsedIP $ip[0];
            
    $port $ip[1];
            
    $return $this->doQuery($deParsedIP$port);
            
    $returnState $return[0];
            
    $queryResult $return[1];
            
    $serverData = [];
            echo(
    "returnState:\n");
            
    var_dump($returnState);
            switch(
    $returnState){
              case -
    1;
                
    $serverData[2] = false;
                break;
              case 
    0:
                  
    $serverData[2] = false;
              break;
              case 
    1:
              
    $serverData[0] = [$queryResult['numplayers'], $queryResult['maxplayers']];
              
    $serverData[1] = $queryResult['hostname'];
                
    $serverData[2] = true;
            }
            
    $serverFINALdata[$deParsedIP.$port] = $serverData;
            
    $this->setResult($serverFINALdata);
          }
        }
        echo(
    "\n");
      }

      public function 
    onCompletion(Server $server){
        
    $server->SSS->asyncTaskCallBack($this->getResult());
      }
    }
  3. Tim // robske Büba
    Offline

    Tim // robske Büba Notable Member

    Joined:
    Feb 26, 2014
    Posts:
    606
    Minecraft User:
    robske_110
    $this->SSS->debug is just a bool (For enabling of debug :p)
    $this->SSS->doCheckServers is an array:
    [[$IP, $port], $doCheck]
    The results looks like this (array):
    $ip.$port => [[$currentPlayers, $maxplayers], $modt, $gotData]
    999.999.999.9991111 => [[10, 50], "MODT", true] or
    999.999.999.9991111 => [NULL, NULL, false]
    Last edited: Jul 10, 2016
  4. Gamecrafter
    Offline

    Gamecrafter

    Joined:
    Nov 20, 2014
    Posts:
    978
    Plugins:
    9
    Storing it in a database would be the preferred way if you had many servers that needed to query the same server(s) over and over again. Why: you would only need to read data sent from server that is being queried once and then store it, then you can have your plugins select it from the database. But what if I only have one server, and I need to query only one server? Well, don't use a database and handle it locally.
  5. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    I think it would be the best if you write a CGI (Common Gateway Interface) that connects your servers (and probably use an SQL database behind it). This gives you more security, flexibility and performance, especially when it comes to temporary data (e.g. data sending among servers or data that last for a limited period of time).

    Note that "performance" refers to the actual operations, but not the increased network latency among queries. For example, a CGI can hold data temporarily in its own memory without saving in files, leading to an overall increase in the machine's performance. Network latency is not considered, since the time between query request and response should not be part of the main thread, but silently waiting aside for a response.
  6. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    I think it would work better if you start a new AsyncTask immediately at the tick/half-tick after the previous one ends. For example, fire a new AsyncTask in the asyncTaskCallBack function.
  7. Tim // robske Büba
    Offline

    Tim // robske Büba Notable Member

    Joined:
    Feb 26, 2014
    Posts:
    606
    Minecraft User:
    robske_110
    Well, that is up to you :)
    And yep that would be better, i actually check if the previous asynctask has returned sth before calling out a new one

Share This Page

Advertisement