summaryrefslogtreecommitdiff
path: root/server.js
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-09-15 20:50:51 +0200
committerTor Andersson <tor@ccxvii.net>2023-09-18 21:16:47 +0200
commitd7ae1e694112d6a4bfc9d528aa738fb04946a0b3 (patch)
treefc4f1c147d5a7887f98240df2851a3ee8f039b29 /server.js
parent9e77cf5b29a533faf1909327772359d189e527b1 (diff)
downloadserver-d7ae1e694112d6a4bfc9d528aa738fb04946a0b3.tar.gz
Enforce limits on how many games you can create and join.
Also limit joining more games if you have too many games waiting. Generous default limits: 7 open, 29 active, and 3 waiting.
Diffstat (limited to 'server.js')
-rw-r--r--server.js51
1 files changed, 44 insertions, 7 deletions
diff --git a/server.js b/server.js
index c07b0d8..2e831eb 100644
--- a/server.js
+++ b/server.js
@@ -21,6 +21,10 @@ const HTTP_PORT = process.env.HTTP_PORT || 8080
const SITE_NAME = process.env.SITE_NAME || "Localhost"
const SITE_URL = process.env.SITE_URL || "http://" + HTTP_HOST + ":" + HTTP_PORT
+const LIMIT_WAITING_GAMES = (process.env.LIMIT_WAITING_GAMES | 0) || 3
+const LIMIT_OPEN_GAMES = (process.env.LIMIT_OPEN_GAMES | 0) || 7
+const LIMIT_ACTIVE_GAMES = (process.env.LIMIT_ACTIVE_GAMES | 0) || 29
+
const REGEX_MAIL = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
const REGEX_NAME = /^[\p{Alpha}\p{Number}'_-]+( [\p{Alpha}\p{Number}'_-]+)*$/u
@@ -1157,6 +1161,12 @@ const SQL_DELETE_PLAYER_ROLE = SQL("DELETE FROM players WHERE game_id=? AND role
const SQL_SELECT_OPEN_GAMES = SQL(`SELECT * FROM games WHERE status=${STATUS_OPEN}`)
const SQL_COUNT_OPEN_GAMES = SQL(`SELECT COUNT(*) FROM games WHERE owner_id=? AND status=${STATUS_OPEN}`).pluck()
+const SQL_COUNT_ACTIVE_GAMES = SQL(`
+ select count(*) from games
+ where status < 2 and exists (
+ select 1 from players where players.user_id=? and players.game_id=games.game_id
+ )
+`).pluck()
const SQL_SELECT_REMATCH = SQL(`SELECT game_id FROM games WHERE status < ${STATUS_FINISHED} AND notice=?`).pluck()
const SQL_INSERT_REMATCH = SQL(`
@@ -1256,7 +1266,7 @@ const QUERY_LIST_ACTIVE_GAMES_OF_USER = SQL(`
( owner_id=$user_id or game_id in ( select game_id from players where players.user_id=$user_id ) )
and
( status <= ${STATUS_FINISHED} )
- order by status asc, mtime desc
+ order by status asc, is_opposed desc, mtime desc
`)
const QUERY_LIST_FINISHED_GAMES_OF_USER = SQL(`
@@ -1268,6 +1278,24 @@ const QUERY_LIST_FINISHED_GAMES_OF_USER = SQL(`
order by status asc, mtime desc
`)
+function check_create_game_limit(user) {
+ if (user.waiting > LIMIT_WAITING_GAMES)
+ return "You have too many games waiting!"
+ if (SQL_COUNT_OPEN_GAMES.get(user.user_id) >= LIMIT_OPEN_GAMES)
+ return "You have too many open games!"
+ if (SQL_COUNT_ACTIVE_GAMES.get(user.user_id) >= LIMIT_ACTIVE_GAMES)
+ return "You cannot join any more games!"
+ return null
+}
+
+function check_join_game_limit(user) {
+ if (user.waiting > LIMIT_WAITING_GAMES + 1)
+ return "You have too many games waiting!"
+ if (SQL_COUNT_ACTIVE_GAMES.get(user.user_id) >= LIMIT_ACTIVE_GAMES)
+ return "You cannot join any more games!"
+ return null
+}
+
function format_options(options) {
function to_english(k) {
if (k === true || k === 1) return 'yes'
@@ -1373,8 +1401,10 @@ app.get('/games', function (req, res) {
})
function sort_your_turn(a, b) {
- if (a.your_turn && !b.your_turn) return -1
- if (!a.your_turn && b.your_turn) return 1
+ if (a.is_opposed && b.is_opposed) {
+ if (a.your_turn && !b.your_turn) return -1
+ if (!a.your_turn && b.your_turn) return 1
+ }
return 0
}
@@ -1486,6 +1516,7 @@ app.get('/create/:title_id', must_be_logged_in, function (req, res) {
res.render('create.pug', {
user: req.user,
title: title,
+ limit: check_create_game_limit(req.user),
scenarios: RULES[title_id].scenarios,
create_html: HTML_CREATE[title_id],
})
@@ -1514,9 +1545,10 @@ app.post("/create/:title_id", must_be_logged_in, function (req, res) {
let options = JSON.stringify(req.body, options_json_replacer)
let notice = req.body.notice
- let count = SQL_COUNT_OPEN_GAMES.get(user_id)
- if (count >= 7)
- return res.send("You have too many open games!")
+ let limit = check_create_game_limit(req.user)
+ if (limit)
+ return res.send(limit)
+
if (!(title_id in RULES))
return res.send("Invalid title.")
if (!RULES[title_id].scenarios.includes(scenario))
@@ -1615,7 +1647,8 @@ app.get('/join/:game_id', must_be_logged_in, function (req, res) {
game.ctime = human_date(game.ctime)
game.mtime = human_date(game.mtime)
res.render('join.pug', {
- user: req.user, game, roles, players, ready, whitelist, blacklist, friends
+ user: req.user, game, roles, players, ready, whitelist, blacklist, friends,
+ limit: check_join_game_limit(req.user)
})
})
@@ -1679,6 +1712,9 @@ function do_join(res, game_id, role, user_id, is_invite) {
app.post('/join/:game_id/:role', must_be_logged_in, function (req, res) {
let game_id = req.params.game_id | 0
let role = req.params.role
+ let limit = check_join_game_limit(req.user)
+ if (limit)
+ return res.send(limit)
do_join(res, game_id, role, req.user.user_id, 0)
})
@@ -1693,6 +1729,7 @@ app.post('/invite/:game_id/:role/:user', must_be_logged_in, function (req, res)
})
app.post('/accept/:game_id/:role', must_be_logged_in, function (req, res) {
+ // TODO: check join game limit if inviting self...
let game_id = req.params.game_id | 0
let role = req.params.role
let info = SQL_UPDATE_PLAYER_ACCEPT.run(game_id, role, req.user.user_id)