Changes (/shrug)

* Added middleware timer for performance debugging
* Relationships and avatar database keys
* CDN
* Profiles are SelfAccounts in most cases, rather than Accounts
* Simplified profile content management
* Progression fixes
* Relationships (favorites not yet implemented)
* Relationship backend
* Relationship and avatar routes
This commit is contained in:
2025-03-31 01:48:46 -04:00
parent 639e809a20
commit 638c0fbf1f
19 changed files with 999 additions and 65 deletions

View File

@@ -9,6 +9,7 @@ import { route as PlayersRoute } from "./api/players.ts"
import { route as SettingsRoute } from "./api/settings.ts";
import { route as PlayerSubscriptionsRoute } from "./api/playersubscriptions.ts";
import { route as PlayerReputationRoute } from "./api/playerReputation.ts";
import { route as AvatarRoute } from "./api/avatar.ts";
export const route = APIUtils.createRouter("/api");
@@ -21,4 +22,5 @@ route.router.use(RelationshipsRoute.path, RelationshipsRoute.router);
route.router.use(PlayersRoute.path, PlayersRoute.router);
route.router.use(SettingsRoute.path, SettingsRoute.router);
route.router.use(PlayerSubscriptionsRoute.path, PlayerSubscriptionsRoute.router);
route.router.use(PlayerReputationRoute.path, PlayerReputationRoute.router);
route.router.use(PlayerReputationRoute.path, PlayerReputationRoute.router);
route.router.use(AvatarRoute.path, AvatarRoute.router);

15
src/routes/api/avatar.ts Normal file
View File

@@ -0,0 +1,15 @@
import { APIUtils } from "../../apiutils.ts";
import { AuthType } from "../../data/users.ts";
export const route = APIUtils.createRouter("/avatar");
route.router.get('/v2',
APIUtils.Authentication,
APIUtils.AuthenticationType(AuthType.Game),
async (_rq, rs) => {
rs.json(await rs.locals.profile.Avatar.getAvatar());
},
);

View File

@@ -1,5 +1,7 @@
import { APIUtils } from "../../apiutils.ts";
import { z } from "zod";
import { APIUtils, NoBody } from "../../apiutils.ts";
import { AuthType } from "../../data/users.ts";
import express from "express";
export const route = APIUtils.createRouter("/relationships");
@@ -12,4 +14,28 @@ route.router.get('/v2/get',
rs.json(rs.locals.profile.Relationships.getRelationships());
}
);
interface BulkIngorePlatformBody {
Platform: string,
PlatformIds: string[]
}
const bulkIgnorePlatformSchema = z.object({
Platform: z.number(),
PlatformIds: z.array(z.string())
});
route.router.post('/v1/bulkignoreplatformusers',
APIUtils.Authentication,
APIUtils.AuthenticationType(AuthType.Game),
express.json(),
APIUtils.validateRequestBody(bulkIgnorePlatformSchema),
(rq: express.Request<NoBody, NoBody, BulkIngorePlatformBody>, rs: express.Response) => {
for (const id of rq.body.PlatformIds) rs.locals.profile.Relationships.ignoreAllAssociatedPlatformUsers(id);
rs.sendStatus(200);
},
);

View File

@@ -6,6 +6,7 @@ import { Config } from "../../config.ts";
import Logging from "@proxnet/undead-logging";
import { z } from "zod";
import { AuthType } from "../../data/users.ts";
import { Redis } from "../../db.ts";
const config = Config.getConfig();
@@ -75,6 +76,7 @@ interface TokenResponseBody {
route.router.post("/token",
APIUtils.startTimer,
APIUtils.Authentication,
APIUtils.AuthenticationType(AuthType.Web),
express.urlencoded({ extended: true }),
@@ -83,6 +85,7 @@ route.router.post("/token",
async (
rq: express.Request<NoBody, NoBody, TokenRequestBody>,
rs: express.Response<TokenResponseBody>,
nxt: express.NextFunction
) => {
function requestFailed(msg: string = "invalid_request") {
@@ -146,6 +149,7 @@ route.router.post("/token",
rs.locals.user.addAssociatedDeviceId(rq.body.device_id);
rs.locals.user.addAssociatedPlatformId(rq.body.platform_id);
Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.PlatformAssociations, rq.body.platform_id), targetAccount);
const profile = UnifiedProfile.get(targetAccount);
if (!(await Profile.exists(profile.getId()))) {
@@ -163,5 +167,9 @@ route.router.post("/token",
});
await profile.setKnownDeviceClass(Number(rq.body.device_class));
nxt();
},
APIUtils.stopTimer
);

6
src/routes/cdn.ts Normal file
View File

@@ -0,0 +1,6 @@
import { APIUtils } from "../apiutils.ts";
import { route as ConfigRoute } from "./cdn/config.ts";
export const route = APIUtils.createRouter("/cdn");
route.router.use(ConfigRoute.path, ConfigRoute.router);

13
src/routes/cdn/config.ts Normal file
View File

@@ -0,0 +1,13 @@
import { APIUtils } from "../../apiutils.ts";
export const route = APIUtils.createRouter("/config");
route.router.get('/LoadingScreenTipData',
APIUtils.Authentication,
(_rq, rs) => {
rs.json([]);
}
);

View File

@@ -84,7 +84,6 @@ route.router.post('/heartbeat',
async (_rq, rs) => {
const pres = await Presence.get(rs.locals.profile);
await pres.update();
log.d(`pres heartbeat for ${rs.locals.profile.getId()}: ${JSON.stringify(await pres.export())}`);
rs.json(await pres.export());
}