nonworking photon stuff

This commit is contained in:
Devin Zuczek
2026-07-28 14:19:49 -04:00
parent d5e3d3946e
commit 3c18d827a8
10 changed files with 418 additions and 26 deletions
+7 -5
View File
@@ -135,7 +135,7 @@ export const ApiConfigV2 = JsonObject.describe(
'The static client config, plus a ShareBaseUrl templated from the deploy domain'
)
/** `GET /api/versioncheck/v4` — whether the client's `?v=` build matches GAME_VERSION. */
/** `GET /api/versioncheck/v4` — whether the client's `?v=` build is one we accept. */
export const VersionCheck = z.object({
VersionStatus: z.int().describe('0 = current, 1 = client on a different build'),
UpdateNotificationStage: z.int(),
@@ -392,12 +392,14 @@ export const SubscriptionResponse = z.object({
/**
* `GET /api/PlayerReporting/v1/moderationBlockDetails` — always the "not blocked"
* answer (no ban storage yet). `ReportCategory` is -1 (no category) rather than 0,
* which is a real category; `Message` is null, not an empty string — the client
* distinguishes "no message" from a blank one.
* answer (no ban storage yet), mirroring the reference server's stub
* `ReturnModerationBlockDetails()`. `ReportCategory` is `Unknown` (-1) rather than 0,
* which is a real category, and `Message` is the empty string the reference sends.
* `IsVoiceModAutoban`/`TimeoutStartedAt` are on the DTO but unset by that stub, so
* they carry their C# defaults (false / null).
*/
export const ModerationBlockDetails = z.object({
ReportCategory: z.int().describe('-1 = no category (0 is a real one)'),
ReportCategory: z.int().describe('-1 = ReportCategory.Unknown (0 is a real category)'),
Duration: z.int(),
GameSessionId: z.int(),
IsBan: z.boolean(),
+10 -3
View File
@@ -17,6 +17,13 @@ import {
import type { App } from '../context'
/**
* Client builds the version check answers as current. `GAME_VERSION` is the build the
* rest of the stack targets; `20230616` is a later client that talks the same protocol,
* so we let it through rather than telling it to update.
*/
const ACCEPTED_GAME_VERSIONS = new Set([GAME_VERSION, '20230616'])
// ---- Config / version ------------------------------------------------------
export const configRoutes = new Hono<App>({ strict: false })
.get(
@@ -100,13 +107,13 @@ export const configRoutes = new Hono<App>({ strict: false })
summary: 'Client version check',
description:
'Whether the client build is current. Compares the clients `?v=` build against ' +
'our target `GAME_VERSION`: `VersionStatus` is 0 when they match, 1 when the ' +
'client is on a different build.',
'the builds we accept — our target `GAME_VERSION` plus `20230616`: ' +
'`VersionStatus` is 0 for either, 1 for any other build.',
responses: { 200: json(VersionCheck, 'Version status') },
}),
(c) =>
c.json({
VersionStatus: c.req.query('v') === GAME_VERSION ? 0 : 1,
VersionStatus: ACCEPTED_GAME_VERSIONS.has(c.req.query('v') ?? '') ? 0 : 1,
UpdateNotificationStage: 0,
IsVersionIslanded: false,
IsCrossPlayDisabled: false,
+13 -10
View File
@@ -14,21 +14,24 @@ import type { App } from '../context'
// ---- Player reporting ------------------------------------------------------
export const moderationRoutes = new Hono<App>({ strict: false })
// Whether the caller is currently blocked (banned / timed out / host-kicked). No
// ban storage yet, so this is always the "not blocked" answer. `ReportCategory` is
// -1 (no category) rather than 0, which is a real category; `Message` is null, not
// an empty string — the client distinguishes "no message" from a blank one.
.get(
// Whether the caller is currently blocked (banned / timed out / host-kicked). No ban
// storage yet, so this is always the "not blocked" answer — the reference server's
// stub `ReturnModerationBlockDetails()` verbatim. `ReportCategory` is `Unknown` (-1),
// not 0, which is a real category, and `Message` is the empty string that stub sends.
// `IsVoiceModAutoban`/`TimeoutStartedAt` are on the DTO but left unset there, so they
// go out with their C# defaults.
// POST with no body — the client's actual call, despite this being a pure read.
.post(
'/api/PlayerReporting/v1/moderationBlockDetails',
describeRoute({
tags: ['Moderation'],
summary: 'Whether the caller is blocked',
description:
'Ban / timeout / host-kick state for the caller. There is no ban storage yet, so ' +
'this is always the “not blocked” answer. Two details matter to the client: ' +
'`ReportCategory` is -1 (no category) rather than 0, which is a real category, and ' +
'`Message` is null rather than an empty string — the client distinguishes “no ' +
'message” from a blank one.',
'this is always the “not blocked” answer, matching the reference servers stub: ' +
'`ReportCategory` is `Unknown` (-1) rather than 0, which is a real category, and ' +
'`Message` is an empty string. `IsVoiceModAutoban` and `TimeoutStartedAt` are on ' +
'the DTO but unset by that stub, so they carry their defaults.',
responses: { 200: json(ModerationBlockDetails, 'Always “not blocked”') },
}),
(c) =>
@@ -39,7 +42,7 @@ export const moderationRoutes = new Hono<App>({ strict: false })
IsBan: false,
IsHostKick: false,
IsVoiceModAutoban: false,
Message: null,
Message: '',
PlayerIdReporter: null,
TimeoutStartedAt: null,
})
+13 -5
View File
@@ -144,6 +144,11 @@ describe('public endpoints', () => {
expect(await res.json()).toMatchObject({ VersionStatus: 0 })
})
test('GET /api/versioncheck/v4 reports current for the 20230616 build', async () => {
const res = await exports.default.fetch(`${ORIGIN}/api/versioncheck/v4?v=20230616`)
expect(await res.json()).toMatchObject({ VersionStatus: 0 })
})
test('GET /api/versioncheck/v4 flags a mismatched build', async () => {
const res = await exports.default.fetch(`${ORIGIN}/api/versioncheck/v4?v=19990101`)
expect(await res.json()).toMatchObject({ VersionStatus: 1 })
@@ -228,12 +233,15 @@ describe('public endpoints', () => {
expect(await res.json()).toEqual([])
})
test('GET /api/PlayerReporting/v1/moderationBlockDetails reports "not blocked"', async () => {
test('POST /api/PlayerReporting/v1/moderationBlockDetails reports "not blocked"', async () => {
// The client POSTs this with no body, despite it being a pure read.
const res = await exports.default.fetch(
`${ORIGIN}/api/PlayerReporting/v1/moderationBlockDetails`
`${ORIGIN}/api/PlayerReporting/v1/moderationBlockDetails`,
{ method: 'POST' }
)
expect(res.status).toBe(200)
// ReportCategory -1 = no category (0 is a real one), and Message is null.
// The reference server's stub verbatim: ReportCategory -1 = Unknown (0 is a real
// category) and an empty-string Message.
expect(await res.json()).toEqual({
ReportCategory: -1,
Duration: 0,
@@ -241,7 +249,7 @@ describe('public endpoints', () => {
IsBan: false,
IsHostKick: false,
IsVoiceModAutoban: false,
Message: null,
Message: '',
PlayerIdReporter: null,
TimeoutStartedAt: null,
})
@@ -1891,7 +1899,6 @@ describe('openapi', () => {
)
expect([...documented].sort()).toEqual([
'DELETE /api/images/v1/deletesaved',
'GET /api/PlayerReporting/v1/moderationBlockDetails',
'GET /api/PlayerReporting/v1/voteToKickReasons',
'GET /api/activities/charades/v1/words/{activity}',
'GET /api/announcement/v1/get',
@@ -1964,6 +1971,7 @@ describe('openapi', () => {
'POST /api/CampusCard/v1/UpdateAndGetSubscription',
'POST /api/PlayerReporting/v1/deviceId',
'POST /api/PlayerReporting/v1/hile',
'POST /api/PlayerReporting/v1/moderationBlockDetails',
'POST /api/avatar/v2/gifts/generate',
'POST /api/gamesight/event',
'POST /api/images/v1/cheer',