This commit is contained in:
2025-09-21 17:47:28 -04:00
parent e759f90a3f
commit 138243a06d
6 changed files with 81 additions and 6 deletions

View File

@@ -1,8 +1,9 @@
import z from "zod";
import { createHonoRoute } from "../../../util/import.ts";
import { authenticate } from "../../../util/api.ts";
import { authenticate, statusResponse } from "../../../util/api.ts";
import { typedZValidator } from "../../../util/validators.ts";
import Server from "../../../server/server.ts";
import { HTTPStatus } from "@oneday/http-status";
export const route = createHonoRoute("/players");
@@ -13,8 +14,10 @@ route.app.get('/v2/progression/bulk', c => {
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').Progression.get());
route.app.get('/v1/progression/:id', typedZValidator('param', getProgParamSchema), async c => {
const prof = await Server.Profiles.get(c.req.valid('param').id);
if (!prof) return statusResponse(c, HTTPStatus.NotFound);
return c.json(await prof.Progression.get());
});
const getProgBulkBodySchema = z.object({

View File

@@ -0,0 +1,21 @@
import z from "zod";
import { authenticate } from "../../../util/api.ts";
import { createHonoRoute } from "../../../util/import.ts";
import { transformCheckEnum, typedZValidator } from "../../../util/validators.ts";
import { CurrencyType, StorefrontBalanceType, StorefrontTypes } from "../../../server/storefronts/types.ts";
export const route = createHonoRoute("/storefronts");
const getGiftDropStoreParamSchema = z.object({
storeId: z.coerce.number().transform(transformCheckEnum<StorefrontTypes>(StorefrontTypes))
});
route.app.get('/v3/giftdropstore/:storeId', authenticate, typedZValidator('param', getGiftDropStoreParamSchema), c => {
return c.json({ StoreItems: [] }); // stub
});
const getCurrencyByTypeParamSchema = z.object({
currencyType: z.coerce.number().transform(transformCheckEnum<CurrencyType>(CurrencyType))
});
route.app.get('/v4/balance/:currencyType', authenticate, typedZValidator('param', getCurrencyByTypeParamSchema), c => {
return c.json([ { Balance: 0, CurrencyType: c.req.valid('param').currencyType, BalanceType: StorefrontBalanceType.NonPurchasedNonP2P } ]); // stub
});

View File

@@ -35,7 +35,8 @@ const authBodyBaseSchema = z.object({
} catch {
ctx.addIssue("Steam Auth Ticket could not be parsed");
}
})
}),
"x-patch-plugin-hash": z.string()
});
const cachedLoginGrantSchema = authBodyBaseSchema.extend({
@@ -80,6 +81,7 @@ route.app.post('/token', typedZValidator('form', tokenGrantSchema), async c => {
const form = c.req.valid('form');
if (typeof form.platform_auth == 'undefined' || typeof form.platform == 'undefined') return error(TokenRequestError.AccessDenied);
if (typeof form.device_class !== 'number') return error(TokenRequestError.AccessDenied);
const { valid } = await Steam.AuthenticateUserTicket(form.platform_auth, form.platform_id);
if (valid == SteamAuthResult.Failure) return error(TokenRequestError.AccessDenied, TokenRequestErrorDescriptions.PlatformVerificationFailed);
@@ -99,6 +101,8 @@ route.app.post('/token', typedZValidator('form', tokenGrantSchema), async c => {
const profile = await Server.Profiles.get(token.sub);
if (!profile) return error(TokenRequestError.AccessDenied);
await profile.Matchmaking.setLastDeviceClass(form.device_class!);
return c.json({
access_token: await Server.Platforms.getToken(profile, TokenType.Access),
refresh_token: await Server.Platforms.getToken(profile, TokenType.Refresh),
@@ -113,7 +117,9 @@ route.app.post('/token', typedZValidator('form', tokenGrantSchema), async c => {
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);
await profile.Matchmaking.setLastDeviceClass(form.device_class!);
log.d(`Patch hash: ${form["x-patch-plugin-hash"]}`);
return c.json({
access_token: await Server.Platforms.getToken(profile, TokenType.Access),
refresh_token: await Server.Platforms.getToken(profile, TokenType.Refresh),

View File

@@ -34,7 +34,7 @@ export class ServerMatchmakingBase extends ServerContentBase {
if (options.roomName === 'DormRoom')
return `@${options.profile.getUsername()}'s Dorm`;
else {
if (options.subRoomName || options.subRoomName !== "Home") return `^${options.roomName}.${options.subRoomName}`;
if (typeof options.subRoomName !== 'undefined' && options.subRoomName !== "Home") return `^${options.roomName}.${options.subRoomName}`;
else return `^${options.roomName}`;
}
}
@@ -73,7 +73,10 @@ export class ServerMatchmakingBase extends ServerContentBase {
let allInstances = this.server.Instances.getAllInstances();
const subroom = (await targetRoom.getAllSubrooms()).values().find(factory => factory.Name == options.subRoomName);
// if a subroom was specified, filter instances that
// filter by instances with the same room ID
allInstances = new Set(allInstances.values().filter(inst => inst.roomId == targetRoom.getRoomId()));
// if a subroom was specified, filter by instances with the same scene ID
if (subroom) allInstances = new Set(allInstances.values().filter(inst => inst.subRoomId == subroom.RoomSceneId));
// filter out instances that are in progress and do not support joininprogress
@@ -86,6 +89,7 @@ export class ServerMatchmakingBase extends ServerContentBase {
if (!foundInstance) {
const matchmakeableSubrooms = (await targetRoom.getAllSubrooms()).values().filter(scene => scene.CanMatchmakeInto).toArray();
if (matchmakeableSubrooms.length === 0) return { errorCode: MatchmakingErrorCode.RoomIsNotActive };
const index = Math.floor(Math.random() * matchmakeableSubrooms.length);
log.d(`Scene ${matchmakeableSubrooms[index].RoomSceneId} was chosen for matchmaking into new instance of room ${targetRoom.getRoomId()}`);

View File

@@ -0,0 +1,41 @@
export enum StorefrontTypes {
None,
LaserTag,
RecCenter,
Watch,
Quest_LostSkulls = 100,
Quest_Dracula,
Quest_GoldenTrophy,
Quest_CrimsonCauldron,
RecRoyale = 200,
Cafe = 300,
Paintball = 400,
Paintball_River,
Paintball_Homestead,
Paintball_Quarry,
Paintball_ClearCut,
Paintball_Spillway,
Paintball_SunsetDriveIn,
Bowling = 500,
StuntRunner = 600,
DormMirror = 700
}
export enum CurrencyType {
Invalid,
LaserTagTickets,
RecCenterTokens,
LostSkullsGold = 100,
DraculaSilver,
RecRoyale_Season1 = 200
}
export enum StorefrontBalanceType {
NonPurchasedNonP2P = -2,
NonPurchasedP2P,
SteamPurchased,
OculusPurchased,
PlayStationPurchased,
MicrosoftPurchased,
IOSPurchased = 5
}