From 0113931c28a495374c7b3f4a633c64f5617aab2e Mon Sep 17 00:00:00 2001 From: tuc56407 Date: Sun, 3 Apr 2022 09:52:53 -0400 Subject: [PATCH 1/5] KC-133 Rename index to server, create matchmaker, create ranked queue buckets NOTE: ALL SERVER CODE IS NOW TARGETING LOCALLY HOSTED SERVERS. This is a large commit involving the initialization and connection of the matchmaker server to the regular mp server. All user communication will go through the mp server only. Additionally, the groundwork has been laid for all server communication from client to matchmaker and back again. The main piece that is missing now is the actual matchmaking logic. Currently, users are placed in a mmr-specific bucket upon joining the queue to simplify matchmaking. All ranked game-joining logic has been set in place. Once a condition is met, the matched players will all be emitted the appropriate lobby ID for their ranked game and the front-end logic should be working. --- .../components/MultiplayerPage/Multiplayer.js | 14 ++++- .../MultiplayerPage/MultiplayerGame.js | 12 +++- .../components/MultiplayerPage/matchmaker.js | 60 +++++++++++++++++++ .../MultiplayerPage/{index.js => server.js} | 22 ++++++- 4 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 KeyCtrl/src/components/MultiplayerPage/matchmaker.js rename KeyCtrl/src/components/MultiplayerPage/{index.js => server.js} (85%) diff --git a/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js b/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js index 2fc8fc8..01e0530 100644 --- a/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js +++ b/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js @@ -34,6 +34,7 @@ const Multiplayer = ({accountInfo}) => { const [lobbyID, setLobbyID] = useState(0) const [name, setName] = useState('guest' + Math.floor(Math.random() * 1000)) const [isFindMatch, setFindMatch] = useState(false) + const [isRanked, setRanked] = useState(false) const socketRef = useRef() @@ -42,7 +43,8 @@ const Multiplayer = ({accountInfo}) => { determineName() if (socketRef.current == null) { console.log("creating new connection") - socketRef.current = io.connect("https://generated-respected-python.glitch.me") + //socketRef.current = io.connect("https://generated-respected-python.glitch.me") + socketRef.current = io.connect("http://localhost:4000") } //Finding Match code... socketRef.current.on('findMatchSuccess', (lobby) => { @@ -78,6 +80,12 @@ const Multiplayer = ({accountInfo}) => { setShowModal(true) } + function findRanked() { + setFindMatch(true) + setShowModal(true) + socketRef.current.emit('findRanked', {username: name, mmr: 5}) + } + return (
@@ -113,7 +121,7 @@ const Multiplayer = ({accountInfo}) => { {joinLobby ? null :
-
+
Ranked @@ -130,7 +138,9 @@ const Multiplayer = ({accountInfo}) => { lobbyID={lobbyID} username={name} isFindMatch={isFindMatch} + isRanked={isRanked} setFindMatch={setFindMatch} + setRanked={setRanked} setJoinLobby={setJoinLobby} setShowModal={setShowModal} setLobbyID={setLobbyID} diff --git a/KeyCtrl/src/components/MultiplayerPage/MultiplayerGame.js b/KeyCtrl/src/components/MultiplayerPage/MultiplayerGame.js index e89905f..bb1ace3 100644 --- a/KeyCtrl/src/components/MultiplayerPage/MultiplayerGame.js +++ b/KeyCtrl/src/components/MultiplayerPage/MultiplayerGame.js @@ -48,7 +48,8 @@ const MultiplayerGame = (props) => { useEffect( () => { - socketRef.current = io.connect("https://generated-respected-python.glitch.me") //LOCALHOST for local testing + //socketRef.current = io.connect("https://generated-respected-python.glitch.me") + socketRef.current = io.connect("http://localhost:4000") console.log(lobbyID, username) socketRef.current.emit('switchLobby', { lobbyID }, username) @@ -69,6 +70,15 @@ const MultiplayerGame = (props) => { props.setJoinLobby(true) }) + socketRef.current.on('findRankedMatchSuccess', (rankedLobby) => { + console.log(socketRef.current.id + " found a ranked match") + socketRef.current.disconnect() + props.setLobbyID(rankedLobby) + props.setShowModal(false) + props.setJoinLobby(false) + props.setJoinLobby(true) + }) + socketRef.current.on("gameStart", () => { console.log("Game Start") setInCountdown(true) diff --git a/KeyCtrl/src/components/MultiplayerPage/matchmaker.js b/KeyCtrl/src/components/MultiplayerPage/matchmaker.js new file mode 100644 index 0000000..fd9de80 --- /dev/null +++ b/KeyCtrl/src/components/MultiplayerPage/matchmaker.js @@ -0,0 +1,60 @@ +const app = require('express')() +const http = require('http').createServer(app) +const io = require('socket.io')(http, { + cors: { + origin: ["http://localhost:3000", "http://localhost:4000", "https://generated-respected-python.glitch.me", "https://keyctrl.net"], //CHANGE TO HOST URL + methods: ["GET", "POST"], + credentials: true, + transports: ['websocket', 'polling'] + }, + allowEIO3: true +}); + +//Initialize Ranked Queue with MMR buckets +var rankedQueue = [] +rankedQueue[0] = new Array() //0-299 +rankedQueue[1] = new Array() //300-599 +rankedQueue[2] = new Array() //600-899 +rankedQueue[3] = new Array() //900+ + +var bucketBracketOne = 300 +var bucketBracketTwo = 600 +var bucketBracketThree = 900 + +var foundPlayers = [] //WARNING: CURRENTLY ALL LOGIC INVOLVING FOUNDPLAYERS WILL FAIL + //AS IT WILL OVERLAP WITH OTHER GAMES. NEEDS TO BE MADE GAME SPECIFIC SOMEHOW + +io.on('connection', (socket) => { + console.log("connection received") + socket.on('addToRankedQueue', function({socketID, username, mmr}) { + console.log("ADDED TO QUEUE - socket: " + socketID + " user: " + username + " mmr: " + mmr) + var queuingPlayer = {socketID, username, mmr} + //Place user in their bucket + switch(mmr) { + case (mmr { + + }) +} + +http.listen(4001, () => { + console.log('listening on *:4001'); + }); \ No newline at end of file diff --git a/KeyCtrl/src/components/MultiplayerPage/index.js b/KeyCtrl/src/components/MultiplayerPage/server.js similarity index 85% rename from KeyCtrl/src/components/MultiplayerPage/index.js rename to KeyCtrl/src/components/MultiplayerPage/server.js index 3112b5d..ae0ac8c 100644 --- a/KeyCtrl/src/components/MultiplayerPage/index.js +++ b/KeyCtrl/src/components/MultiplayerPage/server.js @@ -1,3 +1,4 @@ +const ioclient = require('socket.io-client') const app = require('express')() const http = require('http').createServer(app) const io = require('socket.io')(http, { @@ -15,9 +16,11 @@ var wordsArray = {}; var roomWordsArray = {}; var matchResultsArray = {}; var findMatchPlayers = []; - var gameStartPlayers = 4; +//Matchmaking server connection +var mmServerSocket = ioclient.connect("http://localhost:4001") + //Generate lines to send to players var randWordsFunc = require('random-words'); @@ -78,7 +81,14 @@ io.on('connection', (socket) => { console.log(socket.id + " stopped looking for a match") }) - //Custom Lobby code + //Ranked Queue + socket.on('findRanked', function({username, mmr}) { + var socketID = socket.id + console.log("sending " + username + " " + mmr + " to matchmaker") + mmServerSocket.emit('addToRankedQueue', ({socketID, username, mmr: 5})) + }) + + //Join Lobby socket.on('switchLobby', function(newRoom, username) { socket.join(newRoom.lobbyID); socket.emit('updateLobby', newRoom); @@ -147,6 +157,14 @@ io.on('connection', (socket) => { } }) + socket.on('rankedGameMatched', function(foundPlayers) { + //Create random lobby ID + var rankedLobby = 'rankedLobby' + Math.random() * 10000 + foundPlayers.forEach(player => { + io.to(player.socketID).emit('findRankedMatchSuccess', rankedLobby) + }) + }) + socket.on('message', ({ name, message }, room) => { io.in(room).emit('message', { name, message }); }); From aacb11e4e7f8f8613f3f891cac0704ca567c9842 Mon Sep 17 00:00:00 2001 From: tuc56407 Date: Mon, 4 Apr 2022 17:09:30 -0400 Subject: [PATCH 2/5] KC-133 Get ranked game to start with multi-server communication Still no matchmaking algorithm but all data is being passed properly and the game starts --- .../components/MultiplayerPage/Multiplayer.js | 9 ++++ .../components/MultiplayerPage/matchmaker.js | 53 +++++++++++-------- .../src/components/MultiplayerPage/server.js | 32 ++++++----- 3 files changed, 59 insertions(+), 35 deletions(-) diff --git a/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js b/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js index 01e0530..681124e 100644 --- a/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js +++ b/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js @@ -54,6 +54,15 @@ const Multiplayer = ({accountInfo}) => { setShowModal(false) setJoinLobby(true) }) + + socketRef.current.on('findRankedMatchSuccess', (rankedLobby) => { + console.log(socketRef.current.id + " found a ranked match") + socketRef.current.disconnect() + setLobbyID(rankedLobby) + setShowModal(false) + setJoinLobby(false) + setJoinLobby(true) + }) }) //Enter lobby modal diff --git a/KeyCtrl/src/components/MultiplayerPage/matchmaker.js b/KeyCtrl/src/components/MultiplayerPage/matchmaker.js index fd9de80..7f3dbd6 100644 --- a/KeyCtrl/src/components/MultiplayerPage/matchmaker.js +++ b/KeyCtrl/src/components/MultiplayerPage/matchmaker.js @@ -2,7 +2,7 @@ const app = require('express')() const http = require('http').createServer(app) const io = require('socket.io')(http, { cors: { - origin: ["http://localhost:3000", "http://localhost:4000", "https://generated-respected-python.glitch.me", "https://keyctrl.net"], //CHANGE TO HOST URL + origin: ["http://localhost:3000", "https://generated-respected-python.glitch.me", "https://keyctrl.net"], //CHANGE TO HOST URL methods: ["GET", "POST"], credentials: true, transports: ['websocket', 'polling'] @@ -25,35 +25,46 @@ var foundPlayers = [] //WARNING: CURRENTLY ALL LOGIC INVOLVING FOUNDPLAYER //AS IT WILL OVERLAP WITH OTHER GAMES. NEEDS TO BE MADE GAME SPECIFIC SOMEHOW io.on('connection', (socket) => { - console.log("connection received") + console.log(socket.id + " connected") socket.on('addToRankedQueue', function({socketID, username, mmr}) { console.log("ADDED TO QUEUE - socket: " + socketID + " user: " + username + " mmr: " + mmr) var queuingPlayer = {socketID, username, mmr} //Place user in their bucket - switch(mmr) { - case (mmr= 4) { + console.log("Match Found") + for(var i=0; i<4; i++) { + foundPlayers.push(rankedQueue[0].shift()) + } + console.log("emitting to: ") + for(var i=0; i { +// if(rankedQueue[3].length >= 4) { +// for(var i=0; i<3; i++) { +// foundPlayers.push(rankedQueue[3].shift()) +// } +// } - }) -} http.listen(4001, () => { console.log('listening on *:4001'); diff --git a/KeyCtrl/src/components/MultiplayerPage/server.js b/KeyCtrl/src/components/MultiplayerPage/server.js index ae0ac8c..699ab4c 100644 --- a/KeyCtrl/src/components/MultiplayerPage/server.js +++ b/KeyCtrl/src/components/MultiplayerPage/server.js @@ -3,7 +3,7 @@ const app = require('express')() const http = require('http').createServer(app) const io = require('socket.io')(http, { cors: { - origin: ["https://capstone-projects-2022-spring.github.io", "http://localhost:3000" ,"https://keyctrl.net"], //CHANGE TO HOST URL + origin: ["https://capstone-projects-2022-spring.github.io", "http://localhost:3000", "https://keyctrl.net"], //CHANGE TO HOST URL methods: ["GET", "POST"], credentials: true, transports: ['websocket', 'polling'] @@ -16,6 +16,7 @@ var wordsArray = {}; var roomWordsArray = {}; var matchResultsArray = {}; var findMatchPlayers = []; +var findRankedMatchPlayers = []; var gameStartPlayers = 4; //Matchmaking server connection @@ -81,13 +82,6 @@ io.on('connection', (socket) => { console.log(socket.id + " stopped looking for a match") }) - //Ranked Queue - socket.on('findRanked', function({username, mmr}) { - var socketID = socket.id - console.log("sending " + username + " " + mmr + " to matchmaker") - mmServerSocket.emit('addToRankedQueue', ({socketID, username, mmr: 5})) - }) - //Join Lobby socket.on('switchLobby', function(newRoom, username) { socket.join(newRoom.lobbyID); @@ -157,17 +151,27 @@ io.on('connection', (socket) => { } }) - socket.on('rankedGameMatched', function(foundPlayers) { + socket.on('message', ({ name, message }, room) => { + io.in(room).emit('message', { name, message }); + }); + + //Ranked Queue + socket.on('findRanked', function({username, mmr}) { + var socketID = socket.id + console.log("sending " + socketID + " " + username + " " + mmr + " to matchmaker") + mmServerSocket.emit('addToRankedQueue', ({socketID, username, mmr: 5})) + }) + + mmServerSocket.on('rankedGameMatched', function(foundPlayers) { + console.log("Ranked Match Found! Connecting") //Create random lobby ID var rankedLobby = 'rankedLobby' + Math.random() * 10000 foundPlayers.forEach(player => { - io.to(player.socketID).emit('findRankedMatchSuccess', rankedLobby) + var socketID = player.socketID + console.log(" - " + player.username + "id: " + socketID) + io.to(socketID).emit('findRankedMatchSuccess', rankedLobby) }) }) - - socket.on('message', ({ name, message }, room) => { - io.in(room).emit('message', { name, message }); - }); }); http.listen(4000, () => { From 1e38c7719c02e80a3912b24a473c67d567bea26a Mon Sep 17 00:00:00 2001 From: tuc56407 Date: Wed, 6 Apr 2022 10:57:36 -0400 Subject: [PATCH 3/5] KC-133 Finished ranked communications, requeue and leave options --- KeyCtrl/src/components/MultiplayerPage/Modal.js | 12 +++++++++++- .../components/MultiplayerPage/Multiplayer.js | 14 +++++++++----- .../MultiplayerPage/MultiplayerGame.js | 16 +++++++++++++--- .../src/components/MultiplayerPage/matchmaker.js | 10 ++++++---- KeyCtrl/src/components/MultiplayerPage/server.js | 6 ++++++ 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/KeyCtrl/src/components/MultiplayerPage/Modal.js b/KeyCtrl/src/components/MultiplayerPage/Modal.js index 547968d..011a457 100644 --- a/KeyCtrl/src/components/MultiplayerPage/Modal.js +++ b/KeyCtrl/src/components/MultiplayerPage/Modal.js @@ -1,7 +1,7 @@ //Modal.js import React, { useRef } from "react"; import ReactDom from "react-dom"; -export const Modal = ({ setShowModal, setJoinLobby, setLobbyID, setName, name, isFindMatch, cancelFindMatch }) => { +export const Modal = ({ setShowModal, setJoinLobby, setLobbyID, setName, name, isFindMatch, cancelFindMatch, isRanked, cancelFindRanked }) => { // close the modal when clicking outside the modal. const modalRef = useRef(); const closeModal = (e) => { @@ -28,6 +28,16 @@ export const Modal = ({ setShowModal, setJoinLobby, setLobbyID, setName, name, i
, document.getElementById("portal") ); + } else if (isRanked) { + return ReactDom.createPortal( +
+
+

Finding a Match...

+ +
+
, + document.getElementById("portal") + ); } else { return ReactDom.createPortal(
diff --git a/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js b/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js index 681124e..b2f1009 100644 --- a/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js +++ b/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js @@ -49,7 +49,6 @@ const Multiplayer = ({accountInfo}) => { //Finding Match code... socketRef.current.on('findMatchSuccess', (lobby) => { console.log(socketRef.current.id + " found a match") - //socketRef.current.disconnect() setLobbyID(lobby) setShowModal(false) setJoinLobby(true) @@ -57,10 +56,9 @@ const Multiplayer = ({accountInfo}) => { socketRef.current.on('findRankedMatchSuccess', (rankedLobby) => { console.log(socketRef.current.id + " found a ranked match") - socketRef.current.disconnect() setLobbyID(rankedLobby) setShowModal(false) - setJoinLobby(false) + setRanked(true) setJoinLobby(true) }) }) @@ -90,15 +88,21 @@ const Multiplayer = ({accountInfo}) => { } function findRanked() { - setFindMatch(true) + setRanked(true) setShowModal(true) socketRef.current.emit('findRanked', {username: name, mmr: 5}) } + function cancelFindRanked() { + socketRef.current.emit('cancelFindRanked') + setRanked(false) + setShowModal(false) + } + return (
- {showModal ? : null} + {showModal ? : null} {joinLobby ? null :
diff --git a/KeyCtrl/src/components/MultiplayerPage/MultiplayerGame.js b/KeyCtrl/src/components/MultiplayerPage/MultiplayerGame.js index bb1ace3..e77728f 100644 --- a/KeyCtrl/src/components/MultiplayerPage/MultiplayerGame.js +++ b/KeyCtrl/src/components/MultiplayerPage/MultiplayerGame.js @@ -290,7 +290,11 @@ const MultiplayerGame = (props) => { // --------------------------------------------------- function readyUp() { - if(props.isFindMatch) { + if(props.isRanked) { + console.log("Requeue for Ranked") + props.setShowModal(true) + socketRef.current.emit('findRanked', {username, mmr: 5}) + } else if(props.isFindMatch) { //get back in Find Match queue props.setShowModal(true) socketRef.current.emit('findMatch') @@ -303,11 +307,17 @@ const MultiplayerGame = (props) => { function leaveRoom() { //back to mp menu + props.setRanked(false) props.setJoinLobby(false) props.setFindMatch(false) } - + var readyRequeueBtn + if(props.isRanked || props.isFindMatch) { + readyRequeueBtn = + } else { + readyRequeueBtn = + } return (
@@ -359,7 +369,7 @@ const MultiplayerGame = (props) => {
- + {readyRequeueBtn}
diff --git a/KeyCtrl/src/components/MultiplayerPage/matchmaker.js b/KeyCtrl/src/components/MultiplayerPage/matchmaker.js index 7f3dbd6..58be8b0 100644 --- a/KeyCtrl/src/components/MultiplayerPage/matchmaker.js +++ b/KeyCtrl/src/components/MultiplayerPage/matchmaker.js @@ -49,14 +49,16 @@ io.on('connection', (socket) => { for(var i=0; i<4; i++) { foundPlayers.push(rankedQueue[0].shift()) } - console.log("emitting to: ") - for(var i=0; i { + list.splice(list.indexOf(socketID), 1) + console.log(socketID + " stopped left the queue") + }) + }) }) // if(rankedQueue[3].length >= 4) { diff --git a/KeyCtrl/src/components/MultiplayerPage/server.js b/KeyCtrl/src/components/MultiplayerPage/server.js index 699ab4c..51996ef 100644 --- a/KeyCtrl/src/components/MultiplayerPage/server.js +++ b/KeyCtrl/src/components/MultiplayerPage/server.js @@ -82,6 +82,12 @@ io.on('connection', (socket) => { console.log(socket.id + " stopped looking for a match") }) + socket.on('cancelFindRanked', function() { + console.log("Canceling ranked search") + var socketID = socket.id + mmServerSocket.emit('cancelFindRanked', (socketID)) + }) + //Join Lobby socket.on('switchLobby', function(newRoom, username) { socket.join(newRoom.lobbyID); From 0cbcde1c625820e532a300c158fc3fd8f9284a9d Mon Sep 17 00:00:00 2001 From: tuc56407 Date: Wed, 6 Apr 2022 11:02:46 -0400 Subject: [PATCH 4/5] Update menu button command overwritten by merge --- KeyCtrl/src/components/MultiplayerPage/Multiplayer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js b/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js index dcc3469..daadf78 100644 --- a/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js +++ b/KeyCtrl/src/components/MultiplayerPage/Multiplayer.js @@ -137,7 +137,7 @@ const Multiplayer = ({loggedIn, accountInfo}) => { {joinLobby || !loggedIn ? null :
-
+
Ranked
From 723e4f2c1aa3277ac942897714560fad8822e929 Mon Sep 17 00:00:00 2001 From: tuc56407 Date: Wed, 6 Apr 2022 11:03:36 -0400 Subject: [PATCH 5/5] Fix logging --- KeyCtrl/src/components/MultiplayerPage/matchmaker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KeyCtrl/src/components/MultiplayerPage/matchmaker.js b/KeyCtrl/src/components/MultiplayerPage/matchmaker.js index 58be8b0..de50ae0 100644 --- a/KeyCtrl/src/components/MultiplayerPage/matchmaker.js +++ b/KeyCtrl/src/components/MultiplayerPage/matchmaker.js @@ -56,7 +56,7 @@ io.on('connection', (socket) => { socket.on('cancelFindRanked', function(socketID) { rankedQueue.forEach(list => { list.splice(list.indexOf(socketID), 1) - console.log(socketID + " stopped left the queue") + console.log(socketID + " left the queue") }) }) })