From 4ba0f326bde4697b38db5bd642efaf0cb0dbd48b Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Fri, 27 Nov 2020 01:16:15 -0600 Subject: [PATCH] Implement creating and joining rooms --- imports/api/collections/Players.js | 4 +- imports/api/methods/index.js | 1 + imports/api/methods/joinGame.js | 38 +++++++++++++++++ imports/api/methods/newGame.js | 11 ++++- imports/ui/App.vue | 21 ++++++++- imports/ui/components/Lobby.vue | 61 ++++++++++++++++++++++----- imports/ui/components/WaitingRoom.vue | 8 +++- 7 files changed, 127 insertions(+), 17 deletions(-) create mode 100644 imports/api/methods/joinGame.js diff --git a/imports/api/collections/Players.js b/imports/api/collections/Players.js index 3d306ec..e429750 100644 --- a/imports/api/collections/Players.js +++ b/imports/api/collections/Players.js @@ -2,7 +2,7 @@ import { Mongo } from "meteor/mongo"; let Players = new Mongo.Collection("players"); -// let collection = Players.rawCollection(); -// collection.ensureIndex({ joinCode: 1 }, { unique: true }); +let collection = Players.rawCollection(); +collection.ensureIndex({ name: 1, roomId: 1, }, { unique: true }); export default Players; diff --git a/imports/api/methods/index.js b/imports/api/methods/index.js index 7636156..283b2b5 100644 --- a/imports/api/methods/index.js +++ b/imports/api/methods/index.js @@ -1 +1,2 @@ import "./newGame"; +import "./joinGame"; diff --git a/imports/api/methods/joinGame.js b/imports/api/methods/joinGame.js new file mode 100644 index 0000000..46f3fe2 --- /dev/null +++ b/imports/api/methods/joinGame.js @@ -0,0 +1,38 @@ +import { Meteor } from "meteor/meteor"; +import { Random } from "meteor/random"; +import { check } from "meteor/check"; +import Rooms from "../collections/Rooms.js"; +import Players from "../collections/Players.js"; + +Meteor.methods({ + "joinGame": async ({ code, name }) => { + check(code, String); + check(name, String); + name = name.trim(); + + let room = Rooms.findOne({ joinCode: code }); + if (room === undefined) { + throw new Meteor.Error("room-not-found"); + } + + if (room.state !== "waitingRoom") { + throw new Meteor.Error("room-already-playing"); + } + + let roomId = room._id; + try { + let playerId = Players.insert({ roomId, name }); + } catch (e) { + if (e.code === 11000) { + throw new Meteor.Error("name-collision"); + } + } + + let joinCode = room.joinCode; + let players = {}; + Players.find({ roomId }).forEach((doc) => { + players[doc._id] = doc.name; + }); + return { joinCode, players, roomId }; + } +}); diff --git a/imports/api/methods/newGame.js b/imports/api/methods/newGame.js index da5f9f0..e030acc 100644 --- a/imports/api/methods/newGame.js +++ b/imports/api/methods/newGame.js @@ -7,6 +7,8 @@ import Players from "../collections/Players.js"; Meteor.methods({ "newGame": async ({ name }) => { check(name, String); + name = name.trim(); + let roomId = null; let state = "waitingRoom"; @@ -25,16 +27,21 @@ Meteor.methods({ // BulkWriteError if (e.code === 11000) { remainingAttempts -= 1; + } else { + console.log("UNCAUGHT", e); } } } let playerId = Players.insert({ roomId, name }); + Rooms.update(roomId, { $set: { owner: playerId } }); if (remainingAttempts == 0 && roomId === null) { - return "failed"; + throw new Meteor.Error("no-more-rooms"); } - return { playerId, roomId, joinCode }; + let players = {}; + players[playerId] = name; + return { players, roomId, joinCode }; }, }); diff --git a/imports/ui/App.vue b/imports/ui/App.vue index 16617e5..eb9a81e 100644 --- a/imports/ui/App.vue +++ b/imports/ui/App.vue @@ -1,15 +1,22 @@ diff --git a/imports/ui/components/Lobby.vue b/imports/ui/components/Lobby.vue index 30e7b9b..977ceb9 100644 --- a/imports/ui/components/Lobby.vue +++ b/imports/ui/components/Lobby.vue @@ -2,6 +2,8 @@

LOBBY

+
{{ errorMessage }}
+
- +

or

-
- - - -
+
+ + + +
@@ -32,20 +48,45 @@ export default { return { loading: false, newGameName: "", + joinGameName: "", + joinGameCode: "", + errorMessage: "", }; }, methods: { - newGame: function (evt) { - loading = true; + newGame: function(evt) { + this.loading = true; let name = this.newGameName; Meteor.call("newGame", { name }, (err, res) => { - console.log(err, res); + if (err !== undefined) { + this.errorMessage = err.message; + this.loading = false; + return; + } + this.$emit("newGame", res); }); - } + }, + + joinGame: function(evt) { + this.loading = true; + let name = this.joinGameName; + let code = this.joinGameCode; + Meteor.call("joinGame", { code, name }, (err, res) => { + if (err !== undefined) { + this.errorMessage = err.message; + this.loading = false; + return; + } + this.$emit("joinGame", res); + }); + }, } } diff --git a/imports/ui/components/WaitingRoom.vue b/imports/ui/components/WaitingRoom.vue index 283df85..5428029 100644 --- a/imports/ui/components/WaitingRoom.vue +++ b/imports/ui/components/WaitingRoom.vue @@ -1,10 +1,14 @@