mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-25 23:18:51 -07:00
[msc] make playersettings more efficient
This commit is contained in:
@@ -38,6 +38,8 @@ import {
|
||||
MatchmakingErrorCode,
|
||||
MessageType,
|
||||
MOST_ACTIVE_CLUBHOUSE_LIMIT,
|
||||
putPlayerSettingsIfChanged,
|
||||
readPlayerSettings,
|
||||
recordRoomVisit,
|
||||
recordStat,
|
||||
refreshInstanceFullness,
|
||||
@@ -420,10 +422,7 @@ async function getPlayerSettings(
|
||||
env: Env,
|
||||
accountId: number
|
||||
): Promise<Record<string, string> | null> {
|
||||
return env.RECFLARE_PLAYER_SETTINGS.get<Record<string, string>>(
|
||||
`player:${accountId}`,
|
||||
'json'
|
||||
).catch(() => null)
|
||||
return readPlayerSettings(env.RECFLARE_PLAYER_SETTINGS, accountId).catch(() => null)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,15 +443,16 @@ async function readAvoidJuniors(env: Env, accountId: number): Promise<boolean> {
|
||||
*
|
||||
* The write MERGES, exactly as the `playersettings` worker's own PUT does: the map holds
|
||||
* every setting the player has (OOBE state, tutorial mask, …), so storing this one on its
|
||||
* own would wipe the rest. Read-modify-write on KV isn't atomic, but the same is true of
|
||||
* the settings worker, and two writers racing over one player's own settings means that
|
||||
* player toggling two options in the same instant.
|
||||
* own would wipe the rest. The key is whichever spelling the map already carries, which is
|
||||
* why this doesn't go through `mergePlayerSettings` — but like it, re-posting the stored
|
||||
* value writes nothing. A KV read failure throws (a 500) rather than reading as an empty
|
||||
* map, which would store this one key over everything the player had.
|
||||
*/
|
||||
async function writeAvoidJuniors(env: Env, accountId: number, value: boolean): Promise<void> {
|
||||
const stored = (await getPlayerSettings(env, accountId)) ?? {}
|
||||
const stored = await readPlayerSettings(env.RECFLARE_PLAYER_SETTINGS, accountId)
|
||||
const merged: Record<string, string> = { ...stored }
|
||||
merged[findAvoidJuniorsKey(merged) ?? AVOID_JUNIORS_KEY] = value ? 'True' : 'False'
|
||||
await env.RECFLARE_PLAYER_SETTINGS.put(`player:${accountId}`, JSON.stringify(merged))
|
||||
await putPlayerSettingsIfChanged(env.RECFLARE_PLAYER_SETTINGS, accountId, stored, merged)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -642,6 +642,21 @@ describe('public endpoints', () => {
|
||||
expect(await stored(3202)).toEqual({ AVOID_JUNIORS: 'False' })
|
||||
})
|
||||
|
||||
// Re-posting the stored value writes nothing to KV — writes are the cost, and the
|
||||
// client posts this freely. The raw value is seeded with whitespace JSON.stringify
|
||||
// never produces; surviving the PUT untouched means no write happened. Holds across
|
||||
// the loose key match too: `AVOID_JUNIORS: 'True'` already says what `avoidJuniors=True`
|
||||
// asks for.
|
||||
test('does not write KV when the value is already stored', async () => {
|
||||
const padded = '{ "Recroom.OOBE": "77", "AVOID_JUNIORS": "True" }'
|
||||
await env.RECFLARE_PLAYER_SETTINGS.put('player:3205', padded)
|
||||
expect(await write(3205, 'avoidJuniors=True')).toBe(true)
|
||||
expect(await env.RECFLARE_PLAYER_SETTINGS.get('player:3205', 'text')).toBe(padded)
|
||||
|
||||
expect(await write(3205, 'avoidJuniors=False')).toBe(false)
|
||||
expect(await stored(3205)).toEqual({ 'Recroom.OOBE': '77', AVOID_JUNIORS: 'False' })
|
||||
})
|
||||
|
||||
test('accepts a JSON body', async () => {
|
||||
const res = await exports.default.fetch(`${ORIGIN}/player/avoidjuniors`, {
|
||||
method: 'PUT',
|
||||
|
||||
Reference in New Issue
Block a user