more type hints
This commit is contained in:
parent
623faef6e9
commit
eabe338971
9 changed files with 56 additions and 35 deletions
File diff suppressed because one or more lines are too long
1
build/public/assets/index.50ee8245.js
Normal file
1
build/public/assets/index.50ee8245.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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)) {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 []
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue