183 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const WebSocket = require("ws");
 | 
						|
const { v4: uuidv4 } = require("uuid");
 | 
						|
const puzzles = require('./puzzles.json');
 | 
						|
const names = require('./assignedNames.json');
 | 
						|
const crypto = require('crypto');
 | 
						|
 | 
						|
const wss = new WebSocket.Server({ port: 8080 });
 | 
						|
const rooms = {}; // Stores rooms and their clients
 | 
						|
const wheel = [
 | 
						|
  'lose a turn',800,350,450,700,300,600,5000,
 | 
						|
  300,600,300,500,800,550,400,300,900,500,'spin again',
 | 
						|
  900,'Bankrupt',600,400,300
 | 
						|
] //represents wheel in wheel of fortune game.
 | 
						|
function getRandomValue(array) {
 | 
						|
    const randomIndex = crypto.randomInt(0, array.length);
 | 
						|
    return array[randomIndex];
 | 
						|
}
 | 
						|
function shuffleArray(array) {
 | 
						|
    for (let i = array.length - 1; i > 0; i--) {
 | 
						|
        // Generate a cryptographically secure random index
 | 
						|
        const j = crypto.randomInt(0, i + 1); 
 | 
						|
        // Swap elements
 | 
						|
        [array[i], array[j]] = [array[j], array[i]];
 | 
						|
    }
 | 
						|
    return array;
 | 
						|
}
 | 
						|
 | 
						|
const DefaultNames = shuffleArray(names);
 | 
						|
let NameIndex = 0;
 | 
						|
function getRandomName() {
 | 
						|
  if (NameIndex >= DefaultNames.length) {
 | 
						|
    NameIndex = 0;
 | 
						|
  }else{
 | 
						|
    NameIndex++;
 | 
						|
  }
 | 
						|
  //since we've incremented the index but not returned the value, 
 | 
						|
  //calculate the index again
 | 
						|
  return NameIndex === 0 ? DefaultNames[NameIndex] : DefaultNames[NameIndex-1];
 | 
						|
}
 | 
						|
 | 
						|
function loadCurrentPuzzle(gameStateObject) {
 | 
						|
  console.log(gameStateObject);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// server.js
 | 
						|
wss.on("connection", (ws) => {
 | 
						|
  ws.on("message", (message) => {
 | 
						|
    const data = JSON.parse(message);
 | 
						|
 | 
						|
    if (data.type === "create_room") {
 | 
						|
      const roomCode = uuidv4().slice(0, 5);
 | 
						|
      ws.name = getRandomName();
 | 
						|
      rooms[roomCode] = { 
 | 
						|
        clients: [ws], 
 | 
						|
        leader: ws, 
 | 
						|
        gameState: {
 | 
						|
          started:false,
 | 
						|
          puzzles:shuffleArray(puzzles),
 | 
						|
          puzzleLevel:0,
 | 
						|
        },
 | 
						|
      };
 | 
						|
      ws.roomCode = roomCode;
 | 
						|
      ws.send(JSON.stringify({ type: "room_created", roomCode,
 | 
						|
        isLeader: true,
 | 
						|
        clients: rooms[roomCode].clients.map((i)=> i.name),
 | 
						|
      }));
 | 
						|
    }
 | 
						|
 | 
						|
    if (data.type === "join_room") {
 | 
						|
      const { roomCode } = data;
 | 
						|
      console.log(rooms);
 | 
						|
      console.log(rooms[roomCode],roomCode);
 | 
						|
 | 
						|
      if (!rooms[roomCode]) {
 | 
						|
        ws.send(JSON.stringify({ type: "error", message: "Room not found" }));
 | 
						|
      }
 | 
						|
      else if (rooms[roomCode].gameState.started) {
 | 
						|
        ws.send(JSON.stringify({ type: "error", message: "Game has already Started!!!" }));
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        ws.name = getRandomName();
 | 
						|
        rooms[roomCode].clients.push(ws);
 | 
						|
        ws.roomCode = roomCode;
 | 
						|
        const room = rooms[ws.roomCode];
 | 
						|
        room.clients.forEach((client) => {
 | 
						|
          client.send(JSON.stringify({ 
 | 
						|
            type: "joined_room", roomCode,
 | 
						|
            isLeader: rooms[roomCode].leader === ws ,
 | 
						|
            clients: rooms[roomCode].clients.map((i)=> i.name),
 | 
						|
            leaderName:rooms[roomCode].leader.name
 | 
						|
          }));
 | 
						|
        });
 | 
						|
     
 | 
						|
        ws.send(JSON.stringify({ 
 | 
						|
          type: "joined_room_you", roomCode,
 | 
						|
          isLeader: rooms[roomCode].leader === ws,
 | 
						|
          you:ws.name
 | 
						|
          }));
 | 
						|
      }
 | 
						|
      //console.log('clients: ',rooms[roomCode].leader.name);
 | 
						|
    }
 | 
						|
 | 
						|
    if (data.type === "start_game") {
 | 
						|
      const room = rooms[ws.roomCode];
 | 
						|
      room.gameState.started = true;
 | 
						|
      console.log('game started for:',room);
 | 
						|
      if (room && room.leader === ws) {
 | 
						|
        room.clients.forEach((client) => {
 | 
						|
          client.send(JSON.stringify({ 
 | 
						|
            type: "game_started",
 | 
						|
            roomCode: ws.roomCode, 
 | 
						|
            puzzle:loadCurrentPuzzle(room.gameState)
 | 
						|
          }));
 | 
						|
        });
 | 
						|
      } else {
 | 
						|
        ws.send(JSON.stringify({ type: "error", message: "Only the leader can start the game" }));
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (data.type === "spin_wheel" || data.type === "guess_letter") {
 | 
						|
      const room = rooms[ws.roomCode];
 | 
						|
      if (room && room.clients.includes(ws)) {
 | 
						|
        // Handle spin and guess events
 | 
						|
        if (data.type === "spin_wheel") {
 | 
						|
          // Simulate a wheel spin result and update room state
 | 
						|
          const spinResult = getRandomValue(wheel);
 | 
						|
          room.gameState.spinResult = spinResult;
 | 
						|
          room.clients.forEach((client) =>
 | 
						|
            client.send(JSON.stringify({ 
 | 
						|
              type: "spin_result", spinResult, 
 | 
						|
              player: ws === room.leader ? "Leader" : "Player" 
 | 
						|
            }))
 | 
						|
          );
 | 
						|
        }
 | 
						|
 | 
						|
        if (data.type === "guess_letter") {
 | 
						|
          const { letter } = data;
 | 
						|
          // Handle guess logic (e.g., check if the letter is in the puzzle)
 | 
						|
          const correctGuess = Math.random() > 0.5; // Random outcome for simplicity
 | 
						|
          room.gameState.lastGuess = { letter, correct: correctGuess };
 | 
						|
          room.clients.forEach((client) =>
 | 
						|
            client.send(JSON.stringify({ type: "guess_result", letter, correct: correctGuess, player: ws === room.leader ? "Leader" : "Player" }))
 | 
						|
          );
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ws.send(JSON.stringify({ type: "error", message: "You are not in this room" }));
 | 
						|
      }
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  ws.on("close", () => {
 | 
						|
    if (ws.roomCode && rooms[ws.roomCode]) {
 | 
						|
      console.log('closing');
 | 
						|
      const room = rooms[ws.roomCode];
 | 
						|
      const roomCode = ws.roomCode;
 | 
						|
      room.clients = room.clients.filter((client) => client !== ws);
 | 
						|
      if (room.leader === ws && room.clients.length > 0) {
 | 
						|
        console.log('closing within room leader')
 | 
						|
        room.leader = room.clients[0];
 | 
						|
        room.leader.send(JSON.stringify({ type: "new_leader" }));
 | 
						|
        
 | 
						|
      }
 | 
						|
      room.clients.forEach((client) =>
 | 
						|
            client.send(JSON.stringify({ 
 | 
						|
              type: "joined_room", roomCode,
 | 
						|
              isLeader: rooms[roomCode].leader === ws ,
 | 
						|
              clients: rooms[roomCode].clients.map((i)=> i.name),
 | 
						|
              leaderName:rooms[roomCode].leader.name
 | 
						|
            }))
 | 
						|
          );
 | 
						|
      if (room.clients.length === 0) delete rooms[ws.roomCode];
 | 
						|
    }
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
 | 
						|
console.log("WebSocket server is running on ws://localhost:8080");
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  DefaultNames,NameIndex,
 | 
						|
  getRandomName,getRandomValue,shuffleArray
 | 
						|
} |