Files
kickkingsapi/API_DOCUMENTATION.md
2026-04-04 18:43:36 +00:00

363 lines
9.6 KiB
Markdown

# Cupid Matchmaker API Documentation
## Overview
Cupid Matchmaker is a matchmaking daemon server designed for Unity game matchmaking. It manages player queues, creates game rooms, and spawns game instances when enough players are available.
**Version:** v1.0
**Base URL:** `http://localhost:2612` (configurable via `settings.json`)
---
## Authentication
All endpoints require authentication via a password query parameter. The password is configured in `settings.json`.
**Note:** All requests must include `?password=<your_password>` in the query string.
---
## Endpoints
### 1. Get Server Settings
Retrieve the current server configuration settings.
**Endpoint:** `GET /settings`
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `password` | string | Yes | Server password for authentication |
**Response (200 OK):**
```json
{
"minimum_players": 2,
"maximum_players": 2,
"waiting_time": 60000,
"port_range_min": 26000,
"port_range_max": 27000,
"games": [
{
"id": "soccar",
"exe": "/home/react/CupidServer/games/soccar/soccar.x86_64"
}
]
}
```
**Response Fields:**
- `minimum_players` (number): Minimum number of players required to start a game
- `maximum_players` (number): Maximum number of players allowed in a room
- `waiting_time` (number): Room expiration time in milliseconds
- `port_range_min` (number): Minimum port number for game instances
- `port_range_max` (number): Maximum port number for game instances
- `games` (array): List of available game configurations
- `id` (string): Game identifier
- `exe` (string): Path to game executable
**Error Responses:**
- `403 Unauthorized`: Invalid password
**Example Request:**
```bash
curl "http://localhost:2612/settings?password=HelloWorld"
```
---
### 2. Matchmaking (Join Queue / Get Room)
Main endpoint for matchmaking. Players use this endpoint to join the queue or retrieve their current room information.
**Endpoint:** `GET /`
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `password` | string | Yes | Server password for authentication |
| `username` | string | Yes | Player's username (minimum 2 characters) |
| `game_name` | string | Yes | Name/identifier of the game to matchmake for |
**Response Scenarios:**
#### Scenario 1: Player Already in a Room (200 OK)
Returns the room object if the player is already assigned to a room.
```json
{
"Players": [
{
"Name": "player1",
"LastSeen": 1234567890
},
{
"Name": "player2",
"LastSeen": 1234567891
}
],
"GameName": "soccar",
"Port": 26150,
"InitTime": 1234567800
}
```
#### Scenario 2: Room Created (200 OK)
Returns a new room when enough players are in the queue and a room is created.
```json
{
"Players": [
{
"Name": "player1",
"LastSeen": 1234567890
}
],
"GameName": "soccar",
"Port": 26150,
"InitTime": 1234567890
}
```
#### Scenario 3: Joined Existing Room (200 OK)
Returns the room when a player joins an existing room that has available slots.
```json
{
"Players": [
{
"Name": "player1",
"LastSeen": 1234567890
},
{
"Name": "player2",
"LastSeen": 1234567891
}
],
"GameName": "soccar",
"Port": 26150,
"InitTime": 1234567800
}
```
#### Scenario 4: Added to Queue (200 OK)
Returns `"0"` when the player is added to the queue or is already in the queue waiting for other players.
```
"0"
```
**Response Fields:**
- `Players` (array): List of players in the room
- `Name` (string): Player's username
- `LastSeen` (number): Unix timestamp of last activity
- `GameName` (string): Name of the game
- `Port` (number): Port number assigned to the game instance
- `InitTime` (number): Unix timestamp when the room was created
**Error Responses:**
- `403 Unauthorized`: Invalid password
- `Bad credentials`: Username is less than 2 characters
**Behavior Notes:**
- Players must poll this endpoint regularly (within 2 seconds) to maintain their queue position
- Rooms expire after `waiting_time` milliseconds
- Players are removed from the queue if inactive for more than 2 seconds
- When enough players are in the queue (≥ `minimum_players`), a new room is created and a game instance is spawned
- Players can join existing rooms if they have available slots and match the `game_name`
**Example Request:**
```bash
curl "http://localhost:2612/?password=HelloWorld&username=player1&game_name=soccar"
```
---
### 3. Cancel Queue Entry
Remove a player from the matchmaking queue.
**Endpoint:** `GET /cancel`
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `password` | string | Yes | Server password for authentication |
| `username` | string | Yes | Player's username to remove from queue |
**Response (200 OK):**
- `"1"`: Successfully removed from queue
**Error Responses:**
- `403 Unauthorized`: Invalid password
- `Bad credentials`: Username is less than 2 characters
- `"Couldn't find user <username> in the queue"`: User not found in queue
**Example Request:**
```bash
curl "http://localhost:2612/cancel?password=HelloWorld&username=player1"
```
---
## Data Models
### Player
```typescript
{
Name: string; // Player's username
LastSeen: number; // Unix timestamp of last activity
}
```
### Room
```typescript
{
Players: Player[]; // Array of players in the room
GameName: string; // Name/identifier of the game
Port: number; // Port number for the game instance
InitTime: number; // Unix timestamp when room was created
}
```
### QueueEntry
```typescript
{
Name: string; // Player's username
LastSeen: number; // Unix timestamp of last activity
}
```
---
## Server Configuration
The server is configured via `settings.json`:
```json
{
"port": 2612,
"password": "HelloWorld",
"minimum_players": 2,
"maximum_players": 2,
"waiting_time": 60000,
"port_range_min": 26000,
"port_range_max": 27000,
"game_exe": [
{
"name": "soccar",
"exe": "/home/react/CupidServer/games/soccar/soccar.x86_64"
}
],
"log_level": 1
}
```
**Configuration Fields:**
- `port` (number): Server listening port
- `password` (string): Authentication password for API access
- `minimum_players` (number): Minimum players required to start a game
- `maximum_players` (number): Maximum players allowed per room
- `waiting_time` (number): Room expiration time in milliseconds
- `port_range_min` (number): Minimum port for game instances
- `port_range_max` (number): Maximum port for game instances
- `game_exe` (array): Game executable configurations
- `name` (string): Game identifier
- `exe` (string): Path to game executable
- `log_level` (number): Logging verbosity (0 = minimal, 1 = debug, 2 = verbose)
---
## Matchmaking Flow
1. **Player Joins Queue:**
- Player calls `GET /` with `username` and `game_name`
- If not enough players in queue, player receives `"0"` and is added to queue
2. **Room Creation:**
- When queue reaches `minimum_players`, a new room is created
- A random port is selected from the configured range
- A game instance is spawned with the selected port
- First player receives the room object
3. **Room Joining:**
- Subsequent players calling `GET /` can join existing rooms with available slots
- Players receive the room object with updated player list
4. **Room Expiration:**
- Rooms expire after `waiting_time` milliseconds
- Expired rooms are automatically cleaned up
5. **Queue Maintenance:**
- Players must poll `GET /` at least every 2 seconds to stay in queue
- Inactive players are automatically removed from queue
---
## Error Handling
All endpoints return appropriate HTTP status codes:
- `200 OK`: Successful request
- `403 Unauthorized`: Authentication failure
- Error messages are returned as plain text in the response body
---
## Best Practices
1. **Polling Frequency:** Poll the matchmaking endpoint (`GET /`) every 1-2 seconds to maintain queue position
2. **Error Handling:** Always check for `403 Unauthorized` responses and handle authentication errors
3. **Username Validation:** Ensure usernames are at least 2 characters long
4. **Room Management:** Once a room is received, connect to the game instance on the provided port
5. **Queue Cancellation:** Use `/cancel` endpoint when a player wants to leave the queue
---
## Example Integration
### JavaScript/TypeScript Example
```typescript
const BASE_URL = 'http://localhost:2612';
const PASSWORD = 'HelloWorld';
const USERNAME = 'player1';
const GAME_NAME = 'soccar';
// Join matchmaking queue
async function joinMatchmaking() {
const url = `${BASE_URL}/?password=${PASSWORD}&username=${USERNAME}&game_name=${GAME_NAME}`;
const response = await fetch(url);
const data = await response.text();
if (data === '0') {
console.log('Added to queue, waiting for players...');
// Poll every 1.5 seconds
setTimeout(joinMatchmaking, 1500);
} else {
const room = JSON.parse(data);
console.log('Room found!', room);
console.log(`Connect to game on port ${room.Port}`);
}
}
// Cancel queue
async function cancelQueue() {
const url = `${BASE_URL}/cancel?password=${PASSWORD}&username=${USERNAME}`;
const response = await fetch(url);
const result = await response.text();
console.log('Cancel result:', result);
}
```
---
## Notes
- The server automatically spawns game instances when rooms are created
- Game instances are launched with the `-port` argument
- Rooms are automatically cleaned up when expired or empty
- The queue has a grace period of 2 seconds for player inactivity
- All timestamps are Unix timestamps in milliseconds