Remove SCUM sqlite user projections
This commit is contained in:
@@ -397,6 +397,12 @@ describe("PlatformApiClient AI providers", () => {
|
||||
if (url.endsWith("/api/v1/server-instances/server-1/administrators/user-2") && init?.method === "DELETE") {
|
||||
return jsonResponse({ ...server, adminUserIds: [] });
|
||||
}
|
||||
if (url.endsWith("/api/v1/server-instances/server-1/scum/users?limit=10&online=true")) {
|
||||
return jsonResponse({ items: [{ id: "scum-user-1", steamId: "steam-1", online: true }], count: 1 });
|
||||
}
|
||||
if (url.endsWith("/api/v1/server-instances/server-1/scum/vehicle-locks?limit=10&gameVehicleId=veh-1")) {
|
||||
return jsonResponse({ items: [{ id: "lock-1", gameVehicleId: "veh-1", scumUserId: "scum-user-1" }], count: 1 });
|
||||
}
|
||||
|
||||
if (url.endsWith("/api/v1/server-instances/server-1/runtime/actions")) {
|
||||
return jsonResponse(runtimeActions);
|
||||
@@ -602,6 +608,8 @@ describe("PlatformApiClient AI providers", () => {
|
||||
await expect(client.listServerAdministratorCandidates(server.id)).resolves.toMatchObject({ count: 1 });
|
||||
await expect(client.addServerAdministrator(server.id, { userId: "user-2" })).resolves.toMatchObject({ adminUserIds: ["user-admin-1", "user-2"] });
|
||||
await expect(client.removeServerAdministrator(server.id, "user-2")).resolves.toMatchObject({ adminUserIds: [] });
|
||||
await expect(client.listScumUsers(server.id, { limit: 10, online: true })).resolves.toMatchObject({ items: [{ steamId: "steam-1" }], count: 1 });
|
||||
await expect(client.listScumVehicleLocks(server.id, { limit: 10, gameVehicleId: "veh-1" })).resolves.toMatchObject({ items: [{ scumUserId: "scum-user-1" }], count: 1 });
|
||||
|
||||
const runtime = await client.getServerRuntimeActions(server.id);
|
||||
expect(runtime.runStatus).toBe("online");
|
||||
@@ -629,7 +637,7 @@ describe("PlatformApiClient AI providers", () => {
|
||||
client.invokeAI({ requestId: "ai-1", serverInstanceId: server.id, purpose: "config.suggest", prompt: "Tune PVP safely", currentConfig: "server.name=Example Survival #1\n" })
|
||||
).resolves.toMatchObject({ status: "ok", usage: { mocked: true }, configRecommendation: { diffSummary: "review required" } });
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledTimes(47);
|
||||
expect(fetchMock).toHaveBeenCalledTimes(49);
|
||||
});
|
||||
|
||||
it("normalizes server file workspace null arrays from older platform responses", async () => {
|
||||
|
||||
@@ -87,6 +87,12 @@ import type {
|
||||
ServerMemberListResponse,
|
||||
ServerMemberRequest,
|
||||
ServerMetricsListResponse,
|
||||
ScumListRequest,
|
||||
ScumUserListResponse,
|
||||
ScumUserTrajectoryListResponse,
|
||||
ScumVehicleLockListResponse,
|
||||
ScumVehicleListResponse,
|
||||
ScumVehicleTrajectoryListResponse,
|
||||
SourceRCONCommandRequest,
|
||||
SourceRCONCommandResponse,
|
||||
MetricSampleListResponse,
|
||||
@@ -511,6 +517,26 @@ export class PlatformApiClient {
|
||||
return this.request<RemoteAdapterDeclarationListResponse>(`/server-instances/${encodeURIComponent(serverInstanceId)}/remote-adapters`);
|
||||
}
|
||||
|
||||
async listScumUsers(serverInstanceId: string, request: ScumListRequest = {}): Promise<ScumUserListResponse> {
|
||||
return this.request<ScumUserListResponse>(`/server-instances/${encodeURIComponent(serverInstanceId)}/scum/users${scumListQuery(request)}`);
|
||||
}
|
||||
|
||||
async listScumUserTrajectories(serverInstanceId: string, request: ScumListRequest = {}): Promise<ScumUserTrajectoryListResponse> {
|
||||
return this.request<ScumUserTrajectoryListResponse>(`/server-instances/${encodeURIComponent(serverInstanceId)}/scum/user-trajectories${scumListQuery(request)}`);
|
||||
}
|
||||
|
||||
async listScumVehicles(serverInstanceId: string, request: ScumListRequest = {}): Promise<ScumVehicleListResponse> {
|
||||
return this.request<ScumVehicleListResponse>(`/server-instances/${encodeURIComponent(serverInstanceId)}/scum/vehicles${scumListQuery(request)}`);
|
||||
}
|
||||
|
||||
async listScumVehicleTrajectories(serverInstanceId: string, request: ScumListRequest = {}): Promise<ScumVehicleTrajectoryListResponse> {
|
||||
return this.request<ScumVehicleTrajectoryListResponse>(`/server-instances/${encodeURIComponent(serverInstanceId)}/scum/vehicle-trajectories${scumListQuery(request)}`);
|
||||
}
|
||||
|
||||
async listScumVehicleLocks(serverInstanceId: string, request: ScumListRequest = {}): Promise<ScumVehicleLockListResponse> {
|
||||
return this.request<ScumVehicleLockListResponse>(`/server-instances/${encodeURIComponent(serverInstanceId)}/scum/vehicle-locks${scumListQuery(request)}`);
|
||||
}
|
||||
|
||||
async listPluginData(serverInstanceId: string, collection: string, key?: string): Promise<{ items: Array<{ key: string; value: Record<string, unknown> }>; count: number }> {
|
||||
const params = new URLSearchParams();
|
||||
if (key) params.set("key", key);
|
||||
@@ -931,6 +957,21 @@ function jobListQuery(serverInstanceId: string | undefined, filter: JobListFilte
|
||||
return query ? `?${query}` : "";
|
||||
}
|
||||
|
||||
function scumListQuery(request: ScumListRequest): string {
|
||||
const params = new URLSearchParams();
|
||||
if (request.limit !== undefined) params.set("limit", String(request.limit));
|
||||
if (request.changedAfter) params.set("changedAfter", request.changedAfter);
|
||||
if (request.after) params.set("after", request.after);
|
||||
if (request.online !== undefined) params.set("online", String(request.online));
|
||||
if (request.exists !== undefined) params.set("exists", String(request.exists));
|
||||
if (request.steamId) params.set("steamId", request.steamId);
|
||||
if (request.scumUserId) params.set("scumUserId", request.scumUserId);
|
||||
if (request.gameVehicleId) params.set("gameVehicleId", request.gameVehicleId);
|
||||
if (request.scumVehicleId) params.set("scumVehicleId", request.scumVehicleId);
|
||||
const query = params.toString();
|
||||
return query ? `?${query}` : "";
|
||||
}
|
||||
|
||||
function serverFileListQuery(request: Partial<ServerFileListRequest>): string {
|
||||
const params = new URLSearchParams();
|
||||
if (request.directoryKey) params.set("directoryKey", request.directoryKey);
|
||||
|
||||
@@ -83,14 +83,14 @@ const manifestDeclaration: GameClientBridgeManifestResponse = {
|
||||
timeoutSeconds: 30,
|
||||
maxPayloadBytes: 4096
|
||||
}],
|
||||
snapshots: [{ type: "scum.players", schemaVersion: "1", schemaRef: "schemas/bridge/snapshots/players.json", keepForSeconds: 3600, maxRecords: 24 }],
|
||||
snapshots: [{ type: "game.players", schemaVersion: "1", schemaRef: "schemas/bridge/snapshots/players.json", keepForSeconds: 3600, maxRecords: 24 }],
|
||||
queryTemplates: [{
|
||||
key: "scum.player.search",
|
||||
key: "game.player.search",
|
||||
title: "Search players",
|
||||
permission: "server.game-client.read",
|
||||
engine: "sqlite",
|
||||
transportKey: "scum-database",
|
||||
targetKey: "scum-db",
|
||||
transportKey: "sqlite-db",
|
||||
targetKey: "game-db",
|
||||
parameterSchemaRef: "schemas/bridge/queries/player-search.request.json",
|
||||
resultSchemaRef: "schemas/bridge/queries/player-search.result.json",
|
||||
maxRows: 50,
|
||||
@@ -98,7 +98,7 @@ const manifestDeclaration: GameClientBridgeManifestResponse = {
|
||||
}],
|
||||
commandRetentionSeconds: 86400,
|
||||
maxCommands: 1000,
|
||||
pages: [{ pageKey: "operations", commandTypes: ["scum.diagnostic.ping"], snapshotTypes: ["scum.players"], queryTemplateKeys: ["scum.player.search"] }]
|
||||
pages: [{ pageKey: "operations", commandTypes: ["scum.diagnostic.ping"], snapshotTypes: ["game.players"], queryTemplateKeys: ["game.player.search"] }]
|
||||
};
|
||||
|
||||
const pluginBridgeProjection: Pick<GamePluginResponse, "gameClientBridge"> & Pick<MarketplacePluginResponse, "gameClientBridge"> = {
|
||||
|
||||
@@ -149,6 +149,132 @@ export interface GameClientBridgeCommandListResponse {
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface ScumListRequest {
|
||||
limit?: number;
|
||||
changedAfter?: string;
|
||||
after?: string;
|
||||
online?: boolean;
|
||||
exists?: boolean;
|
||||
steamId?: string;
|
||||
scumUserId?: string;
|
||||
gameVehicleId?: string;
|
||||
scumVehicleId?: string;
|
||||
}
|
||||
|
||||
export interface ScumUserResponse {
|
||||
id: string;
|
||||
serverInstanceId: string;
|
||||
steamId: string;
|
||||
gamePlayerId?: string;
|
||||
displayName?: string;
|
||||
squadId?: number;
|
||||
registeredAt?: string;
|
||||
lastLoginAt?: string;
|
||||
lastSeenAt?: string;
|
||||
lastActivityAt?: string;
|
||||
lastLoginAgeSeconds?: number;
|
||||
lastLoginIp?: string;
|
||||
loginIp?: string;
|
||||
online: boolean;
|
||||
x?: number;
|
||||
y?: number;
|
||||
z?: number;
|
||||
position?: { x: number; y: number; z: number };
|
||||
bankBalance?: number;
|
||||
normalBalance?: number;
|
||||
goldBars?: number;
|
||||
goldBalance?: number;
|
||||
riddenVehicleId?: string;
|
||||
gameVehicleId?: string;
|
||||
source?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface ScumUserListResponse { items: ScumUserResponse[]; count: number; }
|
||||
|
||||
export interface ScumUserTrajectoryResponse {
|
||||
id: string;
|
||||
serverInstanceId: string;
|
||||
scumUserId: string;
|
||||
subjectType: "player";
|
||||
subjectId: string;
|
||||
steamId: string;
|
||||
displayName?: string;
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
riddenVehicleId?: string;
|
||||
gameVehicleId?: string;
|
||||
observedAt?: string;
|
||||
sampledAt?: string;
|
||||
source?: string;
|
||||
createdAt?: string;
|
||||
}
|
||||
|
||||
export interface ScumUserTrajectoryListResponse { items: ScumUserTrajectoryResponse[]; count: number; }
|
||||
|
||||
export interface ScumVehicleResponse {
|
||||
id: string;
|
||||
serverInstanceId: string;
|
||||
vehicleId: string;
|
||||
gameVehicleId: string;
|
||||
entityId?: string;
|
||||
vehicleClass?: string;
|
||||
className?: string;
|
||||
displayName?: string;
|
||||
label?: string;
|
||||
exists: boolean;
|
||||
status?: string;
|
||||
locked?: boolean;
|
||||
x?: number;
|
||||
y?: number;
|
||||
z?: number;
|
||||
position?: { x: number; y: number; z: number };
|
||||
lastObservedAt?: string;
|
||||
vehicleObservedAt?: string;
|
||||
source?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface ScumVehicleListResponse { items: ScumVehicleResponse[]; count: number; }
|
||||
|
||||
export interface ScumVehicleTrajectoryResponse {
|
||||
id: string;
|
||||
serverInstanceId: string;
|
||||
scumVehicleId: string;
|
||||
subjectType: "vehicle";
|
||||
subjectId: string;
|
||||
vehicleId: string;
|
||||
gameVehicleId: string;
|
||||
vehicleClass?: string;
|
||||
className?: string;
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
observedAt?: string;
|
||||
sampledAt?: string;
|
||||
source?: string;
|
||||
createdAt?: string;
|
||||
}
|
||||
|
||||
export interface ScumVehicleTrajectoryListResponse { items: ScumVehicleTrajectoryResponse[]; count: number; }
|
||||
|
||||
export interface ScumVehicleLockResponse {
|
||||
id: string;
|
||||
serverInstanceId: string;
|
||||
scumVehicleId: string;
|
||||
gameVehicleId: string;
|
||||
scumUserId: string;
|
||||
steamId: string;
|
||||
lockedAt?: string;
|
||||
source?: string;
|
||||
createdAt?: string;
|
||||
}
|
||||
|
||||
export interface ScumVehicleLockListResponse { items: ScumVehicleLockResponse[]; count: number; }
|
||||
|
||||
export interface GameClientBridgeCommandFilterRequest {
|
||||
profileKey?: string;
|
||||
state?: GameClientBridgeCommandState;
|
||||
|
||||
Reference in New Issue
Block a user