Register for your free account! | Forgot your password?

You last visited: Today at 21:53

  • Please register to post and access all features, it's quick, easy and FREE!

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.

Reply
 
Old 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
xworldx is offline  
Old 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™ View Post
echo SendServer("","USER_COUNT",13070)

returns just 'Array' :|
You need a first core maybe (wom has it)
.Shōgun is offline  
Old 11/20/2013, 16:14   #18


 
Mr. 'Avenue™'s Avatar
 
elite*gold: 222
The Black Market: 101/0/0
Join Date: Oct 2012
Posts: 2,361
Received Thanks: 3,388
Quote:
Originally Posted by .Shōgun View Post
You need a first core maybe (wom has it)
4 Core in every Channel
Mr. 'Avenue™ is offline  
Old 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™ View Post
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
.Shōgun is offline  
Old 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.
#SoNiice is offline  
Old 11/21/2013, 07:05   #21
 
Mashkin's Avatar
 
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:
  1. players online on the core's channel
  2. players online on the channel's red empire (empire A)
  3. ... yellow empire (empire B)
  4. ... blue empire (empire C)
  5. 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.
Mashkin is offline  
Thanks
2 Users
Old 11/22/2013, 15:56   #22
 
elite*gold: 0
Join Date: Oct 2012
Posts: 111
Received Thanks: 1
Quote:
Originally Posted by Mashkin View Post
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:
  1. players online on the core's channel
  2. players online on the channel's red empire (empire A)
  3. ... yellow empire (empire B)
  4. ... blue empire (empire C)
  5. 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 ?
xworldx is offline  
Old 11/22/2013, 20:34   #23
 
Mashkin's Avatar
 
elite*gold: 44
Join Date: May 2010
Posts: 2,053
Received Thanks: 1,747
Quote:
Originally Posted by xworldx View Post
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.
Mashkin is offline  
Old 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
xworldx is offline  
Old 11/23/2013, 01:47   #25
 
Mashkin's Avatar
 
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($result215);
    
$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";

Mashkin is offline  
Thanks
1 User
Old 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
xworldx is offline  
Old 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 View Post
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:

.Shōgun is offline  
Old 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$port5))
            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(), 0strlen($api->GetBuffer()) - 1);
    
    if(empty(
$apiBuf))
    {
        echo 
"Game did not respond";
        exit;
    }
    
    echo 
$apiBuf;
ProfDrKnowsItAll is offline  
Old 11/24/2013, 04:49   #29
 
Mashkin's Avatar
 
elite*gold: 44
Join Date: May 2010
Posts: 2,053
Received Thanks: 1,747
Quote:
Originally Posted by ProfDrKnowsItAll View Post
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$port5))
            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(), 0strlen($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.
Mashkin is offline  
Old 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$port5))
            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
ProfDrKnowsItAll is offline  
Thanks
4 Users
Reply




All times are GMT +2. The time now is 21:53.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.