# GSM Websocket API
## Configuration
You need to have the following in your config:
```json
{
"api": {
"enabled": true,
"blacklist": [],
"ip": "0.0.0.0",
"port": 3680,
"whitelist": []
}
}
```
You can configure the users in the `users.json`.
Make sure that the passwords in the config are `sha512` hashed.
## General Architecture
There are currently three types of messages:
+ Events
+ Requests
+ Answer
### Event Message Format
```json
{
"type": "event",
"subtype": "<...>",
"data": <json_object>
}
```
### Request Message Format
```json
{
"type": "request",
"subtype": "<...>",
"id": <snowflake_number>,
"data": <json_object>
}
```
You can send any `id` which you will get back in the corresponding answer
### Answer Message Format
```json
{
"type": "answer",
"subtype": "<...>",
"id": <same_as_request_id>,
"error": 0,
"errormessage": "",
"data": <json_object>
}
```
The `"data"` object depends on the `"subtype"` (See Message Catalogue).
## General Protocol Overview
```mermaid
sequenceDiagram
participant Client
participant Server
Client ->> Server: Open Websocket Connection
Client ->>+ Server: Request: apilogin
Server ->>- Client: Answer: token
Server -->> Client: Answer: Error
loop Requests
Client ->>+ Server: Requests
Server ->>- Client: Answers
Server -->> Client: Error
end
loop Events
Server ->> Client: Event
end
```
### Connection Loss
After a connection loss, the token is valid for another 15 minutes to relogin without using the users credentials.
You will get a new token after a successful relogin.
## Error Codes
| Error | Message |
| -------- | -------- |
| 1 | request format error (`id` hardcoded to `-1`. Connection will get closed) |
| 2 | too much data for one frame |
| 3 | not logged in |
| 4 | unknown request subtype |
| 5 | wrong message data format |
| 6 | failed apilogin request |
| 7 | no permission to process request |
| 8 | (`getconfig`/`getlanguage`) error reading file |
| 9 | (`writeconfig`/`writelanguage`) error writing file |
| 10 | (`deleteconfig`/`deletelanguage`) error deleting file |
## Message Catalogue
:::info
Only the `data` object will be shown
:::
### `apilogin`
#### Request
Either `token` or `username` and `password` are null.
```json
{
"username": <string|null>,
"password": <string|null>,
"token": <string|null>
}
```
#### Answer
```json
{
"token": <string>
}
```
### `getplayers`
#### Request
```json
null
```
#### Answer
Array of all players (`Player::getPlayerInfos()`)
```json
[
{"ip": "1.2.3.4", "pid": 8 },
{"ip": "2.3.4.5", "pid": 9 }
]
```
### `getconfig`
#### Request
```json
{
"file": "filename"
}
```
#### Answer
```json
"content of file"
```
### `deleteconfig`
#### Request
```json
{
"file": "filename"
}
```
#### Answer
```json
null
```
### `writeconfig`
#### Request
```json
{
"file": "filename",
"content": "content of file"
}
```
#### Answer
```json
null
```
### `getlanguage`
#### Request
```json
{
"file": "filename"
}
```
#### Answer
```json
"content of file"
```
### `deletelanguage`
#### Request
```json
{
"file": "filename"
}
```
#### Answer
```json
null
```
### `writelanguage`
#### Request
```json
{
"file": "filename",
"content": "content of file"
}
```
#### Answer
```json
null
```
### `addtoken`
#### Request
```json
{
"group": "name of group"
}
```
#### Answer
```json
"token"
```
### `gettokens`
#### Request
```json
null
```
#### Answer
```json
{
"tokenstr": "groupname",
"token2str": "groupname"
}
```
### `deletetoken`
#### Request
```json
{
"token": "tokenstr"
}
```
#### Answer
```json
true
```
### `executeingamecommand`
#### Request
```json
{
"command": "readconfig"
}
```
#### Answer
:::info
The `data` string contains the output the user would normally get via a PM ingame.
So most of the time this will be an empty string.
:::
```json
"Command PM output"
```
### `getplugins`
#### Request
```json
null
```
#### Answer
```json
{
"plugin.name.space1": {
"information": "<...>",
"compatibility": [],
"state": {}
},
"plugin.name.space2": {
"information": "<...>",
"compatibility": [],
"state": {}
}
}
```
### `quitgsmanager`
#### Request
```json
null
```
#### Answer
```json
true
```
### `getbanlist`
#### Request
```json
null
```
#### Answer
:::info
Output of `BanHelper::getAllBans()`
:::
```json
["List of all bans"]
```
### `permissiontest`
#### Request
```json
["permission1", "permission2"]
```
#### Answer
```json
{
"permission1": true,
"permission2": false
}
```
### `getcommandpermissions`
#### Request
```json
null
```
#### Answer
```json
[
"permission1",
"permission2",
"some.other.per.mission"
]
```
### `getplayerinfo`
#### Request
```json
{
"databaseid": 5
}
```
#### Answer
```json
{
"user": "<database_row>",
"stats": "<database_row>",
"rest": "of player info from db"
}
```
### `subscribeevent`
:::info
For List of events check https://www.gsmanager.de/lexicon/entry/34-list-of-events/
<small>(07.03.2018: Status incomplete)</small>
:::
#### Request
```json
{
"name": "playerJoined"
}
```
#### Response
```json
null
```
### `unsubscribeevent`
#### Request
```json
{
"name": "playerJoined"
}
```
#### Response
```json
null
```
### `listpresetfiles`
#### Request
```json
null
```
#### Response
```json
["file1", "file2"]
```