mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 10:12:38 +00:00
Merge branch 'main' into canbuildtransport-perf
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
## API Usage
|
||||
|
||||
### List Game Metadata
|
||||
|
||||
Get game IDs and basic metadata for games that started within a specified time range. Results are sorted by start time and paginated.
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- Maximum time range: 2 days
|
||||
- Maximum limit per request: 1000 games
|
||||
|
||||
**Endpoint:**
|
||||
|
||||
```
|
||||
GET https://api.openfront.io/public/games
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
- `start` (required): ISO 8601 timestamp
|
||||
- `end` (required): ISO 8601 timestamp
|
||||
- `type` (optional): Game type, must be one of `[Private, Public, Singleplayer]`
|
||||
- `limit` (optional): Number of results (max 1000, default 50)
|
||||
- `offset` (optional): Pagination offset
|
||||
|
||||
**Example Request:**
|
||||
|
||||
```bash
|
||||
curl "https://api.openfront.io/public/games?start=2025-10-25T00:00:00Z&end=2025-10-26T23:59:59Z&type=Singleplayer&limit=10&offset=5"
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"game": "ABSgwin6",
|
||||
"start": "2025-10-25T00:00:10.526Z",
|
||||
"end": "2025-10-25T00:19:45.187Z",
|
||||
"type": "Singleplayer",
|
||||
"mode": "Free For All",
|
||||
"difficulty": "Medium"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
The response includes a `Content-Range` header indicating pagination (e.g., `games 5-15/399`).
|
||||
|
||||
---
|
||||
|
||||
### Get Game Info
|
||||
|
||||
Retrieve detailed information about a specific game.
|
||||
|
||||
**Endpoint:**
|
||||
|
||||
```
|
||||
GET https://api.openfront.io/public/game/:gameId
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
- `turns` (optional): Set to `false` to exclude turn data and reduce response size
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Full game data
|
||||
curl "https://api.openfront.io/public/game/ABSgwin6"
|
||||
|
||||
# Without turn data
|
||||
curl "https://api.openfront.io/public/game/ABSgwin6?turns=false"
|
||||
```
|
||||
|
||||
**Note:** Public player IDs are stripped from game records for privacy.
|
||||
|
||||
---
|
||||
|
||||
### Get Player Info
|
||||
|
||||
Retrieve information and stats for a specific player.
|
||||
|
||||
**Endpoint:**
|
||||
|
||||
```
|
||||
GET https://api.openfront.io/public/player/:playerId
|
||||
```
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
curl "https://api.openfront.io/public/player/HabCsQYR"
|
||||
```
|
||||
@@ -17,6 +17,7 @@ export class PublicLobby extends LitElement {
|
||||
private currLobby: GameInfo | null = null;
|
||||
private debounceDelay: number = 750;
|
||||
private lobbyIDToStart = new Map<GameID, number>();
|
||||
private lobbiesFetchInFlight: Promise<GameInfo[]> | null = null;
|
||||
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
@@ -73,16 +74,26 @@ export class PublicLobby extends LitElement {
|
||||
}
|
||||
|
||||
async fetchLobbies(): Promise<GameInfo[]> {
|
||||
try {
|
||||
const response = await fetch(`/api/public_lobbies`);
|
||||
if (!response.ok)
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
const data = await response.json();
|
||||
return data.lobbies;
|
||||
} catch (error) {
|
||||
console.error("Error fetching lobbies:", error);
|
||||
throw error;
|
||||
if (this.lobbiesFetchInFlight) {
|
||||
return this.lobbiesFetchInFlight;
|
||||
}
|
||||
|
||||
this.lobbiesFetchInFlight = (async () => {
|
||||
try {
|
||||
const response = await fetch(`/api/public_lobbies`);
|
||||
if (!response.ok)
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
const data = await response.json();
|
||||
return data.lobbies as GameInfo[];
|
||||
} catch (error) {
|
||||
console.error("Error fetching lobbies:", error);
|
||||
throw error;
|
||||
} finally {
|
||||
this.lobbiesFetchInFlight = null;
|
||||
}
|
||||
})();
|
||||
|
||||
return this.lobbiesFetchInFlight;
|
||||
}
|
||||
|
||||
public stop() {
|
||||
|
||||
@@ -2,7 +2,12 @@ import { PriorityQueue } from "@datastructures-js/priority-queue";
|
||||
import { Colord } from "colord";
|
||||
import { Theme } from "../../../core/configuration/Config";
|
||||
import { EventBus } from "../../../core/EventBus";
|
||||
import { Cell, PlayerType, UnitType } from "../../../core/game/Game";
|
||||
import {
|
||||
Cell,
|
||||
ColoredTeams,
|
||||
PlayerType,
|
||||
UnitType,
|
||||
} from "../../../core/game/Game";
|
||||
import { euclDistFN, TileRef } from "../../../core/game/GameMap";
|
||||
import { GameUpdateType } from "../../../core/game/GameUpdates";
|
||||
import { GameView, PlayerView } from "../../../core/game/GameView";
|
||||
@@ -170,6 +175,7 @@ export class TerritoryLayer implements Layer {
|
||||
.filter((p) => p.type() === PlayerType.Human);
|
||||
|
||||
const focusedPlayer = this.game.focusedPlayer();
|
||||
const teamColors = Object.values(ColoredTeams);
|
||||
for (const human of humans) {
|
||||
if (human === focusedPlayer) {
|
||||
continue;
|
||||
@@ -191,7 +197,17 @@ export class TerritoryLayer implements Layer {
|
||||
// In Team games, the spawn highlight color becomes that player's team color
|
||||
// Optionally, this could be broken down to teammate or enemy and simplified to green and red, respectively
|
||||
const team = human.team();
|
||||
if (team !== null) color = this.theme.teamColor(team);
|
||||
if (team !== null) {
|
||||
if (teamColors.includes(team)) {
|
||||
color = this.theme.teamColor(team);
|
||||
} else {
|
||||
if (myPlayer.isFriendly(human)) {
|
||||
color = this.theme.spawnHighlightTeamColor();
|
||||
} else {
|
||||
color = this.theme.spawnHighlightColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const tile of this.game.bfs(
|
||||
|
||||
@@ -132,12 +132,8 @@ export class PlayerExecution implements Execution {
|
||||
private surroundedBySamePlayer(cluster: Set<TileRef>): false | Player {
|
||||
const enemies = new Set<number>();
|
||||
for (const tile of cluster) {
|
||||
const isOceanShore = this.mg.isOceanShore(tile);
|
||||
if (this.mg.isOceanShore(tile) && !isOceanShore) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
isOceanShore ||
|
||||
this.mg.isOceanShore(tile) ||
|
||||
this.mg.isOnEdgeOfMap(tile) ||
|
||||
this.mg.neighbors(tile).some((n) => !this.mg?.hasOwner(n))
|
||||
) {
|
||||
|
||||
@@ -935,6 +935,9 @@ export class PlayerImpl implements Player {
|
||||
if (!this.isAlive()) {
|
||||
return false;
|
||||
}
|
||||
if (unit.owner() !== this) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user