161 lines
3.7 KiB
JavaScript
161 lines
3.7 KiB
JavaScript
const chars = require('./characters.json');
|
|
const rooms = {};
|
|
|
|
function shuffle(a) {
|
|
for (let i = a.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|
[a[i], a[j]] = [a[j], a[i]];
|
|
}
|
|
return a;
|
|
}
|
|
|
|
function getOrCreateRoom(roomId) {
|
|
let room = rooms[roomId];
|
|
|
|
if (!room) {
|
|
room = {
|
|
roomId: roomId,
|
|
participants: [],
|
|
audience: [],
|
|
characters: shuffle(chars),
|
|
canBuzz: true
|
|
};
|
|
rooms[roomId] = room;
|
|
}
|
|
|
|
return room;
|
|
}
|
|
|
|
function addParticipant(roomId, participantId, participantName) {
|
|
let room = getOrCreateRoom(roomId);
|
|
|
|
room.participants.push({
|
|
participantId,
|
|
participantName,
|
|
character: room.characters[room.participants.length],
|
|
active: true
|
|
});
|
|
|
|
rooms[roomId] = room;
|
|
}
|
|
|
|
function removeParticipant(roomId, participantId) {
|
|
let room = getOrCreateRoom(roomId);
|
|
let participant = room.participants.find(p => p.participantId === participantId);
|
|
if (participant) {
|
|
participant.active = false;
|
|
room.audience.forEach(ws => {
|
|
ws.send(JSON.stringify({
|
|
type: "participants",
|
|
participants: room.participants
|
|
}));
|
|
});
|
|
}
|
|
}
|
|
|
|
function addParticipantWS(roomId, participantId, ws) {
|
|
let room = getOrCreateRoom(roomId);
|
|
let participant = room.participants.find(p => p.participantId === participantId);
|
|
if (participant) {
|
|
participant.ws = ws;
|
|
room.audience.forEach(ws => {
|
|
ws.send(JSON.stringify({
|
|
type: "participants",
|
|
participants: room.participants
|
|
}));
|
|
});
|
|
}
|
|
}
|
|
|
|
function addAudienceWS(roomId, ws) {
|
|
let room = getOrCreateRoom(roomId);
|
|
room.audience.push(ws);
|
|
ws.send(JSON.stringify({
|
|
type: "participants",
|
|
participants: room.participants
|
|
}));
|
|
}
|
|
|
|
function buzz(roomId, participant) {
|
|
let room = getOrCreateRoom(roomId);
|
|
if (room.canBuzz) {
|
|
room.canBuzz = false;
|
|
|
|
participant = room.participants.find(p => p.participantId === participant.participantId);
|
|
|
|
if (participant) {
|
|
room.participants.forEach(p => {
|
|
if (p.ws && p.participantId !== participant.participantId) {
|
|
p.ws.send(JSON.stringify({
|
|
type: "buzz",
|
|
participant: participant.participantName,
|
|
msg: `<img src="${participant.character}"><div>${participant.participantName} buzzed!</div>`
|
|
}));
|
|
}
|
|
});
|
|
room.audience.forEach(ws => {
|
|
ws.send(JSON.stringify({
|
|
type: "buzz",
|
|
participant: participant
|
|
}));
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function reset(roomId) {
|
|
let room = getOrCreateRoom(roomId);
|
|
room.canBuzz = true;
|
|
|
|
room.participants.forEach(p => {
|
|
p.ws.send(JSON.stringify({
|
|
type: "reset"
|
|
}));
|
|
});
|
|
}
|
|
|
|
function closeRoom(roomId) {
|
|
let room = getOrCreateRoom(roomId);
|
|
room.canBuzz = false;
|
|
|
|
room.participants.forEach(p => {
|
|
if (p.ws) {
|
|
p.ws.send(JSON.stringify({
|
|
type: "close"
|
|
}));
|
|
}
|
|
});
|
|
|
|
delete rooms[roomId];
|
|
}
|
|
|
|
function updateScore(roomId, participantId, points) {
|
|
let room = getOrCreateRoom(roomId);
|
|
let participant = room.participants.find(p => p.participantId === participantId);
|
|
if (participant) {
|
|
if (!participant.score) participant.score = 0;
|
|
|
|
participant.score += points;
|
|
|
|
participant.ws.send(JSON.stringify({
|
|
type: "score",
|
|
score: participant.score,
|
|
}));
|
|
}
|
|
|
|
room.audience.forEach(ws => {
|
|
ws.send(JSON.stringify({
|
|
type: "participants",
|
|
participants: room.participants.map(p => { return {
|
|
participantId: p.participantId,
|
|
character: p.character,
|
|
participantName: p.participantName,
|
|
score: p.score,
|
|
active: p.active,
|
|
}})
|
|
}));
|
|
});
|
|
}
|
|
|
|
module.exports = {getOrCreateRoom, addParticipant, addParticipantWS, addAudienceWS, buzz, removeParticipant, reset, closeRoom, updateScore}
|