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...
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 [-1, NULL];} socket_set_timeout($sock, 0, 500000); if([email protected]fwrite($sock, "\xFE\xFD\x09\x10\x20\x30\x40\xFF\xFF\xFF\x01")){return [0, NULL];} $challenge = fread($sock, 1400); if(!$challenge){return [0, NULL];} $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 [0, NULL];} $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 == 0 ? $type = 1 : $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()); }}
$this->SSS->debug is just a bool (For enabling of debug ) $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]
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.
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.
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.
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