From 8a4479ca3eefd5c986076079768a2e26a4f88a29 Mon Sep 17 00:00:00 2001 From: Jeffery R Date: Sat, 27 Jan 2018 14:36:37 -0500 Subject: [PATCH 1/6] Defined events for socket.io --- README.md | 1 + googletrendsgame/server/server.js | 98 ++++++++++++++++++++++---- googletrendsgame/server/serverUtils.js | 19 +++++ 3 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 googletrendsgame/server/serverUtils.js diff --git a/README.md b/README.md index 2096d85..0e1f6f1 100644 --- a/README.md +++ b/README.md @@ -12,4 +12,5 @@ npm install socket.io npm install mysql npm install sanitizer npm install google-trends-api +npm install promise ```` \ No newline at end of file diff --git a/googletrendsgame/server/server.js b/googletrendsgame/server/server.js index 273fd20..eaf97d0 100644 --- a/googletrendsgame/server/server.js +++ b/googletrendsgame/server/server.js @@ -1,8 +1,6 @@ -var app = require('express')(); -var http = require('http').Server(app); -var io = require('socket.io')(http); -const port = 3000; +//list of all the rooms +var rooms = []; var room = function(capacityP, roomN) { @@ -15,27 +13,54 @@ var room = function(capacityP, roomN) //list of words used in the game this.words = []; - //list of clients sockets -- so we can push requests to them + //list players -- so we can push requests to them this.users = []; //increments when rounds pass this.currentRoom = 0; + // the password of the room -- null if no password + this.password = null; + /** * adds a user to a room - * @param socket + * @param p + * return 0 if they could join + */ + this.addUser = function(player) + { + //check if room is not full + if(this.users.length != this.capacity) + { + this.users.push(player) + } + else + { + + } + } + + /** + * + * @param p */ - this.addUser = function(socket) + this.removeUser = function(p) { + this.users.remove(p); + //if room is empty remove the room from rooms list + rooms.remove(this); } } -var player = function(name) +var player = function(s) { //name of the user - this.name = name; + this.name = null; + + //players socket + this.socket = s; //score of the player this.score = 0; @@ -48,19 +73,68 @@ var player = function(name) this.sumbission = null; } -//list of all the rooms -var rooms = []; + +var app = require('express')(); +var http = require('http').Server(app); +var io = require('socket.io')(http); + +const port = 3000; + +const utils = require('./serverUtils.js'); //Whenever someone connects this gets executed io.on('connection', function(socket) { + var player = new player(socket); + console.log('A user connected'); + /** + *Register user nickname/handle (register) Client => Server + */ + socket.on('register', function(data) { + console.log("Register event called"); + console.log(data); + console.log(" "); + + //checks for user name in use + if(utils.userAvailable(data, rooms)) + { + player.name = data; + } + else + { + socket.emit('registerFailed', 'User name taken'); + } + + }); - socket.on('clientEvent', function(data) { + /** + *Create Room (createRoom) Client => Server + * data {password: , capacity: } + */ + socket.on('createRoom', function(data) { + console.log("create room event called"); console.log(data); + console.log(" "); + + }); + /** + * + */ + socket.on('joinRoom', function(data) { + console.log("join room event called"); + console.log(data); + console.log(" "); + }); + + socket.on('submitWord', function(data) { + console.log("submitWord called"); + console.log(data); + console.log(" "); + }); //Whenever someone disconnects this piece of code executed socket.on('disconnect', function () { diff --git a/googletrendsgame/server/serverUtils.js b/googletrendsgame/server/serverUtils.js new file mode 100644 index 0000000..18d527c --- /dev/null +++ b/googletrendsgame/server/serverUtils.js @@ -0,0 +1,19 @@ +module.exports= + { + /** + * Returns a random word + * @returns {string} + */ + roomOpen : function(name, rooms) + { + return true; + }, + userAvailable : function(name, rooms) + { + return true; + }, + exists: function(name, rooms) + { + + } + }; \ No newline at end of file From 7b786b24ccb501268f0d2890a9918ddc2af35413 Mon Sep 17 00:00:00 2001 From: ritfsaecdaq Date: Sat, 27 Jan 2018 14:47:32 -0500 Subject: [PATCH 2/6] added word scoring functionality --- googletrendsgame/server/trendsAPI.js | 34 ++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/googletrendsgame/server/trendsAPI.js b/googletrendsgame/server/trendsAPI.js index c3abe26..2cf9303 100644 --- a/googletrendsgame/server/trendsAPI.js +++ b/googletrendsgame/server/trendsAPI.js @@ -1,9 +1,35 @@ - - +const googt = require('google-trends-api'); +const Promise = require('promise'); +const DAY = 1000 * 60 * 60 * 24; module.exports= { + /* + desc: returns an integer score for the word over the day + */ getPopularity: function(word) { - return 0; + //must be a promise since call to trends API is async + return new Promise(function(resolve, reject){ + + //specifies the keyword, time interval, and granularity + googt.interestOverTime({keyword:word, + startTime:new Date(Date.now() - DAY),granularTimeResolution:true}) + .then(function(results){ + //turn into json object + data = JSON.parse(results).default.timelineData; + + //add up values + var total = 0; + data.forEach(function(element){ + console.log(element.formattedTime + " " + element.value[0]); + total += element.value[0]; + }) + + //tell function to return + resolve(total); + }).catch(function(err){ + reject("Google Trends Query Failed"); + }); + }); } - }; \ No newline at end of file + }; From 4bc8d5d2e237c7ee1e0498a277e7d047e799669b Mon Sep 17 00:00:00 2001 From: Jeffery R Date: Sat, 27 Jan 2018 16:07:57 -0500 Subject: [PATCH 3/6] Fleshed out socket events and player, and room objects --- googletrendsgame/server/server.js | 95 ++++++++++++++++++++------ googletrendsgame/server/serverUtils.js | 50 +++++++++++++- 2 files changed, 124 insertions(+), 21 deletions(-) diff --git a/googletrendsgame/server/server.js b/googletrendsgame/server/server.js index eaf97d0..12a6717 100644 --- a/googletrendsgame/server/server.js +++ b/googletrendsgame/server/server.js @@ -1,14 +1,16 @@ //list of all the rooms -var rooms = []; +var rooms = {}; -var room = function(capacityP, roomN) +var room = function(capacityP, pass, owner) { //max capacity of room -- default is 4 for now this.capacity = capacityP; //name of the room - this.roomName = roomN; + this.roomName = owner.name; + + this.addUser(owner); //list of words used in the game this.words = []; @@ -17,11 +19,13 @@ var room = function(capacityP, roomN) this.users = []; //increments when rounds pass - this.currentRoom = 0; + this.currentRound = 0; // the password of the room -- null if no password this.password = null; + this.state = 1; + /** * adds a user to a room * @param p @@ -30,14 +34,8 @@ var room = function(capacityP, roomN) this.addUser = function(player) { //check if room is not full - if(this.users.length != this.capacity) - { - this.users.push(player) - } - else - { - - } + this.users.push(player); + player.room = this; } /** @@ -46,10 +44,44 @@ var room = function(capacityP, roomN) */ this.removeUser = function(p) { - this.users.remove(p); + var temp = new Array(); + + for(var i = 0; i < temp.length; i++) + { + if(p.name === this.users[i].name) + { + + } + else + { + temp.push(this.users[i]); + } + } + + this.users = temp; //if room is empty remove the room from rooms list - rooms.remove(this); + if(this.users.length == 0) + { + rooms[this.roomName] = null; + } + } + + this.generateRoomUpdate() + { + + } + + this.canJoin = function(p) + { + if(this.password == null) + { + return (this.users.length < this.capacity); + } + else + { + return (this.users.length < this.capacity) && (p === this.password); + } } } @@ -68,11 +100,11 @@ var player = function(s) //reference to the room -- might not need this this.room = null; - - // this.sumbission = null; } +var players = {}; + var app = require('express')(); var http = require('http').Server(app); @@ -80,7 +112,7 @@ var io = require('socket.io')(http); const port = 3000; -const utils = require('./serverUtils.js'); +const serverUtils = require('./serverUtils.js'); //Whenever someone connects this gets executed io.on('connection', function(socket) @@ -98,15 +130,18 @@ io.on('connection', function(socket) console.log(" "); //checks for user name in use - if(utils.userAvailable(data, rooms)) + if(serverUtils.userAvailable(data, players)) { player.name = data; + + players[data] = player; + + socket.emit('sendRooms', serverUtils.generateSendRoomsJSON(rooms)); } else { socket.emit('registerFailed', 'User name taken'); } - }); /** @@ -117,6 +152,7 @@ io.on('connection', function(socket) console.log("create room event called"); console.log(data); console.log(" "); + rooms[player.name] = new room(data.capacity, data.password, player); }); @@ -128,6 +164,15 @@ io.on('connection', function(socket) console.log("join room event called"); console.log(data); console.log(" "); + + if(rooms[data.name].canJoin(data.password)) + { + rooms[data.name].addUser(player); + } + else + { + socket.emit('registerFailed', 'Failed connecting to room'); + } }); socket.on('submitWord', function(data) { @@ -139,6 +184,18 @@ io.on('connection', function(socket) //Whenever someone disconnects this piece of code executed socket.on('disconnect', function () { console.log('A user disconnected'); + + if(rooms[player.name] != null) + { + rooms[player.name] = null; + } + + //leave the room + if(player.room != null) + { + player.room.removeUser(player); + } + }); }); diff --git a/googletrendsgame/server/serverUtils.js b/googletrendsgame/server/serverUtils.js index 18d527c..cef83f9 100644 --- a/googletrendsgame/server/serverUtils.js +++ b/googletrendsgame/server/serverUtils.js @@ -6,14 +6,60 @@ module.exports= */ roomOpen : function(name, rooms) { + rooms.foreach(function(r) + { + if(name === r.roomName) + { + return false; + } + }); return true; }, - userAvailable : function(name, rooms) + userAvailable : function(name, players) { + // players.foreach(function(p) + // { + // if(name === p.roomName) + // { + // return false; + // } + // }); + + if(players[name] != null) + return false return true; }, - exists: function(name, rooms) + + generateSendRoomsJSON : function(rooms) + { + var obj = new Object(); + obj.rooms = []; + + rooms.forEach(function(r) + { + var roomObj = new Object(); + + if(r.password.password == null) + { + roomObj.passwordBool = false; + } + else + { + roomObj.passwordBool = r.password; + } + roomObj.capacity = r.capacity; + roomObj.occupents = r.users.length; + + obj.rooms.push(roomObj); + + }); + + return obj; + }, + + getOpenIndex : function(rooms) { } + }; \ No newline at end of file From a321beeb63c9a633dcc122f2a40ca8732b436d88 Mon Sep 17 00:00:00 2001 From: Jeffery R Date: Sat, 27 Jan 2018 16:29:33 -0500 Subject: [PATCH 4/6] Updated utils for later implementation --- googletrendsgame/server/server.js | 49 ++++++++++++++++++++++++++----- googletrendsgame/server/utils.js | 10 +++++++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/googletrendsgame/server/server.js b/googletrendsgame/server/server.js index 12a6717..d60ec16 100644 --- a/googletrendsgame/server/server.js +++ b/googletrendsgame/server/server.js @@ -1,7 +1,11 @@ -//list of all the rooms -var rooms = {}; +/** + * Object used for storing rooms + * @param capacityP -- the number of people that can be in room + * @param pass -- the room password -- null if none + * @param owner -- the person who is creating the room + */ var room = function(capacityP, pass, owner) { //max capacity of room -- default is 4 for now @@ -39,7 +43,8 @@ var room = function(capacityP, pass, owner) } /** - * + * Removes a specific user from the room and adjusts the size of the array + * if the array is empty, the room closes * @param p */ this.removeUser = function(p) @@ -67,11 +72,20 @@ var room = function(capacityP, pass, owner) } } + /** + * creates json to send in the 'roomUpdate' socket event + */ this.generateRoomUpdate() { } + /** + * Whether or not a user can join this room -- checks for number of people are + * already in the room and the password + * @param p + * @returns {boolean} + */ this.canJoin = function(p) { if(this.password == null) @@ -86,6 +100,9 @@ var room = function(capacityP, pass, owner) } +//list of all the rooms +var rooms = {}; + var player = function(s) { //name of the user @@ -101,8 +118,16 @@ var player = function(s) this.room = null; this.sumbission = null; -} + /** + * generate the json object used in 'roomUpdate' socket io event + */ + this.genJASON = function() + { + + } +} +//list of all players --accessed using names like a dic var players = {}; @@ -114,6 +139,8 @@ const port = 3000; const serverUtils = require('./serverUtils.js'); + + //Whenever someone connects this gets executed io.on('connection', function(socket) { @@ -158,16 +185,17 @@ io.on('connection', function(socket) }); /** - * + * Room Selection (joinRoom) Client => Server + * data {roomName: , password: } */ socket.on('joinRoom', function(data) { console.log("join room event called"); console.log(data); console.log(" "); - if(rooms[data.name].canJoin(data.password)) + if(rooms[data.roomName].canJoin(data.password)) { - rooms[data.name].addUser(player); + rooms[data.roomName].addUser(player); } else { @@ -175,13 +203,16 @@ io.on('connection', function(socket) } }); + /** + * data -- literally a string + */ socket.on('submitWord', function(data) { console.log("submitWord called"); console.log(data); console.log(" "); }); - //Whenever someone disconnects this piece of code executed + //Whenever someone disconnects socket.on('disconnect', function () { console.log('A user disconnected'); @@ -196,6 +227,8 @@ io.on('connection', function(socket) player.room.removeUser(player); } + players[player.name] = null; + }); }); diff --git a/googletrendsgame/server/utils.js b/googletrendsgame/server/utils.js index f647cc8..fa2633d 100644 --- a/googletrendsgame/server/utils.js +++ b/googletrendsgame/server/utils.js @@ -12,5 +12,15 @@ module.exports= getRandomWord : function() { return ''; + }, + + /** + * returns a specific amount of words -- unique + * @param num + * @returns {Array} + */ + getRandomWords : function(num) + { + return []; } }; \ No newline at end of file From e605e333738ea59434463bb73fc0e2362b8f12e4 Mon Sep 17 00:00:00 2001 From: Jeffery R Date: Sat, 27 Jan 2018 17:19:36 -0500 Subject: [PATCH 5/6] Updated stuff for client - server test --- googletrendsgame/server/server.js | 75 ++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/googletrendsgame/server/server.js b/googletrendsgame/server/server.js index d60ec16..e121119 100644 --- a/googletrendsgame/server/server.js +++ b/googletrendsgame/server/server.js @@ -1,4 +1,6 @@ +const serverUtils = require('./serverUtils.js'); +const utils = require("./utils.js"); /** * Object used for storing rooms @@ -17,7 +19,10 @@ var room = function(capacityP, pass, owner) this.addUser(owner); //list of words used in the game - this.words = []; + //7 for now will change later to be room specific + this.words = utils.getRandomWords(7); + + this.currentWord = this.words.pop(); //list players -- so we can push requests to them this.users = []; @@ -28,6 +33,12 @@ var room = function(capacityP, pass, owner) // the password of the room -- null if no password this.password = null; + /** + 1 = Waiting for users + 2 = Word shown, Waiting for response from users + 3 = Showing Result + 4 = Game Over, Display Final Results + */ this.state = 1; /** @@ -40,6 +51,23 @@ var room = function(capacityP, pass, owner) //check if room is not full this.users.push(player); player.room = this; + + if(this.users.length == this.capacity) + { + this.state = 2; + } + + this.sendRoomUpdate(); + + } + + this.sendRoomUpdate = function() + { + var message = this.generateRoomUpdate(); + this.users.forEach(function(u) + { + u.socket.emit('roomUpdate', message); + }); } /** @@ -74,10 +102,25 @@ var room = function(capacityP, pass, owner) /** * creates json to send in the 'roomUpdate' socket event + * + * {users: gameState: roundWinner: currentWord: } */ - this.generateRoomUpdate() + this.generateRoomUpdate = function() { + var result = new Object(); + result.users = []; + this.users.forEach(function(u) + { + result.users.push(u.genJASON()); + }); + + result.gameState = this.state; + + result.roundWinner = "meh"; + result.currentWord = this.currentWord; + + return result; } /** @@ -98,6 +141,12 @@ var room = function(capacityP, pass, owner) } } + //updates room variables + this.update = function() + { + + } + } //list of all the rooms @@ -117,14 +166,31 @@ var player = function(s) //reference to the room -- might not need this this.room = null; + //the word the user selected for current round this.sumbission = null; /** * generate the json object used in 'roomUpdate' socket io event + * + * return {name: score: word:} */ this.genJASON = function() { + var result = new Object(); + result.name = this.name; + result.score = this.score; + result.word = this.sumbission; + } + /** + * data -- literally a string + * @param data + */ + this.selectWord = function(data) + { + this.sumbission = data; + + this.room.update(); } } //list of all players --accessed using names like a dic @@ -137,9 +203,6 @@ var io = require('socket.io')(http); const port = 3000; -const serverUtils = require('./serverUtils.js'); - - //Whenever someone connects this gets executed io.on('connection', function(socket) @@ -210,6 +273,8 @@ io.on('connection', function(socket) console.log("submitWord called"); console.log(data); console.log(" "); + + player.selectWord(data); }); //Whenever someone disconnects From f79709c451583dde56b0cf5a0144a963c976457e Mon Sep 17 00:00:00 2001 From: ritfsaecdaq Date: Sat, 27 Jan 2018 18:41:01 -0500 Subject: [PATCH 6/6] added year popularity record retrieval functionality --- googletrendsgame/server/trendsAPI.js | 59 ++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/googletrendsgame/server/trendsAPI.js b/googletrendsgame/server/trendsAPI.js index 2cf9303..d359614 100644 --- a/googletrendsgame/server/trendsAPI.js +++ b/googletrendsgame/server/trendsAPI.js @@ -1,6 +1,38 @@ const googt = require('google-trends-api'); const Promise = require('promise'); -const DAY = 1000 * 60 * 60 * 24; +const DAY = 1000 * 60 * 60 * 24; // 1 day in milliseconds +const YEAR = DAY * 365; // 1 year in milliseconds +const GEO = 'US'; //the scope of the trends + + +/** +desc: helper function for getYearStats, gets list of popularity for days in +the month. +*/ +function getMonthStats(word, month){ + + return new Promise(function(resolve, reject){ + //set up query for 1 month length + googt.interestOverTime({ + keyword:word, + startTime:new Date(Date.now() - (YEAR * month/12)), + endTime:new Date(Date.now() - (YEAR * (month-1)/12)) + }).then(function(results){ + //parse the json, fill return array w tuples of date + value + var times = JSON.parse(results).default.timelineData; + var ret = []; + for(var i = 0; i < times.length; ++i){ + var tup = new Object(); + tup.time = times[i].formattedTime; + tup.value = times[i].value[0]; + ret[i] = tup; + + } + resolve(ret); + }); + }); +} + module.exports= { /* @@ -11,9 +43,11 @@ module.exports= //must be a promise since call to trends API is async return new Promise(function(resolve, reject){ - //specifies the keyword, time interval, and granularity + //specifies the keyword, time interval, granularity, and region googt.interestOverTime({keyword:word, - startTime:new Date(Date.now() - DAY),granularTimeResolution:true}) + startTime:new Date(Date.now() - DAY),granularTimeResolution:true, + geo:GEO + }) .then(function(results){ //turn into json object data = JSON.parse(results).default.timelineData; @@ -21,7 +55,6 @@ module.exports= //add up values var total = 0; data.forEach(function(element){ - console.log(element.formattedTime + " " + element.value[0]); total += element.value[0]; }) @@ -31,5 +64,23 @@ module.exports= reject("Google Trends Query Failed"); }); }); + }, + + /** + desc: returns a list of tuples (date, value) representing word's + popularity for the past year + */ + getYearStats: async function(word){ + var ret = []; + + for (var i = 9; i > 0; --i) { + await getMonthStats(word,i).then(function(data){ + ret = ret.concat(data); + }); + console.log(i); + } + + return ret; } + };