update stream card, update leaderboards on match finished webhook

This commit is contained in:
2025-04-24 00:58:22 +02:00
parent 002fdd4c6d
commit 68540ee136
9 changed files with 362 additions and 63 deletions

View File

@@ -1,6 +1,7 @@
import { discord_router } from '@/server/api/routers/discord'
import { history_router } from '@/server/api/routers/history'
import { leaderboard_router } from '@/server/api/routers/leaderboard'
import { playerStateRouter } from '@/server/api/routers/player-state'
import { createCallerFactory, createTRPCRouter } from '@/server/api/trpc'
/**
@@ -12,6 +13,7 @@ export const appRouter = createTRPCRouter({
history: history_router,
discord: discord_router,
leaderboard: leaderboard_router,
playerState: playerStateRouter,
})
// export type definition of API

View File

@@ -0,0 +1,50 @@
import { createEventIterator, globalEmitter } from '@/lib/events'
import { redis } from '@/server/redis'
import { tracked } from '@trpc/server'
import { z } from 'zod'
import { createTRPCRouter, publicProcedure } from '../trpc'
export type PlayerState = {
status: 'idle' | 'queuing' | 'in_game'
queueStartTime?: number
currentMatch?: {
opponentId: string
startTime: number
}
}
const PLAYER_STATE_KEY = (userId: string) => `player:${userId}:state`
export const playerStateRouter = createTRPCRouter({
getState: publicProcedure
.input(z.string())
.query(async ({ input: userId }) => {
const state = await redis.get(PLAYER_STATE_KEY(userId))
return state ? (JSON.parse(state) as PlayerState) : null
}),
onStateChange: publicProcedure
.input(
z.object({
userId: z.string(),
lastEventId: z.string().optional(),
})
)
.subscription(async function* ({ input, ctx, signal }) {
const iterator = createEventIterator<PlayerState>(
globalEmitter,
`state-change:${input.userId}`,
{ signal: signal }
)
// get initial state
const initialState = await redis.get(PLAYER_STATE_KEY(input.userId))
if (initialState) {
yield tracked('initial', JSON.parse(initialState) as PlayerState)
}
// listen for updates
for await (const [state] of iterator) {
yield tracked(Date.now().toString(), state)
}
}),
})