Unify player profiles across T5 and T6
This commit is contained in:
@@ -42,16 +42,16 @@ it('starts counting at round 2, preserves early stats, and excludes players who
|
||||
await report('game_start', 0, [player(), departed]);
|
||||
await report('round_change', 1, [player(undefined, { kills: 6, score: 1000 }), departed]);
|
||||
expect(getLeaderboard()).toMatchObject({ entries: [], maps: [], total: 0, summary: { players: 0, matches: 0, kills: 0 } });
|
||||
expect(getPlayerProfile('t5', player().guid)).toBeNull();
|
||||
expect(getPlayerProfile(player().guid)).toBeNull();
|
||||
expect(serverMatchHistory()).toEqual({ total: 0, matches: [] });
|
||||
await report('round_change', 2, [player(undefined, { kills: 6, score: 500 })]);
|
||||
expect(getLeaderboard()).toMatchObject({ total: 1, entries: [expect.objectContaining({
|
||||
highestRound: 2, kills: 6, bestScore: 1000, roundsSurvived: 1, gamesPlayed: 1, gamesCompleted: 0
|
||||
})], summary: { players: 1, matches: 1, kills: 6 } });
|
||||
expect(getPlayerProfile('t5', departed.guid)).toBeNull();
|
||||
expect(getPlayerProfile(departed.guid)).toBeNull();
|
||||
await report('game_end', 2, [player(undefined, { kills: 10 })]);
|
||||
const board = getLeaderboard();
|
||||
const profile = getPlayerProfile('t5', player().guid);
|
||||
const profile = getPlayerProfile(player().guid);
|
||||
const history = serverMatchHistory();
|
||||
expect(history).toMatchObject({ total: 1, matches: [{ startPlayers: 2, uniquePlayers: 2, durationMs: 3000, finalRound: 2 }] });
|
||||
await report('game_start');
|
||||
@@ -62,7 +62,7 @@ it('starts counting at round 2, preserves early stats, and excludes players who
|
||||
closeDb();
|
||||
expect(getLeaderboard()).toEqual(board);
|
||||
// Identity timestamps still reflect live presence, but gameplay records do not change.
|
||||
expect(getPlayerProfile('t5', player().guid)).toMatchObject({ stats: profile!.stats, maps: profile!.maps, matches: profile!.matches });
|
||||
expect(getPlayerProfile(player().guid)).toMatchObject({ stats: profile!.stats, maps: profile!.maps, matches: profile!.matches });
|
||||
expect(serverMatchHistory()).toEqual(history);
|
||||
const { GET } = await import('../../src/routes/api/matches/+server.js');
|
||||
expect(await GET({ url: new URL('http://localhost/api/matches?limit=1') }).json()).toEqual(history);
|
||||
@@ -165,13 +165,13 @@ it('persists independent stat high-water marks without adding cumulative snapsho
|
||||
})]);
|
||||
});
|
||||
|
||||
it('keeps a latest player identity across games on different servers without merging different game GUIDs', async () => {
|
||||
it('retains per-game identities while combining the same GUID in one profile', async () => {
|
||||
await report('round_change', 8, [player(undefined, { kills: 111 })]);
|
||||
await report('game_end', 8, [player(undefined, { kills: 120, name: 'New name' })]);
|
||||
await report('game_start');
|
||||
await report('game_end', 2, [player(undefined, { kills: 20, name: 'Latest name' })]);
|
||||
await report('game_end', 5, [player(undefined, { kills: 200, name: 'Other game' })], 't6_zombie_town_1', 'zm_transit');
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { db, closeDb } = await import('../../src/lib/server/db/index.js');
|
||||
expect(db().prepare('SELECT game, guid, name FROM leaderboard_players ORDER BY game').all()).toEqual([
|
||||
{ game: 't5', guid: '2741626', name: 'Latest name' },
|
||||
{ game: 't6', guid: '2741626', name: 'Other game' }
|
||||
@@ -180,6 +180,16 @@ it('keeps a latest player identity across games on different servers without mer
|
||||
expect(db().prepare(`SELECT SUM(p.rounds_survived) AS total FROM leaderboard_match_players p
|
||||
JOIN leaderboard_matches m ON m.id = p.match_id WHERE m.game = 't5' AND p.guid = ?`).get('2741626'))
|
||||
.toEqual({ total: 1 });
|
||||
closeDb();
|
||||
const { getPlayerProfile } = await import('../../src/lib/server/fleet/player-profile.js');
|
||||
const profile = getPlayerProfile(player().guid)!;
|
||||
expect(profile).toMatchObject({ guid: player().guid, name: 'Other game',
|
||||
firstSeen: '2026-09-18T20:00:00.000Z', lastSeen: '2026-09-18T20:00:04.000Z',
|
||||
stats: { gamesPlayed: 3, gamesCompleted: 3, kills: 340, highestRound: 8, bestKills: 200, roundsSurvived: 1 } });
|
||||
expect(profile.matches.map(match => match.game)).toEqual(['t6', 't5', 't5']);
|
||||
await report('game_start', 0, [player(undefined, { name: 'Live name' })]);
|
||||
expect(getPlayerProfile(player().guid)).toMatchObject({ name: 'Live name', lastSeen: '2026-09-18T20:00:05.000Z',
|
||||
stats: profile.stats, maps: profile.maps, matches: profile.matches });
|
||||
});
|
||||
|
||||
it('credits the highest round but only observed survival for a late join or a return after an absent roster', async () => {
|
||||
@@ -312,7 +322,7 @@ it('keeps deleted match identities and starts a separate match when the server n
|
||||
server, server_deleted_at: expect.any(String), status: 'interrupted'
|
||||
});
|
||||
expect(history.find(match => match.id !== original.id)).toMatchObject({ server, server_deleted_at: null, status: 'active' });
|
||||
const profile = getPlayerProfile('t5', player().guid)!;
|
||||
const profile = getPlayerProfile(player().guid)!;
|
||||
expect(profile.stats.gamesPlayed).toBe(2);
|
||||
expect(profile.matches.find(match => match.id === original.id)?.server_deleted_at).toEqual(expect.any(String));
|
||||
expect(profile.stats.kills).toBe(240);
|
||||
|
||||
Reference in New Issue
Block a user