Implement creating and joining rooms
This commit is contained in:
parent
50f359c1c3
commit
4ba0f326bd
7 changed files with 127 additions and 17 deletions
|
@ -2,7 +2,7 @@ import { Mongo } from "meteor/mongo";
|
||||||
|
|
||||||
let Players = new Mongo.Collection("players");
|
let Players = new Mongo.Collection("players");
|
||||||
|
|
||||||
// let collection = Players.rawCollection();
|
let collection = Players.rawCollection();
|
||||||
// collection.ensureIndex({ joinCode: 1 }, { unique: true });
|
collection.ensureIndex({ name: 1, roomId: 1, }, { unique: true });
|
||||||
|
|
||||||
export default Players;
|
export default Players;
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
import "./newGame";
|
import "./newGame";
|
||||||
|
import "./joinGame";
|
||||||
|
|
38
imports/api/methods/joinGame.js
Normal file
38
imports/api/methods/joinGame.js
Normal file
|
@ -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 };
|
||||||
|
}
|
||||||
|
});
|
|
@ -7,6 +7,8 @@ import Players from "../collections/Players.js";
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
"newGame": async ({ name }) => {
|
"newGame": async ({ name }) => {
|
||||||
check(name, String);
|
check(name, String);
|
||||||
|
name = name.trim();
|
||||||
|
|
||||||
let roomId = null;
|
let roomId = null;
|
||||||
let state = "waitingRoom";
|
let state = "waitingRoom";
|
||||||
|
|
||||||
|
@ -25,16 +27,21 @@ Meteor.methods({
|
||||||
// BulkWriteError
|
// BulkWriteError
|
||||||
if (e.code === 11000) {
|
if (e.code === 11000) {
|
||||||
remainingAttempts -= 1;
|
remainingAttempts -= 1;
|
||||||
|
} else {
|
||||||
|
console.log("UNCAUGHT", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let playerId = Players.insert({ roomId, name });
|
let playerId = Players.insert({ roomId, name });
|
||||||
|
Rooms.update(roomId, { $set: { owner: playerId } });
|
||||||
|
|
||||||
if (remainingAttempts == 0 && roomId === null) {
|
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 };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<component v-bind:is="whatScreen"></component>
|
<component
|
||||||
|
v-bind:is="whatScreen"
|
||||||
|
v-bind="currentRoom"
|
||||||
|
v-on:newGame="newGame"
|
||||||
|
v-on:joinGame="joinGame"
|
||||||
|
></component>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Lobby from './components/Lobby.vue'
|
import Lobby from './components/Lobby.vue'
|
||||||
|
import WaitingRoom from './components/WaitingRoom.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Lobby,
|
Lobby,
|
||||||
|
WaitingRoom,
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
@ -18,6 +25,18 @@ export default {
|
||||||
whatScreen: Lobby,
|
whatScreen: Lobby,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
newGame: function(args) {
|
||||||
|
this.currentRoom = args;
|
||||||
|
this.whatScreen = WaitingRoom;
|
||||||
|
},
|
||||||
|
|
||||||
|
joinGame: function(args) {
|
||||||
|
this.currentRoom = args;
|
||||||
|
this.whatScreen = WaitingRoom;
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
<div>
|
<div>
|
||||||
<h1>LOBBY</h1>
|
<h1>LOBBY</h1>
|
||||||
|
|
||||||
|
<div id="error">{{ errorMessage }}</div>
|
||||||
|
|
||||||
<form v-on:submit.prevent="newGame">
|
<form v-on:submit.prevent="newGame">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -11,16 +13,30 @@
|
||||||
v-model="newGameName"
|
v-model="newGameName"
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
/>
|
/>
|
||||||
<button type="submit">new game</button>
|
<button type="submit" :disabled="loading">new game</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p>or</p>
|
<p>or</p>
|
||||||
|
|
||||||
<div>
|
<form v-on:submit.prevent="joinGame">
|
||||||
<input type="text" autocomplete="off" name="name" placeholder="what's your name?" />
|
<input
|
||||||
<input type="text" autocomplete="off" name="code" placeholder="join code" />
|
type="text"
|
||||||
<button id="joingame-btn">join game</button>
|
autocomplete="off"
|
||||||
</div>
|
required
|
||||||
|
placeholder="join code"
|
||||||
|
v-model="joinGameCode"
|
||||||
|
:disabled="loading"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
autocomplete="off"
|
||||||
|
required
|
||||||
|
placeholder="what's your name?"
|
||||||
|
v-model="joinGameName"
|
||||||
|
:disabled="loading"
|
||||||
|
/>
|
||||||
|
<button type="submit" :disabled="loading">join game</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -32,20 +48,45 @@ export default {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
newGameName: "",
|
newGameName: "",
|
||||||
|
joinGameName: "",
|
||||||
|
joinGameCode: "",
|
||||||
|
errorMessage: "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
newGame: function (evt) {
|
newGame: function(evt) {
|
||||||
loading = true;
|
this.loading = true;
|
||||||
let name = this.newGameName;
|
let name = this.newGameName;
|
||||||
Meteor.call("newGame", { name }, (err, res) => {
|
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);
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
#error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Waiting for players...</h1>
|
||||||
|
<p>Join code: {{ joinCode.toUpperCase() }}</p>
|
||||||
|
<p>Players: {{ players }}</p>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
|
props: ["joinCode", "players"],
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue