|
You last visited: Today at 21:53
Advertisement
[HowTo] Metin2 Web API
Discussion on [HowTo] Metin2 Web API within the Metin2 PServer Guides & Strategies forum part of the Metin2 Private Server category.
11/16/2013, 14:45
|
#16
|
elite*gold: 0
Join Date: Oct 2012
Posts: 111
Received Thanks: 1
|
and how to IS_SERVER_UP for example? I try it but nothing. THX
|
|
|
11/20/2013, 15:53
|
#17
|
elite*gold: 11
Join Date: Nov 2010
Posts: 1,709
Received Thanks: 3,828
|
Quote:
Originally Posted by Mr. 'Avenue™
echo SendServer("","USER_COUNT",13070)
returns just 'Array' :|
|
You need a first core maybe (wom has it)
|
|
|
11/20/2013, 16:14
|
#18
|
elite*gold: 222
Join Date: Oct 2012
Posts: 2,361
Received Thanks: 3,388
|
Quote:
Originally Posted by .Shōgun
You need a first core maybe (wom has it)
|
4 Core in every Channel
|
|
|
11/20/2013, 17:06
|
#19
|
elite*gold: 11
Join Date: Nov 2010
Posts: 1,709
Received Thanks: 3,828
|
Quote:
Originally Posted by Mr. 'Avenue™
4 Core in every Channel
|
A first core is a core with no maps on MAP_ALLOW, there is one in each channel.
Thats how official servers are setup
|
|
|
11/20/2013, 17:20
|
#20
|
elite*gold: 0
Join Date: Feb 2010
Posts: 7,221
Received Thanks: 6,758
|
Shogun, you are wrong -lol- Avenue, $variable[0] = Alle Reiche, 1 = Rot, 2 = Gelb, 3 = Blau - Du musst es halt als Array ansprechen. Du könntest auch var_dump($array) machen und schon siehst du alle Inhalte.
|
|
|
11/21/2013, 07:05
|
#21
|
elite*gold: 44
Join Date: May 2010
Posts: 2,053
Received Thanks: 1,747
|
WOW, years after Infinity released his API tool there finally appears a public guide how to use it for a good purpose.
Seriously, why are people so dumb to not know this?
About USER_COUNT:
- players online on the core's channel
- players online on the channel's red empire (empire A)
- ... yellow empire (empire B)
- ... blue empire (empire C)
- players online on current game core (only this core, not the whole channel)
I tested this and the resulting numbers make sense like that (e.g. 2.+ 3.+ 4. = 1.; sum of 5. of all channel cores = 1. of the channel).
For NOTICE you should take into account to escape special characters (like umlauts ä ö ü etc.).
RELOAD behaves similar to the in-game command (with parameter q, p, a etc.).
I know about a server managemant script written years ago that used the API for RELOAD actions and I currently use a PHP CLI script for easy management as well as the USER_COUNT call for live statistics.
If you ever think about writing a library then you should do so in PHP because you will be able to use it for both command line (CLI) and website scripts.
|
|
|
11/22/2013, 15:56
|
#22
|
elite*gold: 0
Join Date: Oct 2012
Posts: 111
Received Thanks: 1
|
Quote:
Originally Posted by Mashkin
WOW, years after Infinity released his API tool there finally appears a public guide how to use it for a good purpose.
Seriously, why are people so dumb to not know this?
About USER_COUNT:
- players online on the core's channel
- players online on the channel's red empire (empire A)
- ... yellow empire (empire B)
- ... blue empire (empire C)
- players online on current game core (only this core, not the whole channel)
I tested this and the resulting numbers make sense like that (e.g. 2.+ 3.+ 4. = 1.; sum of 5. of all channel cores = 1. of the channel).
For NOTICE you should take into account to escape special characters (like umlauts ä ö ü etc.).
RELOAD behaves similar to the in-game command (with parameter q, p, a etc.).
I know about a server managemant script written years ago that used the API for RELOAD actions and I currently use a PHP CLI script for easy management as well as the USER_COUNT call for live statistics.
If you ever think about writing a library then you should do so in PHP because you will be able to use it for both command line (CLI) and website scripts.
|
thank you .. and how to IS_SERVER_UP ?
|
|
|
11/22/2013, 20:34
|
#23
|
elite*gold: 44
Join Date: May 2010
Posts: 2,053
Received Thanks: 1,747
|
Quote:
Originally Posted by xworldx
thank you .. and how to IS_SERVER_UP ?
|
Well, for a core that is online the call will return "YES" (I guess the opposite would be "NO").
I believe the core is marked online as long as it is not marked offline with ingame oder API command "/shutdown" or "SHUTDOWN".
I think I also saw an option for CONFIG files to mark a core as offline right from the start but don't know what its purpose could be.
However, I've never seen an way to switch an "offline" core as online again without killing and restarting it.
|
|
|
11/22/2013, 21:15
|
#24
|
elite*gold: 0
Join Date: Oct 2012
Posts: 111
Received Thanks: 1
|
okok.. i try echo SendServer("","IS_SERVER_UP ",13000)
but nothing.. haw to do it? thx
|
|
|
11/23/2013, 01:47
|
#25
|
elite*gold: 44
Join Date: May 2010
Posts: 2,053
Received Thanks: 1,747
|
I suggest you replace
PHP Code:
if ($result2 == "OK") { echo "OK!!\n";
} else { $count = substr($result2, 15); $count = explode(' ', $count); //$count[0] = total users online //$count[1] = users in red kingdom online //$count[2] = users in yellow kingdom online //$count[3] = users in blue kingdom online return $count;
}
with
PHP Code:
if ($type == "USER_COUNT") { $count = trim($result2); $count = explode(' ', $count); //$count[0] = users on channel online //$count[1] = users in red kingdom online //$count[2] = users in yellow kingdom online //$count[3] = users in blue kingdom online //$count[4] = users on core online return $count; } else { return "$result2\n"; }
|
|
|
11/23/2013, 16:24
|
#26
|
elite*gold: 0
Join Date: Oct 2012
Posts: 111
Received Thanks: 1
|
hmm I try it and only UNKNOWN
|
|
|
11/23/2013, 16:41
|
#27
|
elite*gold: 11
Join Date: Nov 2010
Posts: 1,709
Received Thanks: 3,828
|
Quote:
Originally Posted by xworldx
hmm I try it and only UNKNOWN
|
UNKNOWN means the command succeeded and is the expected response (don't ask me why, it's YMIR logic). Look at this:
|
|
|
11/23/2013, 17:27
|
#28
|
elite*gold: 0
Join Date: Nov 2013
Posts: 12
Received Thanks: 23
|
If you send it right (the IS_SERVER_UP) command the server responds with YES or NO.
And it is easier to use this code:
SocketConnection.class.php
PHP Code:
<?php
class SocketConnection { private $m_socket; private $m_recv_buf; public function __construct() { $this->m_socket = 0; $this->m_recv_buf = ""; }
public function Connect($host, $port, $timeout) { $this->m_socket = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$this->m_socket) { echo(sprintf("%s (%d)<br>\n", $errstr, $errno)); return false; }
return true; }
public function Recv($len) { $this->m_recv_buf = fread($this->fp, $len); }
public function Send($buf) { fwrite($this->m_socket, $buf); } public function GetRecvBuf() { return $this->m_recv_buf; }
}
GameConnector.class.php
PHP Code:
<?php require_once("SocketConnection.class.php");
class GameConnector { private $m_socketConnector;
public function __construct($host, $port) { $this->m_socketConnector = new SocketConnection;
if (!$this->m_socketConnector->Connect($host, $port, 5)) return false;
$this->m_socketConnector->Recv(32);
$recvBuf = $this->m_socketConnector->GetRecvBuf() if (ord($recvBuf[0]) != 253) { echo("GameConnector does not handle this packet!"); return false; } }
public function Send($str) { $this->m_socketConnector->Send($str."\n"); $this->m_socketConnector->Recv(64); }
public function GetBuffer() { return $this->m_socketConnector->GetRecvBuf() } }
example:
PHP Code:
<?php include "GameConnector.class.php";
$api = new GameConnector($host, $port); $api->Send("@USER_COUNT"); $apiBuf = substr($api->GetBuffer(), 0, strlen($api->GetBuffer()) - 1); if(empty($apiBuf)) { echo "Game did not respond"; exit; } echo $apiBuf;
|
|
|
11/24/2013, 04:49
|
#29
|
elite*gold: 44
Join Date: May 2010
Posts: 2,053
Received Thanks: 1,747
|
Quote:
Originally Posted by ProfDrKnowsItAll
If you send it right (the IS_SERVER_UP) command the server responds with YES or NO.
And it is easier to use this code:
SocketConnection.class.php
PHP Code:
<?php
class SocketConnection { private $m_socket; private $m_recv_buf; public function __construct() { $this->m_socket = 0; $this->m_recv_buf = ""; }
public function Connect($host, $port, $timeout) { $this->m_socket = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$this->m_socket) { echo(sprintf("%s (%d)<br>\n", $errstr, $errno)); return false; }
return true; }
public function Recv($len) { $this->m_recv_buf = fread($this->fp, $len); }
public function Send($buf) { fwrite($this->m_socket, $buf); } public function GetRecvBuf() { return $this->m_recv_buf; }
}
GameConnector.class.php
PHP Code:
<?php require_once("SocketConnection.class.php");
class GameConnector { private $m_socketConnector;
public function __construct($host, $port) { $this->m_socketConnector = new SocketConnection;
if (!$this->m_socketConnector->Connect($host, $port, 5)) return false;
$this->m_socketConnector->Recv(32);
$recvBuf = $this->m_socketConnector->GetRecvBuf() if (ord($recvBuf[0]) != 253) { echo("GameConnector does not handle this packet!"); return false; } }
public function Send($str) { $this->m_socketConnector->Send($str."\n"); $this->m_socketConnector->Recv(64); }
public function GetBuffer() { return $this->m_socketConnector->GetRecvBuf() } }
example:
PHP Code:
<?php include "GameConnector.class.php";
$api = new GameConnector($host, $port); $api->Send("@USER_COUNT"); $apiBuf = substr($api->GetBuffer(), 0, strlen($api->GetBuffer()) - 1); if(empty($apiBuf)) { echo "Game did not respond"; exit; } echo $apiBuf;
|
Well, I'm not exactly sure why I would want to wrap the socket functions in a class.
It's everyone's personal choice. I did write a class for the API but used the socket functions directly.
Sidenote: You can replace your third substr argument (the strlen(...) - 1 thing) with " -1", since a negative length will do exactly the same as the calculation you are doing.
|
|
|
11/24/2013, 10:41
|
#30
|
elite*gold: 0
Join Date: Nov 2013
Posts: 12
Received Thanks: 23
|
I like wrappers that's my thing
Here a complete working example:
PHP Code:
<?php
class SocketConnection { private $m_socket; private $m_recv_buf; public function __construct() { $this->m_socket = 0; $this->m_recv_buf = ""; }
public function Connect($host, $port, $timeout) { $this->m_socket = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$this->m_socket) { echo(sprintf("%s (%d)<br>\n", $errstr, $errno)); return false; }
return true; }
public function Recv($len) { $this->m_recv_buf = fread($this->m_socket, $len); }
public function Send($buf) { fwrite($this->m_socket, $buf); } public function GetRecvBuf() { return $this->m_recv_buf; }
}
class GameConnector { private $m_socketConnector;
public function __construct($host, $port) { $this->m_socketConnector = new SocketConnection;
if (!$this->m_socketConnector->Connect($host, $port, 5)) return false;
$this->m_socketConnector->Recv(32);
$recvBuf = $this->m_socketConnector->GetRecvBuf(); if (ord($recvBuf[0]) != 253) { echo("GameConnector does not handle this packet!"); return false; } }
public function Send($str) { $this->m_socketConnector->Send("@".$str."\n"); $this->m_socketConnector->Recv(64); }
public function GetBuffer() { return $this->m_socketConnector->GetRecvBuf(); } }
$host = "192.162.0.1"; $port = 13000; $api = new GameConnector($host, $port); $api->Send("MyApiKeyIsSecureLol"); $api->Send("USER_COUNT"); //$api->Send("IS_SERVER_UP"); $apiBuf = substr($api->GetBuffer(), 0, -1); if(empty($apiBuf)) { echo "Game did not respond"; exit; } if(is_numeric($apiBuf[0])) { $userCount = explode(" ", $apiBuf); echo sprintf("Total[%d] %d / %d / %d (this server %d)", $userCount[0], $userCount[1], $userCount[2], $userCount[3], $userCount[4]); exit; } if($apiBuf=="UNKNOWN") echo "Command send and executed no custom response"; else echo $apiBuf;
Changes:
Added packet header to send function, at the moment we don't want to send other packets.
Fixed various bugs
Changed substr <- Thanks to Mashkin
Added user count formatting
Added check for no custom response
|
|
|
All times are GMT +2. The time now is 21:53.
|
|