more type hints

This commit is contained in:
Zutatensuppe 2021-05-28 23:01:00 +02:00
parent 623faef6e9
commit eabe338971
9 changed files with 56 additions and 35 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>🧩 jigsaw.hyottoko.club</title> <title>🧩 jigsaw.hyottoko.club</title>
<script type="module" crossorigin src="/assets/index.47e2ba43.js"></script> <script type="module" crossorigin src="/assets/index.50ee8245.js"></script>
<link rel="modulepreload" href="/assets/vendor.b622ee49.js"> <link rel="modulepreload" href="/assets/vendor.b622ee49.js">
<link rel="stylesheet" href="/assets/index.f7304069.css"> <link rel="stylesheet" href="/assets/index.f7304069.css">
</head> </head>

View file

@ -851,7 +851,7 @@ const getPlayerPoints = (gameId, playerId) => {
const areGrouped = (gameId, tileIdx1, tileIdx2) => { const areGrouped = (gameId, tileIdx1, tileIdx2) => {
const g1 = getTileGroup(gameId, tileIdx1); const g1 = getTileGroup(gameId, tileIdx1);
const g2 = getTileGroup(gameId, tileIdx2); const g2 = getTileGroup(gameId, tileIdx2);
return g1 && g1 === g2; return !!(g1 && g1 === g2);
}; };
const getTableWidth = (gameId) => { const getTableWidth = (gameId) => {
return GAMES[gameId].puzzle.info.table.width; return GAMES[gameId].puzzle.info.table.width;
@ -1358,11 +1358,14 @@ async function getDimensions(imagePath) {
// https://jdhao.github.io/2019/07/31/image_rotation_exif_info/ // https://jdhao.github.io/2019/07/31/image_rotation_exif_info/
if (orientation === 6 || orientation === 8) { if (orientation === 6 || orientation === 8) {
return { return {
width: dimensions.height, w: dimensions.height || 0,
height: dimensions.width, h: dimensions.width || 0,
}; };
} }
return dimensions; return {
w: dimensions.width || 0,
h: dimensions.height || 0,
};
} }
var Images = { var Images = {
allImagesFromDisk, allImagesFromDisk,
@ -1380,10 +1383,10 @@ async function createPuzzle(rng, targetTiles, image, ts) {
const imageUrl = image.url; const imageUrl = image.url;
// determine puzzle information from the image dimensions // determine puzzle information from the image dimensions
const dim = await Images.getDimensions(imagePath); const dim = await Images.getDimensions(imagePath);
if (!dim || !dim.width || !dim.height) { if (!dim.w || !dim.h) {
throw `[ 2021-05-16 invalid dimension for path ${imagePath} ]`; throw `[ 2021-05-16 invalid dimension for path ${imagePath} ]`;
} }
const info = determinePuzzleInfo(dim.width, dim.height, targetTiles); const info = determinePuzzleInfo(dim.w, dim.h, targetTiles);
let tiles = new Array(info.tiles); let tiles = new Array(info.tiles);
for (let i = 0; i < tiles.length; i++) { for (let i = 0; i < tiles.length; i++) {
tiles[i] = { idx: i }; tiles[i] = { idx: i };
@ -1579,7 +1582,9 @@ function loadGame(gameId) {
game.puzzle.data.started = Math.round(fs.statSync(file).ctimeMs); game.puzzle.data.started = Math.round(fs.statSync(file).ctimeMs);
} }
if (typeof game.puzzle.data.finished === 'undefined') { if (typeof game.puzzle.data.finished === 'undefined') {
let unfinished = game.puzzle.tiles.map(Util.decodeTile).find((t) => t.owner !== -1); const unfinished = game.puzzle.tiles
.map(Util.decodeTile)
.find((t) => t.owner !== -1);
game.puzzle.data.finished = unfinished ? 0 : Time.timestamp(); game.puzzle.data.finished = unfinished ? 0 : Time.timestamp();
} }
if (!Array.isArray(game.players)) { if (!Array.isArray(game.players)) {

View file

@ -31,7 +31,7 @@ async function createGame(
image: { file: string, url: string }, image: { file: string, url: string },
ts: number, ts: number,
scoreMode: ScoreMode scoreMode: ScoreMode
) { ): Promise<void> {
const gameObject = await createGameObject(gameId, targetTiles, image, ts, scoreMode) const gameObject = await createGameObject(gameId, targetTiles, image, ts, scoreMode)
GameLog.create(gameId) GameLog.create(gameId)
@ -41,7 +41,7 @@ async function createGame(
GameStorage.setDirty(gameId) GameStorage.setDirty(gameId)
} }
function addPlayer(gameId: string, playerId: string, ts: number) { function addPlayer(gameId: string, playerId: string, ts: number): void {
const idx = GameCommon.getPlayerIndexById(gameId, playerId) const idx = GameCommon.getPlayerIndexById(gameId, playerId)
const diff = ts - GameCommon.getStartTs(gameId) const diff = ts - GameCommon.getStartTs(gameId)
if (idx === -1) { if (idx === -1) {
@ -54,7 +54,12 @@ function addPlayer(gameId: string, playerId: string, ts: number) {
GameStorage.setDirty(gameId) GameStorage.setDirty(gameId)
} }
function handleInput(gameId: string, playerId: string, input: any, ts: number) { function handleInput(
gameId: string,
playerId: string,
input: any,
ts: number
): Array<Array<any>> {
const idx = GameCommon.getPlayerIndexById(gameId, playerId) const idx = GameCommon.getPlayerIndexById(gameId, playerId)
const diff = ts - GameCommon.getStartTs(gameId) const diff = ts - GameCommon.getStartTs(gameId)
GameLog.log(gameId, Protocol.LOG_HANDLE_INPUT, idx, input, diff) GameLog.log(gameId, Protocol.LOG_HANDLE_INPUT, idx, input, diff)

View file

@ -4,16 +4,16 @@ import WebSocket from 'ws'
const log = logger('GameSocket.js') const log = logger('GameSocket.js')
// Map<gameId, Socket[]> // Map<gameId, Socket[]>
const SOCKETS = {} as Record<string, Array<WebSocket>> const SOCKETS = {} as Record<string, WebSocket[]>
function socketExists(gameId: string, socket: WebSocket) { function socketExists(gameId: string, socket: WebSocket): boolean {
if (!(gameId in SOCKETS)) { if (!(gameId in SOCKETS)) {
return false return false
} }
return SOCKETS[gameId].includes(socket) return SOCKETS[gameId].includes(socket)
} }
function removeSocket(gameId: string, socket: WebSocket) { function removeSocket(gameId: string, socket: WebSocket): void {
if (!(gameId in SOCKETS)) { if (!(gameId in SOCKETS)) {
return return
} }
@ -22,7 +22,7 @@ function removeSocket(gameId: string, socket: WebSocket) {
log.log('socket count: ', Object.keys(SOCKETS[gameId]).length) log.log('socket count: ', Object.keys(SOCKETS[gameId]).length)
} }
function addSocket(gameId: string, socket: WebSocket) { function addSocket(gameId: string, socket: WebSocket): void {
if (!(gameId in SOCKETS)) { if (!(gameId in SOCKETS)) {
SOCKETS[gameId] = [] SOCKETS[gameId] = []
} }
@ -33,7 +33,7 @@ function addSocket(gameId: string, socket: WebSocket) {
} }
} }
function getSockets(gameId: string) { function getSockets(gameId: string): WebSocket[] {
if (!(gameId in SOCKETS)) { if (!(gameId in SOCKETS)) {
return [] return []
} }

View file

@ -1,5 +1,5 @@
import fs from 'fs' import fs from 'fs'
import GameCommon, { ScoreMode } from './../common/GameCommon' import GameCommon, { Piece, ScoreMode } from './../common/GameCommon'
import Util, { logger } from './../common/Util' import Util, { logger } from './../common/Util'
import { Rng } from './../common/Rng' import { Rng } from './../common/Rng'
import { DATA_DIR } from './Dirs' import { DATA_DIR } from './Dirs'
@ -40,7 +40,9 @@ function loadGame(gameId: string): void {
game.puzzle.data.started = Math.round(fs.statSync(file).ctimeMs) game.puzzle.data.started = Math.round(fs.statSync(file).ctimeMs)
} }
if (typeof game.puzzle.data.finished === 'undefined') { if (typeof game.puzzle.data.finished === 'undefined') {
let unfinished = game.puzzle.tiles.map(Util.decodeTile).find((t: any) => t.owner !== -1) const unfinished = game.puzzle.tiles
.map(Util.decodeTile)
.find((t: Piece) => t.owner !== -1)
game.puzzle.data.finished = unfinished ? 0 : Time.timestamp() game.puzzle.data.finished = unfinished ? 0 : Time.timestamp()
} }
if (!Array.isArray(game.players)) { if (!Array.isArray(game.players)) {
@ -60,13 +62,13 @@ function loadGame(gameId: string): void {
GameCommon.setGame(gameObject.id, gameObject) GameCommon.setGame(gameObject.id, gameObject)
} }
function persistGames() { function persistGames(): void {
for (const gameId of Object.keys(DIRTY_GAMES)) { for (const gameId of Object.keys(DIRTY_GAMES)) {
persistGame(gameId) persistGame(gameId)
} }
} }
function persistGame(gameId: string) { function persistGame(gameId: string): void {
const game = GameCommon.get(gameId) const game = GameCommon.get(gameId)
if (game.id in DIRTY_GAMES) { if (game.id in DIRTY_GAMES) {
setClean(game.id) setClean(game.id)

View file

@ -5,6 +5,7 @@ import sharp from 'sharp'
import {UPLOAD_DIR, UPLOAD_URL} from './Dirs' import {UPLOAD_DIR, UPLOAD_URL} from './Dirs'
import Db from './Db' import Db from './Db'
import { Dim } from '../common/Geometry'
const resizeImage = async (filename: string) => { const resizeImage = async (filename: string) => {
if (!filename.toLowerCase().match(/\.(jpe?g|webp|png)$/)) { if (!filename.toLowerCase().match(/\.(jpe?g|webp|png)$/)) {
@ -150,18 +151,21 @@ const allImagesFromDisk = (tags: string[], sort: string) => {
return images return images
} }
async function getDimensions(imagePath: string) { async function getDimensions(imagePath: string): Promise<Dim> {
let dimensions = sizeOf(imagePath) let dimensions = sizeOf(imagePath)
const orientation = await getExifOrientation(imagePath) const orientation = await getExifOrientation(imagePath)
// when image is rotated to the left or right, switch width/height // when image is rotated to the left or right, switch width/height
// https://jdhao.github.io/2019/07/31/image_rotation_exif_info/ // https://jdhao.github.io/2019/07/31/image_rotation_exif_info/
if (orientation === 6 || orientation === 8) { if (orientation === 6 || orientation === 8) {
return { return {
width: dimensions.height, w: dimensions.height || 0,
height: dimensions.width, h: dimensions.width || 0,
} }
} }
return dimensions return {
w: dimensions.width || 0,
h: dimensions.height || 0,
}
} }
export default { export default {

View file

@ -1,9 +1,10 @@
import Util from './../common/Util' import Util from './../common/Util'
import { Rng } from './../common/Rng' import { Rng } from './../common/Rng'
import Images from './Images' import Images from './Images'
import { EncodedPiece, EncodedPieceShape, PieceShape } from '../common/GameCommon' import { EncodedPiece, EncodedPieceShape, PieceShape, Puzzle } from '../common/GameCommon'
import { Point } from '../common/Geometry'
interface PuzzleInfo { interface PuzzleCreationInfo {
width: number width: number
height: number height: number
tileSize: number tileSize: number
@ -23,16 +24,20 @@ async function createPuzzle(
targetTiles: number, targetTiles: number,
image: { file: string, url: string }, image: { file: string, url: string },
ts: number ts: number
) { ): Promise<Puzzle> {
const imagePath = image.file const imagePath = image.file
const imageUrl = image.url const imageUrl = image.url
// determine puzzle information from the image dimensions // determine puzzle information from the image dimensions
const dim = await Images.getDimensions(imagePath) const dim = await Images.getDimensions(imagePath)
if (!dim || !dim.width || !dim.height) { if (!dim.w || !dim.h) {
throw `[ 2021-05-16 invalid dimension for path ${imagePath} ]` throw `[ 2021-05-16 invalid dimension for path ${imagePath} ]`
} }
const info: PuzzleInfo = determinePuzzleInfo(dim.width, dim.height, targetTiles) const info: PuzzleCreationInfo = determinePuzzleInfo(
dim.w,
dim.h,
targetTiles
)
let tiles = new Array(info.tiles) let tiles = new Array(info.tiles)
for (let i = 0; i < tiles.length; i++) { for (let i = 0; i < tiles.length; i++) {
@ -40,10 +45,10 @@ async function createPuzzle(
} }
const shapes = determinePuzzleTileShapes(rng, info) const shapes = determinePuzzleTileShapes(rng, info)
let positions = new Array(info.tiles) let positions: Point[] = new Array(info.tiles)
for (let tile of tiles) { for (let tile of tiles) {
const coord = Util.coordByTileIdx(info, tile.idx) const coord = Util.coordByTileIdx(info, tile.idx)
positions[tile.idx] ={ positions[tile.idx] = {
// instead of info.tileSize, we use info.tileDrawSize // instead of info.tileSize, we use info.tileDrawSize
// to spread the tiles a bit // to spread the tiles a bit
x: coord.x * info.tileSize * 1.5, x: coord.x * info.tileSize * 1.5,
@ -55,7 +60,7 @@ async function createPuzzle(
const tableHeight = info.height * 3 const tableHeight = info.height * 3
const off = info.tileSize * 1.5 const off = info.tileSize * 1.5
let last = { let last: Point = {
x: info.width - (1 * off), x: info.width - (1 * off),
y: info.height - (2 * off), y: info.height - (2 * off),
} }
@ -159,7 +164,7 @@ async function createPuzzle(
function determinePuzzleTileShapes( function determinePuzzleTileShapes(
rng: Rng, rng: Rng,
info: PuzzleInfo info: PuzzleCreationInfo
): Array<EncodedPieceShape> { ): Array<EncodedPieceShape> {
const tabs = [-1, 1] const tabs = [-1, 1]
@ -196,7 +201,7 @@ const determinePuzzleInfo = (
w: number, w: number,
h: number, h: number,
targetTiles: number targetTiles: number
): PuzzleInfo => { ): PuzzleCreationInfo => {
const {tilesX, tilesY} = determineTilesXY(w, h, targetTiles) const {tilesX, tilesY} = determineTilesXY(w, h, targetTiles)
const tiles = tilesX * tilesY const tiles = tilesX * tilesY
const tileSize = TILE_SIZE const tileSize = TILE_SIZE