diff --git a/src/server/Game.ts b/src/server/Game.ts index 4b1aba2..2eb5ae0 100644 --- a/src/server/Game.ts +++ b/src/server/Game.ts @@ -1,5 +1,5 @@ import GameCommon from './../common/GameCommon' -import { Change, Game, Input, ScoreMode, ShapeMode, SnapMode,ImageInfo, Timestamp } from './../common/Types' +import { Change, Game, Input, ScoreMode, ShapeMode, SnapMode,ImageInfo, Timestamp, GameSettings } from './../common/Types' import Util, { logger } from './../common/Util' import { Rng } from './../common/Rng' import GameLog from './GameLog' @@ -34,24 +34,24 @@ async function createGameObject( } } -async function createGame( - gameId: string, - targetTiles: number, - image: ImageInfo, +async function createNewGame( + gameSettings: GameSettings, ts: Timestamp, - scoreMode: ScoreMode, - shapeMode: ShapeMode, - snapMode: SnapMode, creatorUserId: number -): Promise { +): Promise { + let gameId; + do { + gameId = Util.uniqId() + } while (GameCommon.exists(gameId)) + const gameObject = await createGameObject( gameId, - targetTiles, - image, + gameSettings.tiles, + gameSettings.image, ts, - scoreMode, - shapeMode, - snapMode, + gameSettings.scoreMode, + gameSettings.shapeMode, + gameSettings.snapMode, creatorUserId ) @@ -60,17 +60,19 @@ async function createGame( gameId, Protocol.LOG_HEADER, 1, - targetTiles, - image, + gameSettings.tiles, + gameSettings.image, ts, - scoreMode, - shapeMode, - snapMode, + gameSettings.scoreMode, + gameSettings.shapeMode, + gameSettings.snapMode, gameObject.creatorUserId ) GameCommon.setGame(gameObject.id, gameObject) GameStorage.setDirty(gameId) + + return gameId } function addPlayer(gameId: string, playerId: string, ts: Timestamp): void { @@ -105,7 +107,7 @@ function handleInput( export default { createGameObject, - createGame, + createNewGame, addPlayer, handleInput, } diff --git a/src/server/GameLog.ts b/src/server/GameLog.ts index 05ef870..ec7a898 100644 --- a/src/server/GameLog.ts +++ b/src/server/GameLog.ts @@ -90,7 +90,7 @@ const get = ( log[0][5] = DefaultScoreMode(log[0][5]) log[0][6] = DefaultShapeMode(log[0][6]) log[0][7] = DefaultSnapMode(log[0][7]) - log[0][8] = log[0][8] || null + log[0][8] = log[0][8] || null // creatorUserId } return log } diff --git a/src/server/GameStorage.ts b/src/server/GameStorage.ts index b5df21a..4b2de65 100644 --- a/src/server/GameStorage.ts +++ b/src/server/GameStorage.ts @@ -41,7 +41,7 @@ function loadGameFromDb(db: Db, gameId: string): void { if (!Array.isArray(game.players)) { game.players = Object.values(game.players) } - + const gameObject: Game = storeDataToGame(game, game.creator_user_id) GameCommon.setGame(gameObject.id, gameObject) } @@ -122,32 +122,6 @@ function loadGameFromDisk(gameId: string): void { GameCommon.setGame(gameObject.id, gameObject) } -/** - * @deprecated - */ -function persistGamesToDisk(): void { - for (const gameId of Object.keys(dirtyGames)) { - persistGameToDisk(gameId) - } -} - -/** - * @deprecated - */ -function persistGameToDisk(gameId: string): void { - const game = GameCommon.get(gameId) - if (!game) { - log.error(`[ERROR] unable to persist non existing game ${gameId}`) - return - } - - if (game.id in dirtyGames) { - setClean(game.id) - } - fs.writeFileSync(`${DATA_DIR}/${game.id}.json`, gameToStoreData(game)) - log.info(`[INFO] persisted game ${game.id}`) -} - function storeDataToGame(storeData: any, creatorUserId: number|null): Game { return { id: storeData.id, @@ -181,16 +155,14 @@ function gameToStoreData(game: Game): string { } export default { - // disk functions are deprecated + // disk functions are deprecated loadGamesFromDisk, loadGameFromDisk, - persistGamesToDisk, - persistGameToDisk, loadGamesFromDb, loadGameFromDb, persistGamesToDb, persistGameToDb, - + setDirty, } diff --git a/src/server/Images.ts b/src/server/Images.ts index dd46e07..7632b2a 100644 --- a/src/server/Images.ts +++ b/src/server/Images.ts @@ -6,7 +6,7 @@ import sharp from 'sharp' import {UPLOAD_DIR, UPLOAD_URL} from './Dirs' import Db, { OrderBy, WhereRaw } from './Db' import { Dim } from '../common/Geometry' -import { logger } from '../common/Util' +import Util, { logger } from '../common/Util' import { Tag, ImageInfo } from '../common/Types' const log = logger('Images.ts') @@ -209,6 +209,20 @@ async function getDimensions(imagePath: string): Promise { } } +const setTags = (db: Db, imageId: number, tags: string[]): void => { + db.delete('image_x_category', { image_id: imageId }) + tags.forEach((tag: string) => { + const slug = Util.slug(tag) + const id = db.upsert('categories', { slug, title: tag }, { slug }, 'id') + if (id) { + db.insert('image_x_category', { + image_id: imageId, + category_id: id, + }) + } + }) +} + export default { allImagesFromDisk, imageFromDb, @@ -216,4 +230,5 @@ export default { getAllTags, resizeImage, getDimensions, + setTags, } diff --git a/src/server/Users.ts b/src/server/Users.ts new file mode 100644 index 0000000..4c5fb00 --- /dev/null +++ b/src/server/Users.ts @@ -0,0 +1,36 @@ +import Time from '../common/Time' +import Db from './Db' + +const TABLE = 'users' + +const HEADER_CLIENT_ID = 'client-id' +const HEADER_CLIENT_SECRET = 'client-secret' + +const getOrCreateUser = (db: Db, req: any): any => { + let user = getUser(db, req) + if (!user) { + db.insert(TABLE, { + 'client_id': req.headers[HEADER_CLIENT_ID], + 'client_secret': req.headers[HEADER_CLIENT_SECRET], + 'created': Time.timestamp(), + }) + user = getUser(db, req) + } + return user +} + +const getUser = (db: Db, req: any): any => { + const user = db.get(TABLE, { + 'client_id': req.headers[HEADER_CLIENT_ID], + 'client_secret': req.headers[HEADER_CLIENT_SECRET], + }) + if (user) { + user.id = parseInt(user.id, 10) + } + return user +} + +export default { + getOrCreateUser, + getUser, +} diff --git a/src/server/main.ts b/src/server/main.ts index 47cdaba..8242b21 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -22,6 +22,7 @@ import GameCommon from '../common/GameCommon' import { ServerEvent, Game as GameType, GameSettings } from '../common/Types' import GameStorage from './GameStorage' import Db from './Db' +import Users from './Users' const db = new Db(DB_FILE, DB_PATCHES_DIR) db.patch() @@ -58,7 +59,7 @@ const storage = multer.diskStorage({ const upload = multer({storage}).single('file'); app.get('/api/me', (req, res): void => { - let user = getUser(db, req) + let user = Users.getUser(db, req) res.send({ id: user ? user.id : null, created: user ? user.created : null, @@ -142,52 +143,15 @@ interface SaveImageRequestData { tags: string[] } -const getOrCreateUser = (db: Db, req: any): any => { - let user = getUser(db, req) - if (!user) { - db.insert('users', { - 'client_id': req.headers['client-id'], - 'client_secret': req.headers['client-secret'], - 'created': Time.timestamp(), - }) - user = getUser(db, req) - } - return user -} - -const getUser = (db: Db, req: any): any => { - let user = db.get('users', { - 'client_id': req.headers['client-id'], - 'client_secret': req.headers['client-secret'], - }) - if (user) { - user.id = parseInt(user.id, 10) - } - return user -} - -const setImageTags = (db: Db, imageId: number, tags: string[]): void => { - tags.forEach((tag: string) => { - const slug = Util.slug(tag) - const id = db.upsert('categories', { slug, title: tag }, { slug }, 'id') - if (id) { - db.insert('image_x_category', { - image_id: imageId, - category_id: id, - }) - } - }) -} - app.post('/api/save-image', express.json(), (req, res): void => { - let user = getUser(db, req) + const user = Users.getUser(db, req) if (!user || !user.id) { res.status(403).send({ ok: false, error: 'forbidden' }) return } const data = req.body as SaveImageRequestData - let image = db.get('images', {id: data.id}) + const image = db.get('images', {id: data.id}) if (parseInt(image.uploader_user_id, 10) !== user.id) { res.status(403).send({ ok: false, error: 'forbidden' }) return @@ -199,11 +163,7 @@ app.post('/api/save-image', express.json(), (req, res): void => { id: data.id, }) - db.delete('image_x_category', { image_id: data.id }) - - if (data.tags) { - setImageTags(db, data.id, data.tags) - } + Images.setTags(db, data.id, data.tags || []) res.send({ ok: true }) }) @@ -211,17 +171,19 @@ app.post('/api/upload', (req, res): void => { upload(req, res, async (err: any): Promise => { if (err) { log.log(err) - res.status(400).send("Something went wrong!"); + res.status(400).send("Something went wrong!") + return } try { await Images.resizeImage(req.file.filename) } catch (err) { log.log(err) - res.status(400).send("Something went wrong!"); + res.status(400).send("Something went wrong!") + return } - const user = getOrCreateUser(db, req) + const user = Users.getOrCreateUser(db, req) const dim = await Images.getDimensions( `${UPLOAD_DIR}/${req.file.filename}` @@ -238,7 +200,7 @@ app.post('/api/upload', (req, res): void => { if (req.body.tags) { const tags = req.body.tags.split(',').filter((tag: string) => !!tag) - setImageTags(db, imageId as number, tags) + Images.setTags(db, imageId as number, tags) } res.send(Images.imageFromDb(db, imageId as number)) @@ -246,28 +208,12 @@ app.post('/api/upload', (req, res): void => { }) app.post('/api/newgame', express.json(), async (req, res): Promise => { - let user = getOrCreateUser(db, req) - if (!user || !user.id) { - res.status(403).send({ ok: false, error: 'forbidden' }) - return - } - - const gameSettings = req.body as GameSettings - log.log(gameSettings) - const gameId = Util.uniqId() - if (!GameCommon.exists(gameId)) { - const ts = Time.timestamp() - await Game.createGame( - gameId, - gameSettings.tiles, - gameSettings.image, - ts, - gameSettings.scoreMode, - gameSettings.shapeMode, - gameSettings.snapMode, - user.id, - ) - } + const user = Users.getOrCreateUser(db, req) + const gameId = await Game.createNewGame( + req.body as GameSettings, + Time.timestamp(), + user.id + ) res.send({ id: gameId }) })