rooooms are mostly dooone, misc routes, instance management stubs, and matchmaking base

This commit is contained in:
2025-09-07 17:28:13 -04:00
parent 2aa5352350
commit eef3667618
36 changed files with 627 additions and 122 deletions

View File

@@ -1,7 +1,12 @@
import Server from "../../../server/server.ts";
import { createHonoRoute } from "../../../util/import.ts";
export const route = createHonoRoute("/config");
route.app.get('/v1/amplitude', c => {
return c.json({AmplitudeKey: ""});
});
route.app.get('/v2', c => {
return c.json(Server.getPublicConfig());
});

View File

@@ -1,7 +1,8 @@
import { authenticate } from "../../../util/api.ts";
import { createHonoRoute } from "../../../util/import.ts";
export const route = createHonoRoute("/messages");
route.app.get('/v2/get', async c => {
route.app.get('/v2/get', authenticate, async c => {
return c.json(await c.get('profile').Messages.getMessages());
});

View File

@@ -9,21 +9,26 @@ export const route = createHonoRoute("/playerReputation");
const getRepIdParamSchema = z.object({
id: z.coerce.number().min(0).max(2_147_483_647)
})
route.app.get('/v1/:id', typedZValidator('param', getRepIdParamSchema), authenticate, async c => {
route.app.get('/v1/:id', authenticate, typedZValidator('param', getRepIdParamSchema), authenticate, async c => {
const { id } = c.req.valid('param');
const prof = await Server.Profiles.get(id);
if (!prof) return c.status(404);
else return c.json({
AccountId: id,
Noteriety: 0.0,
CheerGeneral: 0,
CheerHelpful: 0,
CheerGreatHost: 0,
CheerSportsman: 0,
CheerCreative: 0,
CheerCredit: 0,
SubscriberCount: 0,
SubscribedCount: 0,
});
else return c.json(await prof.Reputation.export());
});
const getRepBulkBodySchema = z.object({
Ids: z.array(z.coerce.number())
});
route.app.post('/v1/bulk', authenticate, typedZValidator('form', getRepBulkBodySchema), async c => {
const ids = c.req.valid('form').Ids;
if (typeof ids == 'object') {
const profs = await Server.Profiles.getMany(...ids);
return c.json(await Promise.all(profs.map(prof => prof.Reputation.export())));
} else {
const prof = await Server.Profiles.get(ids);
if (!prof) return c.json([]);
return c.json([await prof.Reputation.export()]);
}
});

View File

@@ -2,6 +2,7 @@ import z from "zod";
import { createHonoRoute } from "../../../util/import.ts";
import { authenticate } from "../../../util/api.ts";
import { typedZValidator } from "../../../util/validators.ts";
import Server from "../../../server/server.ts";
export const route = createHonoRoute("/players");
@@ -14,4 +15,20 @@ const getProgParamSchema = z.object({
});
route.app.get('/v1/progression/:id', authenticate, typedZValidator('param', getProgParamSchema), async c => {
return c.json(await c.get('profile').Reputation.export());
});
const getProgBulkBodySchema = z.object({
Ids: z.union([z.array(z.coerce.number()), z.coerce.number()])
});
route.app.post('/v1/progression/bulk', authenticate, typedZValidator('form', getProgBulkBodySchema), async c => {
const ids = c.req.valid('form').Ids;
if (typeof ids == 'object') {
const profs = await Server.Profiles.getMany(...ids);
return c.json(await Promise.all(profs.map(prof => prof.Progression.get())));
} else {
const prof = await Server.Profiles.get(ids);
if (!prof) return c.json([]);
return c.json([await prof.Progression.get()]);
}
});

View File

@@ -0,0 +1,7 @@
import { createHonoRoute } from "../../../util/import.ts";
export const route = createHonoRoute("/quickPlay");
route.app.get('/v1/getandclear', c => {
return c.json({});
});

View File

@@ -1,7 +1,14 @@
import { HTTPStatus } from "@oneday/http-status";
import { statusResponse } from "../../../util/api.ts";
import { createHonoRoute } from "../../../util/import.ts";
export const route = createHonoRoute('/relationships');
route.app.get('/v2/get', c => {
return c.json([]);
});
// deno-lint-ignore require-await
route.app.post('/v1/bulkignoreplatformusers', async c => {
return statusResponse(c, HTTPStatus.OK);
});

View File

@@ -1,9 +1,10 @@
import z from "zod";
import { authenticate } from "../../../util/api.ts";
import { authenticate, statusResponse } from "../../../util/api.ts";
import { createHonoRoute } from "../../../util/import.ts";
import { typedZValidator } from "../../../util/validators.ts";
import { HonoEnv } from "../../../util/types.ts";
import { Context } from "@hono/hono";
import { HTTPStatus } from "@oneday/http-status";
export const route = createHonoRoute('/settings');
@@ -25,5 +26,5 @@ route.app.post('/v2/set', typedZValidator('json', settingsSetSchema), async c =>
const { Key, Value } = c.req.valid('json');
await c.get('profile').Settings.setSetting(Key, Value);
return c.status(200);
return statusResponse(c, HTTPStatus.OK);
});

View File

@@ -1,7 +1,50 @@
import { createHonoRoute, routeImporter } from "../../util/import.ts";
import { Context, Next } from "@hono/hono";
import z from "zod";
import { HonoEnv } from "../../util/types.ts";
import { statusResponse } from "../../util/api.ts";
import { HTTPStatus } from "@oneday/http-status";
import Logging from "@proxnet/undead-logging";
const log = new Logging("MatchRoute");
export const route = createHonoRoute('/match');
const loginLockBodySchema = z.object({
LoginLock: z.uuidv4()
});
export const loginLockMiddleware = async (c: Context<HonoEnv>, nxt: Next) => {
function unauthorized() {
return statusResponse(c, HTTPStatus.Unauthorized);
}
if (c.req.header("Content-Type") !== "application/x-www-form-urlencoded") return unauthorized();
try {
const form = await c.req.formData();
const body = await loginLockBodySchema.safeParseAsync(Object.fromEntries(form.entries()));
if (body.success) {
if (typeof c.get('profile') == 'undefined') {
log.w(`Profile was not set, cannot validate LoginLock. Was the request authorized?`);
return statusResponse(c, HTTPStatus.InternalServerError);
}
const profile = c.get('profile');
const loginLock = await profile.Matchmaking.getLoginLock();
if (!loginLock) await profile.Matchmaking.setLoginLock(body.data.LoginLock);
else if (body.data.LoginLock !== loginLock) {
log.w(`LoginLock did not match. The token for this profile could be compromised or the client is an unknown state.`);
return unauthorized();
}
return await nxt();
} else return unauthorized();
} catch {
return unauthorized();
}
}
await routeImporter(route.app, 'src/routes/match/', [
'routes'
]);

View File

@@ -0,0 +1,13 @@
import { HTTPStatus } from "@oneday/http-status";
import { statusResponse } from "../../../util/api.ts";
import { createHonoRoute } from "../../../util/import.ts";
export const route = createHonoRoute("/goto");
route.app.post('/room/:roomName', c => {
return statusResponse(c, HTTPStatus.NotImplemented);
});
route.app.post('/room/:roomName/:subRoomName', c => {
return statusResponse(c, HTTPStatus.NotImplemented);
});

View File

@@ -1,10 +1,20 @@
import { authenticate } from "../../../util/api.ts";
import { authenticate, statusResponse } from "../../../util/api.ts";
import { createHonoRoute } from "../../../util/import.ts";
import { loginLockMiddleware } from "../root.ts";
import { HTTPStatus } from "@oneday/http-status";
export const route = createHonoRoute("/player");
route.app.use(authenticate);
route.app.post('/login', _c => {
return new Response("OK", { status: 200 });
route.app.post('/login', authenticate, loginLockMiddleware, async c => {
});
route.app.post('/player/vrmovementmode', authenticate, loginLockMiddleware, async c => {
return statusResponse(c, HTTPStatus.OK); // stub
});
route.app.post('/player/statusvisibility', authenticate, loginLockMiddleware, async c => {
return statusResponse(c, HTTPStatus.OK); // stub
});