screeps-connectivity 0.13.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 57a7e1d: Hide the connection ("server") password field for xxscreeps servers.
8
+
9
+ `screeps-connectivity` adds a `hasOfficialLike(version)` capability helper that
10
+ detects the `official-like` feature advertised at `/api/version`. The login
11
+ screens (web and desktop) now use it to hide the server-password field on
12
+ xxscreeps servers, where the screepsmod-auth connection password does not apply.
13
+
14
+ ### Patch Changes
15
+
16
+ - 5d46b8e: Fix flag removal and color changes failing with "invalid shard" on multi-shard servers. `removeFlag` and `changeFlagColor` now accept and forward the current shard, matching the other room-scoped game endpoints.
17
+ - 3b9b951: Revamp the public profile page (`/profile/<username>`):
18
+
19
+ - Header now mirrors the self Overview chrome — small badge, the player's name
20
+ as the title, and a compact GCL/GPL readout rendered as rounded chips bordered
21
+ in the rank color (teal / red).
22
+ - The "Last 7 days" stat block is now a dropdown (1 hour / 24 hours / 7 days);
23
+ the tiles refetch the user's public stats for the selected window.
24
+ - Stat tiles now render correctly on servers that return `/api/user/stats`
25
+ metrics as a single pre-summed total per interval, not just per-tick buckets
26
+ (`ApiUserStatsResponse.stats` widened to `number | bucket[]`).
27
+ - Cross-links between the two account views: the username on the self Overview
28
+ links to the public profile, and your own public profile links back to your
29
+ private Overview.
30
+ - The top-bar Overview button no longer appears active while a profile is open —
31
+ a profile is a separate view.
32
+
33
+ - 79bd3d0: Add a read-only per-room overview page at `/room-overview/<shard>/<room>` (or
34
+ `/room-overview/<room>` on single-shard servers):
35
+
36
+ - Header with the room name, owner (badge + profile link, or "Unclaimed room"),
37
+ and a room minimap thumbnail that opens the live room view.
38
+ - The same seven stat tiles as the account Overview, summed over a selectable
39
+ interval (1 hour / 24 hours / 7 days).
40
+ - A history graph rendering the six per-bucket metrics (energy harvested,
41
+ construction, control, energy on creeps, creeps produced/lost) as
42
+ opacity-scaled dot strips.
43
+ - Entry points: a chart button next to each room name on the self Overview and
44
+ public Profile pages, plus a button in the in-game room view's left toolbar
45
+ (between the World Map and History buttons).
46
+ - `screeps-connectivity`: the existing `game.roomOverview` endpoint is now typed
47
+ with the new exported `ApiRoomOverviewResponse` (was `unknown`).
48
+
3
49
  ## 0.13.1
4
50
 
5
51
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screeps-connectivity",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "repository": {
@@ -19,6 +19,7 @@ import type {
19
19
  ApiMarketOrdersResponse,
20
20
  ApiMarketMyOrdersResponse,
21
21
  ApiMarketStatsResponse,
22
+ ApiRoomOverviewResponse,
22
23
  } from '../../types/api.js'
23
24
  import { createPowerCreepsEndpoints, type PowerCreepsEndpoints } from './power-creeps.js'
24
25
 
@@ -28,7 +29,7 @@ export interface GameEndpoints {
28
29
  roomObjects(room: string, shard?: string | null): Promise<ApiRoomObjectsResponse>
29
30
  roomDecorations(room: string, shard?: string | null): Promise<ApiRoomDecorationsResponse>
30
31
  roomStatus(room: string, shard?: string | null): Promise<{ ok: number; status: string; novice?: string }>
31
- roomOverview(room: string, interval?: number, shard?: string | null): Promise<unknown>
32
+ roomOverview(room: string, interval?: number, shard?: string | null): Promise<ApiRoomOverviewResponse>
32
33
  time(shard?: string | null): Promise<{ ok: number; time: number }>
33
34
  tick(): Promise<ApiGameTickResponse>
34
35
  worldSize(shard?: string | null): Promise<unknown>
@@ -37,8 +38,8 @@ export interface GameEndpoints {
37
38
  createFlag(room: string, x: number, y: number, name: string, color: number, secondaryColor: number, shard?: string | null): Promise<ApiCreateFlagResponse>
38
39
  genUniqueFlagName(): Promise<ApiGenUniqueFlagNameResponse>
39
40
  checkUniqueFlagName(name: string): Promise<ApiCheckUniqueFlagNameResponse>
40
- changeFlagColor(room: string, name: string, color: number, secondaryColor: number): Promise<ApiChangeFlagColorResponse>
41
- removeFlag(room: string, name: string): Promise<ApiRemoveFlagResponse>
41
+ changeFlagColor(room: string, name: string, color: number, secondaryColor: number, shard?: string | null): Promise<ApiChangeFlagColorResponse>
42
+ removeFlag(room: string, name: string, shard?: string | null): Promise<ApiRemoveFlagResponse>
42
43
  genUniqueObjectName(type: string, shard?: string | null): Promise<ApiGenUniqueObjectNameResponse>
43
44
  checkUniqueObjectName(type: string, name: string, shard?: string | null): Promise<ApiCheckUniqueObjectNameResponse>
44
45
  placeSpawn(room: string, x: number, y: number, name?: string, shard?: string | null): Promise<{ ok: number }>
@@ -88,8 +89,8 @@ export function createGameEndpoints(http: HttpClient, decorationsMock?: ApiRoomD
88
89
  createFlag: (room, x, y, name, color, secondaryColor, shard) => http.request('POST', '/api/game/create-flag', withShard({ room, x, y, name, color, secondaryColor }, shard)),
89
90
  genUniqueFlagName: () => http.request('POST', '/api/game/gen-unique-flag-name'),
90
91
  checkUniqueFlagName: (name) => http.request('POST', '/api/game/check-unique-flag-name', { name }),
91
- changeFlagColor: (room, name, color, secondaryColor) => http.request('POST', '/api/game/change-flag-color', { room, name, color, secondaryColor }),
92
- removeFlag: (room, name) => http.request('POST', '/api/game/remove-flag', { room, name }),
92
+ changeFlagColor: (room, name, color, secondaryColor, shard) => http.request('POST', '/api/game/change-flag-color', withShard({ room, name, color, secondaryColor }, shard)),
93
+ removeFlag: (room, name, shard) => http.request('POST', '/api/game/remove-flag', withShard({ room, name }, shard)),
93
94
  genUniqueObjectName: (type, shard) => http.request('POST', '/api/game/gen-unique-object-name', withShard({ type }, shard)),
94
95
  checkUniqueObjectName: (type, name, shard) => http.request('POST', '/api/game/check-unique-object-name', withShard({ type, name }, shard)),
95
96
  placeSpawn: (room, x, y, name, shard) => http.request('POST', '/api/game/place-spawn', withShard({ room, x, y, ...(name ? { name } : {}) }, shard)),
@@ -206,3 +206,16 @@ export function getXxscreepsModClientFeature(version: ServerVersion): XxscreepsM
206
206
  export function getDiscordFeature(version: ServerVersion): DiscordFeature | undefined {
207
207
  return getServerFeature<DiscordFeature>(version, 'discord')
208
208
  }
209
+
210
+ /**
211
+ * Returns `true` when the server advertises the `official-like` feature — the
212
+ * marker xxscreeps servers publish at `/api/version`. Such servers do not
213
+ * implement the screepsmod-auth connection ("server") password, so the client
214
+ * can hide that field entirely.
215
+ *
216
+ * @example
217
+ * if (hasOfficialLike(version)) hideServerPasswordField()
218
+ */
219
+ export function hasOfficialLike(version: ServerVersion): boolean {
220
+ return getServerFeature(version, 'official-like') !== undefined
221
+ }
package/src/index.ts CHANGED
@@ -42,9 +42,9 @@ export type {
42
42
  MapVisualEntry,
43
43
  } from './types/game.js'
44
44
 
45
- export { fetchServerVersion, fetchAuthModInfo, checkUsername, checkEmail, registerUser, fetchAuthMeWithToken, completeProviderRegistration, getServerFeature, getScreepsmodAuth, getXxscreepsModClientFeature, getDiscordFeature } from './http/fetchServerVersion.js'
45
+ export { fetchServerVersion, fetchAuthModInfo, checkUsername, checkEmail, registerUser, fetchAuthMeWithToken, completeProviderRegistration, getServerFeature, getScreepsmodAuth, getXxscreepsModClientFeature, getDiscordFeature, hasOfficialLike } from './http/fetchServerVersion.js'
46
46
  export type { ApiAuthModInfoResponse } from './http/fetchServerVersion.js'
47
- export type { ApiAuthMeResponse, RoomHistoryChunk, ApiRoomDecorationsResponse, ApiRoomDecorationItem, ApiRoomDecorationDef, ApiRoomDecorationGraphic, ApiRoomDecorationActive, ApiUserOverviewResponse, ApiUserOverviewTotals, ApiUserRoomsResponse, ApiUserStatsResponse, ApiLeaderboardFindResponse, ApiUserMoneyHistoryResponse, ApiMarketOrder, ApiMarketOrdersIndexResponse, ApiMarketOrdersResponse, ApiMarketMyOrdersResponse, ApiMarketStat, ApiMarketStatsResponse, ApiPowerCreep, ApiPowerCreepsListResponse, ApiUserMessage, ApiUserMessagesListResponse, ApiUserMessagesIndexEntry, ApiUserMessagesIndexResponse, ApiUserMessagesUnreadCountResponse, ApiUserFindResponse } from './types/api.js'
47
+ export type { ApiAuthMeResponse, RoomHistoryChunk, ApiRoomDecorationsResponse, ApiRoomDecorationItem, ApiRoomDecorationDef, ApiRoomDecorationGraphic, ApiRoomDecorationActive, ApiUserOverviewResponse, ApiUserOverviewTotals, ApiRoomOverviewResponse, ApiUserRoomsResponse, ApiUserStatsResponse, ApiLeaderboardFindResponse, ApiUserMoneyHistoryResponse, ApiMarketOrder, ApiMarketOrdersIndexResponse, ApiMarketOrdersResponse, ApiMarketMyOrdersResponse, ApiMarketStat, ApiMarketStatsResponse, ApiPowerCreep, ApiPowerCreepsListResponse, ApiUserMessage, ApiUserMessagesListResponse, ApiUserMessagesIndexEntry, ApiUserMessagesIndexResponse, ApiUserMessagesUnreadCountResponse, ApiUserFindResponse } from './types/api.js'
48
48
  export { ROOM_DECORATIONS_MOCK } from './mocks/roomDecorations.js'
49
49
 
50
50
  export { badgeToSvg } from './badge/index.js'
package/src/types/api.ts CHANGED
@@ -46,6 +46,15 @@ export interface ApiUserOverviewResponse {
46
46
  statsMax?: number
47
47
  }
48
48
 
49
+ /** Response of GET /api/game/room-overview?room=&interval=&shard=. `stats` holds per-stat time-series buckets over the requested interval (same metric keys as the account overview tiles); `owner` is absent for unowned rooms. */
50
+ export interface ApiRoomOverviewResponse {
51
+ ok: number
52
+ owner?: { username: string; badge: import('./game.js').Badge } | null
53
+ stats?: Record<string, Array<{ value: number; endTime: number }>>
54
+ statsMax?: Record<string, number>
55
+ totals?: ApiUserOverviewTotals
56
+ }
57
+
49
58
  /** Response of GET /api/user/rooms?id=<userId> — the rooms a user owns. Multishard servers key by shard; single-shard servers may return a flat list. */
50
59
  export interface ApiUserRoomsResponse {
51
60
  ok: number
@@ -271,10 +280,14 @@ export interface ApiUserFindResponse {
271
280
  }
272
281
  }
273
282
 
274
- /** Response of GET /api/user/stats?id=&interval=. `stats` maps a metric to per-tick buckets; consumers sum the bucket values over the interval. */
283
+ /**
284
+ * Response of GET /api/user/stats?id=&interval=. `stats` maps a metric to
285
+ * either per-tick buckets (consumers sum the bucket values over the interval)
286
+ * or a single pre-summed total for the interval — servers differ on which.
287
+ */
275
288
  export interface ApiUserStatsResponse {
276
289
  ok: number
277
- stats?: Record<string, Array<{ value: number; endTime?: number }>>
290
+ stats?: Record<string, number | Array<{ value: number; endTime?: number }>>
278
291
  statsMax?: Record<string, number>
279
292
  }
280
293