Plus Exchange

From EQdkp Plus
Jump to: navigation, search


What is Plus Exchange (pex)

Plus Exchange is a class that provides you the possibility to communicate with your EQdkp Plus using REST. It's possible to signup for Raids or getting a list of upcoming events.

Creating an own exchange-module

Every exchange-module must have an unique name!

Sample exchange-module

<?php
if (!defined('EQDKP_INC')){
	die('Do not access this file directly.');
}

if (!class_exists('exchange_check_session')){
	class exchange_check_session {

		public function post_check_session($params, $arrBody){
			$status = 0;
			if (isset($arrBody['sid'])){
				$result = $this->user->check_session($arrBody['sid']);
				if ($result != ANONYMOUS){
					$status = 1;
				} else {
					$status = 0;
				}
			}
			return array('valid' => $result);
		}
	}
}
?>

Our Example has the Name "check_session". The class has to be named "exchange_", followed by the module, name, e.g. "exchange_check_session".

You could make an REST-Request with 4 different methods:

  • GET - just receive data, don't use when sending additional data like XML
  • POST - update data, used when sendig additional data liks XML, as seen in the example above
  • PUT - insert new data
  • DELETE - delete data

For each of this four methods, you can create on own function, e.g. "post_check_session" if you want to use the POST-Method, or "get_check_session" when using the GET-Method, ... $params will contain all GET- and POST-Parameter, $body contains the body, like an XML-Feed with data (not possible when using a GET-Method). Returnvalue is an array containing the data you want to send back. If you want to send back an error, use "return $pex->error('Your error message');".

Folder

Put all exchange-modules into the folder
root/core/exchange/
or if you have a plugin, into
root/plugins/PLUGINNAME/exchange/

Perform Methods

To perform Methods, you need the following information:

  • URL to the user's EQdkp Plus, e.g. http://domain.com/eqdkp07/. Split it into Host (= Domain, without protocol and path)and the Path, e.g. Host (<<HOST>>): domain.com, Path (<<Path>>): /eqdkp07/. Normally, a REST-Class would do that for you.
  • The Name of the exchange-module, in this example "rest_dummy"
Index Description
Name rest_dummy
Description Just an example, it's not implemented ;)
Method POST
URL-Params
  • dummyid (integer)
Sample Call
POST <<PATH>>/api.php?function=rest_dummy&dummyid=42 HTTP/1.1
Host: <<HOST>>
Content-Length: 53
Content-Type: application/atom+xml; charset=UTF-8
Connection: Close

<request><text>This is a dummy Text</text></request>
Sample Return on success
<?xml version="1.0" encoding="utf-8"?>
<response>
  <status>1</status>
  <message>Everything ok</message>
</response>
Sample Return if an error occurs
<?xml version="1.0" encoding="utf-8"?>
<response>
  <status>0</status>
  <error>Error Message</error>
</response>

You will always get an status tag, so you can always check if an error occured or not.

Output Format

Default output format is XML. If you want JSON, use URL-Parameter format=json.

Sample Call
GET <<PATH>>/api.php?function=user_chars&format=json HTTP/1.1
Host: <<HOST>>
Connection: Close
Sample Return
{"chars":{"char:79":{"id":79,"name":"Kultschack","main":1,"class":"4","classname":"Magier","race":"10","racename":"Blutelf","roles":{"role:3":{"id":3,"name":"DD Fernkampf","default":0}}},"char:114":{"id":114,"name":"Bluebellow","main":0,"class":"1","classname":"Todesritter","race":"5","racename":"Troll","roles":{"role:2":{"id":2,"name":"Tank","default":0},"role:4":{"id":4,"name":"DD Nahkampf","default":0}}}},"status":1}

Also, LUA format is available.

Sample Call
GET <<PATH>>/api.php?function=user_chars&format=lua HTTP/1.1
Host: <<HOST>>
Connection: Close
Sample Return
response = {["chars"] = {[1] = {["id"] = "1",["name"] = "aaaa",["name_export"] = "aaaa-Antonidas",["main"] = "1",["class"] = "1",["classname"] = "Todesritter",["roles"] = {[2] = {["id"] = "2",["name"] = "Tank",["default"] = "0"},[4] = {["id"] = "4",["name"] = "Melee",["default"] = "1"}},["raidgroups"] = {[1] = {["id"] = "1",["name"] = "Default",["default"] = "1",["color"] = "#000000",["status"] = "1"}},["profiledata"] = {["faction"] = "",["race"] = "2",["class"] = "1",["talent1"] = "0",["talent2"] = "0",["guild"] = "",["servername"] = "Antonidas",["gender"] = "male",["level"] = "0",["health_bar"] = "0",["second_bar"] = "0",["second_name"] = "rage",["prof1_name"] = "trade_alchemy",["prof1_value"] = "0",["prof2_name"] = "trade_alchemy",["prof2_value"] = "0"}},[2] = {["id"] = "2",["name"] = "Bbbbb",["name_export"] = "Bbbbb-Maj'Dul",["main"] = "0",["class"] = "",["classname"] = "Unbekannt",["roles"] = {},["raidgroups"] = {[1] = {["id"] = "1",["name"] = "Default",["default"] = "1",["color"] = "#000000",["status"] = "1"}},["profiledata"] = {}},[3] = {["id"] = "3",["name"] = "ccccc",["name_export"] = "ccccc-Maj'Dul",["main"] = "0",["class"] = "",["classname"] = "Unbekannt",["roles"] = {},["raidgroups"] = {[1] = {["id"] = "1",["name"] = "Default",["default"] = "1",["color"] = "#000000",["status"] = "1"}},["profiledata"] = {}}},["status"] = "1"}

Authentification Functions

Login-Flow (until 2.2)

Please note that since 2.3 the API access is only possible with the API Key method.

Exchange login flow.jpg

  • User has to insert his Username and Passwort
  • The App get's the User-Salt from the EQdkp Plus
  • You create with the Salt and the given Password a sha512-Hash which can be saved on the client
  • User-Login with Username and saved hash
  • You'll get an session-ID and a date until the session is valid and has to be renewed
  • With this session-ID, you can use the exchange-functions like posting a shout

Getting Salt

Index Description
Name get_salt
Description Returns the user's salt
Method POST
URL-Params none
XML-Data
  • user (string; Username)
Sample Call
POST <<PATH>>/api.php?function=get_salt HTTP/1.1
Host: <<HOST>>
Content-Length: 36
Content-Type: application/atom+xml; charset=UTF-8
Connection: Close
 
<request><user>root</user></request>
Sample Return
<?xml version="1.0" encoding="utf-8"?>
<response><status>1</status><salt>ZjU4MzYxYTMxMzA2MzI1OTQwODg5ZGE=</salt></response>
Error Return
<?xml version="1.0" encoding="utf-8"?>
<response><status>0</status><error>user not found</error></response>

The salt is returned base64-encodet, so you've to decode it. With the encoded salt, you can create the hash with following method:

$hash = hash('sha512', $salt.$password);

This Hash can be saved on the client, but never the clean password!!!

Login

Index Description
Name login
Description User-Login
Method POST
URL-Params none
XML-Data
  • user (string; Username)
  • password (string; hashed password, NOT clean password!)
Sample Call
POST <<PATH>>/api.php?function=login HTTP/1.1
Host: <<HOST>>
Content-Length: 89
Content-Type: application/atom+xml; charset=UTF-8
Connection: Close
 
<request><user>root</user><password>96917805fd060e3766a9a1b834639d35</password></request>
Sample Return
<?xml version="1.0" encoding="utf-8"?>
<response><status>1</status><sid>1f93fcfb4f2447c5c50f851be2269ba</sid><end>1279053414</end></response>
Error Return
<?xml version="1.0" encoding="utf-8"?>
<response><status>0</status><error>access denied</error></response>

Session-Check

To check if a session is valid and you user is logged in, use this Function.

Index Description
Name check_session
Description Checks if a given Session-ID is valid, means if User is logged in.
Method POST
URL-Params none
XML-Data
  • sid (string;)
Sample Call
POST <<PATH>>/api.php?function=check_session HTTP/1.1
Host: <<HOST>>
Content-Length: 61
Content-Type: application/atom+xml; charset=UTF-8
Connection: Close
 
<request><sid>1f93fcfb4f2447c5c50f851be2269ba</sid></request>
Sample Return

Returns 1 is user is logged in (that means session for this user is still active), or 0 if User is Guest.

<?xml version="1.0" encoding="utf-8"?>
<response><status>1</status><valid>1</valid></response>

Logout

Index Description
Name logout
Description Destroys a given session
Method POST
URL-Params none
XML-Data
  • sid (string; The Session you want to destroy)
Sample Call
POST <<PATH>>/api.php?function=logout HTTP/1.1
Host: <<HOST>>
Content-Length: 61
Content-Type: application/atom+xml; charset=UTF-8
Connection: Close
 
<request><sid>1f93fcfb4f2447c5c50f851be2269ba</sid></request>
Sample Return
<?xml version="1.0" encoding="utf-8"?>
<response><status>1</status><result>1</result></response>
Error Return
<?xml version="1.0" encoding="utf-8"?>
<response><status>0</status><error>no sid given</error></response>

Using API Keys (since 2.1)

Since EQdkp Plus 2.1, accessing the api.php is now possible with API Tokens. There is one Core API Token which has access to almost every exchange module (except the ones where a User is needed, e.g. raid signup). Also, every user has an own API Token. With these tokens, the whole Login process for Plus Exchange is not neccessary anymore.

You can pass the Tokens by two ways: Pass them as a parameter atoken and atype:

.../api.php?function=points&atoken=5e4e4b620d4b2afaec7b6192472f81b9bddb592a1914589c&atype=api

or add them as a Request Header:

X-Custom-Authorization: token=5e4e4b620d4b2afaec7b6192472f81b9bddb592a1914589c&type=api

Type is api if it's the Core-Token, and user if its an user Token. The Core-Token is available for Superadmins at the Data-Export-Page in ACP.

Core Exchange Modules

The Exchange Modules are divided into read and write modules. Read modules can need authentication, write modules require authentication.

Read Modules

All core read modules can be found here: /Read

Write Modules

All core read modules can be found here: /Write

Plugin Exchange Modules

List Shouts

Index Description
Name shoutbox_list
Description Returns a list of the latest shouts
Plugin Shoutbox
Method GET
URL-Params
  • s (Session-ID <<SID>>)
  • number (optional; integer; default: 10)
  • sort (optional; string desc/asc; default: asc )
Sample Call
GET <<PATH>>/api.php?function=shoutbox_list&number=20&sort=desc&s=<<SID>> HTTP/1.1
Host: <<HOST>>
Connection: Close
Sample Return
<?xml version="1.0" encoding="utf-8"?>
<response>
  <entries>
    <entry>
      <id>1</id>
      <member_id>79</member_id>
      <user_id>1</user_id>
      <name>Kàltschack</name>
      <text>&lt;p&gt;Test&lt;/p&gt;</text>
      <date>2011-07-24 14:30</date>
      <timestamp>1309797805</timestamp>
    </entry>
    <entry>
      <id>2</id>
      <member_id>79</member_id>
      <user_id>1</user_id>
      <name>Kàltschack</name>
      <text>&lt;p&gt;test&lt;/p&gt;</text>
      <date>2011-07-24 14:30</date>
      <timestamp>1309797805</timestamp>
    </entry>
    <entry>
      <id>3</id>
      <member_id>79</member_id>
      <user_id>1</user_id>
      <name>Kàltschack</name>
      <text>&lt;p&gt;test&lt;/p&gt;</text>
      <date>2011-07-24 14:30</date>
      <timestamp>1309797805</timestamp>
    </entry>
    <entry>
      <id>4</id>
      <member_id>79</member_id>
      <user_id>1</user_id>
      <name>Kàltschack</name>
      <text>&lt;p&gt;Das ist eine Testnachricht&lt;/p&gt;</text>
      <date>2011-07-24 14:30</date>
      <timestamp>1309797805</timestamp>
    </entry>
    <entry>
      <id>5</id>
      <member_id>79</member_id>
      <user_id>1</user_id>
      <name>Kàltschack</name>
      <text>&lt;p&gt;&lt;img alt=";)" src="http://localhost/web/eqdkp07/libraries/jquery/core/images/editor/icons/wink.png" /&gt; &lt;img alt=":)" src="http://localhost/web/eqdkp07/libraries/jquery/core/images/editor/icons/happy.png" /&gt; :-) ? &amp;&lt;/p&gt;</text>
      <date>2011-07-24 14:30</date>
      <timestamp>1309797805</timestamp>
    </entry>
  </entries>
  <status>1</status>
</response>

If Shoutboxes uses only user-IDs, member_id will contain -1.

Add Shout

Index Description
Name shoutbox_add
Description Add a Shout
Plugin Shoutbox
Method POST
URL-Params
  • s (Session-ID <<SID>>)
XML-Data
  • text (string; Text you want to shout)
  • charid (integer; ID of user's char)

Sample Call
POST <<PATH>>/api.php?function=shoutbox_add&s=<<SID>> HTTP/1.1
Host: <<HOST>>
Content-Length: 66
Content-Type: application/atom+xml; charset=UTF-8
Connection: Close
<request>
	<charid>18</charid>
	<text>Testshout</text>
</request>
Sample Return
<response>
  <status>1</status>
</response>

Testing Client for REST

<?php

$xml = '<request><user>root</user><password>96917805fd060e3766a9a1b834639d35</password></request>';
	
	$fp = fsockopen("localhost", 80, $errno, $errstr, 30);
	if (!$fp) {
    	    return array(false, "$errstr ($errno)");		
	} else {
		$out = "POST /web/eqdkp07/api.php?function=login HTTP/1.1\r\n";
		$out .= "Host: localhost\r\n";
		$out .= "Content-Length: ".strlen($xml)."\r\n";
		$out .= "Content-Type: application/atom+xml; charset=UTF-8\r\n";
		$out .= "Connection: Close\r\n\r\n";
		$out .= $xml;
		$return = "";
		fwrite($fp, $out);
		while (!feof($fp)) {
			$return .= fgets($fp);
		}
		fclose($fp);
	}
	
	var_dump($return);
?>