commit
c1b32f1cb7
9 changed files with 62 additions and 23 deletions
|
|
@ -2,17 +2,17 @@
|
||||||
1. `cd` into this `server` directory.
|
1. `cd` into this `server` directory.
|
||||||
2. Run `pnpm install` to install all of the required dependencies.
|
2. Run `pnpm install` to install all of the required dependencies.
|
||||||
3. Create a copy of the `template.toml` file, and name it `server.toml`.
|
3. Create a copy of the `template.toml` file, and name it `server.toml`.
|
||||||
4. Edit the `server.toml` file to adjust the
|
4. Edit the `server.toml` file to adjust the server and game settings.
|
||||||
5. Run `tsc` to compile the TypeScript into Javascript. This should create a
|
5. Run `tsc` to compile the TypeScript into Javascript. This should create a
|
||||||
`dist` directory.
|
`dist` directory.
|
||||||
|
|
||||||
|
|
||||||
## Using systemd to manage the server: (Not currently implemented)
|
## Using systemd to manage the server:
|
||||||
This app comes with a `ghost-writer.service` file which is already set up to
|
This app comes with a `ghost-writer.service` file which is already set up to
|
||||||
manage the server, it just requires a little bit of additional setup. If you
|
manage the server, it just requires a little bit of additional setup. If you
|
||||||
change any of the symlinking in the steps below, it is your responsibility to
|
change any of the symlinking in the steps below, it is your responsibility to
|
||||||
figure it out, I will not guarantee support for people who attempt to modify
|
figure it out, I will not guarantee support for people who attempt to modify
|
||||||
the service file.
|
the service file beyond the steps below.
|
||||||
|
|
||||||
6. Create a symlink named `server` in the server root (`/`) pointing to the
|
6. Create a symlink named `server` in the server root (`/`) pointing to the
|
||||||
server folder in the Ghost Writer git repository.
|
server folder in the Ghost Writer git repository.
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export default (io: Server, socket: Socket, data: NewHand) => {
|
||||||
// Add the questions and then alert the game clients about the changes
|
// Add the questions and then alert the game clients about the changes
|
||||||
team.addCardsToHand(deck.draw(handSize));
|
team.addCardsToHand(deck.draw(handSize));
|
||||||
game.log.silly(`Drew a new hand of cards for team ${data.team}.`);
|
game.log.silly(`Drew a new hand of cards for team ${data.team}.`);
|
||||||
io.to(game.id).emit(`UpdateHand`, {
|
io.to(`${game.id}:${team.id}:guesser`).emit(`UpdateHand`, {
|
||||||
status: 200,
|
status: 200,
|
||||||
mode: `replace`,
|
mode: `replace`,
|
||||||
questions: team.hand,
|
questions: team.hand,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ export default (io: Server, socket: Socket, data: SendCard) => {
|
||||||
|
|
||||||
// Assert game exists
|
// Assert game exists
|
||||||
if (!games[data.game_code]) {
|
if (!games[data.game_code]) {
|
||||||
log.debug(`Can't send a card in a game that doesn't exist: ${data.game_code}`);
|
log.debug(`Can't fing a game with code: ${data.game_code}`);
|
||||||
socket.emit(`UpdateHand`, {
|
socket.emit(`UpdateHand`, {
|
||||||
status: 404,
|
status: 404,
|
||||||
message: `Game with code ${data.game_code} could not be found`,
|
message: `Game with code ${data.game_code} could not be found`,
|
||||||
|
|
@ -20,7 +20,7 @@ export default (io: Server, socket: Socket, data: SendCard) => {
|
||||||
|
|
||||||
// The writer is answering
|
// The writer is answering
|
||||||
if (data.from === "writer") {
|
if (data.from === "writer") {
|
||||||
game.log.debug(`Writer selected question to answer.`);
|
game.log.debug(`Writer selected question to answer`);
|
||||||
|
|
||||||
// Draw new cards for team
|
// Draw new cards for team
|
||||||
deck.discard(data.text);
|
deck.discard(data.text);
|
||||||
|
|
@ -42,7 +42,7 @@ export default (io: Server, socket: Socket, data: SendCard) => {
|
||||||
|
|
||||||
// The writer is sending the card to the writer
|
// The writer is sending the card to the writer
|
||||||
else if (data.from === "guesser") {
|
else if (data.from === "guesser") {
|
||||||
game.log.debug(`Guesser is sending a card to the writer.`);
|
game.log.debug(`Guesser is sending a card to the writer`);
|
||||||
|
|
||||||
// Update the team's hand
|
// Update the team's hand
|
||||||
team.removeCard(data.text);
|
team.removeCard(data.text);
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ key = ''
|
||||||
# directory of the CLI instantiating the server. (or an absolute path)
|
# directory of the CLI instantiating the server. (or an absolute path)
|
||||||
# - If "type" is "sheets", then this is a sheet identifier used by Google
|
# - If "type" is "sheets", then this is a sheet identifier used by Google
|
||||||
# Sheets to indicate which sheet to use when downloading the content.
|
# Sheets to indicate which sheet to use when downloading the content.
|
||||||
|
# In the published URL, this is the sequence of number between the
|
||||||
|
# `gid=` and the `&`, so if the URL has `gid=123456789&`, the fingerprint
|
||||||
|
# would be `123456789`.
|
||||||
fingerprint = ''
|
fingerprint = ''
|
||||||
|
|
||||||
# The zero-indexed column number to use when getting the question text.
|
# The zero-indexed column number to use when getting the question text.
|
||||||
|
|
@ -46,6 +49,9 @@ column = 0
|
||||||
# directory of the CLI instantiating the server. (or an absolute path)
|
# directory of the CLI instantiating the server. (or an absolute path)
|
||||||
# - If "type" is "sheets", then this is a sheet identifier used by Google
|
# - If "type" is "sheets", then this is a sheet identifier used by Google
|
||||||
# Sheets to indicate which sheet to use when downloading the content.
|
# Sheets to indicate which sheet to use when downloading the content.
|
||||||
|
# In the published URL, this is the sequence of number between the
|
||||||
|
# `gid=` and the `&`, so if the URL has `gid=123456789&`, the fingerprint
|
||||||
|
# would be `123456789`.
|
||||||
fingerprint = ''
|
fingerprint = ''
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
v-for="answerIndex in 8"
|
v-for="answerIndex in 8"
|
||||||
:class="[
|
:class="[
|
||||||
`answer`,
|
`answer`,
|
||||||
answers[`team_${3 - $store.state.team}`][answerIndex-1].toLowerCase() === getObject
|
answers[`team_${3 - $store.state.team}`][answerIndex-1].toLowerCase().match(getObject)
|
||||||
? `correct`: ``
|
? `correct`: ``
|
||||||
]"
|
]"
|
||||||
:key="`${otherTeamID}-answer-container-${answerIndex}`"
|
:key="`${otherTeamID}-answer-container-${answerIndex}`"
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
v-for="answerIndex in 8"
|
v-for="answerIndex in 8"
|
||||||
:class="[
|
:class="[
|
||||||
`answer`,
|
`answer`,
|
||||||
answers[`team_${$store.state.team}`][answerIndex-1].toLowerCase() === getObject
|
answers[`team_${$store.state.team}`][answerIndex-1].toLowerCase().match(getObject)
|
||||||
? `correct`: ``
|
? `correct`: ``
|
||||||
]"
|
]"
|
||||||
:key="`${teamID}-answer-container-${answerIndex}`"
|
:key="`${teamID}-answer-container-${answerIndex}`"
|
||||||
|
|
@ -109,7 +109,7 @@ import PastQuestions from './PastQuestions';
|
||||||
export default {
|
export default {
|
||||||
name: `GameBoard`,
|
name: `GameBoard`,
|
||||||
components: {
|
components: {
|
||||||
"past-questions": PastQuestions
|
"past-questions": PastQuestions,
|
||||||
},
|
},
|
||||||
data() {return {
|
data() {return {
|
||||||
visible: false,
|
visible: false,
|
||||||
|
|
@ -126,9 +126,9 @@ export default {
|
||||||
},
|
},
|
||||||
getObject() {
|
getObject() {
|
||||||
if (!this.$store.state.chosen_object) {
|
if (!this.$store.state.chosen_object) {
|
||||||
return ``;
|
return /\n/;
|
||||||
};
|
};
|
||||||
return this.$store.state.chosen_object.toLowerCase() + `.`;
|
return new RegExp(`${this.$store.state.chosen_object.toLowerCase()}\\.?`);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,11 @@ export default {
|
||||||
},
|
},
|
||||||
gameOver() {
|
gameOver() {
|
||||||
if (this.$store.state.chosen_object) {
|
if (this.$store.state.chosen_object) {
|
||||||
let targetAnswer = this.$store.state.chosen_object.toLowerCase()+`.`;
|
let answerRegex = new RegExp(`${this.$store.state.chosen_object.toLowerCase()}\\.?`);
|
||||||
|
|
||||||
for (var team in this.$store.state.answers) {
|
for (var team in this.$store.state.answers) {
|
||||||
for (var answer of this.$store.state.answers[team]) {
|
for (var answer of this.$store.state.answers[team]) {
|
||||||
if (answer.toLowerCase() === targetAnswer) {
|
if (answer.toLowerCase().match(answerRegex)) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,10 @@
|
||||||
<div id="player_list" class="centre">
|
<div id="player_list" class="centre">
|
||||||
<h2>Players:</h2>
|
<h2>Players:</h2>
|
||||||
<div
|
<div
|
||||||
v-for="player in $store.state.players"
|
v-for="player in players"
|
||||||
:key="player.name"
|
:key="player.name"
|
||||||
>
|
>
|
||||||
{{ player.name }}
|
{{ player.name }}
|
||||||
<span v-if="player.role" class="player-role">
|
|
||||||
( {{ teamName(player.team) }} {{ roleName(player.role) }} )
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -22,7 +19,9 @@ export default {
|
||||||
return this.$store.state.is_host;
|
return this.$store.state.is_host;
|
||||||
},
|
},
|
||||||
players() {
|
players() {
|
||||||
return this.$store.state.players;
|
return this.$store.state.players.filter(
|
||||||
|
p => p.role == null && p.team == null
|
||||||
|
);
|
||||||
},
|
},
|
||||||
gameCode() {
|
gameCode() {
|
||||||
return this.$store.state.game_code;
|
return this.$store.state.game_code;
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,31 @@
|
||||||
>
|
>
|
||||||
{{ $store.state.writer_name }}
|
{{ $store.state.writer_name }}
|
||||||
</button>
|
</button>
|
||||||
|
<div class="players">
|
||||||
|
<div
|
||||||
|
class="player"
|
||||||
|
v-for="player in writers"
|
||||||
|
:key="player.name"
|
||||||
|
>
|
||||||
|
{{ player.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
<button
|
<button
|
||||||
class="clickable"
|
class="clickable"
|
||||||
@click.stop="joinRole(`guesser`)"
|
@click.stop="joinRole(`guesser`)"
|
||||||
>
|
>
|
||||||
{{ $store.state.guesser_name }}
|
{{ $store.state.guesser_name }}
|
||||||
</button>
|
</button>
|
||||||
|
<div class="players">
|
||||||
|
<div
|
||||||
|
class="player"
|
||||||
|
v-for="player in guessers"
|
||||||
|
:key="player.name"
|
||||||
|
>
|
||||||
|
{{ player.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -29,7 +48,17 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
teamName() {
|
teamName() {
|
||||||
return this.$store.state[`team_${this.teamID}`].name;
|
return this.$store.state[`team_${this.teamID}`].name;
|
||||||
}
|
},
|
||||||
|
writers() {
|
||||||
|
return this.$store.state.players.filter(
|
||||||
|
p => p.team === this.teamID && p.role === `writer`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
guessers() {
|
||||||
|
return this.$store.state.players.filter(
|
||||||
|
p => p.team === this.teamID && p.role === `guesser`
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
joinRole(role) {
|
joinRole(role) {
|
||||||
|
|
@ -81,6 +110,10 @@ export default {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
background-color: var(--background3);
|
background-color: var(--background3);
|
||||||
color: var(--background3-text);
|
color: var(--background3-text);
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,8 @@
|
||||||
--confirm-background-darken: #006600;
|
--confirm-background-darken: #006600;
|
||||||
--confirm-background-lighten: #00aa00;
|
--confirm-background-lighten: #00aa00;
|
||||||
--confirm-text: white;
|
--confirm-text: white;
|
||||||
--cancel-background: #aa0000;
|
--cancel-background: #c94a4a;
|
||||||
--cancel-background-darken: #830101;
|
--cancel-background-darken: #a54141;
|
||||||
--cancel-background-lighten: #e71111;
|
--cancel-background-lighten: #fa7d7d;
|
||||||
--cancel-text: white;
|
--cancel-text: white;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue