owned this note
owned this note
Published
Linked with GitHub
# かこみますネットワークプロトコルを決めようの会
:::warning
ここに書いてある情報は開発中のため、変更される恐れがあります。
:::
## 使用するプロトコル
全国高等専門学校第30 回プログラミングコンテストで使われた回答システムを参考に製作
参考ページ
[競技部門・データ書式に関する情報を公開しました](http://www.procon.gr.jp/?p=76334)
[簡易回答システムを公開しました!](http://www.procon.gr.jp/?p=76395)
## エンドポイント
ここに書いてある`Example ResponsBody`は成功したときのレスポンスである。
リクエストが間違っていた場合などは、コード:400で、Bodyに以下のようなエラーメッセージが入ったレスポンスが帰ってくる。
```json=
{
"error":errorMessage
}
```
### ユーザアカウントAPI
#### 登録
POST /users/regist
##### Example RequestBody
```json=
{
"screenName":"高専太郎",
"name":"nit-taro"
"password":"password"
}
```
- `screenName`:表示名、好きな名前を指定できる
- `name`:ユーザネーム、固有
- `password`:パスワード
##### Example ResponsBody
```json=
{
"screenName": "高専太郎",
"name": "nit-taro",
"id": "565b5b1e-a2c7-4769-a6ed-332a917f4fff",
"password": "password"
}
```
- `id`:ユーザ固有のID。ユーザネームはあとから変更できるが、IDは変更不可(ユーザーネーム変更APIは未実装)
#### 取得
GET /users/show/:(userId or userName or 無し)
`userId` または`userName`で指定したユーザの情報を取得することができる。
指定しないと、全ユーザの情報が配列で帰ってくる。
#### Example ResponsBody
```json=
{
"screenName": "高専太郎",
"name": "nit-taro",
"id": "565b5b1e-a2c7-4769-a6ed-332a917f4fff"
}
```
#### 削除
POST /users/delete
##### Example RequestBody
```json=
{
"name": "nit-taro",
"id": "565b5b1e-a2c7-4769-a6ed-332a917f4fff",
"password": "password"
}
```
- `name`または`id`:どちらかを指定。どちらも指定した場合は`id`が優先される
- `password`:アカウント登録時に設定したパスワードを指定
##### Example ResponseBody
レスポンスはなし。
### ゲームAPI
#### プレイヤー登録&トークン・ゲームID取得
POST /match
`name`と`spec`をBodyに含めてリクエストすると、`playerId`と`roomId`が取得できる。
##### Example RequestBody
```json=
{
"name": "nit-taro",
"id": "565b5b1e-a2c7-4769-a6ed-332a917f4fff",
"password": "password",
"spec":"human",
"useAi": true,
"aiOption": {
"aiName": "a1"
}
}
```
|Name|Type|Discription|
|-|-|-|
|`name`|string|ユーザネーム。`id`とどちらかは指定しなければならない
|`id`|string|ユーザID。`name`とどちらかは指定しなければならない
|`password`必須|string|ユーザのパスワード
|`spec`任意|string|スペック(任意、ゲームには影響しない)
|`gameId`任意|string|参加するゲームID
|`useAi`任意|boolean|対AI戦を利用するかどうか
|`aiOption.aiName`任意|string|対AI戦を利用する場合に使用するAI名(useAiがtrueの場合は必須パラメータ)|
|`aiOption.boardName`任意|string|対AI戦を利用する場合に使用するボード名|
##### Example ResponsBody
```json=
{
"userId": "e848248b-0182-4433-8b6e-9d17fd65d816",
"spec": "test",
"accessToken": "ed2b135c-2c46-488e-8453-562272ed0fe3",
"gameId": "734bdd48-7b16-4f52-89b5-fda3f631df62",
"index":0,
}
```
- `userId`:ユーザID(リクエストで`name`のみ送信した場合にもユーザIDが帰ってくる)
- `accessToken`:行動(Action)するときに必要なトークン
- `gameId`:ゲームID。試合情報を取得するときにはこのIDを使用する。
- `index`:自身がplayer1かplayer2かを判別用(試合情報のplayers配列番号)
#### 試合状態取得
GET /match/:gameId
`gameId`が分かれば、誰でも試合状態を取得することができる。
##### Example ResponsBody
```json=
{
"gameId":"8c080c7b-286f-4407-82e2-4d6e8cd06b61",
"gaming":false,
"ending":false,
"board":{
"width":10,
"height":10,
"nAgent":8,
"nPlayer":2,
"nTurn": 30,
"nSec": 1,
"points":[
12,3,5,3,1,1,3,5,3,12,
3,5,7,5,3,3,5,7,5,3,
5,7,10,7,5,5,7,10,7,5,
3,5,7,5,3,3,5,7,5,3,
1,3,5,3,12,12,3,5,3,1,
1,3,5,3,12,12,3,5,3,1,
3,5,7,5,3,3,5,7,5,3,
5,7,10,7,5,5,7,10,7,5,
3,5,7,5,3,3,5,7,5,3,
12,3,5,3,1,1,3,5,3,12
]
},
"startedAtUnixTime":1597162330,
"nextTurnUnixTime":1597162333,
"turn":0,
"totalTurn":30,
"tiled":[
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],
[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1],[0,-1]
],
"players":[
{
"id":"3678abbc-1249-4b4a-90e8-b75a5688fe47",
"agents":[
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1}
],
"point":{
"basepoint":0,
"wallpoint":0
},
"tilePoint":null,
"areaPoint":null
},
{
"id":"3678abbc-1249-4b4a-90e8-b75a5688fe47",
"agents":[
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1},
{"x":-1,"y":-1}
],
"point":{
"basepoint":0,
"wallpoint":0
},
"tilePoint":null,
"areaPoint":null
}
],
"log": [
[
{
"point": {
"basepoint": 0,
"wallpoint": 5
},
"actions": [
{
"agentId": 0,
"type": 1,
"x": 1,
"y": 1,
"res": 0
}
]
},
{
"point": {
"basepoint": 0,
"wallpoint": 0
},
"actions": []
}
]
]
}
```
- `gameId`:ゲームID
- `gaming`:ゲーム中かどうか
- `ending`:ゲーム終了したかどうか
- `board`:ボード情報(両プレイヤーが揃ったら開示。揃ってない時にはnull)
- `width`:フィールドの横幅
- `height`:フィールドの縦幅
- `nAgent`:エージェントの数
- `nPlayer`:ゲームに参加しているプレイヤー人数
- `points`:フィールドのポイント配列(1次元配列)
- `startedAtUnixTime`:ゲームのスタート時間
- `nextTurnUnixTime`:次のターンまでの時間
- `turn`:現在のターン数
- `totalTurn`:総ターン数(非推奨、代わりにboard.nTurnを使用)
- `tiled`:タイル配置状況配列(1次元配列)
- index 0 : タイルの状態(0:陣地、1:壁)
- index 1 : そのタイルを所持するプレイヤーIndex(-1のときは空白マスとなります。)
- `players`:各プレイヤー状況
- `id`:ユーザID
- `agents`:各エージェント状況
- `x`:x座標
- `y`:y座標
- `tilePoint`:タイルポイント
- `areaPoint`:領域ポイント
- `log`:ログ
- turnごとの配列
- playerごとの配列
- `points`
- `basepoint`
- `wallpoint`
- `actions`
- `agentId`:エージェント ID
- `type`:行動の種類,1:配置, 2:停留, 3:移動, 4:除去
- `x`:x座標
- `y`:y座標
- `res`:行動の適応状況,0:成功, 1:競合, 2:REVERT, 3:同じエージェントに対して複数のアクションを同時に送った, 4:ERR_ILLEGAL_AGENT, 5:ERR_ILLEGAL_ACTION
#### 行動更新
POST /match/:RoomID/action
各アクションを送信できる。
matchで取得できる`accessToken`をヘッダー`Authorization`に含める必要がある。
##### Example Request & ResponseBody
```json=
{
actions:[
{ "agentId": 0, "type": "PUT", "x": 1, "y": 1},
{ "agentId": 1, "type": "MOVE", "x": 2, "y": 2}
]
}
```
- `agentId`:エージェント ID
- `type`:行動の種類,"PUT":配置, “MOVE”:移動, “REMOVE”:除去, “STAY”:停留
- `x`:x座標
- `y`:y座標
##### Example ResponseBody
```json=
{
"receptionUnixTime": 1597323035,
"turn": 1
}
```
- `receptionUnixTime`:サーバ受理時刻(タイムラグなどの判定に使える?)
- `turn`:Actionが実行されるターン数
### 動作確認用API(未実装)
/pingにトークンを付けてアクセスすることで トークン がプログラムからサーバーに 正しく送られているかを確認できます。
### ストリーミングAPI(WebSockets)
後ほど…