diff --git a/src/public/script.js b/src/public/script.js index 9b167b5..18dee46 100644 --- a/src/public/script.js +++ b/src/public/script.js @@ -24,7 +24,7 @@ let playerTimerRemaining=0,playerTimerInterval=null; const saveMod=(id,s)=>localStorage.setItem('mod',JSON.stringify({id,s})); const loadMod=()=>{try{return JSON.parse(localStorage.getItem('mod')||'null');}catch{return null;}}; const clearMod=()=>{localStorage.removeItem('mod');document.getElementById('rejoin-bar').style.display='none';}; -const savePlay=(rid,pid,name)=>localStorage.setItem('play',JSON.stringify({rid,pid,name})); +const savePlay=(rid,pid)=>localStorage.setItem('play',JSON.stringify({rid,pid})); const loadPlay=()=>{try{return JSON.parse(localStorage.getItem('play')||'null');}catch{return null;}}; // ══════════════════════════════════════════════════════ @@ -45,7 +45,7 @@ function schedReconn(){ const d=Math.min(8000,500*Math.pow(1.5,reconnAttempts++)); reconnTimer=setTimeout(()=>{ if(role==='mod'){const m=loadMod();if(m)connect(()=>ws_send({type:'mod_rejoin',roomId:m.id,modSecret:m.s}));} - else if(role==='player'&&myId){const p=loadPlay();if(p)connect(()=>ws_send({type:'join_room',roomId:p.rid,playerName:p.name,playerId:p.pid}));} + else if(role==='player'&&myId){const p=loadPlay();if(p)connect(()=>ws_send({type:'join_room',roomId:p.rid,playerId:p.pid}));} else connect(null); },d); } @@ -68,7 +68,7 @@ function handle(msg){ break; case 'joined': myId=msg.playerId;room=msg.room;role='player'; - savePlay(room.id,myId,document.getElementById('ji-name').value||loadPlay()?.name||''); + savePlay(room.id,myId); showScr('s-player');renderPlayer(); break; case 'room_update': @@ -171,10 +171,9 @@ function setConn(on){ function goSetup(){renderSetupTeamNames();showScr('s-setup');} function joinRoom(){ const code=document.getElementById('ji-code').value.trim().toUpperCase(); - const name=document.getElementById('ji-name').value.trim(); if(!code){toast('Enter room code','err');return;} - if(!name){toast('Enter your name','err');return;} - connect(()=>ws_send({type:'join_room',roomId:code,playerName:name})); + const autoId=Math.floor(Math.random()*99999999)+1; + connect(()=>ws_send({type:'join_room',roomId:code,playerId:autoId})); } function openRejoin(){ const m=loadMod();if(!m)return; @@ -411,7 +410,7 @@ function renderModPlayerList(){ row.className='pl-row'+(p.isConnected?'':' offline'); row.innerHTML=`
-
${esc(p.name)} ${p.isConnected?'':`OFFLINE`}
+
${esc(p.name)} #${p.playerId} ${p.isConnected?'':`OFFLINE`}
${teamName?`
${esc(teamName)}
`:'
No team
'} ${teamSel}
@@ -437,7 +436,7 @@ function renderModTeams(){ card.innerHTML=`
${esc(name)}
${members.length}
-
${members.map(p=>esc(p.name)).join('
')||'—'}
+
${members.map(p=>`#${p.playerId}`).join('
')||'—'}
`; grid.appendChild(card); if(typeof gsap!=='undefined'){ @@ -527,7 +526,7 @@ function renderPlayer(){ if(!room)return; document.getElementById('p-code').textContent=room.id; const me=room.players.find(p=>p.id===myId); - document.getElementById('p-namelbl').textContent=me?.name??''; + document.getElementById('p-namelbl').textContent=`#${me?.playerId||'?'}`; renderTeamPicker(); renderPlayerBuzzer(); renderRoster(); @@ -626,7 +625,7 @@ function renderRoster(){ row.className='roster-row'+(isMe?' roster-me':''); row.innerHTML=`
-
${esc(p.name)}${isMe?' (YOU)':''}
+
${esc(p.name)} ${isMe?`(#${p.playerId}) (YOU)`:''}
${teamName?`
${esc(teamName)}
`:''} `; el.appendChild(row); @@ -638,10 +637,11 @@ function addFeed(evt){ const isFirst=evt.buzzOrder?.[0]===evt.playerId; const color=evt.teamIndex!==null?teamColor(evt.teamIndex):'var(--g)'; const teamStr=(room?.settings.mode==='teams'&&evt.teamIndex!==null)?` [${esc(room.settings.teamNames[evt.teamIndex]??'')}]`:''; + const playerStr=`#${evt.playerId}`; const div=document.createElement('div'); div.className='feed-entry'+(isFirst?' first':''); div.style.borderLeftColor=isFirst?'var(--yellow)':color; - div.innerHTML=`${esc(evt.playerName)}${teamStr} buzzed${isFirst?' — FIRST!':''}`; + div.innerHTML=`${playerStr}${teamStr} buzzed${isFirst?' — FIRST!':''}`; feed.prepend(div); if(typeof gsap!=='undefined'){ gsap.fromTo(div, diff --git a/src/ws-handler.ts b/src/ws-handler.ts index 1c582d2..2eed9a7 100644 --- a/src/ws-handler.ts +++ b/src/ws-handler.ts @@ -2,7 +2,7 @@ import type { ServerWebSocket } from "bun"; import { rooms, wsToPlayer, Room, Player, - genId, greekName, sanitize, freshBuzzer, publicRoom, broadcast, toMod, + sanitize, freshBuzzer, publicRoom, broadcast, toMod, } from "./rooms"; type WS = ServerWebSocket; @@ -65,15 +65,19 @@ export function handleMessage(ws: WS, raw: string) { if (!room) { er(ws, "Room not found"); return; } if (room.locked) { er(ws, "Room is locked"); return; } - const name = sanitize(msg.playerName ?? "Player", 24) || "Player"; const existingId = sanitize(msg.playerId ?? "", 12); let player: Player | undefined; - if (existingId && room.players.has(existingId)) { - player = room.players.get(existingId)!; - player.ws = ws; player.isConnected = true; player.name = name; + if (existingId && existingId.match(/^\d+$/)) { + if (room.players.has(existingId)) { + player = room.players.get(existingId)!; + player.ws = ws; player.isConnected = true; + } else { + er(ws, "Invalid player ID"); return; + } } else { - player = { id: genId(), name, teamIndex: null, ws, isConnected: true }; + const autoId = Math.floor(Math.random() * 99999999) + 1; + player = { id: autoId, teamIndex: null, ws, isConnected: true }; room.players.set(player.id, player); } @@ -118,8 +122,8 @@ export function handleMessage(ws: WS, raw: string) { const p = room.players.get(ctx.playerId)!; const pubOrder = room.settings.showBuzzOrder ? bz.buzzOrder : [bz.buzzOrder[0]]; - broadcast(room, { type: "buzz_event", playerId: ctx.playerId, playerName: p.name, teamIndex: p.teamIndex, buzzOrder: pubOrder, room: publicRoom(room) }); - toMod(room, { type: "buzz_event", playerId: ctx.playerId, playerName: p.name, teamIndex: p.teamIndex, buzzOrder: bz.buzzOrder, buzzTimes: Object.fromEntries(bz.buzzTimes), room: publicRoom(room) }); + broadcast(room, { type: "buzz_event", playerId: ctx.playerId, teamIndex: p.teamIndex, buzzOrder: pubOrder, room: publicRoom(room) }); + toMod(room, { type: "buzz_event", playerId: ctx.playerId, teamIndex: p.teamIndex, buzzOrder: bz.buzzOrder, buzzTimes: Object.fromEntries(bz.buzzTimes), room: publicRoom(room) }); return; }