duhhhhhhhh
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
import { authenticate, galvanicError, GalvanicErrors, RateLimiter, recNetError } from "../../../util/api.ts";
|
||||
import { authenticate, galvanicError, GalvanicErrors, RateLimiter, recNetError, statusResponse } from "../../../util/api.ts";
|
||||
import Server from "../../../server/server.ts";
|
||||
import z from "zod";
|
||||
import { transformStringToEnum, typedZValidator } from "../../../util/validators.ts";
|
||||
import { transformCheckEnum, typedZValidator } from "../../../util/validators.ts";
|
||||
import { PlatformType } from "../../../server/platforms/types.ts";
|
||||
import Steam from "../../../util/steam/steam.ts";
|
||||
import { HTTPStatus } from "@oneday/http-status";
|
||||
|
||||
export const route = createHonoRoute('/account');
|
||||
|
||||
@@ -28,7 +29,7 @@ route.app.get('/bulk', typedZValidator('query', bulkAccountQuerySchema), async c
|
||||
|
||||
const postCreateRateLimiter = new RateLimiter(60, 3);
|
||||
const createAccountBodySchema = z.object({
|
||||
platform: z.string().transform(transformStringToEnum<PlatformType>(PlatformType)),
|
||||
platform: z.coerce.number().transform(transformCheckEnum<PlatformType>(PlatformType)),
|
||||
platformId: z.string().min(14).max(20),
|
||||
deviceId: z.string().min(32).max(64)
|
||||
});
|
||||
@@ -71,9 +72,16 @@ route.app.post('/create', postCreateRateLimiter.middle(), typedZValidator('form'
|
||||
|
||||
});
|
||||
|
||||
route.app.use(authenticate);
|
||||
|
||||
route.app.get('/me', c => {
|
||||
route.app.get('/me', authenticate, c => {
|
||||
const profile = c.get('profile');
|
||||
return c.json(profile.selfExport());
|
||||
});
|
||||
|
||||
const getAccountByIdParamSchema = z.object({
|
||||
id: z.coerce.number().max(Math.pow(2, 31))
|
||||
});
|
||||
route.app.get('/:id', typedZValidator('param', getAccountByIdParamSchema), async c => {
|
||||
const prof = await Server.Profiles.get(c.req.valid('param').id);
|
||||
if (prof) return c.json(prof.export());
|
||||
else return statusResponse(c, HTTPStatus.NotFound);
|
||||
});
|
||||
8
src/routes/api/routes/announcement.ts
Normal file
8
src/routes/api/routes/announcement.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import Server from "../../../server/server.ts";
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute("/announcement");
|
||||
|
||||
route.app.get('/v1/get', c => {
|
||||
return c.json(Server.getAnnouncements());
|
||||
});
|
||||
@@ -24,4 +24,12 @@ route.app.post('/v2/set', typedZValidator('json', profileAvatarSchema), async c
|
||||
const outfit = c.req.valid('json');
|
||||
await c.get('profile').Avatar.setAvatar(outfit);
|
||||
return c.status(200);
|
||||
});
|
||||
|
||||
route.app.get('/v3/saved', c => {
|
||||
return c.json([]); // stub
|
||||
});
|
||||
|
||||
route.app.get('/v2/gifts', c => {
|
||||
return c.json([]); // stub
|
||||
});
|
||||
19
src/routes/api/routes/challenge.ts
Normal file
19
src/routes/api/routes/challenge.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute('/challenge');
|
||||
|
||||
route.app.get('/v2/getCurrent', c => {
|
||||
return c.json({
|
||||
ChallengeMapId: 0,
|
||||
CompletedRequired: false,
|
||||
StartAt: new Date(new Date().getTime() - 604_800_000).toISOString(),
|
||||
EndAt: new Date(new Date().getTime() + 999_999_999_999).toISOString(),
|
||||
ServerTime: new Date().toISOString(),
|
||||
Challenges: [],
|
||||
Gift: {
|
||||
GiftDropId: 0,
|
||||
Xp: 0,
|
||||
Level: 0
|
||||
}
|
||||
}) // stub
|
||||
});
|
||||
171
src/routes/api/routes/checklist.ts
Normal file
171
src/routes/api/routes/checklist.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
import { ObjectiveType } from "../../../server/objectives/base.ts";
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute('/checklist');
|
||||
|
||||
route.app.get('/v1/current', c => {
|
||||
return c.json([
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
},
|
||||
{
|
||||
Order: 1,
|
||||
Objective: ObjectiveType.CompleteAnyDaily,
|
||||
Count: 1,
|
||||
CreditAmount: -1
|
||||
}
|
||||
]); // stub
|
||||
});
|
||||
23
src/routes/api/routes/communityboard.ts
Normal file
23
src/routes/api/routes/communityboard.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute("/communityboard");
|
||||
|
||||
route.app.get('/v1/current', c => {
|
||||
return c.json({
|
||||
FeaturedPlayer: {
|
||||
Id: 1,
|
||||
TitleOverride: "",
|
||||
UrlOverride: ""
|
||||
},
|
||||
FeaturedRoomGroup: {
|
||||
Name: "",
|
||||
FeaturedRooms: []
|
||||
},
|
||||
CurrentAnnouncement: {
|
||||
Message: "Galvanic Corrosion",
|
||||
MoreInfoUrl: ""
|
||||
},
|
||||
InstagramImages: [],
|
||||
Videos: []
|
||||
}); // stub
|
||||
});
|
||||
8
src/routes/api/routes/consumables.ts
Normal file
8
src/routes/api/routes/consumables.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import Server from "../../../server/server.ts";
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute("/consumables");
|
||||
|
||||
route.app.get('/v1/getUnlocked', c => {
|
||||
return c.json(Server.Consumables.getAllDev());
|
||||
});
|
||||
7
src/routes/api/routes/equipment.ts
Normal file
7
src/routes/api/routes/equipment.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute("/equipment");
|
||||
|
||||
route.app.get('/v2/getUnlocked', c => {
|
||||
return c.json([]); // stub
|
||||
});
|
||||
7
src/routes/api/routes/images.ts
Normal file
7
src/routes/api/routes/images.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute('/images');
|
||||
|
||||
route.app.get('/v2/named', c => {
|
||||
return c.json([]); // stub
|
||||
});
|
||||
10
src/routes/api/routes/objectives.ts
Normal file
10
src/routes/api/routes/objectives.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute('/objectives');
|
||||
|
||||
route.app.get('/v1/myprogress', c => {
|
||||
return c.json({
|
||||
Objectives: [],
|
||||
ObjectiveGroups: []
|
||||
}); // stub
|
||||
});
|
||||
10
src/routes/api/routes/playerevents.ts
Normal file
10
src/routes/api/routes/playerevents.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute('/playerevents');
|
||||
|
||||
route.app.get('/v1/all', c => {
|
||||
return c.json({
|
||||
Created: [],
|
||||
Responses: []
|
||||
}) // stub
|
||||
});
|
||||
@@ -14,14 +14,14 @@ const getProgParamSchema = z.object({
|
||||
id: z.coerce.number()
|
||||
});
|
||||
route.app.get('/v1/progression/:id', authenticate, typedZValidator('param', getProgParamSchema), async c => {
|
||||
return c.json(await c.get('profile').Reputation.export());
|
||||
return c.json(await c.get('profile').Progression.get());
|
||||
});
|
||||
|
||||
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;
|
||||
route.app.post('/v1/progression/bulk', authenticate, typedZValidator('json', getProgBulkBodySchema), async c => {
|
||||
const ids = c.req.valid('json').Ids;
|
||||
|
||||
if (typeof ids == 'object') {
|
||||
const profs = await Server.Profiles.getMany(...ids);
|
||||
|
||||
7
src/routes/api/routes/playersubscriptions.ts
Normal file
7
src/routes/api/routes/playersubscriptions.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
|
||||
export const route = createHonoRoute("/playersubscriptions");
|
||||
|
||||
route.app.get('/v1/my', c => {
|
||||
return c.json([]); // stub
|
||||
});
|
||||
@@ -8,7 +8,6 @@ route.app.get('/v2/get', c => {
|
||||
return c.json([]);
|
||||
});
|
||||
|
||||
// deno-lint-ignore require-await
|
||||
route.app.post('/v1/bulkignoreplatformusers', async c => {
|
||||
route.app.post('/v1/bulkignoreplatformusers', c => {
|
||||
return statusResponse(c, HTTPStatus.OK);
|
||||
});
|
||||
@@ -2,6 +2,7 @@ import z from "zod";
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
import { typedZValidator } from "../../../util/validators.ts";
|
||||
import Server from "../../../server/server.ts";
|
||||
import { authenticate } from "../../../util/api.ts";
|
||||
|
||||
export const route = createHonoRoute("/rooms");
|
||||
|
||||
@@ -23,4 +24,13 @@ route.app.get('/v2/name/:name', typedZValidator('param', getRoomByNameParamSchem
|
||||
const room = await Server.Rooms.get(id);
|
||||
if (room == null) return await nxt();
|
||||
else return c.json((await room.export()).Room);
|
||||
});
|
||||
|
||||
route.app.get('/v2/myrooms', authenticate, async c => {
|
||||
const myrooms = c.get('profile').Rooms.getRooms().values().toArray();
|
||||
const factories = await Server.Rooms.getMany(...myrooms);
|
||||
const exs = await Promise.all(factories.map(factory => factory.export()));
|
||||
const rooms = exs.map(ex => ex.Room);
|
||||
|
||||
return c.json(rooms);
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import z from "zod";
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
import { transformStringToEnum, typedZValidator } from "../../../util/validators.ts";
|
||||
import { transformCheckEnum, typedZValidator } from "../../../util/validators.ts";
|
||||
import { PlatformType } from "../../../server/platforms/types.ts";
|
||||
import Server from "../../../server/server.ts";
|
||||
import { authenticate } from "../../../util/api.ts";
|
||||
@@ -11,7 +11,7 @@ const log = new Logging("CachedLoginDebug");
|
||||
export const route = createHonoRoute("/cachedlogin");
|
||||
|
||||
const cachedLoginFetchParamSchema = z.object({
|
||||
platformType: z.string().transform(transformStringToEnum<PlatformType>(PlatformType)),
|
||||
platformType: z.coerce.number().transform(transformCheckEnum<PlatformType>(PlatformType)),
|
||||
platformId: z.string().min(4)
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
import z from "zod";
|
||||
import { transformStringToEnum, typedZValidator } from "../../../util/validators.ts";
|
||||
import { transformCheckEnum, typedZValidator } from "../../../util/validators.ts";
|
||||
import { DeviceClass, PlatformType, TokenFormat, TokenType } from "../../../server/platforms/types.ts";
|
||||
import { steamAuthTicketSchema } from "../../../server/platforms/base.ts";
|
||||
import { gameVerString } from "../../api/routes/versioncheck.ts";
|
||||
@@ -16,13 +16,13 @@ export const route = createHonoRoute("/connect");
|
||||
|
||||
const authBodyBaseSchema = z.object({
|
||||
client_id: z.literal("recroom"),
|
||||
platform: z.string().transform(Number).transform((arg, ctx) => { // we only support steam right now
|
||||
platform: z.coerce.number().transform((arg, ctx) => { // we only support steam right now
|
||||
if (arg !== PlatformType.Steam) ctx.addIssue("platform was not Steam");
|
||||
else return PlatformType.Steam;
|
||||
}),
|
||||
platform_id: z.string().min(4),
|
||||
device_id: z.string().min(4),
|
||||
device_class: z.string().transform(transformStringToEnum<DeviceClass>(DeviceClass)),
|
||||
device_class: z.string().transform(transformCheckEnum<DeviceClass>(DeviceClass)),
|
||||
time: z.coerce.date(),
|
||||
ver: z.literal(gameVerString),
|
||||
asid: z.coerce.number(),
|
||||
@@ -39,7 +39,7 @@ const authBodyBaseSchema = z.object({
|
||||
|
||||
const cachedLoginGrantSchema = authBodyBaseSchema.extend({
|
||||
grant_type: z.literal('cached_login'),
|
||||
account_id: z.string().transform(Number),
|
||||
account_id: z.coerce.number(),
|
||||
});
|
||||
const refreshTokenGrantSchema = authBodyBaseSchema.extend({
|
||||
grant_type: z.literal('refresh_token'),
|
||||
@@ -97,24 +97,25 @@ route.app.post('/token', typedZValidator('form', tokenGrantSchema), async c => {
|
||||
|
||||
const profile = await Server.Profiles.get(token.sub);
|
||||
if (!profile) return error(TokenRequestError.AccessDenied);
|
||||
const accessToken = await Server.Platforms.getToken(profile.getId(), TokenType.Access);
|
||||
const accessToken = await Server.Platforms.getToken(profile, TokenType.Access);
|
||||
const refreshToken = await Server.Platforms.getToken(profile, TokenType.Refresh);
|
||||
|
||||
return c.json({
|
||||
access_token: accessToken,
|
||||
refresh_token: form.refresh_token,
|
||||
refresh_token: refreshToken,
|
||||
});
|
||||
} catch (err) {
|
||||
log.w(`Authentication error (token req): ${(err as Error).stack}`);
|
||||
return error(TokenRequestError.InvalidClient);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (logins.find(login => login.accountId === form.account_id)) {
|
||||
const profile = await Server.Profiles.get(form.account_id);
|
||||
if (!profile) return error(TokenRequestError.InvalidRequest, "No such profile");
|
||||
await Server.Platforms.updateLastLoginTime(form.platform, form.platform_id, form.account_id);
|
||||
const accessToken = await Server.Platforms.getToken(profile.getId(), TokenType.Access);
|
||||
const refreshToken = await Server.Platforms.getToken(profile.getId(), TokenType.Refresh);
|
||||
const accessToken = await Server.Platforms.getToken(profile, TokenType.Access);
|
||||
const refreshToken = await Server.Platforms.getToken(profile, TokenType.Refresh);
|
||||
|
||||
return c.json({
|
||||
access_token: accessToken,
|
||||
|
||||
@@ -1,50 +1,7 @@
|
||||
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'
|
||||
]);
|
||||
@@ -1,13 +1,76 @@
|
||||
import { HTTPStatus } from "@oneday/http-status";
|
||||
import { statusResponse } from "../../../util/api.ts";
|
||||
import { authenticate, loginLockMiddleware, statusResponse } from "../../../util/api.ts";
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
import Server from "../../../server/server.ts";
|
||||
import z from "zod";
|
||||
import { typedZValidator } from "../../../util/validators.ts";
|
||||
import { type MatchmakingResponse } from "../../../server/matchmaking/base.ts";
|
||||
import { roomNameSchema } from "../../../server/rooms/base.ts";
|
||||
|
||||
export const route = createHonoRoute("/goto");
|
||||
|
||||
route.app.post('/room/:roomName', c => {
|
||||
return statusResponse(c, HTTPStatus.NotImplemented);
|
||||
const gotoRoomBodySchema = z.object({
|
||||
CreatePrivateInstance: z.boolean().optional(),
|
||||
ExpectedPlayerIds: z.array(z.int()).optional(),
|
||||
BypassMovementModeRestriction: z.boolean().optional()
|
||||
});
|
||||
|
||||
route.app.post('/room/:roomName/:subRoomName', c => {
|
||||
return statusResponse(c, HTTPStatus.NotImplemented);
|
||||
});
|
||||
const gotoRoomParamSchema = z.object({
|
||||
roomName: roomNameSchema
|
||||
});
|
||||
route.app.post('/room/:roomName',
|
||||
authenticate,
|
||||
loginLockMiddleware,
|
||||
|
||||
typedZValidator('json', gotoRoomBodySchema),
|
||||
typedZValidator('param', gotoRoomParamSchema),
|
||||
|
||||
async c => {
|
||||
const body = c.req.valid("json");
|
||||
|
||||
const res = await Server.Matchmaking.matchmake({
|
||||
roomName: c.req.param('roomName'),
|
||||
private: body.CreatePrivateInstance,
|
||||
profile: c.get('profile')
|
||||
});
|
||||
if (!res) return statusResponse(c, HTTPStatus.InternalServerError, "Matchmaking failed");
|
||||
|
||||
const m: MatchmakingResponse = {
|
||||
roomInstance: res.roomInstance ? res.roomInstance.export() : undefined,
|
||||
errorCode: res.errorCode
|
||||
}
|
||||
return c.json(m);
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
const gotoSubroomParamSchema = gotoRoomParamSchema.extend({
|
||||
subRoomName: roomNameSchema
|
||||
});
|
||||
route.app.post('/room/:roomName/:subRoomName',
|
||||
|
||||
authenticate,
|
||||
loginLockMiddleware,
|
||||
|
||||
typedZValidator('json', gotoRoomBodySchema),
|
||||
typedZValidator('param', gotoSubroomParamSchema),
|
||||
|
||||
async c => {
|
||||
const body = c.req.valid("json");
|
||||
|
||||
const res = await Server.Matchmaking.matchmake({
|
||||
roomName: c.req.param('roomName'),
|
||||
subRoomName: c.req.param('subRoomName'),
|
||||
private: body.CreatePrivateInstance,
|
||||
profile: c.get('profile')
|
||||
});
|
||||
if (!res) return statusResponse(c, HTTPStatus.InternalServerError, "Matchmaking failed");
|
||||
|
||||
const m: MatchmakingResponse = {
|
||||
roomInstance: res.roomInstance ? res.roomInstance.export() : undefined,
|
||||
errorCode: res.errorCode
|
||||
}
|
||||
return c.json(m);
|
||||
}
|
||||
|
||||
);
|
||||
@@ -1,20 +1,70 @@
|
||||
import { authenticate, statusResponse } from "../../../util/api.ts";
|
||||
import z from "zod";
|
||||
import Server from "../../../server/server.ts";
|
||||
import { authenticate, loginLockMiddleware, statusResponse } from "../../../util/api.ts";
|
||||
import { createHonoRoute } from "../../../util/import.ts";
|
||||
import { loginLockMiddleware } from "../root.ts";
|
||||
import { HTTPStatus } from "@oneday/http-status";
|
||||
import { transformCheckEnum, typedZValidator } from "../../../util/validators.ts";
|
||||
import { PlayerStatusVisibility, VRMovementMode } from "../../../server/presence/base.ts";
|
||||
|
||||
export const route = createHonoRoute("/player");
|
||||
|
||||
route.app.use(authenticate);
|
||||
|
||||
route.app.post('/login', authenticate, loginLockMiddleware, async c => {
|
||||
const playerIdsQuerySchema = z.object({
|
||||
id: z.union([z.coerce.number(), z.array(z.coerce.number())])
|
||||
});
|
||||
route.app.get('/', typedZValidator('query', playerIdsQuerySchema), async c => {
|
||||
const id = c.req.valid('query').id;
|
||||
|
||||
if (typeof id == 'object') {
|
||||
const profs = await Server.Profiles.getMany(...id);
|
||||
return c.json(profs.map(prof => Server.Presence.getPresence(prof).export()));
|
||||
} else {
|
||||
const prof = await Server.Profiles.get(id);
|
||||
if (!prof) return c.json([]);
|
||||
|
||||
return c.json([Server.Presence.getPresence(prof).export()]);
|
||||
}
|
||||
});
|
||||
|
||||
route.app.post('/player/vrmovementmode', authenticate, loginLockMiddleware, async c => {
|
||||
return statusResponse(c, HTTPStatus.OK); // stub
|
||||
route.app.post('/login', authenticate, loginLockMiddleware, c => {
|
||||
const pres = Server.Presence.getPresence(c.get('profile'));
|
||||
pres.updateLastSeen();
|
||||
|
||||
return statusResponse(c, HTTPStatus.OK);
|
||||
});
|
||||
route.app.post('/logout', authenticate, loginLockMiddleware, c => {
|
||||
const pres = Server.Presence.getPresence(c.get('profile'));
|
||||
pres.updateLastSeen();
|
||||
|
||||
pres.setStatusVisibility(PlayerStatusVisibility.Offline);
|
||||
|
||||
c.get('profile').updateInstance(null);
|
||||
|
||||
Server.Instances.clearEmptyInstances();
|
||||
|
||||
return statusResponse(c, HTTPStatus.OK);
|
||||
});
|
||||
|
||||
route.app.post('/player/statusvisibility', authenticate, loginLockMiddleware, async c => {
|
||||
return statusResponse(c, HTTPStatus.OK); // stub
|
||||
const vrMovementModeBodySchema = z.object({
|
||||
vrMovementMode: z.coerce.number().transform(transformCheckEnum<VRMovementMode>(VRMovementMode))
|
||||
});
|
||||
route.app.put('/vrmovementmode', authenticate, typedZValidator('form', vrMovementModeBodySchema), c => {
|
||||
const pres = Server.Presence.getPresence(c.get('profile'));
|
||||
pres.updateLastSeen();
|
||||
|
||||
return statusResponse(c, HTTPStatus.OK);
|
||||
});
|
||||
const statusVisibilityBodySchema = z.object({
|
||||
statusVisibility: z.coerce.number().transform(transformCheckEnum<PlayerStatusVisibility>(PlayerStatusVisibility))
|
||||
});
|
||||
route.app.put('/statusvisibility', authenticate, typedZValidator('form', statusVisibilityBodySchema), c => {
|
||||
const pres = Server.Presence.getPresence(c.get('profile'));
|
||||
pres.updateLastSeen();
|
||||
|
||||
return statusResponse(c, HTTPStatus.OK);
|
||||
});
|
||||
|
||||
route.app.post('/heartbeat', authenticate, loginLockMiddleware, c => {
|
||||
const pres = Server.Presence.getPresence(c.get('profile'));
|
||||
|
||||
return c.json(pres.export());
|
||||
});
|
||||
Reference in New Issue
Block a user