diff options
-rw-r--r-- | server.js | 45 | ||||
-rw-r--r-- | tools/sql/schema.txt | 2 | ||||
-rw-r--r-- | views/create.ejs | 12 | ||||
-rw-r--r-- | views/join.ejs | 12 |
4 files changed, 49 insertions, 22 deletions
@@ -603,9 +603,9 @@ const QUERY_PART_GAME = db.prepare("DELETE FROM players WHERE game_id = ? AND ro const QUERY_START_GAME = db.prepare("UPDATE games SET status = 1, state = ?, active = ?, mtime = datetime('now') WHERE game_id = ?"); const QUERY_CREATE_GAME = db.prepare(` INSERT INTO games - (owner_id,title_id,scenario,private,random,ctime,mtime,description,status,state) + (owner_id,title_id,scenario,options,private,random,ctime,mtime,description,status,state) VALUES - (?,?,?,?,?,datetime('now'),datetime('now'),?,0,NULL) + (?,?,?,?,?,?,datetime('now'),datetime('now'),?,0,NULL) `); const QUERY_UPDATE_GAME_SET_PRIVATE = db.prepare("UPDATE games SET private = 1 WHERE game_id = ?"); const QUERY_ASSIGN_ROLE = db.prepare("UPDATE players SET role = ? WHERE game_id = ? AND user_id = ? AND role = ?"); @@ -619,9 +619,9 @@ const QUERY_REMATCH_FIND = db.prepare(` const QUERY_REMATCH_CREATE = db.prepare(` INSERT INTO games - (owner_id, title_id, scenario, private, random, ctime, mtime, description, status, state) + (owner_id, title_id, scenario, options, private, random, ctime, mtime, description, status, state) SELECT - $user_id, title_id, scenario, private, random, datetime('now'), datetime('now'), $magic, 0, NULL + $user_id, title_id, scenario, options, private, random, datetime('now'), datetime('now'), $magic, 0, NULL FROM games WHERE game_id = $game_id AND NOT EXISTS ( SELECT * FROM games WHERE description=$magic @@ -704,14 +704,26 @@ app.get('/create/:title_id', must_be_logged_in, function (req, res) { res.render('create.ejs', { user: req.user, message: req.flash('message'), title: title, scenarios: RULES[title_id].scenarios }); }); +function options_json_replacer(key, value) { + if (key === 'scenario') return undefined; + if (key === 'description') return undefined; + if (key === 'random') return undefined; + if (key === 'private') return undefined; + if (value === 'true') return true; + if (value === 'false') return false; + if (value === '') return undefined; + return value; +} + app.post('/create/:title_id', must_be_logged_in, function (req, res) { let title_id = req.params.title_id; let descr = req.body.description; - let priv = req.body.private === 'private'; - let rand = req.body.random === 'random'; - let scenario = req.body.scenario; + let priv = req.body.private === 'true'; + let rand = req.body.random === 'true'; let user_id = req.user.user_id; - LOG(req, "POST /create/" + req.params.title_id, scenario, priv, JSON.stringify(descr)); + let scenario = req.body.scenario; + let options = JSON.stringify(req.body, options_json_replacer); + LOG(req, "POST /create/" + req.params.title_id, scenario, options, priv, JSON.stringify(descr)); try { let count = QUERY_COUNT_OPEN_GAMES.get(user_id); if (count >= MAX_OPEN_GAMES) { @@ -724,7 +736,7 @@ app.post('/create/:title_id', must_be_logged_in, function (req, res) { if (!RULES[title_id].scenarios.includes(scenario)) { return res.status(404).send("That scenario doesn't exist."); } - let info = QUERY_CREATE_GAME.run(user_id, title_id, scenario, priv ? 1 : 0, rand ? 1 : 0, descr); + let info = QUERY_CREATE_GAME.run(user_id, title_id, scenario, options, priv ? 1 : 0, rand ? 1 : 0, descr); res.redirect('/join/'+info.lastInsertRowid); } catch (err) { req.flash('message', err.toString()); @@ -820,7 +832,7 @@ function update_join_clients_players(game_id) { let list = join_clients[game_id]; if (list && list.length > 0) { let players = QUERY_PLAYERS.all(game_id); - let ready = RULES[list.title_id].ready(list.scenario, players); + let ready = RULES[list.title_id].ready(list.scenario, list.options, players); for (let res of list) { res.write("retry: 15000\n"); res.write("event: players\n"); @@ -839,7 +851,7 @@ app.get('/join/:game_id', must_be_logged_in, function (req, res) { return res.status(404).send("That game doesn't exist."); let roles = QUERY_ROLES.all(game.title_id); let players = QUERY_PLAYERS.all(game_id); - let ready = (game.status === 0) && RULES[game.title_id].ready(game.scenario, players); + let ready = (game.status === 0) && RULES[game.title_id].ready(game.scenario, game.options, players); res.set("Cache-Control", "no-store"); res.render('join.ejs', { user: req.user, @@ -868,6 +880,7 @@ app.get('/join-events/:game_id', must_be_logged_in, function (req, res) { join_clients[game_id] = []; join_clients[game_id].title_id = game.title_id; join_clients[game_id].scenario = game.scenario; + join_clients[game_id].options = JSON.parse(game.options); } join_clients[game_id].push(res); @@ -939,15 +952,15 @@ app.get('/start/:game_id', must_be_logged_in, function (req, res) { if (game.status !== 0) return res.send("The game is already started!"); let players = QUERY_PLAYERS.all(game_id); - if (!RULES[game.title_id].ready(game.scenario, players)) + if (!RULES[game.title_id].ready(game.scenario, game.options, players)) return res.send("Invalid player configuration!"); if (game.random) { assign_random_roles(game, players); update_join_clients_players(game_id); } let seed = random_seed(); - let state = RULES[game.title_id].setup(seed, game.scenario, players); - put_replay(game_id, null, 'setup', [seed, game.scenario, players]); + let state = RULES[game.title_id].setup(seed, game.scenario, game.options, players); + put_replay(game_id, null, 'setup', [seed, game.scenario, game.options, players]); QUERY_START_GAME.run(JSON.stringify(state), state.active, game_id); let is_solo = players.every(p => p.user_id === players[0].user_id); if (is_solo) @@ -1123,7 +1136,7 @@ function notify_ready_to_start_reminder() { return; for (let game of QUERY_LIST_UNSTARTED_GAMES.all()) { let players = QUERY_PLAYERS.all(game.game_id); - if (RULES[game.title_id].ready(game.scenario, players)) { + if (RULES[game.title_id].ready(game.scenario, game.options, players)) { let owner = sql_offline_user.get(game.owner_id, '+3 minutes'); if (owner) { if (owner.notifications) @@ -1376,7 +1389,7 @@ io.on('connection', (socket) => { try { let seed = random_seed(); let state = socket.rules.setup(seed, scenario, players); - put_replay(socket.game_id, null, 'setup', [seed, scenario, players]); + put_replay(socket.game_id, null, 'setup', [seed, scenario, options, players]); for (let other of clients[socket.game_id]) { other.log_length = 0; send_state(other, state); diff --git a/tools/sql/schema.txt b/tools/sql/schema.txt index 1623ec3..da77956 100644 --- a/tools/sql/schema.txt +++ b/tools/sql/schema.txt @@ -43,6 +43,7 @@ CREATE TABLE IF NOT EXISTS games ( game_id INTEGER PRIMARY KEY, title_id TEXT, scenario TEXT, + options TEXT, owner_id INTEGER, private BOOLEAN, random BOOLEAN, @@ -149,6 +150,7 @@ CREATE VIEW game_view AS , games.title_id , titles.title_name , games.scenario + , games.options , games.owner_id , owner.name AS owner_name , players.player_names diff --git a/views/create.ejs b/views/create.ejs index b995639..74f9276 100644 --- a/views/create.ejs +++ b/views/create.ejs @@ -4,7 +4,7 @@ <form action="/create/<%= title.title_id %>" method="post"> <p> Scenario:<br> -<select id="scenario" name="scenario"> +<select name="scenario"> <% scenarios.forEach((scenario) => { %> <option value="<%= scenario %>"><%= scenario %></option> <% }); %> @@ -12,16 +12,16 @@ Scenario:<br> <%- include('../public/' + title.title_id + '/create.html') %> <p> Description:<br> -<input type="text" autocomplete="off" id="description" name="description" size="50"> +<input type="text" autocomplete="off" name="description" size="50"> <p> <label> -<input type="checkbox" id="random" name="random" value="random"> -<span>Random player roles</span> +<input type="checkbox" name="random" value="true"> +Random player roles </label> <p> <label> -<input type="checkbox" id="private" name="private" value="private"> -<span>Private</span> +<input type="checkbox" name="private" value="true"> +Private </label> <p> <button type="submit">Create</button> diff --git a/views/join.ejs b/views/join.ejs index 1d9347d..b9cf824 100644 --- a/views/join.ejs +++ b/views/join.ejs @@ -1,4 +1,14 @@ <%- include('header', { title: game.title_name }) -%> +<% +function to_english(k) { + if (k === true) return 'yes'; + if (k === false) return 'no'; + return k.replace(/_/g, " ").replace(/^\w/, c => c.toUpperCase()); +} +function format_options(options) { + return Object.entries(options||{}).map(([k,v]) => v === true ? to_english(k) : `${to_english(k)}=${to_english(v)}`).join(", "); +} +-%> <style> th, td { min-width: 10em; font-size: 16px; } a.red { text-decoration: none; color: brown; font-size: 15px; } @@ -24,6 +34,8 @@ Private: <%= game.private ? "yes" : "no" %> <br> Scenario: <%= game.scenario %> <br> +Options: <%- format_options(JSON.parse(game.options)) %> +<br> Description: <%= game.description || "No description." %> <br> Status: <span id="game_status"></span> |