Updating to working state
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
7de9b3ab64
commit
fd2795892f
@ -209,9 +209,7 @@ const Chat = ({ board, promoteGameState }) => {
|
|||||||
console.log(`Send: ${event.target.value}`);
|
console.log(`Send: ${event.target.value}`);
|
||||||
promoteGameState({
|
promoteGameState({
|
||||||
chat: {
|
chat: {
|
||||||
player: board.game.activePlayer ?
|
player: board.game.color ? board.game.color : undefined,
|
||||||
board.game.activePlayer :
|
|
||||||
undefined,
|
|
||||||
message: event.target.value
|
message: event.target.value
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -246,7 +244,7 @@ const Chat = ({ board, promoteGameState }) => {
|
|||||||
{ messages }
|
{ messages }
|
||||||
</List>
|
</List>
|
||||||
<TextField className="chatInput"
|
<TextField className="chatInput"
|
||||||
disabled={!board.game.activePlayerName}
|
disabled={!board.game.name}
|
||||||
onChange={chatInput}
|
onChange={chatInput}
|
||||||
onKeyPress={chatKeyPress}
|
onKeyPress={chatKeyPress}
|
||||||
label={(<Moment format="h:mm:ss" interval={1000}/>)} variant="outlined"/>
|
label={(<Moment format="h:mm:ss" interval={1000}/>)} variant="outlined"/>
|
||||||
@ -283,7 +281,7 @@ const Action = ({ board }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PlayerName = ({board}) => {
|
const PlayerName = ({board}) => {
|
||||||
const [name, setName] = useState((board && board.game && board.game.activePlayerName) ? board.game.activePlayerName : "");
|
const [name, setName] = useState((board && board.game && board.game.name) ? board.game.name : "");
|
||||||
|
|
||||||
const nameChange = (event) => {
|
const nameChange = (event) => {
|
||||||
setName(event.target.value);
|
setName(event.target.value);
|
||||||
@ -292,7 +290,7 @@ const PlayerName = ({board}) => {
|
|||||||
const nameKeyPress = (event) => {
|
const nameKeyPress = (event) => {
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
console.log(`Send: ${name}`);
|
console.log(`Send: ${name}`);
|
||||||
if (name != board.game.activePlayerName) {
|
if (name != board.game.name) {
|
||||||
board.setPlayerName(name);
|
board.setPlayerName(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,38 +310,48 @@ const PlayerName = ({board}) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getPlayerName = (sessions, color) => {
|
||||||
|
for (let i = 0; i < sessions.length; i++) {
|
||||||
|
const session = sessions[i];
|
||||||
|
if (session.color === color) {
|
||||||
|
return session.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/* This needs to take in a mechanism to declare the
|
/* This needs to take in a mechanism to declare the
|
||||||
* player's active item in the game */
|
* player's active item in the game */
|
||||||
const Players = ({ board }) => {
|
const Players = ({ board }) => {
|
||||||
const selected = board.game && board.game.activePlayer ? board.game.activePlayer : "";
|
|
||||||
|
|
||||||
const toggleSelected = (key) => {
|
const toggleSelected = (key) => {
|
||||||
board.setSelected(selected === key ? "" : key);
|
board.setSelected(board.game.color === key ? "" : key);
|
||||||
}
|
}
|
||||||
|
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
||||||
const players = [];
|
const players = [];
|
||||||
for (let key in board.game.players) {
|
console.log(`Player ${board.game.name} is ${board.game.color}`);
|
||||||
const item = board.game.players[key];
|
for (let color in board.game.players) {
|
||||||
|
const item = board.game.players[color];
|
||||||
if (board.game.state !== "lobby" && item.status === 'Not active') {
|
if (board.game.state !== "lobby" && item.status === 'Not active') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
const name = getPlayerName(board.game.sessions, color);
|
||||||
item.lastActive = item.lastActive > Date.now() ? Date.now() : item.lastActive;
|
item.lastActive = item.lastActive > Date.now() ? Date.now() : item.lastActive;
|
||||||
players.push((
|
players.push((
|
||||||
<ListItem key={`player-${key}`}>
|
<ListItem key={`player-${color}`}>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar className={classes[key]}>{key}</Avatar>
|
<Avatar className={classes[color]}>{color}</Avatar>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText primary={item.name} secondary={(
|
<ListItemText primary={name} secondary={(
|
||||||
<>
|
<>
|
||||||
{ item.status + ' ' }
|
{ item.status + ' ' }
|
||||||
{ item.status != 'Not active' && <Moment fromNow date={item.lastActive}/>}
|
{ item.status != 'Not active' && <Moment fromNow date={item.lastActive}/>}
|
||||||
</>)} />
|
</>)} />
|
||||||
{ (item.status === 'Not active' || selected === key) &&
|
{ (item.status === 'Not active' || board.game.color === color) &&
|
||||||
<Switch edge="end"
|
<Switch edge="end"
|
||||||
checked={selected === key}
|
checked={board.game.color === color}
|
||||||
onChange={() => toggleSelected(key)}/>
|
onChange={() => toggleSelected(color)}/>
|
||||||
}
|
}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
));
|
));
|
||||||
@ -449,13 +457,7 @@ class Board extends React.Component {
|
|||||||
return res.json();
|
return res.json();
|
||||||
}).then((game) => {
|
}).then((game) => {
|
||||||
let message;
|
let message;
|
||||||
if (game.status == 'success') {
|
if (game.status !== 'success') {
|
||||||
if (key) {
|
|
||||||
message = `Player selected ${key}!`;
|
|
||||||
} else {
|
|
||||||
message = `Player deselected ${game.activePlayer}!`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
message = game.status;
|
message = game.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,13 +492,7 @@ class Board extends React.Component {
|
|||||||
return res.json();
|
return res.json();
|
||||||
}).then((game) => {
|
}).then((game) => {
|
||||||
let message;
|
let message;
|
||||||
if (game.status == 'success') {
|
if (game.status !== 'success') {
|
||||||
if (name) {
|
|
||||||
message = `Player name set to ${name}`;
|
|
||||||
} else {
|
|
||||||
message = `Player name cleared.`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
message = game.status;
|
message = game.status;
|
||||||
}
|
}
|
||||||
this.updateGame(game);
|
this.updateGame(game);
|
||||||
@ -561,9 +557,10 @@ class Board extends React.Component {
|
|||||||
}
|
}
|
||||||
return res.json();
|
return res.json();
|
||||||
}).then((game) => {
|
}).then((game) => {
|
||||||
let message = game.status != "success" ? game.status : "Dice rolled!"
|
let message;
|
||||||
if (game.status != "success") {
|
if (game.status !== "success") {
|
||||||
game.dice = [];
|
game.dice = [];
|
||||||
|
message = game.status;
|
||||||
}
|
}
|
||||||
this.updateGame(game);
|
this.updateGame(game);
|
||||||
this.setState({ game: { ...this.state.game, dice: game.dice }, message: message } );
|
this.setState({ game: { ...this.state.game, dice: game.dice }, message: message } );
|
||||||
@ -1323,10 +1320,10 @@ class Board extends React.Component {
|
|||||||
<div className="Cards" ref={el => this.cards = el}>
|
<div className="Cards" ref={el => this.cards = el}>
|
||||||
{ game &&
|
{ game &&
|
||||||
<div className={'Game ' + game.state}>
|
<div className={'Game ' + game.state}>
|
||||||
{game.activePlayer === "" && <PlayerName board={this}/> }
|
{!game.color && <PlayerName board={this}/> }
|
||||||
<Players board={this} promoteGameState={this.promoteGameState}/>
|
<Players board={this} promoteGameState={this.promoteGameState}/>
|
||||||
<Chat board={this} promoteGameState={this.promoteGameState}/>
|
<Chat board={this} promoteGameState={this.promoteGameState}/>
|
||||||
{ game.activePlayer !== "" &&
|
{ game.color &&
|
||||||
<Action board={this}/>
|
<Action board={this}/>
|
||||||
}
|
}
|
||||||
{ this.state.message != "" && <Paper><div style={{align:"left",fontSize:"8pt"}}>{this.state.message}</div></Paper> }
|
{ this.state.message != "" && <Paper><div style={{align:"left",fontSize:"8pt"}}>{this.state.message}</div></Paper> }
|
||||||
|
12
server/kick
12
server/kick
@ -1,15 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
ADMIN=$(jq .admin config/local.json)
|
ADMIN=$(jq -r .admin config/local.json)
|
||||||
if [[ "${ADMIN}" == "" ]]; then
|
if [[ "${ADMIN}" == "" ]]; then
|
||||||
echo "You need to set your { 'admin': 'secret' } in config/local.json"
|
echo "You need to set your { 'admin': 'secret' } in config/local.json"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
id=$1
|
id=$1
|
||||||
user=$2
|
color=$2
|
||||||
|
|
||||||
if [[ "${id}" == "" ]] || [[ "${user}" == "" ]]; then
|
if [[ "${id}" == "" ]] || [[ "${color}" == "" ]]; then
|
||||||
echo "Usage: kick GAME-ID USER-NAME"
|
echo "Usage: kick GAME-ID red|white|blue|orange"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -17,6 +17,6 @@ curl --noproxy '*' -s -L \
|
|||||||
--request PUT \
|
--request PUT \
|
||||||
--header "PRIVATE-TOKEN: ${ADMIN}" \
|
--header "PRIVATE-TOKEN: ${ADMIN}" \
|
||||||
--header "Content-Type: application/json" \
|
--header "Content-Type: application/json" \
|
||||||
http://localhost:8930/ketr.ketran/api/v1/games/${id}/kick/${user} |
|
http://localhost:8930/ketr.ketran/api/v1/games/${id}/kick/${color} |
|
||||||
jq .status
|
jq -r .status
|
||||||
|
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const express = require("express"),
|
const express = require("express"),
|
||||||
config = require("config"),
|
|
||||||
moment = require("moment"),
|
|
||||||
crypto = require("crypto"),
|
crypto = require("crypto"),
|
||||||
util = require("util"),
|
|
||||||
Promise = require("bluebird"),
|
|
||||||
{ readFile, writeFile } = require("fs").promises;
|
{ readFile, writeFile } = require("fs").promises;
|
||||||
|
|
||||||
let gameDB;
|
let gameDB;
|
||||||
@ -100,34 +96,68 @@ for (let i = 0; i < 5; i++) {
|
|||||||
|
|
||||||
const games = {};
|
const games = {};
|
||||||
|
|
||||||
const roll = (game, player) => {
|
const roll = (game, session) => {
|
||||||
let error;
|
let message;
|
||||||
if (!player) {
|
|
||||||
error = "No player active; roll has no action";
|
|
||||||
console.log(error);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
const name = player.name;
|
const player = session.player,
|
||||||
|
name = session.name ? session.name : "Unnamed";
|
||||||
|
|
||||||
switch (game.state) {
|
switch (game.state) {
|
||||||
case "lobby":
|
case "lobby":
|
||||||
if (player.order) {
|
return `Rolling dice in the lobby is not allowed!`;
|
||||||
error = `Player ${name} already rolled for order.`;
|
|
||||||
console.log(error);
|
case "game-order":
|
||||||
return error;
|
if (player.order) {
|
||||||
}
|
retrun = `Player ${name} already rolled for order.`;
|
||||||
game.dice = [ Math.ceil(Math.random() * 6) ];
|
}
|
||||||
player.order = game.dice[0];
|
player.order = game.dice[0];
|
||||||
const message = `${name} rolled ${game.dice[0]} for play order.`;
|
message = `${name} rolled ${game.dice[0]} for play order.`;
|
||||||
game.chat.push({ date: Date.now(), message: message });
|
game.chat.push({ date: Date.now(), message: message });
|
||||||
console.log(message);
|
break;
|
||||||
return;
|
|
||||||
|
case "in-game":
|
||||||
|
game.dice = [ Math.ceil(Math.random() * 6), Math.ceil(Math.random() * 6) ];
|
||||||
|
message = `${name} rolled ${game.dice[0] + game.dice[1]}.`;
|
||||||
|
game.chat.push({ date: Date.now(), message: message });
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return `Invalid game state (${game.state}) in roll.`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPlayer = (game, color) => {
|
||||||
|
if (!game) {
|
||||||
|
return {
|
||||||
|
roads: 15,
|
||||||
|
cities: 4,
|
||||||
|
settlements: 5,
|
||||||
|
points: 0,
|
||||||
|
status: "Not active",
|
||||||
|
lastActive: 0,
|
||||||
|
order: 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
error = `Invalid game state (${game.state}) in roll.`;
|
return game.players[color];
|
||||||
return error;
|
};
|
||||||
}
|
|
||||||
|
const getSession = (game, session) => {
|
||||||
|
if (!game.sessions) {
|
||||||
|
game.sessions = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this session is not yet in the game,
|
||||||
|
* add it and set the player's name */
|
||||||
|
if (!(session in game.sessions)) {
|
||||||
|
game.sessions[session] = {
|
||||||
|
name: undefined,
|
||||||
|
player: undefined
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return game.sessions[session];
|
||||||
|
};
|
||||||
|
|
||||||
const loadGame = async (id) => {
|
const loadGame = async (id) => {
|
||||||
if (/^\.|\//.exec(id)) {
|
if (/^\.|\//.exec(id)) {
|
||||||
@ -138,27 +168,165 @@ const loadGame = async (id) => {
|
|||||||
return games[id];
|
return games[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
const game = await readFile(`games/${id}`)
|
let game = await readFile(`games/${id}`)
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!game) {
|
if (!game) {
|
||||||
games[id] = createGame(id);
|
game = createGame(id);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
games[id] = JSON.parse(game);
|
game = JSON.parse(game);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error, game);
|
console.error(error, game);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return games[id];
|
/* Reconnect session player colors to the player objects */
|
||||||
|
for (let id in game.sessions) {
|
||||||
|
const session = game.sessions[id];
|
||||||
|
if (session.color && session.color in game.players) {
|
||||||
|
session.player = game.players[session.color];
|
||||||
|
} else {
|
||||||
|
session.color = undefined;
|
||||||
|
session.player = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
games[id] = game;
|
||||||
|
return game;
|
||||||
|
};
|
||||||
|
|
||||||
|
const adminActions = (game, action, value) => {
|
||||||
|
switch (action) {
|
||||||
|
case "kick":
|
||||||
|
let color;
|
||||||
|
switch (value) {
|
||||||
|
case 'orange': color = 'O'; break;
|
||||||
|
case 'red': color = 'R'; break;
|
||||||
|
case 'blue': color = 'B'; break;
|
||||||
|
case 'white': color = 'W'; break;
|
||||||
|
}
|
||||||
|
if (!color) {
|
||||||
|
return `Unable to find player ${value}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const player = game.players[color];
|
||||||
|
for (let id in game.sessions) {
|
||||||
|
const session = game.sessions[id];
|
||||||
|
if (session.player !== player) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
console.log(`Kicking ${value} from ${game.id}.`);
|
||||||
|
const name = session.name ? `${session.name} (${color})` : color;
|
||||||
|
game.chat.push({
|
||||||
|
date: Date.now(),
|
||||||
|
message: `${name} has been kicked from game.`
|
||||||
|
});
|
||||||
|
session.player = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return `Unable to find active session for ${color} (${value})`;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return `Invalid admin action ${action}.`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setPlayerName = (game, session, name) => {
|
||||||
|
if (session.color) {
|
||||||
|
return `You cannot change your name while you are in game.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check to ensure name is not already in use */
|
||||||
|
if (game && name) for (let key in game.sessions) {
|
||||||
|
const tmp = game.sessions[key];
|
||||||
|
if (tmp.name && tmp.name.toLowerCase() === name.toLowerCase()) {
|
||||||
|
return `${name} is already taken.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const old = session.name ? session.name : "Unknown";
|
||||||
|
let message;
|
||||||
|
|
||||||
|
session.name = name;
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
message = `${old} is now known as ${name}.`;
|
||||||
|
} else {
|
||||||
|
message = `${old} no longer has a name.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
game.chat.push({
|
||||||
|
date: Date.now(),
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const setPlayerColor = (game, session, color) => {
|
||||||
|
if (!game) {
|
||||||
|
return `No game found`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = session.name, player = session.player;
|
||||||
|
|
||||||
|
/* Selecting the same color is a NO-OP */
|
||||||
|
if (session.color === color) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player) {
|
||||||
|
/* Deselect currently active player for this session */
|
||||||
|
player.status = 'Not active';
|
||||||
|
player.lastActive = 0;
|
||||||
|
game.chat.push({
|
||||||
|
date: Date.now(),
|
||||||
|
message: `${session.color} is no longer claimed.`
|
||||||
|
});
|
||||||
|
session.player = undefined;
|
||||||
|
session.color = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify the player has a name set */
|
||||||
|
if (!name) {
|
||||||
|
return `You may only select a player when you have set your name.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the player is not selecting a color, then return */
|
||||||
|
if (!color) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify selection is valid */
|
||||||
|
if (!(color in game.players)) {
|
||||||
|
return `An invalid player selection was attempted.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify selection is not already taken */
|
||||||
|
for (let key in game.sessions) {
|
||||||
|
const tmp = game.sessions[key].player;
|
||||||
|
if (tmp && tmp.color === color) {
|
||||||
|
return `${game.sessions[key].name} already has ${color}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All good -- set this player to requested selection */
|
||||||
|
session.player = getPlayer(game, color);
|
||||||
|
|
||||||
|
session.player.status = `Active`;
|
||||||
|
session.player.lastActive = Date.now();
|
||||||
|
session.color = color;
|
||||||
|
game.chat.push({
|
||||||
|
date: Date.now(),
|
||||||
|
message: `${color} is now '${session.name}'.`
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
router.put("/:id/:action/:value?", async (req, res) => {
|
router.put("/:id/:action/:value?", async (req, res) => {
|
||||||
const { action, id, value } = req.params;
|
const { action, id } = req.params,
|
||||||
|
value = req.params.value ? req.params.value : "";
|
||||||
console.log(`PUT games/${id}/${action}/${value}`);
|
console.log(`PUT games/${id}/${action}/${value}`);
|
||||||
|
|
||||||
const game = await loadGame(id);
|
const game = await loadGame(id);
|
||||||
@ -167,159 +335,38 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
return res.status(404).send(error);
|
return res.status(404).send(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const color = req.session && req.session.playerColor in game.players ?
|
|
||||||
req.session.playerColor : undefined;
|
|
||||||
|
|
||||||
let player;
|
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
if ('private-token' in req.headers) {
|
if ('private-token' in req.headers) {
|
||||||
if (req.headers['private-token'] !== req.app.get('admin')) {
|
if (req.headers['private-token'] !== req.app.get('admin')) {
|
||||||
error = `Invalid admin credentials.`;
|
error = `Invalid admin credentials.`;
|
||||||
}
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case "kick":
|
|
||||||
error = `Unable to find player ${value}`
|
|
||||||
for (let color in game.players) {
|
|
||||||
player = game.players[color];
|
|
||||||
if (player.name.toLowerCase() === value.toLowerCase()) {
|
|
||||||
console.log(`Kicking ${value} from ${id}.`);
|
|
||||||
game.chat.push({
|
|
||||||
date: Date.now(),
|
|
||||||
message: `${player.name} has been kicked from game.`
|
|
||||||
});
|
|
||||||
player.session = '';
|
|
||||||
player.name = '';
|
|
||||||
player.status = 'Not active';
|
|
||||||
player.lastActive = 0;
|
|
||||||
error = undefined;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sendGame(res, req, game, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action == "player-name") {
|
|
||||||
const name = value ? value : "";
|
|
||||||
if (color) {
|
|
||||||
error = `You cannot change your name while you are in game.`;
|
|
||||||
} else {
|
} else {
|
||||||
if (game) for (let key in game.players) {
|
error = adminActions(game, action, value);
|
||||||
player = game.players[key];
|
|
||||||
if (player.name && player.name.toLowerCase() === name.toLowerCase()) {
|
|
||||||
error = `${name} is already taken by ${key}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return sendGame(req, res, game, error);
|
||||||
if (!error) {
|
|
||||||
const old = req.session.playerName ? req.session.PlayerName : "Unknown";
|
|
||||||
let message;
|
|
||||||
req.session.playerName = name;
|
|
||||||
if (name) {
|
|
||||||
message = `${old} is now known as ${name}.`;
|
|
||||||
} else {
|
|
||||||
message = `${old} no longer has a name.`;
|
|
||||||
}
|
|
||||||
game.chat.push({
|
|
||||||
date: Date.now(),
|
|
||||||
message: message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return sendGame(res, req, game, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == "player-selected") {
|
const session = getSession(game, req.session.id);
|
||||||
if (!game) {
|
|
||||||
error = `No game found`;
|
|
||||||
return sendGame(res, req, game, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
const selected = req.params.value,
|
switch (action) {
|
||||||
name = req.session.playerName;
|
case 'player-name':
|
||||||
|
error = setPlayerName(game, session, value);
|
||||||
console.log(`player-selected requested for ${selected} by ${name}`);
|
return sendGame(req, res, game, error);
|
||||||
|
case 'player-selected':
|
||||||
/* Deselect currently active player for this session */
|
error = setPlayerColor(game, session, value);
|
||||||
for (let key in game.players) {
|
return sendGame(req, res, game, error);
|
||||||
if (key === color && selected !== key) {
|
|
||||||
player = game.players[key];
|
|
||||||
if (player.session === req.session.id) {
|
|
||||||
player.session = '';
|
|
||||||
player.name = '';
|
|
||||||
player.status = 'Not active';
|
|
||||||
req.session.playerColor = '';
|
|
||||||
game.chat.push({
|
|
||||||
date: Date.now(),
|
|
||||||
message: `${key} is no longer claimed.`
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify the player has a name set */
|
|
||||||
if (!name) {
|
|
||||||
error = `You may only select a player when you have set your name.`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify this player's name is not already active in the game */
|
|
||||||
if (!error) {
|
|
||||||
for (let key in game.players) {
|
|
||||||
player = game.players[key];
|
|
||||||
if (key === color && selected !== key && player.name == name) {
|
|
||||||
error = `This name is already taken by ${key}`;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify selection is valid */
|
|
||||||
if (!error && !(selected in game.players)) {
|
|
||||||
error = `An invalid player selection was attempted.`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify selection is not already taken */
|
|
||||||
if (!error) {
|
|
||||||
player = game.players[selected];
|
|
||||||
if (player.session) {
|
|
||||||
error = `${player.name} already has ${selected}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All good -- set this player to requested selection */
|
|
||||||
if (!error) {
|
|
||||||
player.session = req.session.id;
|
|
||||||
player.name = req.session.playerName;
|
|
||||||
player.status = `Active`;
|
|
||||||
player.lastActive = Date.now();
|
|
||||||
req.session.playerColor = selected;
|
|
||||||
game.chat.push({
|
|
||||||
date: Date.now(),
|
|
||||||
message: `${selected} is now '${player.name}'.`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return sendGame(res, req, game, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req.session.playerColor ||
|
if (!session.player) {
|
||||||
!(req.session.playerColor in game.players)) {
|
error = `Player must have an active color.`;
|
||||||
error = `Invalid player: ${req.session.playerColor}`;
|
return sendGame(req, res, game, error);
|
||||||
return sendGame(res, req, game, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
player = game.players[req.session.playerColor];
|
const name = session.name;
|
||||||
const name = player.name;
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "roll":
|
case "roll":
|
||||||
error = roll(game, player);
|
error = roll(game, session);
|
||||||
break;
|
break;
|
||||||
case "shuffle":
|
case "shuffle":
|
||||||
if (game.state !== "lobby") {
|
if (game.state !== "lobby") {
|
||||||
@ -336,8 +383,10 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "state":
|
case "state":
|
||||||
const state = req.params.value ? req.params.value : "active";
|
const state = value;
|
||||||
if (state != game.state) {
|
if (!state) {
|
||||||
|
error = `Invalid state.`;
|
||||||
|
} else if (state != game.state) {
|
||||||
game.state = state;
|
game.state = state;
|
||||||
const message = `${name} set game state to ${state}.`;
|
const message = `${name} set game state to ${state}.`;
|
||||||
game.chat.push({ date: Date.now(), message: message });
|
game.chat.push({ date: Date.now(), message: message });
|
||||||
@ -345,7 +394,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendGame(res, req, game, error);
|
return sendGame(req, res, game, error);
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get("/:id", async (req, res/*, next*/) => {
|
router.get("/:id", async (req, res/*, next*/) => {
|
||||||
@ -354,52 +403,48 @@ router.get("/:id", async (req, res/*, next*/) => {
|
|||||||
|
|
||||||
let game = await loadGame(id);
|
let game = await loadGame(id);
|
||||||
if (game) {
|
if (game) {
|
||||||
return sendGame(res, req, game)
|
return sendGame(req, res, game)
|
||||||
}
|
}
|
||||||
|
|
||||||
game = createGame(id);
|
game = createGame(id);
|
||||||
req.session.playerColor = null;
|
|
||||||
|
|
||||||
return sendGame(res, req, game);
|
return sendGame(req, res, game);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.put("/:id", (req, res/*, next*/) => {
|
router.put("/:id", (req, res/*, next*/) => {
|
||||||
console.log("PUT games/" + req.params.id);
|
const { id } = req.params;
|
||||||
if (req.params.id in games) {
|
|
||||||
const game = games[req.params.id],
|
|
||||||
changes = req.body;
|
|
||||||
|
|
||||||
console.log(req.session.id, req.session.playerColor);
|
console.log("PUT games/" + id);
|
||||||
console.log(JSON.stringify(changes, null, 2));
|
if (!(id in games)) {
|
||||||
|
|
||||||
for (let change in changes) {
|
|
||||||
switch (change) {
|
|
||||||
case "players":
|
|
||||||
break;
|
|
||||||
case "chat":
|
|
||||||
console.log("Chat change.");
|
|
||||||
game.chat.push({
|
|
||||||
from: changes.chat.player,
|
|
||||||
date: Date.now(),
|
|
||||||
message: changes.chat.message
|
|
||||||
});
|
|
||||||
if (game.chat.length > 10) {
|
|
||||||
game.chat.splice(0, game.chat.length - 10);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sendGame(res, req, game);
|
|
||||||
} else {
|
|
||||||
const error = `Game not found: ${req.params.id}`;
|
const error = `Game not found: ${req.params.id}`;
|
||||||
return res.status(404).send(error);
|
return res.status(404).send(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const game = games[id],
|
||||||
|
changes = req.body;
|
||||||
|
|
||||||
|
for (let change in changes) {
|
||||||
|
switch (change) {
|
||||||
|
case "chat":
|
||||||
|
console.log("Chat change.");
|
||||||
|
game.chat.push({
|
||||||
|
from: changes.chat.player,
|
||||||
|
date: Date.now(),
|
||||||
|
message: changes.chat.message
|
||||||
|
});
|
||||||
|
if (game.chat.length > 10) {
|
||||||
|
game.chat.splice(0, game.chat.length - 10);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sendGame(req, res, game);
|
||||||
});
|
});
|
||||||
|
|
||||||
const sendGame = async (res, req, game, error) => {
|
const sendGame = async (req, res, game, error) => {
|
||||||
let active = 0;
|
let active = 0;
|
||||||
for (let player in game.players) {
|
for (let color in game.players) {
|
||||||
player = game.players[player];
|
const player = game.players[color];
|
||||||
active += ((player.status && player.status != 'Not active') ? 1 : 0);
|
active += ((player.status && player.status != 'Not active') ? 1 : 0);
|
||||||
}
|
}
|
||||||
if (active < 2 && game.state != 'lobby' && game.state != 'invalid') {
|
if (active < 2 && game.state != 'lobby' && game.state != 'invalid') {
|
||||||
@ -408,26 +453,49 @@ const sendGame = async (res, req, game, error) => {
|
|||||||
console.log(message);
|
console.log(message);
|
||||||
game.state = 'lobby';
|
game.state = 'lobby';
|
||||||
}
|
}
|
||||||
const playerColor = (req.session && req.session.playerColor) ? req.session.playerColor : "",
|
|
||||||
playerName = (req.session && req.session.playerName) ? req.session.playerName : "";
|
let session;
|
||||||
if (playerColor in game.players) {
|
if (req.session) {
|
||||||
game.players[playerColor].lastActive = Date.now();
|
session = getSession(game, req.session.id);
|
||||||
|
session.lastActive = Date.now();
|
||||||
|
} else {
|
||||||
|
session = {
|
||||||
|
name: "command line"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
await writeFile(`games/${game.id}`, JSON.stringify(game, null, 2))
|
/* Shallow copy game, filling its sessions with a shallow copy of sessions so we can then
|
||||||
|
* delete the player field from them */
|
||||||
|
const reducedGame = Object.assign({}, game, { sessions: {} });
|
||||||
|
for (let id in game.sessions) {
|
||||||
|
const reduced = Object.assign({}, game.sessions[id]);
|
||||||
|
if (reduced.player) {
|
||||||
|
delete reduced.player;
|
||||||
|
}
|
||||||
|
reducedGame.sessions[id] = reduced;
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeFile(`games/${game.id}`, JSON.stringify(reducedGame, null, 2))
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(`Unable to write to games/${game.id}`);
|
console.error(`Unable to write to games/${game.id}`);
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
});
|
||||||
const playerGame = Object.assign({}, game, {
|
|
||||||
|
/* Do not send session-id as those are secrets */
|
||||||
|
const sessions = [];
|
||||||
|
for (let id in reducedGame.sessions) {
|
||||||
|
const reduced = reducedGame.sessions[id];
|
||||||
|
sessions.push(reduced);
|
||||||
|
}
|
||||||
|
|
||||||
|
const playerGame = Object.assign({}, reducedGame, {
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
status: error ? error : "success",
|
status: error ? error : "success",
|
||||||
activePlayerName: playerName,
|
name: session.name,
|
||||||
activePlayer: playerColor
|
color: session.color,
|
||||||
|
sessions: sessions
|
||||||
});
|
});
|
||||||
if (game.id == 'b3c4bd15efe212a2') {
|
|
||||||
// console.log(req.session);
|
|
||||||
}
|
|
||||||
return res.status(200).send(playerGame);
|
return res.status(200).send(playerGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,10 +510,10 @@ const createGame = (id) => {
|
|||||||
borders: [],
|
borders: [],
|
||||||
tokens: [],
|
tokens: [],
|
||||||
players: {
|
players: {
|
||||||
R: { roads: 15, cities: 4, settlements: 5, points: 0, name: "", status: "Not active" },
|
R: getPlayer(),
|
||||||
O: { roads: 15, cities: 4, settlements: 5, points: 0, name: "", status: "Not active" },
|
O: getPlayer(),
|
||||||
B: { roads: 15, cities: 4, settlements: 5, points: 0, name: "", status: "Not active" },
|
B: getPlayer(),
|
||||||
W: { roads: 15, cities: 4, settlements: 5, points: 0, name: "", status: "Not active" }
|
W: getPlayer()
|
||||||
},
|
},
|
||||||
developmentCards: assetData.developmentCards.slice(),
|
developmentCards: assetData.developmentCards.slice(),
|
||||||
dice: [ 0, 0 ],
|
dice: [ 0, 0 ],
|
||||||
@ -475,9 +543,8 @@ router.post("/:id?", (req, res/*, next*/) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const game = createGame(id);
|
const game = createGame(id);
|
||||||
req.session.playerColor = null;
|
|
||||||
|
|
||||||
return sendGame(res, req, game);
|
return sendGame(req, res, game);
|
||||||
});
|
});
|
||||||
|
|
||||||
const shuffleBoard = (game) => {
|
const shuffleBoard = (game) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user