Advertisement
emesten

Untitled

Jul 8th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const express = require('express');
  2. const MongoClient = require('mongodb').MongoClient;
  3. const WebSocket = require('ws');
  4. var cookieParser = require('cookie-parser');
  5. const sha256 = require('sha256');
  6. const uuid = require('rand-token').uid;
  7. const Room = require('./Classes/Room');
  8. const Client = require('./Classes/Client');
  9. const Lurker = require('./Classes/Lurker');
  10. const Message = require('./Classes/Message');
  11. const Tool = require('./utils/Tool');
  12. const Logger = require('./utils/Logger');
  13. const WSHandler = require('./utils/WebSocketHandler');
  14. const Error = require('./consts/Error')
  15. const Type = require('./consts/Type');
  16.  
  17. let db;
  18. const app = express();
  19. let ROOMS = [];
  20. let ROOMSLIST = [];
  21.  
  22. app.use(express.json());
  23. app.use(express.urlencoded({ extended: false }));
  24. app.use(cookieParser());
  25. app.use(function (req, res, next) {
  26.     res.setHeader('Access-Control-Allow-Origin', 'http://app.math');
  27.     res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  28.     res.setHeader('Access-Control-Allow-Credentials', true);
  29.     res.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
  30.     next();
  31. })
  32.  
  33. //Run websocket server
  34. const wss = new WebSocket.Server({ port: 8080 });
  35.  
  36. wss.on('connection', (ws, req) => {
  37.     ws.on('message', async message => {
  38.         let roomReq;
  39.         try {
  40.             roomReq = JSON.parse(message);
  41.         } catch (e) {
  42.             return;
  43.         }
  44.  
  45.         //Check if requested room exists
  46.         if (roomReq.type === Type.EXISTS) {
  47.             const room = Tool.getRoomById(ROOMS, roomReq.roomID);
  48.             Logger.WebSocket.request(roomReq.roomID);
  49.  
  50.             if (room === undefined || room.gameStarted || room.spaceLimit === 0 || Tool.isAlreadyPlaying(ROOMS, roomReq.token))
  51.                 return ws.send(JSON.stringify({
  52.                     error: Error.ROOMLOADFAILED,
  53.                     exists: false
  54.                 }));
  55.  
  56.             //Check if users exists
  57.             const tuser = await Tool.findUserInDatabase(db, roomReq.token);
  58.             if (tuser.length === 0)
  59.                 return ws.send(JSON.stringify({
  60.                     error: Error.USERNOTFOUND,
  61.                     exists: false
  62.                 }));
  63.                
  64.             const user = tuser[0];
  65.             room.spaceLimit--;
  66.             room.clients.push(new Client(user.login, user.token, ws));
  67.             WSHandler.sendRoomsData(ROOMS, ROOMSLIST);
  68.             room.creatorFound = room.creator === roomReq.token;
  69.             ws.token = roomReq.token;
  70.             ws.roomID = roomReq.roomID;
  71.  
  72.             const formattedClients = Tool.getFormattedClients(room.clients);
  73.             WSHandler.sendClientsUpdateInfo(room, user.token, formattedClients);
  74.            
  75.             return ws.send(JSON.stringify({
  76.                 type: Type.EXISTS,
  77.                 error: null,
  78.                 exists: true,
  79.                 room: {
  80.                     roomName: room.name,
  81.                     roomID: room.id,
  82.                     clients: formattedClients,
  83.                     isListed: room.isListed
  84.                 },
  85.                 creator: room.creator === roomReq.token,
  86.                 creatorNick: room.creatorNick,
  87.                 spaceLimit: room.spaceLimit,
  88.                 nick: user.login
  89.             }));
  90.         }
  91.  
  92.         //Start a game in the room
  93.         else if (roomReq.type === Type.GAMEINIT) {
  94.             const room = Tool.getRoomById(ROOMS, roomReq.roomID);
  95.             Logger.WebSocket.gameStarted(room.id);
  96.            
  97.             room.questions = await Tool.getQuestions(db);
  98.             room.gameStarted = true;
  99.             WSHandler.sendRoomsData(ROOMS, ROOMSLIST);
  100.  
  101.             for (const client of room.clients)
  102.                 if (client.socket.readyState !== 3)
  103.                     client.socket.send(JSON.stringify({
  104.                         type: Type.GAMEINIT,
  105.                         error: null,
  106.                         questions: room.questions
  107.                     }));
  108.         }
  109.  
  110.         //Client has answered the questions
  111.         else if (roomReq.type === Type.GAMESTOP) {
  112.             const room = Tool.getRoomById(ROOMS, roomReq.roomID);
  113.             const points = roomReq.points;
  114.             const token = roomReq.token;
  115.             Logger.WebSocket.donePlaying(token, room.id);
  116.  
  117.             room.clients.find(client => client.token === token).currentPoints += points;
  118.             room.clientsDoneCounter++;
  119.             await Tool.updateCurrentProgress(db, token, points, roomReq.correct, roomReq.incorrect);
  120.  
  121.             //If everyone has ended playing a game, send informations to everyone
  122.             if (room.clientsDoneCounter >= room.clients.length) {
  123.                 const formattedClients = Tool.getFormattedClients(room.clients);
  124.                 room.gameStarted = false;
  125.  
  126.                 WSHandler.sendRoomsData(ROOMS, ROOMSLIST);
  127.                 for (const client of room.clients)
  128.                     if (client.socket.readyState !== 3)
  129.                             client.socket.send(JSON.stringify({
  130.                                 type: Type.GAMESTOP,
  131.                                 error: null,
  132.                                 clients: formattedClients
  133.                             }));
  134.                 room.clientsDoneCounter = 0;
  135.             }
  136.         }
  137.  
  138.         //There is a new message in the room
  139.         else if (roomReq.type === Type.NEWMESSAGE) {
  140.             const room = Tool.getRoomById(ROOMS, roomReq.roomID);
  141.  
  142.             //If request comes from a person that has recently joined the room,
  143.             //return every message sent till now.
  144.             if (roomReq.new) {
  145.                 return ws.send(JSON.stringify({
  146.                     type: Type.NEWMESSAGE,
  147.                     messages: room.messages
  148.                 }))
  149.             }
  150.            
  151.             room.messages.push(new Message(roomReq.sender, roomReq.content))
  152.             for (client of room.clients) {
  153.                 if (client.socket.readyState !== 3) {
  154.                     client.socket.send(JSON.stringify({
  155.                         type: Type.NEWMESSAGE,
  156.                         messages: room.messages
  157.                     }))
  158.                 }
  159.             }
  160.         }
  161.  
  162.         //List of available rooms
  163.         else if (roomReq.type === Type.GETROOMS) {
  164.             ROOMSLIST.push(new Lurker(ws, roomReq.token));
  165.             return WSHandler.sendRoomsData(ROOMS, new Array(new Lurker(ws, roomReq.token)));
  166.         }
  167.  
  168.         //Change if room is listed or not.
  169.         else if (roomReq.type === Type.LISTED) {
  170.             const room = Tool.getRoomById(ROOMS, roomReq.roomID);
  171.             if (room === undefined)
  172.                 return;
  173.             room.isListed = roomReq.isListed;
  174.             WSHandler.sendRoomsData(ROOMS, ROOMSLIST);
  175.             WSHandler.changeListedState(room);
  176.             return;
  177.         }
  178.     })
  179.  
  180.     ws.on('close', async () => {
  181.         const token = ws.token;
  182.         const roomID = ws.roomID;
  183.         const room = Tool.getRoomById(ROOMS, roomID);
  184.         Logger.WebSocket.connectionClosed(token, roomID)
  185.        
  186.         if (room === undefined)
  187.             return;
  188.         room.spaceLimit++;
  189.  
  190.         let newClients = room.clients.find(client => client.token !== token)
  191.         if (!Array.isArray(newClients) && newClients !== undefined)
  192.             newClients = new Array(newClients);
  193.         room.clients = newClients;
  194.         if (newClients === undefined || newClients.length === 0) {
  195.             ROOMS = Tool.resetRoom(ROOMS, room);
  196.             WSHandler.sendRoomsData(ROOMS, ROOMSLIST);
  197.             return;
  198.         }
  199.         else if (token === room.creator) {
  200.             const index = Math.floor(Math.random()*(room.clients.length));
  201.             room.creator = room.clients[index].token;
  202.             room.creatorNick = room.clients[index].nick;
  203.             WSHandler.changeCreator(room)
  204.         }
  205.         WSHandler.sendRoomsData(ROOMS, ROOMSLIST);
  206.         WSHandler.sendClientsUpdateInfo(room, null, Tool.getFormattedClients(room.clients));
  207.         return room.clients = newClients;
  208.     })
  209. })
  210.  
  211.  
  212. //app
  213. app.get('/api/Account/Logged', async (req, res) => {
  214.     const cookie = req.cookies.mathimeauth;
  215.     const acc = await Tool.findUserInDatabase(db, cookie);
  216.  
  217.     if (acc.length === 0)
  218.         return res.send(JSON.stringify({
  219.             isLogged: false
  220.         }));
  221.  
  222.     return res.send(JSON.stringify({
  223.         isLogged: true,
  224.         login: acc[0].login
  225.     }));
  226. })
  227.  
  228. //Create new room
  229. app.post('/api/Room/Create', async (req, res) => {
  230.     const roomName = req.body.room;
  231.     const token = req.cookies.mathimeauth;
  232.     const roomID = uuid(16);
  233.     if (token === undefined || Tool.isAlreadyPlaying(ROOMS, token))
  234.         return res.send(JSON.stringify({
  235.             hbCreated: false
  236.         }));
  237.  
  238.     const acc = await Tool.findUserInDatabase(db, token);
  239.     const room = new Room(roomID, roomName, token, acc[0].login);
  240.     ROOMS.push(room);
  241.  
  242.     WSHandler.sendRoomsData(ROOMS, ROOMSLIST);
  243.     Logger.backend.newRoom(token, roomName);
  244.     return res.send({
  245.         roomCreated: true,
  246.         roomID: roomID,
  247.         roomName: roomName
  248.     });
  249. })
  250.  
  251.  
  252. // Handling register and login
  253. app.post('/api/Account/Login', async (req, response) => {
  254.     const dbo = db.db('mathime');
  255.     const login = req.body.login;
  256.     const password = sha256(req.body.password);
  257.     const acc = await Tool.findUserInDatabaseByName(db, login);
  258.  
  259.     if (acc.length === 0 || acc[0].password !== password) {
  260.         return response.send(JSON.stringify({
  261.             isLogged: false
  262.         }));
  263.     }
  264.     const token = uuid(32);
  265.     const obj = {
  266.         $set: {
  267.             token: token
  268.         }
  269.     }
  270.     await dbo.collection('users').updateOne({login: login}, obj, (err)=> {
  271.         if (err)
  272.             throw err
  273.        
  274.         Logger.backend.loggedIn(login);
  275.         response.cookie('mathimeauth', token, {expires: new Date(Date.now() + 1000*60*60*24*14), path: '/' });
  276.         response.send(JSON.stringify({
  277.             isLogged: true,
  278.             token: token
  279.         }));
  280.     })
  281. })
  282.  
  283.  
  284. //Create an account
  285. app.post('/api/Account/Register', async (req, response) => {
  286.     const dbo = db.db('mathime');
  287.     const login = req.body.login;
  288.     const password = sha256(req.body.password);
  289.     const email = req.body.email;
  290.     const token = uuid(32);
  291.     const obj = {
  292.         token: token,
  293.         login: login,
  294.         password: password,
  295.         email: email,
  296.         points: 0,
  297.         correct: 0,
  298.         incorrect: 0,
  299.         gamesPlayed: 0
  300.     }
  301.     const acc = await Tool.findUserInDatabaseByName(db, login);
  302.     if (acc.length !== 0)
  303.         return response.send(JSON.stringify({
  304.             hbCreated: false
  305.         }));
  306.  
  307.     await dbo.collection('users').insertOne(obj, (err, res) => {
  308.         if (err)
  309.             return response.send(JSON.stringify({
  310.                 hbCreated: false
  311.             }));
  312.  
  313.         Logger.backend.newAccount(login);
  314.         response.cookie('mathimeauth', token, { expires: new Date(Date.now() + 1000*60*60*24*14), path: '/' });
  315.         response.send(JSON.stringify({
  316.             hbCreated: true,
  317.             token: token
  318.         }));
  319.     })
  320.  
  321. })
  322.  
  323. //Return requested profile (is exists)
  324. app.post('/api/Profile/Fetch', async (req, response) => {
  325.     const nick = req.body.nick;
  326.     const user = await Tool.findUserInDatabaseByName(db, nick);
  327.     if (user.length === 0)
  328.         return response.send(JSON.stringify({
  329.             fetched: false,
  330.             profile: null
  331.         }))
  332.     return response.send(JSON.stringify({
  333.         fetched: true,
  334.         profile: {
  335.             nick: user[0].login,
  336.             points: user[0].points,
  337.             correct: user[0].correct,
  338.             incorrect: user[0].incorrect,
  339.             gamesPlayed: user[0].gamesPlayed
  340.         }
  341.     }))
  342. })
  343.  
  344. app.get('/api/Ranking/Get', async (req, response) => {
  345.     const users = await db.db('mathime').collection('users')
  346.                         .find({}, {sort: {points: -1}, fields: { _id: 0, login: 1, points: 1 }})
  347.                         .limit(100)
  348.                         .toArray();
  349.     return response.send(JSON.stringify({
  350.         fetched: true,
  351.         users: users
  352.     }))
  353. })
  354.  
  355.  
  356. MongoClient.connect('mongodb://localhost:27017/', (err, database) => {
  357.     if (err)
  358.         throw err;
  359.     console.log('[Database] Running at 27017');
  360.     db = database;
  361.    
  362.     app.listen(3000, () => {
  363.         Logger.backend.running();
  364.     })
  365. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement