PUBG drop map: live squad map with WebSocket rooms
All checks were successful
Deploy production / deploy (push) Successful in 1m15s
All checks were successful
Deploy production / deploy (push) Successful in 1m15s
- server.js wraps Bun.serve to add /ws/<channel> upgrades (same server and port) and serve the map tiles from the host mount; Dockerfile now runs bun ./server.js - ws hub (channel registry, origin check) + pubg-map channel: rooms by unguessable code, validated + rate-limited messages, per-room write queue, presence - games.pubg_rooms / pubg_matches / pubg_markers; per-match sessions with history - /trackers/games/pubg/map hub (owner: rooms, landings over time, history) and /trackers/games/pubg/map/<code> fullscreen Leaflet map (all 11 maps) - deploy-remote.sh bind-mounts ~/pubg-maps; scripts/build-pubg-tiles.py rebuilds it
This commit is contained in:
@@ -27,3 +27,4 @@ export * from './music';
|
||||
export * from './hardware';
|
||||
export * from './dataholders';
|
||||
export * from './stats';
|
||||
export * from './pubg-map';
|
||||
|
||||
62
src/lib/server/db/schema/pubg-map.ts
Normal file
62
src/lib/server/db/schema/pubg-map.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { doublePrecision, index, integer, text, uniqueIndex } from 'drizzle-orm/pg-core';
|
||||
import { gamesSchema } from './schemas';
|
||||
import { id, timestamps, timestamptz } from './helpers';
|
||||
|
||||
// The live PUBG drop map (/trackers/games/pubg/map): rooms that friends join with an
|
||||
// unguessable share code, one match per game played (map, landings, plane path, hotspots,
|
||||
// vehicles, notes), and the markers themselves. Only the owner creates rooms and deletes
|
||||
// history; anyone with a room's code edits that room's current match over the site WebSocket.
|
||||
|
||||
export const pubgRooms = gamesSchema.table('pubg_rooms', {
|
||||
id: id(),
|
||||
/** 20 characters of base62; the share link is /trackers/games/pubg/map/<code>. */
|
||||
code: text('code').notNull().unique(),
|
||||
name: text('name').notNull(),
|
||||
...timestamps
|
||||
});
|
||||
|
||||
export const pubgMatches = gamesSchema.table(
|
||||
'pubg_matches',
|
||||
{
|
||||
id: id(),
|
||||
roomId: integer('room_id')
|
||||
.notNull()
|
||||
.references(() => pubgRooms.id, { onDelete: 'cascade' }),
|
||||
/** 1, 2, 3… within the room. */
|
||||
number: integer('number').notNull(),
|
||||
/** #lib/pubg-map/shared MAPS slug: erangel, miramar, sanhok, vikendi… */
|
||||
map: text('map').notNull(),
|
||||
startedAt: timestamptz('started_at').notNull().defaultNow(),
|
||||
/** Set when "New match" archives it; null for the room's current match. */
|
||||
endedAt: timestamptz('ended_at')
|
||||
},
|
||||
(t) => [
|
||||
uniqueIndex('pubg_matches_room_number_idx').on(t.roomId, t.number),
|
||||
index('pubg_matches_map_idx').on(t.map, t.startedAt)
|
||||
]
|
||||
);
|
||||
|
||||
export const pubgMarkers = gamesSchema.table(
|
||||
'pubg_markers',
|
||||
{
|
||||
/** Made by the browser that placed it, so its own copy and the broadcast share an id. */
|
||||
id: text('id').primaryKey(),
|
||||
matchId: integer('match_id')
|
||||
.notNull()
|
||||
.references(() => pubgMatches.id, { onDelete: 'cascade' }),
|
||||
/** landing, plane, hotspot, vehicle, poi, note. */
|
||||
kind: text('kind').notNull(),
|
||||
/** 0..1 across and down the map image. */
|
||||
x: doublePrecision('x').notNull(),
|
||||
y: doublePrecision('y').notNull(),
|
||||
/** Plane path end point. */
|
||||
x2: doublePrecision('x2'),
|
||||
y2: doublePrecision('y2'),
|
||||
label: text('label'),
|
||||
/** Nickname and colour of whoever placed it (friends have no account). */
|
||||
player: text('player').notNull(),
|
||||
color: text('color').notNull(),
|
||||
...timestamps
|
||||
},
|
||||
(t) => [index('pubg_markers_match_idx').on(t.matchId)]
|
||||
);
|
||||
Reference in New Issue
Block a user