diff --git a/leaky-ships/.prettierrc.json b/leaky-ships/.prettierrc.json
index 5b746c7..cce9d3c 100644
--- a/leaky-ships/.prettierrc.json
+++ b/leaky-ships/.prettierrc.json
@@ -1,3 +1,3 @@
{
- "semi": false
+ "semi": false
}
diff --git a/leaky-ships/components/Bluetooth.tsx b/leaky-ships/components/Bluetooth.tsx
index a52aa4f..ac117db 100644
--- a/leaky-ships/components/Bluetooth.tsx
+++ b/leaky-ships/components/Bluetooth.tsx
@@ -1,175 +1,189 @@
import { useState } from "react"
function Bluetooth() {
- const [startDisabled, setStartDisabled] = useState(true)
- const [stopDisabled, setStopDisabled] = useState(true)
+ const [startDisabled, setStartDisabled] = useState(true)
+ const [stopDisabled, setStopDisabled] = useState(true)
- const deviceName = 'Chromecast Remote'
- // ble UV Index
- const bleService = 'environmental_sensing'
- const bleCharacteristic = 'uv_index'
+ const deviceName = "Chromecast Remote"
+ // ble UV Index
+ const bleService = "environmental_sensing"
+ const bleCharacteristic = "uv_index"
- // ble Battery percentage
- // const bleService = 'battery_service'
- // const bleCharacteristic = 'battery_level'
+ // ble Battery percentage
+ // const bleService = 'battery_service'
+ // const bleCharacteristic = 'battery_level'
- // ble Manufacturer Name
- // const bleService = 'device_information'
- // const bleCharacteristic = 'manufacturer_name_string'
- let bluetoothDeviceDetected: BluetoothDevice
- let gattCharacteristic: BluetoothRemoteGATTCharacteristic
+ // ble Manufacturer Name
+ // const bleService = 'device_information'
+ // const bleCharacteristic = 'manufacturer_name_string'
+ let bluetoothDeviceDetected: BluetoothDevice
+ let gattCharacteristic: BluetoothRemoteGATTCharacteristic
- function isWebBluetoothEnabled() {
- if (!navigator.bluetooth) {
- alert('Web Bluetooth API is not available in this browser!')
- return false
- }
- return true
+ function isWebBluetoothEnabled() {
+ if (!navigator.bluetooth) {
+ alert("Web Bluetooth API is not available in this browser!")
+ return false
}
- function getDeviceInfo() {
- const options = {
- // acceptAllDevices: true,
- filters: [
- { name: deviceName }
- ],
- // optionalServices: ['battery_service'],
- }
-
- console.log('Requesting Bluetooth Device...')
-
- return navigator.bluetooth
- .requestDevice(options)
- .then(device => {
- bluetoothDeviceDetected = device
- console.log('> Name: ' + device.name)
- device.addEventListener('gattserverdisconnected', onDisconnected)
- })
- .catch(error => console.log('Argh! ' + error))
- }
- function read() {
- if (!isWebBluetoothEnabled())
- return
- return getDeviceInfo()
- .then(connectGatt)
- .then(_ => {
- console.log('Reading UV Index...')
- return gattCharacteristic.readValue()
- })
- .catch(error => console.log('Waiting to start reading: ' + error))
- }
- function connectGatt() {
- if (bluetoothDeviceDetected.gatt && bluetoothDeviceDetected.gatt.connected && gattCharacteristic)
- return Promise.resolve()
- if (!bluetoothDeviceDetected || !bluetoothDeviceDetected.gatt)
- return Promise.reject()
- return bluetoothDeviceDetected.gatt.connect()
- .then(server => {
- console.log('Getting GATT Service...')
- return server.getPrimaryService(bleService)
- })
- .then(service => {
- console.log('Getting GATT Characteristic...')
- return service.getCharacteristic(bleCharacteristic)
- })
- .then(characteristic => {
- gattCharacteristic = characteristic
- characteristic.addEventListener('characteristicvaluechanged', handleChangedValue)
-
- setStartDisabled(false)
- setStopDisabled(true)
- })
- }
- function handleChangedValue(event: Event) {
- const characteristic = event.target as BluetoothRemoteGATTCharacteristic
- if (!characteristic.value) {
- console.log('Characteristic undefined!')
- return
- }
- const value = characteristic.value.getUint8(0)
- const now = new Date()
- // Output the UV Index
- console.log(`> ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} UV Index is ${value}`)
-
- // Output the Battery percentage
- // console.log(`> ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} Battery percentage is ${value}`)
-
- // Output the Manufacturer Name
- // let decoder = new TextDecoder('utf-8')
- // console.log(`> ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} Manufacturer Name is ${decoder.decode(characteristic.value)}`)
- }
- function start() {
- if (!isWebBluetoothEnabled())
- return
- gattCharacteristic.startNotifications()
- .then(_ => {
- console.log('Start reading...')
- setStartDisabled(true)
- setStopDisabled(false)
- })
- .catch(error => console.log('[ERROR] Start: ' + error))
- }
- function stop() {
- if (!isWebBluetoothEnabled())
- return
- gattCharacteristic.stopNotifications()
- .then(_ => {
- console.log('Stop reading...')
- setStartDisabled(false)
- setStopDisabled(true)
- })
- .catch(error => console.log('[ERROR] Stop: ' + error))
- }
- function onDisconnected(event: Event) {
- alert("Device Disconnected")
- // console.log(event)
- const device = event.target as BluetoothDevice
- console.log(`Device "${device.name}" is disconnected.`)
+ return true
+ }
+ function getDeviceInfo() {
+ const options = {
+ // acceptAllDevices: true,
+ filters: [{ name: deviceName }],
+ // optionalServices: ['battery_service'],
}
- return (
-
-
-
-
-
- { navigator.clipboard.writeText("chrome://flags/#enable-experimental-web-platform-features") }}
- // target="_blank"
- style={{ "cursor": "pointer" }}
- // rel="noopener noreferrer"
- >
- Step 1
-
- {" "}
- { navigator.clipboard.writeText("chrome://flags/#enable-web-bluetooth-new-permissions-backend") }}
- // target="_blank"
- style={{ "cursor": "pointer" }}
- // rel="noopener noreferrer"
+ console.log("Requesting Bluetooth Device...")
- >
- Step 2
-
-
-
+ return navigator.bluetooth
+ .requestDevice(options)
+ .then((device) => {
+ bluetoothDeviceDetected = device
+ console.log("> Name: " + device.name)
+ device.addEventListener("gattserverdisconnected", onDisconnected)
+ })
+ .catch((error) => console.log("Argh! " + error))
+ }
+ function read() {
+ if (!isWebBluetoothEnabled()) return
+ return getDeviceInfo()
+ .then(connectGatt)
+ .then((_) => {
+ console.log("Reading UV Index...")
+ return gattCharacteristic.readValue()
+ })
+ .catch((error) => console.log("Waiting to start reading: " + error))
+ }
+ function connectGatt() {
+ if (
+ bluetoothDeviceDetected.gatt &&
+ bluetoothDeviceDetected.gatt.connected &&
+ gattCharacteristic
+ )
+ return Promise.resolve()
+ if (!bluetoothDeviceDetected || !bluetoothDeviceDetected.gatt)
+ return Promise.reject()
+ return bluetoothDeviceDetected.gatt
+ .connect()
+ .then((server) => {
+ console.log("Getting GATT Service...")
+ return server.getPrimaryService(bleService)
+ })
+ .then((service) => {
+ console.log("Getting GATT Characteristic...")
+ return service.getCharacteristic(bleCharacteristic)
+ })
+ .then((characteristic) => {
+ gattCharacteristic = characteristic
+ characteristic.addEventListener(
+ "characteristicvaluechanged",
+ handleChangedValue
+ )
+
+ setStartDisabled(false)
+ setStopDisabled(true)
+ })
+ }
+ function handleChangedValue(event: Event) {
+ const characteristic = event.target as BluetoothRemoteGATTCharacteristic
+ if (!characteristic.value) {
+ console.log("Characteristic undefined!")
+ return
+ }
+ const value = characteristic.value.getUint8(0)
+ const now = new Date()
+ // Output the UV Index
+ console.log(
+ `> ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} UV Index is ${value}`
)
+ // Output the Battery percentage
+ // console.log(`> ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} Battery percentage is ${value}`)
+
+ // Output the Manufacturer Name
+ // let decoder = new TextDecoder('utf-8')
+ // console.log(`> ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} Manufacturer Name is ${decoder.decode(characteristic.value)}`)
+ }
+ function start() {
+ if (!isWebBluetoothEnabled()) return
+ gattCharacteristic
+ .startNotifications()
+ .then((_) => {
+ console.log("Start reading...")
+ setStartDisabled(true)
+ setStopDisabled(false)
+ })
+ .catch((error) => console.log("[ERROR] Start: " + error))
+ }
+ function stop() {
+ if (!isWebBluetoothEnabled()) return
+ gattCharacteristic
+ .stopNotifications()
+ .then((_) => {
+ console.log("Stop reading...")
+ setStartDisabled(false)
+ setStopDisabled(true)
+ })
+ .catch((error) => console.log("[ERROR] Stop: " + error))
+ }
+ function onDisconnected(event: Event) {
+ alert("Device Disconnected")
+ // console.log(event)
+ const device = event.target as BluetoothDevice
+ console.log(`Device "${device.name}" is disconnected.`)
+ }
+
+ return (
+
+
+
+
+
+ {
+ navigator.clipboard.writeText(
+ "chrome://flags/#enable-experimental-web-platform-features"
+ )
+ }}
+ // target="_blank"
+ style={{ cursor: "pointer" }}
+ // rel="noopener noreferrer"
+ >
+ Step 1
+ {" "}
+ {
+ navigator.clipboard.writeText(
+ "chrome://flags/#enable-web-bluetooth-new-permissions-backend"
+ )
+ }}
+ // target="_blank"
+ style={{ cursor: "pointer" }}
+ // rel="noopener noreferrer"
+ >
+ Step 2
+
+
+
+ )
}
-export default Bluetooth
\ No newline at end of file
+export default Bluetooth
diff --git a/leaky-ships/components/BorderTiles.tsx b/leaky-ships/components/BorderTiles.tsx
index 580eb45..eef503b 100644
--- a/leaky-ships/components/BorderTiles.tsx
+++ b/leaky-ships/components/BorderTiles.tsx
@@ -1,53 +1,65 @@
-import { CSSProperties, Dispatch, SetStateAction } from 'react'
-import { borderCN, cornerCN, fieldIndex } from '../lib/utils/helpers'
-import { Position, MouseCursor } from '../interfaces/frontend'
+import { CSSProperties, Dispatch, SetStateAction } from "react"
+import { borderCN, cornerCN, fieldIndex } from "../lib/utils/helpers"
+import { Position, MouseCursor } from "../interfaces/frontend"
type TilesType = {
- key: number,
- isGameTile: boolean,
- classNameString: string,
- x: number,
- y: number
+ key: number
+ isGameTile: boolean
+ classNameString: string
+ x: number
+ y: number
}
-function BorderTiles({ props: { count, settingTarget, setMouseCursor, setLastLeftTile } }: {
- props: {
- count: number,
- settingTarget: (isGameTile: boolean, x: number, y: number) => void,
- setMouseCursor: Dispatch>,
- setLastLeftTile: Dispatch>
- }
+function BorderTiles({
+ props: { count, settingTarget, setMouseCursor, setLastLeftTile },
+}: {
+ props: {
+ count: number
+ settingTarget: (isGameTile: boolean, x: number, y: number) => void
+ setMouseCursor: Dispatch>
+ setLastLeftTile: Dispatch>
+ }
}) {
- let tilesProperties: TilesType[] = []
+ let tilesProperties: TilesType[] = []
- for (let y = 0; y < count + 2; y++) {
- for (let x = 0; x < count + 2; x++) {
- const key = fieldIndex(count, x, y)
- const cornerReslt = cornerCN(count, x, y)
- const borderType = cornerReslt ? cornerReslt : borderCN(count, x, y)
- const isGameTile = x > 0 && x < count + 1 && y > 0 && y < count + 1
- const classNames = ['border-tile']
- if (borderType)
- classNames.push('edge', borderType)
- if (isGameTile)
- classNames.push('game-tile')
- const classNameString = classNames.join(' ')
- tilesProperties.push({ key, classNameString, isGameTile, x: x + 1, y: y + 1 })
- }
+ for (let y = 0; y < count + 2; y++) {
+ for (let x = 0; x < count + 2; x++) {
+ const key = fieldIndex(count, x, y)
+ const cornerReslt = cornerCN(count, x, y)
+ const borderType = cornerReslt ? cornerReslt : borderCN(count, x, y)
+ const isGameTile = x > 0 && x < count + 1 && y > 0 && y < count + 1
+ const classNames = ["border-tile"]
+ if (borderType) classNames.push("edge", borderType)
+ if (isGameTile) classNames.push("game-tile")
+ const classNameString = classNames.join(" ")
+ tilesProperties.push({
+ key,
+ classNameString,
+ isGameTile,
+ x: x + 1,
+ y: y + 1,
+ })
}
+ }
- return (<>
- {tilesProperties.map(({ key, classNameString, isGameTile, x, y }) => {
- return settingTarget(isGameTile, x, y)}
- onMouseEnter={() => setMouseCursor({ x, y, shouldShow: isGameTile })}
- onMouseLeave={() => setLastLeftTile({ x, y })}
- >
- })}
- >)
+ return (
+ <>
+ {tilesProperties.map(({ key, classNameString, isGameTile, x, y }) => {
+ return (
+ settingTarget(isGameTile, x, y)}
+ onMouseEnter={() =>
+ setMouseCursor({ x, y, shouldShow: isGameTile })
+ }
+ onMouseLeave={() => setLastLeftTile({ x, y })}
+ >
+ )
+ })}
+ >
+ )
}
export default BorderTiles
diff --git a/leaky-ships/components/EventBar.tsx b/leaky-ships/components/EventBar.tsx
index 5b55bda..cdb1353 100644
--- a/leaky-ships/components/EventBar.tsx
+++ b/leaky-ships/components/EventBar.tsx
@@ -1,33 +1,38 @@
-import React, { Dispatch, SetStateAction } from 'react'
-import { Items, Target } from '../interfaces/frontend'
-import Item from './Item'
+import React, { Dispatch, SetStateAction } from "react"
+import { Items, Target } from "../interfaces/frontend"
+import Item from "./Item"
-function EventBar({ props: { setMode, setTarget } }: {
- props: {
- setMode: Dispatch>,
- setTarget: Dispatch>
- }
+function EventBar({
+ props: { setMode, setTarget },
+}: {
+ props: {
+ setMode: Dispatch>
+ setTarget: Dispatch>
+ }
}) {
- const items: Items[] = [
- { icon: 'burger-menu', text: 'Menu' },
- { icon: 'radar', text: 'Radar scan', mode: 0, amount: 1 },
- { icon: 'torpedo', text: 'Fire torpedo', mode: 1, amount: 1 },
- { icon: 'scope', text: 'Fire missile', mode: 2 },
- { icon: 'gear', text: 'Settings' }
- ]
- return (
-
- {items.map((e, i) => (
- - {
- if (e.mode !== undefined)
- setMode(e.mode)
- setTarget(e => ({ ...e, show: false }))
- }
- }} />
- ))}
-
- )
+ const items: Items[] = [
+ { icon: "burger-menu", text: "Menu" },
+ { icon: "radar", text: "Radar scan", mode: 0, amount: 1 },
+ { icon: "torpedo", text: "Fire torpedo", mode: 1, amount: 1 },
+ { icon: "scope", text: "Fire missile", mode: 2 },
+ { icon: "gear", text: "Settings" },
+ ]
+ return (
+
+ {items.map((e, i) => (
+ - {
+ if (e.mode !== undefined) setMode(e.mode)
+ setTarget((e) => ({ ...e, show: false }))
+ },
+ }}
+ />
+ ))}
+
+ )
}
-export default EventBar
\ No newline at end of file
+export default EventBar
diff --git a/leaky-ships/components/FogImages.tsx b/leaky-ships/components/FogImages.tsx
index 9d75c1b..06ba202 100644
--- a/leaky-ships/components/FogImages.tsx
+++ b/leaky-ships/components/FogImages.tsx
@@ -1,11 +1,13 @@
import Image from "next/image"
function FogImages() {
- return <>
-
-
-
+ return (
+ <>
+
+
+
>
+ )
}
export default FogImages
diff --git a/leaky-ships/components/Gamefield.tsx b/leaky-ships/components/Gamefield.tsx
index 8f0b65f..8a9b630 100644
--- a/leaky-ships/components/Gamefield.tsx
+++ b/leaky-ships/components/Gamefield.tsx
@@ -1,47 +1,41 @@
-import { CSSProperties } from 'react'
+import { CSSProperties } from "react"
// import Bluetooth from './Bluetooth'
-import BorderTiles from './BorderTiles'
-import EventBar from './EventBar'
+import BorderTiles from "./BorderTiles"
+import EventBar from "./EventBar"
// import FogImages from './FogImages'
-import HitElems from './HitElems'
-import Labeling from './Labeling'
-import Ships from './Ships'
-import useGameEvent from '../lib/hooks/useGameEvent'
-import Targets from './Targets'
+import HitElems from "./HitElems"
+import Labeling from "./Labeling"
+import Ships from "./Ships"
+import useGameEvent from "../lib/hooks/useGameEvent"
+import Targets from "./Targets"
function Gamefield() {
+ const count = 12
+ const { pointersProps, targetsProps, tilesProps, hits } = useGameEvent(count)
- const count = 12
- const {
- pointersProps,
- targetsProps,
- tilesProps,
- hits
- } = useGameEvent(count)
+ return (
+
+ {/*
*/}
+
+ {/* Bordes */}
+
- return (
-
- {/*
*/}
-
- {/* Bordes */}
-
+ {/* Collumn lettes and row numbers */}
+
- {/* Collumn lettes and row numbers */}
-
+ {/* Ships */}
+
- {/* Ships */}
-
+
-
-
- {/* Fog images */}
- {/* */}
-
- {/* Debug */}
-
-
-
- )
+ {/* Fog images */}
+ {/*
*/}
+
+ {/*
Debug */}
+
+
+
+ )
}
-export default Gamefield
\ No newline at end of file
+export default Gamefield
diff --git a/leaky-ships/components/GamefieldPointer.tsx b/leaky-ships/components/GamefieldPointer.tsx
index 9222d8e..c90cc9e 100644
--- a/leaky-ships/components/GamefieldPointer.tsx
+++ b/leaky-ships/components/GamefieldPointer.tsx
@@ -1,30 +1,39 @@
-import { faCrosshairs } from '@fortawesome/pro-solid-svg-icons'
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
-import { CSSProperties } from 'react'
-import classNames from 'classnames'
-import { faRadar } from '@fortawesome/pro-thin-svg-icons'
-import { Target, TargetList } from '../interfaces/frontend'
+import { faCrosshairs } from "@fortawesome/pro-solid-svg-icons"
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
+import { CSSProperties } from "react"
+import classNames from "classnames"
+import { faRadar } from "@fortawesome/pro-thin-svg-icons"
+import { Target, TargetList } from "../interfaces/frontend"
export interface PointerProps extends Target, TargetList {
- imply: boolean;
+ imply: boolean
}
-function GamefieldPointer({ props: {
- preview,
- x,
- y,
- show,
- type,
- edges,
- imply
-} }: { props: PointerProps }) {
- const isRadar = type === 'radar'
- const style = !(isRadar && !edges.filter(s => s).length) ? { '--x': x, '--y': y } : { '--x1': x - 1, '--x2': x + 2, '--y1': y - 1, '--y2': y + 2 }
- return (
-
-
-
- )
+function GamefieldPointer({
+ props: { preview, x, y, show, type, edges, imply },
+}: {
+ props: PointerProps
+}) {
+ const isRadar = type === "radar"
+ const style = !(isRadar && !edges.filter((s) => s).length)
+ ? { "--x": x, "--y": y }
+ : { "--x1": x - 1, "--x2": x + 2, "--y1": y - 1, "--y2": y + 2 }
+ return (
+
+
+
+ )
}
-export default GamefieldPointer
\ No newline at end of file
+export default GamefieldPointer
diff --git a/leaky-ships/components/Grid.tsx b/leaky-ships/components/Grid.tsx
index 3d5dde4..e39e9fc 100644
--- a/leaky-ships/components/Grid.tsx
+++ b/leaky-ships/components/Grid.tsx
@@ -1,95 +1,112 @@
-import classNames from 'classnames'
-import { CSSProperties, useEffect, useMemo, useState } from 'react'
+import classNames from "classnames"
+import { CSSProperties, useEffect, useMemo, useState } from "react"
function Grid() {
+ function floorClient(number: number) {
+ return Math.floor(number / 50)
+ }
- function floorClient(number: number) {
- return Math.floor(number / 50)
+ const [columns, setColumns] = useState(0)
+ const [rows, setRows] = useState(0)
+ const [params, setParams] = useState({
+ columns,
+ rows,
+ quantity: columns * rows,
+ })
+ const [position, setPosition] = useState([0, 0])
+ const [active, setActve] = useState(false)
+ const [count, setCount] = useState(0)
+
+ useEffect(() => {
+ function handleResize() {
+ setColumns(floorClient(document.body.clientWidth))
+ setRows(floorClient(document.body.clientHeight))
}
+ handleResize()
+ window.addEventListener("resize", handleResize)
+ }, [])
- const [columns, setColumns] = useState(0)
- const [rows, setRows] = useState(0)
- const [params, setParams] = useState({ columns, rows, quantity: columns * rows })
- const [position, setPosition] = useState([0, 0])
- const [active, setActve] = useState(false)
- const [count, setCount] = useState(0)
+ useEffect(() => {
+ const timeout = setTimeout(() => {
+ setParams({ columns, rows, quantity: columns * rows })
+ }, 500)
+ return () => clearTimeout(timeout)
+ }, [columns, rows])
- useEffect(() => {
- function handleResize() {
- setColumns(floorClient(document.body.clientWidth))
- setRows(floorClient(document.body.clientHeight))
+ const createTiles = useMemo(() => {
+ const colors = [
+ "rgb(229, 57, 53)",
+ "rgb(253, 216, 53)",
+ "rgb(244, 81, 30)",
+ "rgb(76, 175, 80)",
+ "rgb(33, 150, 243)",
+ "rgb(156, 39, 176)",
+ ]
+
+ function createTile(index: number) {
+ const x = index % params.columns
+ const y = Math.floor(index / params.columns)
+ const xDiff = (x - position[0]) / 20
+ const yDiff = (y - position[1]) / 20
+ const pos = Math.sqrt(xDiff * xDiff + yDiff * yDiff).toFixed(2)
+
+ function doEffect(posX: number, posY: number) {
+ if (active) return
+ setPosition([posX, posY])
+ setActve(true)
+
+ function xDiff(x: number) {
+ return (x - posX) / 20
}
- handleResize()
- window.addEventListener('resize', handleResize)
- }, [])
-
- useEffect(() => {
- const timeout = setTimeout(() => {
- setParams({ columns, rows, quantity: columns * rows })
- }, 500)
- return () => clearTimeout(timeout)
- }, [columns, rows])
-
- const createTiles = useMemo(() => {
-
- const colors = [
- 'rgb(229, 57, 53)',
- 'rgb(253, 216, 53)',
- 'rgb(244, 81, 30)',
- 'rgb(76, 175, 80)',
- 'rgb(33, 150, 243)',
- 'rgb(156, 39, 176)'
+ function yDiff(y: number) {
+ return (y - posY) / 20
+ }
+ function pos(x: number, y: number) {
+ return Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
+ }
+ const diagonals = [
+ pos(0, 0),
+ pos(params.columns, 0),
+ pos(0, params.rows),
+ pos(params.columns, params.rows),
]
- function createTile(index: number) {
+ setTimeout(() => {
+ setActve(false)
+ setCount((e) => e + 1)
+ }, Math.max(...diagonals) * 1000 + 300)
+ }
- const x = index % params.columns
- const y = Math.floor(index / params.columns)
- const xDiff = (x - position[0]) / 20
- const yDiff = (y - position[1]) / 20
- const pos = (Math.sqrt(xDiff * xDiff + yDiff * yDiff)).toFixed(2)
+ return (
+ doEffect(x, y)}
+ >
+ )
+ }
- function doEffect(posX: number, posY: number) {
- if (active)
- return
- setPosition([posX, posY])
- setActve(true)
-
- function xDiff(x: number) {
- return (x - posX) / 20
- }
- function yDiff(y: number) {
- return (y - posY) / 20
- }
- function pos(x: number, y: number) {
- return Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
- }
- const diagonals = [pos(0, 0), pos(params.columns, 0), pos(0, params.rows), pos(params.columns, params.rows)]
-
- setTimeout(() => {
- setActve(false)
- setCount(e => e + 1)
- }, Math.max(...diagonals) * 1000 + 300)
- }
-
- return (
- doEffect(x, y)}
- >
- )
+ return (
+
+ {Array.from(Array(params.quantity), (_tile, index) =>
+ createTile(index)
+ )}
+
+ )
+ }, [params, position, active, count])
- return (
-
- {Array.from(Array(params.quantity), (_tile, index) => createTile(index))}
-
- )
- }, [params, position, active, count])
-
- return createTiles
+ return createTiles
}
-export default Grid
\ No newline at end of file
+export default Grid
diff --git a/leaky-ships/components/Grid2.tsx b/leaky-ships/components/Grid2.tsx
index 54a1dd6..7dda33c 100644
--- a/leaky-ships/components/Grid2.tsx
+++ b/leaky-ships/components/Grid2.tsx
@@ -1,100 +1,118 @@
-import classNames from 'classnames'
-import { CSSProperties, useEffect, useMemo, useState } from 'react'
+import classNames from "classnames"
+import { CSSProperties, useEffect, useMemo, useState } from "react"
function Grid2() {
+ function floorClient(number: number) {
+ return Math.floor(number / 50)
+ }
- function floorClient(number: number) {
- return Math.floor(number / 50)
+ const [columns, setColumns] = useState(0)
+ const [rows, setRows] = useState(0)
+ const [params, setParams] = useState({
+ columns,
+ rows,
+ quantity: columns * rows,
+ })
+ const [position, setPosition] = useState([0, 0])
+ const [active, setActve] = useState(false)
+ const [action, setAction] = useState(false)
+ const [count, setCount] = useState(0)
+
+ useEffect(() => {
+ function handleResize() {
+ setColumns(floorClient(document.body.clientWidth))
+ setRows(floorClient(document.body.clientHeight))
}
+ handleResize()
+ window.addEventListener("resize", handleResize)
+ }, [])
- const [columns, setColumns] = useState(0)
- const [rows, setRows] = useState(0)
- const [params, setParams] = useState({ columns, rows, quantity: columns * rows })
- const [position, setPosition] = useState([0, 0])
- const [active, setActve] = useState(false)
- const [action, setAction] = useState(false)
- const [count, setCount] = useState(0)
+ useEffect(() => {
+ const timeout = setTimeout(() => {
+ setParams({ columns, rows, quantity: columns * rows })
+ }, 500)
+ return () => clearTimeout(timeout)
+ }, [columns, rows])
- useEffect(() => {
- function handleResize() {
- setColumns(floorClient(document.body.clientWidth))
- setRows(floorClient(document.body.clientHeight))
+ const createTiles = useMemo(() => {
+ const sentences = [
+ "Ethem ...",
+ "hat ...",
+ "lange ...",
+ "Hörner 🐂",
+ "Grüße von Mallorca 🌊 🦦 ☀️",
+ ]
+
+ function createTile(index: number) {
+ const x = index % params.columns
+ const y = Math.floor(index / params.columns)
+ const xDiff = (x - position[0]) / 20
+ const yDiff = (y - position[1]) / 20
+ const pos = Math.sqrt(xDiff * xDiff + yDiff * yDiff).toFixed(2)
+
+ function doEffect(posX: number, posY: number) {
+ if (action) return
+ setPosition([posX, posY])
+ setActve((e) => !e)
+ setAction(true)
+
+ function xDiff(x: number) {
+ return (x - posX) / 20
}
- handleResize()
- window.addEventListener('resize', handleResize)
- }, [])
-
- useEffect(() => {
- const timeout = setTimeout(() => {
- setParams({ columns, rows, quantity: columns * rows })
- }, 500)
- return () => clearTimeout(timeout)
- }, [columns, rows])
-
- const createTiles = useMemo(() => {
-
- const sentences = [
- 'Ethem ...',
- 'hat ...',
- 'lange ...',
- 'Hörner 🐂',
- 'Grüße von Mallorca 🌊 🦦 ☀️'
+ function yDiff(y: number) {
+ return (y - posY) / 20
+ }
+ function pos(x: number, y: number) {
+ return Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
+ }
+ const diagonals = [
+ pos(0, 0),
+ pos(params.columns, 0),
+ pos(0, params.rows),
+ pos(params.columns, params.rows),
]
- function createTile(index: number) {
+ setTimeout(() => {
+ setAction(false)
+ if (active) setCount((e) => e + 1)
+ }, Math.max(...diagonals) * 1000 + 1000)
+ }
- const x = index % params.columns
- const y = Math.floor(index / params.columns)
- const xDiff = (x - position[0]) / 20
- const yDiff = (y - position[1]) / 20
- const pos = (Math.sqrt(xDiff * xDiff + yDiff * yDiff)).toFixed(2)
+ return (
+ doEffect(x, y)}
+ >
+ )
+ }
- function doEffect(posX: number, posY: number) {
- if (action)
- return
- setPosition([posX, posY])
- setActve(e => !e)
- setAction(true)
-
- function xDiff(x: number) {
- return (x - posX) / 20
- }
- function yDiff(y: number) {
- return (y - posY) / 20
- }
- function pos(x: number, y: number) {
- return Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
- }
- const diagonals = [pos(0, 0), pos(params.columns, 0), pos(0, params.rows), pos(params.columns, params.rows)]
-
- setTimeout(() => {
- setAction(false)
- if (active)
- setCount(e => e + 1)
- }, Math.max(...diagonals) * 1000 + 1000)
- }
-
- return (
- doEffect(x, y)}
- >
- )
+ return (
+
+
+
+ {sentences[count % sentences.length]}
+
+
+ {Array.from(Array(params.quantity), (_tile, index) =>
+ createTile(index)
+ )}
+
+ )
+ }, [params, position, active, action, count])
- return (
-
-
-
{sentences[count % sentences.length]}
-
- {Array.from(Array(params.quantity), (_tile, index) => createTile(index))}
-
- )
- }, [params, position, active, action, count])
-
- return createTiles
+ return createTiles
}
-export default Grid2
\ No newline at end of file
+export default Grid2
diff --git a/leaky-ships/components/HitElems.tsx b/leaky-ships/components/HitElems.tsx
index a657da5..0a39749 100644
--- a/leaky-ships/components/HitElems.tsx
+++ b/leaky-ships/components/HitElems.tsx
@@ -1,17 +1,22 @@
-import { faBurst, faXmark } from '@fortawesome/pro-solid-svg-icons'
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
-import { CSSProperties } from 'react'
-import { Hit } from '../interfaces/frontend'
+import { faBurst, faXmark } from "@fortawesome/pro-solid-svg-icons"
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
+import { CSSProperties } from "react"
+import { Hit } from "../interfaces/frontend"
-function HitElems({hits}: {hits: Hit[]}) {
-
- return <>
- {hits.map(({hit, x, y}, i) =>
-
-
-
- )}
+function HitElems({ hits }: { hits: Hit[] }) {
+ return (
+ <>
+ {hits.map(({ hit, x, y }, i) => (
+
+
+
+ ))}
>
+ )
}
export default HitElems
diff --git a/leaky-ships/components/Item.tsx b/leaky-ships/components/Item.tsx
index 9218365..13b7cb3 100644
--- a/leaky-ships/components/Item.tsx
+++ b/leaky-ships/components/Item.tsx
@@ -1,22 +1,33 @@
-import classNames from 'classnames'
-import React, { CSSProperties } from 'react'
+import classNames from "classnames"
+import React, { CSSProperties } from "react"
-function Item({ props: { icon, text, amount, callback } }: {
- props: {
- icon: string,
- text: string,
- amount?: number,
- callback: () => void
- }
+function Item({
+ props: { icon, text, amount, callback },
+}: {
+ props: {
+ icon: string
+ text: string
+ amount?: number
+ callback: () => void
+ }
}) {
- return (
-
-
-

-
-
{text}
-
- )
+ return (
+
+
+

+
+
{text}
+
+ )
}
-export default Item
\ No newline at end of file
+export default Item
diff --git a/leaky-ships/components/Labeling.tsx b/leaky-ships/components/Labeling.tsx
index 7c093de..6244ed5 100644
--- a/leaky-ships/components/Labeling.tsx
+++ b/leaky-ships/components/Labeling.tsx
@@ -1,30 +1,50 @@
-import classNames from 'classnames'
-import { CSSProperties } from 'react'
-import { fieldIndex } from '../lib/utils/helpers'
-import { Field } from '../interfaces/frontend'
+import classNames from "classnames"
+import { CSSProperties } from "react"
+import { fieldIndex } from "../lib/utils/helpers"
+import { Field } from "../interfaces/frontend"
-function Labeling({count}: {count: number}) {
- let elems: (Field & {
- orientation: string
- })[] = []
- for (let x = 0; x < count; x++) {
- elems.push(
- // Up
- {field: String.fromCharCode(65+x), x: x+2, y: 1, orientation: 'up'},
- // Left
- {field: (x+1).toString(), x: 1, y: x+2, orientation: 'left'},
- // Bottom
- {field: String.fromCharCode(65+x), x: x+2, y: count+2, orientation: 'bottom'},
- // Right
- {field: (x+1).toString(), x: count+2, y: x+2, orientation: 'right'}
- )
- }
- elems = elems.sort((a, b) => fieldIndex(count, a.x, a.y)-fieldIndex(count, b.x, b.y))
- return <>
- {elems.map(({field, x, y, orientation}, i) =>
- {field}
- )}
+function Labeling({ count }: { count: number }) {
+ let elems: (Field & {
+ orientation: string
+ })[] = []
+ for (let x = 0; x < count; x++) {
+ elems.push(
+ // Up
+ { field: String.fromCharCode(65 + x), x: x + 2, y: 1, orientation: "up" },
+ // Left
+ { field: (x + 1).toString(), x: 1, y: x + 2, orientation: "left" },
+ // Bottom
+ {
+ field: String.fromCharCode(65 + x),
+ x: x + 2,
+ y: count + 2,
+ orientation: "bottom",
+ },
+ // Right
+ {
+ field: (x + 1).toString(),
+ x: count + 2,
+ y: x + 2,
+ orientation: "right",
+ }
+ )
+ }
+ elems = elems.sort(
+ (a, b) => fieldIndex(count, a.x, a.y) - fieldIndex(count, b.x, b.y)
+ )
+ return (
+ <>
+ {elems.map(({ field, x, y, orientation }, i) => (
+
+ {field}
+
+ ))}
>
+ )
}
export default Labeling
diff --git a/leaky-ships/components/Ships.tsx b/leaky-ships/components/Ships.tsx
index a9e89f3..016ca5c 100644
--- a/leaky-ships/components/Ships.tsx
+++ b/leaky-ships/components/Ships.tsx
@@ -1,26 +1,34 @@
-import classNames from 'classnames'
-import { CSSProperties } from 'react'
+import classNames from "classnames"
+import { CSSProperties } from "react"
function Ships() {
- let shipIndexes = [
- { size: 2, index: null },
- { size: 3, index: 1 },
- { size: 3, index: 2 },
- { size: 3, index: 3 },
- { size: 4, index: 1 },
- { size: 4, index: 2 }
- ]
+ let shipIndexes = [
+ { size: 2, index: null },
+ { size: 3, index: 1 },
+ { size: 3, index: 2 },
+ { size: 3, index: 3 },
+ { size: 4, index: 1 },
+ { size: 4, index: 2 },
+ ]
- return <>
- {shipIndexes.map(({ size, index }, i) => {
- const filename = `/assets/ship_blue_${size}x${index ? '_' + index : ''}.gif`
- return (
-
-

-
- )
- })}
+ return (
+ <>
+ {shipIndexes.map(({ size, index }, i) => {
+ const filename = `/assets/ship_blue_${size}x${
+ index ? "_" + index : ""
+ }.gif`
+ return (
+
+

+
+ )
+ })}
>
+ )
}
export default Ships
diff --git a/leaky-ships/components/SocketIO.tsx b/leaky-ships/components/SocketIO.tsx
index dca3aca..6267cc0 100644
--- a/leaky-ships/components/SocketIO.tsx
+++ b/leaky-ships/components/SocketIO.tsx
@@ -1,40 +1,38 @@
-import { useEffect } from 'react'
-import { io } from 'socket.io-client'
+import { useEffect } from "react"
+import { io } from "socket.io-client"
function SocketIO() {
- useEffect(() => {
- socketInitializer()
- }, [])
+ useEffect(() => {
+ socketInitializer()
+ }, [])
- const socketInitializer = async () => {
- await fetch('/api/ws')
+ const socketInitializer = async () => {
+ await fetch("/api/ws")
- const socket = io()
- socket.on('test2', (warst) => {
- console.log('Test2:', warst, socket.id)
- })
- socket.on("connect", () => {
- console.log(socket.connected) // true
- setTimeout(() => {
- socket.emit('test', "warst")
- socket.emit('test', "tsra")
- socket.emit('test', "1234")
- // socket.disconnect()
- }, 1000)
- })
+ const socket = io()
+ socket.on("test2", (warst) => {
+ console.log("Test2:", warst, socket.id)
+ })
+ socket.on("connect", () => {
+ console.log(socket.connected) // true
+ setTimeout(() => {
+ socket.emit("test", "warst")
+ socket.emit("test", "tsra")
+ socket.emit("test", "1234")
+ // socket.disconnect()
+ }, 1000)
+ })
- socket.on("test", () => {
- console.log("Got test1234") // false
- })
+ socket.on("test", () => {
+ console.log("Got test1234") // false
+ })
- socket.on("disconnect", () => {
- console.log(socket.connected) // false
- })
- }
+ socket.on("disconnect", () => {
+ console.log(socket.connected) // false
+ })
+ }
- return (
- SocketIO
- )
+ return SocketIO
}
-export default SocketIO
\ No newline at end of file
+export default SocketIO
diff --git a/leaky-ships/components/Targets.tsx b/leaky-ships/components/Targets.tsx
index 1139860..6388a5b 100644
--- a/leaky-ships/components/Targets.tsx
+++ b/leaky-ships/components/Targets.tsx
@@ -1,20 +1,28 @@
-import React from 'react'
-import { Target } from '../interfaces/frontend'
-import GamefieldPointer, { PointerProps } from './GamefieldPointer'
+import React from "react"
+import { Target } from "../interfaces/frontend"
+import GamefieldPointer, { PointerProps } from "./GamefieldPointer"
-function Targets({ props: { composeTargetTiles, target, targetPreview } }: {
- props: {
- composeTargetTiles: (target: Target) => PointerProps[],
- target: Target,
- targetPreview: Target
- }
+function Targets({
+ props: { composeTargetTiles, target, targetPreview },
+}: {
+ props: {
+ composeTargetTiles: (target: Target) => PointerProps[]
+ target: Target
+ targetPreview: Target
+ }
}) {
- return (<>
- {[
- ...composeTargetTiles(target).map((props, i) => ),
- ...composeTargetTiles(targetPreview).map((props, i) => )
- ]}
- >)
+ return (
+ <>
+ {[
+ ...composeTargetTiles(target).map((props, i) => (
+
+ )),
+ ...composeTargetTiles(targetPreview).map((props, i) => (
+
+ )),
+ ]}
+ >
+ )
}
-export default Targets
\ No newline at end of file
+export default Targets
diff --git a/leaky-ships/global.d.ts b/leaky-ships/global.d.ts
index 9ad9a7a..1a8523e 100644
--- a/leaky-ships/global.d.ts
+++ b/leaky-ships/global.d.ts
@@ -1,3 +1,3 @@
declare module globalThis {
- var prismaClient: PrismaClient
+ var prismaClient: PrismaClient
}
diff --git a/leaky-ships/interfaces/NextApiSocket.ts b/leaky-ships/interfaces/NextApiSocket.ts
index 01e1ca2..3020036 100644
--- a/leaky-ships/interfaces/NextApiSocket.ts
+++ b/leaky-ships/interfaces/NextApiSocket.ts
@@ -1,7 +1,7 @@
-import type { Server as HTTPServer } from 'http'
-import type { NextApiResponse } from 'next'
-import type { Socket as NetSocket } from 'net'
-import type { Server as IOServer } from 'socket.io'
+import type { Server as HTTPServer } from "http"
+import type { NextApiResponse } from "next"
+import type { Socket as NetSocket } from "net"
+import type { Server as IOServer } from "socket.io"
interface SocketServer extends HTTPServer {
io?: IOServer | undefined
@@ -13,4 +13,4 @@ interface SocketWithIO extends NetSocket {
export interface NextApiResponseWithSocket extends NextApiResponse {
socket: SocketWithIO
-}
\ No newline at end of file
+}
diff --git a/leaky-ships/interfaces/frontend.ts b/leaky-ships/interfaces/frontend.ts
index 85d78d0..9d0bb9a 100644
--- a/leaky-ships/interfaces/frontend.ts
+++ b/leaky-ships/interfaces/frontend.ts
@@ -1,50 +1,50 @@
export interface Position {
- x: number,
- y: number
+ x: number
+ y: number
}
export interface Target extends Position {
- preview: boolean,
- show: boolean
+ preview: boolean
+ show: boolean
}
export interface MouseCursor extends Position {
- shouldShow: boolean
+ shouldShow: boolean
}
export interface TargetList extends Position {
- type: string,
- edges: string[]
+ type: string
+ edges: string[]
}
export interface Mode {
- pointerGrid: any[][],
- type: string
+ pointerGrid: any[][]
+ type: string
}
export interface Items {
- icon: string,
- text: string,
- mode?: number,
- amount?: number,
+ icon: string
+ text: string
+ mode?: number
+ amount?: number
}
export interface Field extends Position {
- field: string
+ field: string
}
export interface Hit extends Position {
- hit: boolean
+ hit: boolean
}
interface fireMissile {
- type: 'fireMissile',
- payload: {
- x: number,
- y: number,
- hit: boolean
- }
+ type: "fireMissile"
+ payload: {
+ x: number
+ y: number
+ hit: boolean
+ }
}
interface removeMissile {
- type: 'removeMissile',
- payload: {
- x: number,
- y: number,
- hit: boolean
- }
+ type: "removeMissile"
+ payload: {
+ x: number
+ y: number
+ hit: boolean
+ }
}
export type HitDispatch = fireMissile | removeMissile
diff --git a/leaky-ships/lib/backend/components/checkPasswordIsValid.ts b/leaky-ships/lib/backend/components/checkPasswordIsValid.ts
index eb4d3f1..55639d5 100644
--- a/leaky-ships/lib/backend/components/checkPasswordIsValid.ts
+++ b/leaky-ships/lib/backend/components/checkPasswordIsValid.ts
@@ -1,22 +1,23 @@
import { Player } from "@prisma/client"
import bcrypt from "bcrypt"
-export default async function checkPasswordIsValid(payload: T & { player: Player, password: string }) {
- const { player, password } = payload
+export default async function checkPasswordIsValid(
+ payload: T & { player: Player; password: string }
+) {
+ const { player, password } = payload
- // Validate for correct password
- return bcrypt.compare(password, player.passwordHash)
- .then(async result => {
- if (!result) {
- return Promise.reject({
- message: 'Passwords do not match!',
- statusCode: 401,
- solved: true,
- })
- }
- return {
- ...payload,
- passwordIsValid: true
- }
- })
-}
\ No newline at end of file
+ // Validate for correct password
+ return bcrypt.compare(password, player.passwordHash).then(async (result) => {
+ if (!result) {
+ return Promise.reject({
+ message: "Passwords do not match!",
+ statusCode: 401,
+ solved: true,
+ })
+ }
+ return {
+ ...payload,
+ passwordIsValid: true,
+ }
+ })
+}
diff --git a/leaky-ships/lib/backend/components/checkTokenIsValid.ts b/leaky-ships/lib/backend/components/checkTokenIsValid.ts
index 3fb5001..d24d22e 100644
--- a/leaky-ships/lib/backend/components/checkTokenIsValid.ts
+++ b/leaky-ships/lib/backend/components/checkTokenIsValid.ts
@@ -2,27 +2,29 @@ import { Token } from "@prisma/client"
import jwt from "jsonwebtoken"
import jwtVerifyCatch from "../jwtVerifyCatch"
-async function checkTokenIsValid(payload: T & { token: string, tokenType: Token['type'] }) {
- const { token, tokenType } = payload
+async function checkTokenIsValid(
+ payload: T & { token: string; tokenType: Token["type"] }
+) {
+ const { token, tokenType } = payload
- // Verify the token and get the payload
- let tokenData: string | jwt.JwtPayload
- try {
- tokenData = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET as string)
- } catch (err: any) {
- // Deal with the problem in more detail
- return Promise.reject(jwtVerifyCatch(tokenType, err))
- }
- // Making sure the token data is not a string (because it should be an object)
- if (typeof tokenData === 'string') {
- return Promise.reject({
- message: tokenType + '-Token data was a string. Token: ' + token,
- statusCode: 401,
- solved: false
- })
- }
+ // Verify the token and get the payload
+ let tokenData: string | jwt.JwtPayload
+ try {
+ tokenData = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET as string)
+ } catch (err: any) {
+ // Deal with the problem in more detail
+ return Promise.reject(jwtVerifyCatch(tokenType, err))
+ }
+ // Making sure the token data is not a string (because it should be an object)
+ if (typeof tokenData === "string") {
+ return Promise.reject({
+ message: tokenType + "-Token data was a string. Token: " + token,
+ statusCode: 401,
+ solved: false,
+ })
+ }
- return { ...payload, tokenBody: token, tokenIsValid: true }
+ return { ...payload, tokenBody: token, tokenIsValid: true }
}
-export default checkTokenIsValid
\ No newline at end of file
+export default checkTokenIsValid
diff --git a/leaky-ships/lib/backend/components/createAnonymousDB.ts b/leaky-ships/lib/backend/components/createAnonymousDB.ts
index 65c486d..ef83488 100644
--- a/leaky-ships/lib/backend/components/createAnonymousDB.ts
+++ b/leaky-ships/lib/backend/components/createAnonymousDB.ts
@@ -1,28 +1,28 @@
import prisma from "../../prisma"
async function createAnonymousDB(payload: T) {
- const player = await prisma.player.create({
- data: {
- anonymous: true
- }
- })
- // .catch((err: any) => {
- // if (err.code === 11000) {
- // return Promise.reject({
- // message: `Duplicate key error while creating Player in DB!`,
- // statusCode: 409,
- // solved: true,
- // type: 'warn'
- // })
- // } else {
- // console.log(err)
- // return Promise.reject({
- // message: `Unknown error while creating Player in DB.`,
- // solved: false
- // })
- // }
- // })
- return { ...payload, player }
+ const player = await prisma.player.create({
+ data: {
+ anonymous: true,
+ },
+ })
+ // .catch((err: any) => {
+ // if (err.code === 11000) {
+ // return Promise.reject({
+ // message: `Duplicate key error while creating Player in DB!`,
+ // statusCode: 409,
+ // solved: true,
+ // type: 'warn'
+ // })
+ // } else {
+ // console.log(err)
+ // return Promise.reject({
+ // message: `Unknown error while creating Player in DB.`,
+ // solved: false
+ // })
+ // }
+ // })
+ return { ...payload, player }
}
-export default createAnonymousDB
\ No newline at end of file
+export default createAnonymousDB
diff --git a/leaky-ships/lib/backend/components/createPlayerDB.ts b/leaky-ships/lib/backend/components/createPlayerDB.ts
index ba5ea01..e9c9ff2 100644
--- a/leaky-ships/lib/backend/components/createPlayerDB.ts
+++ b/leaky-ships/lib/backend/components/createPlayerDB.ts
@@ -1,34 +1,38 @@
import bcrypt from "bcrypt"
import prisma from "../../prisma"
-async function createPlayerDB(payload: T & { username: string, password: string }) {
- const { username, password } = payload
+async function createPlayerDB(
+ payload: T & { username: string; password: string }
+) {
+ const { username, password } = payload
- return await prisma.player.create({
- data: {
- username,
- passwordHash: await bcrypt.hash(password, 10),
- anonymous: false
- }
+ return await prisma.player
+ .create({
+ data: {
+ username,
+ passwordHash: await bcrypt.hash(password, 10),
+ anonymous: false,
+ },
})
- .then(player => {
- return { ...payload, player }
- }).catch((err: any) => {
- if (err.code === 11000) {
- return Promise.reject({
- message: `Duplicate key error while creating Player in DB!`,
- statusCode: 409,
- solved: true,
- type: 'warn'
- })
- } else {
- console.log(err)
- return Promise.reject({
- message: `Unknown error while creating Player in DB.`,
- solved: false
- })
- }
+ .then((player) => {
+ return { ...payload, player }
+ })
+ .catch((err: any) => {
+ if (err.code === 11000) {
+ return Promise.reject({
+ message: `Duplicate key error while creating Player in DB!`,
+ statusCode: 409,
+ solved: true,
+ type: "warn",
})
+ } else {
+ console.log(err)
+ return Promise.reject({
+ message: `Unknown error while creating Player in DB.`,
+ solved: false,
+ })
+ }
+ })
}
-export default createPlayerDB
\ No newline at end of file
+export default createPlayerDB
diff --git a/leaky-ships/lib/backend/components/createTokenDB.ts b/leaky-ships/lib/backend/components/createTokenDB.ts
index cdee377..9ded9c4 100644
--- a/leaky-ships/lib/backend/components/createTokenDB.ts
+++ b/leaky-ships/lib/backend/components/createTokenDB.ts
@@ -4,33 +4,39 @@ import { v4 as uuidv4 } from "uuid"
import prisma from "../../prisma"
const tokenLifetime = {
- REFRESH: 172800,
- ACCESS: 15
-};
+ REFRESH: 172800,
+ ACCESS: 15,
+}
-export default async function createTokenDB(payload: T & { player: Player, newTokenType: Token['type'] }) {
- const { player, newTokenType } = payload
+export default async function createTokenDB(
+ payload: T & { player: Player; newTokenType: Token["type"] }
+) {
+ const { player, newTokenType } = payload
- // Sign a new access token
- const newToken = jwt.sign({ uuid: uuidv4(), user: player.id }, process.env.ACCESS_TOKEN_SECRET as string, { expiresIn: tokenLifetime[newTokenType] })
+ // Sign a new access token
+ const newToken = jwt.sign(
+ { uuid: uuidv4(), user: player.id },
+ process.env.ACCESS_TOKEN_SECRET as string,
+ { expiresIn: tokenLifetime[newTokenType] }
+ )
- // Save token to DB
- const newTokenDB = await prisma.token.create({
- data: {
- token: newToken,
- type: newTokenType,
- expires: new Date(Date.now() + tokenLifetime[newTokenType] + '000'),
- owner: {
- connect: {
- id: player.id
- }
- }
- }
- })
+ // Save token to DB
+ const newTokenDB = await prisma.token.create({
+ data: {
+ token: newToken,
+ type: newTokenType,
+ expires: new Date(Date.now() + tokenLifetime[newTokenType] + "000"),
+ owner: {
+ connect: {
+ id: player.id,
+ },
+ },
+ },
+ })
- return {
- ...payload,
- newToken,
- newTokenDB
- }
-}
\ No newline at end of file
+ return {
+ ...payload,
+ newToken,
+ newTokenDB,
+ }
+}
diff --git a/leaky-ships/lib/backend/components/getPlayerByIdDB.ts b/leaky-ships/lib/backend/components/getPlayerByIdDB.ts
index ec1a5d9..a3814cc 100644
--- a/leaky-ships/lib/backend/components/getPlayerByIdDB.ts
+++ b/leaky-ships/lib/backend/components/getPlayerByIdDB.ts
@@ -1,24 +1,26 @@
import { Token } from "@prisma/client"
import prisma from "../../prisma"
-export default async function getPlayerByIdDB(payload: T & { tokenDB: Token }) {
- const { tokenDB } = payload
- // Find Host in DB if it still exists (just to make sure)
- const player = await prisma.player.findUnique({
- where: {
- id: tokenDB.ownerId
- }
+export default async function getPlayerByIdDB(
+ payload: T & { tokenDB: Token }
+) {
+ const { tokenDB } = payload
+ // Find Host in DB if it still exists (just to make sure)
+ const player = await prisma.player.findUnique({
+ where: {
+ id: tokenDB.ownerId,
+ },
+ })
+ if (!player) {
+ return Promise.reject({
+ message: "Player not found in DB!",
+ statusCode: 401,
+ solved: false,
})
- if (!player) {
- return Promise.reject({
- message: 'Player not found in DB!',
- statusCode: 401,
- solved: false
- })
- }
+ }
- return {
- ...payload,
- player
- }
-}
\ No newline at end of file
+ return {
+ ...payload,
+ player,
+ }
+}
diff --git a/leaky-ships/lib/backend/components/getPlayerByNameDB.ts b/leaky-ships/lib/backend/components/getPlayerByNameDB.ts
index 82d79d6..3de1a82 100644
--- a/leaky-ships/lib/backend/components/getPlayerByNameDB.ts
+++ b/leaky-ships/lib/backend/components/getPlayerByNameDB.ts
@@ -1,29 +1,32 @@
import prisma from "../../prisma"
-export default async function getPlayerByNameDB(payload: T & { username: string }) {
- const { username } = payload
- // Find Player in DB if it still exists (just to make sure)
- const player = await Promise.any([
- prisma.player.findUnique({
- where: {
- username: username
- }
- }), prisma.player.findUnique({
- where: {
- email: username
- }
- })
- ])
- if (!player) {
- return Promise.reject({
- message: 'Player not found in DB!',
- statusCode: 401,
- solved: false
- })
- }
+export default async function getPlayerByNameDB(
+ payload: T & { username: string }
+) {
+ const { username } = payload
+ // Find Player in DB if it still exists (just to make sure)
+ const player = await Promise.any([
+ prisma.player.findUnique({
+ where: {
+ username: username,
+ },
+ }),
+ prisma.player.findUnique({
+ where: {
+ email: username,
+ },
+ }),
+ ])
+ if (!player) {
+ return Promise.reject({
+ message: "Player not found in DB!",
+ statusCode: 401,
+ solved: false,
+ })
+ }
- return {
- ...payload,
- player
- }
-}
\ No newline at end of file
+ return {
+ ...payload,
+ player,
+ }
+}
diff --git a/leaky-ships/lib/backend/components/getTokenDB.ts b/leaky-ships/lib/backend/components/getTokenDB.ts
index 69d8456..4c21da4 100644
--- a/leaky-ships/lib/backend/components/getTokenDB.ts
+++ b/leaky-ships/lib/backend/components/getTokenDB.ts
@@ -1,52 +1,54 @@
import { NextApiRequest, NextApiResponse } from "next"
import prisma from "../../prisma"
-async function getTokenDB(payload: T & {
+async function getTokenDB(
+ payload: T & {
tokenBody: string
- tokenIsValid: boolean,
- req: NextApiRequest,
- res: NextApiResponse,
-}) {
- const { tokenBody } = payload
+ tokenIsValid: boolean
+ req: NextApiRequest
+ res: NextApiResponse
+ }
+) {
+ const { tokenBody } = payload
- // Find refresh token in DB
- const tokenDB = await prisma.token.findUnique({
- where: {
- token: tokenBody
- }
+ // Find refresh token in DB
+ const tokenDB = await prisma.token.findUnique({
+ where: {
+ token: tokenBody,
+ },
+ })
+ if (!tokenDB) {
+ return Promise.reject({
+ message: "Access-Token not found in DB!",
+ statusCode: 401,
+ solved: true,
+ type: "warn",
})
- if (!tokenDB) {
- return Promise.reject({
- message: 'Access-Token not found in DB!',
- statusCode: 401,
- solved: true,
- type: 'warn'
- })
- }
+ }
- if (tokenDB.used) {
- return Promise.reject({
- message: 'DBToken was already used!',
- statusCode: 401,
- solved: true
- })
- }
-
- await prisma.token.update({
- where: {
- token: tokenBody
- },
- data: {
- used: true
- }
+ if (tokenDB.used) {
+ return Promise.reject({
+ message: "DBToken was already used!",
+ statusCode: 401,
+ solved: true,
})
+ }
- // await logging('Old token has been invalidated.', ['debug'], req)
+ await prisma.token.update({
+ where: {
+ token: tokenBody,
+ },
+ data: {
+ used: true,
+ },
+ })
- return {
- ...payload,
- tokenDB
- }
+ // await logging('Old token has been invalidated.', ['debug'], req)
+
+ return {
+ ...payload,
+ tokenDB,
+ }
}
-export default getTokenDB
\ No newline at end of file
+export default getTokenDB
diff --git a/leaky-ships/lib/backend/components/getTokenFromBody.ts b/leaky-ships/lib/backend/components/getTokenFromBody.ts
index 61ebd9d..2e12e0a 100644
--- a/leaky-ships/lib/backend/components/getTokenFromBody.ts
+++ b/leaky-ships/lib/backend/components/getTokenFromBody.ts
@@ -1,19 +1,19 @@
import { NextApiRequest } from "next"
async function getTokenFromBody(payload: T & { req: NextApiRequest }) {
- const { req } = payload
- const token: string = req.body.token
+ const { req } = payload
+ const token: string = req.body.token
- // Checking for cookie presens, because it is necessary
- if (!token) {
- return Promise.reject({
- message: 'Unauthorized. No Access-Token.',
- statusCode: 401,
- solved: true,
- })
- }
+ // Checking for cookie presens, because it is necessary
+ if (!token) {
+ return Promise.reject({
+ message: "Unauthorized. No Access-Token.",
+ statusCode: 401,
+ solved: true,
+ })
+ }
- return { ...payload, token }
+ return { ...payload, token }
}
-export default getTokenFromBody
\ No newline at end of file
+export default getTokenFromBody
diff --git a/leaky-ships/lib/backend/components/getTokenFromCookie.ts b/leaky-ships/lib/backend/components/getTokenFromCookie.ts
index e8caa89..4798e29 100644
--- a/leaky-ships/lib/backend/components/getTokenFromCookie.ts
+++ b/leaky-ships/lib/backend/components/getTokenFromCookie.ts
@@ -2,19 +2,19 @@ import { Token } from "@prisma/client"
import { NextApiRequest } from "next"
async function getTokenFromCookie(payload: T & { req: NextApiRequest }) {
- const { req } = payload
- const token = req.cookies.token
+ const { req } = payload
+ const token = req.cookies.token
- // Checking for cookie presens, because it is necessary
- if (!token) {
- return Promise.reject({
- message: 'Unauthorized. No cookie.',
- statusCode: 401,
- solved: true,
- })
- }
+ // Checking for cookie presens, because it is necessary
+ if (!token) {
+ return Promise.reject({
+ message: "Unauthorized. No cookie.",
+ statusCode: 401,
+ solved: true,
+ })
+ }
- return { ...payload, token, tokenType: 'REFRESH' as Token['type'] }
+ return { ...payload, token, tokenType: "REFRESH" as Token["type"] }
}
-export default getTokenFromCookie
\ No newline at end of file
+export default getTokenFromCookie
diff --git a/leaky-ships/lib/backend/components/loginCheck.ts b/leaky-ships/lib/backend/components/loginCheck.ts
index 36ef428..4cd9cc2 100644
--- a/leaky-ships/lib/backend/components/loginCheck.ts
+++ b/leaky-ships/lib/backend/components/loginCheck.ts
@@ -1,15 +1,17 @@
import { Token } from "@prisma/client"
import { Logging } from "../logging"
-export default async function loginCheck(payload: T & { loginCheck: boolean, tokenDB: Token, tokenType: 'REFRESH' }) {
- const { loginCheck, tokenDB } = payload
- // True login check response
- if (loginCheck) {
- return Promise.resolve({
- message: 'loginCheck ' + loginCheck + ' of ' + tokenDB.id,
- body: { loggedIn: true },
- type: ['debug', 'info.cyan'] as Logging[]
- })
- }
- return payload
-}
\ No newline at end of file
+export default async function loginCheck(
+ payload: T & { loginCheck: boolean; tokenDB: Token; tokenType: "REFRESH" }
+) {
+ const { loginCheck, tokenDB } = payload
+ // True login check response
+ if (loginCheck) {
+ return Promise.resolve({
+ message: "loginCheck " + loginCheck + " of " + tokenDB.id,
+ body: { loggedIn: true },
+ type: ["debug", "info.cyan"] as Logging[],
+ })
+ }
+ return payload
+}
diff --git a/leaky-ships/lib/backend/components/sendError.ts b/leaky-ships/lib/backend/components/sendError.ts
index 7d54118..92db74c 100644
--- a/leaky-ships/lib/backend/components/sendError.ts
+++ b/leaky-ships/lib/backend/components/sendError.ts
@@ -2,11 +2,11 @@ import { NextApiRequest, NextApiResponse } from "next"
import logging from "../logging"
export default function sendError(
- req: NextApiRequest,
- res: NextApiResponse,
- err: any
+ req: NextApiRequest,
+ res: NextApiResponse,
+ err: any
) {
- // If something went wrong, let the client know with status 500
- res.status(err.statusCode ?? 500).end()
- logging(err.message, [err.type ?? (err.solved ? 'debug' : 'error')], req)
-}
\ No newline at end of file
+ // If something went wrong, let the client know with status 500
+ res.status(err.statusCode ?? 500).end()
+ logging(err.message, [err.type ?? (err.solved ? "debug" : "error")], req)
+}
diff --git a/leaky-ships/lib/backend/components/sendResponse.ts b/leaky-ships/lib/backend/components/sendResponse.ts
index e3b2eda..2defd35 100644
--- a/leaky-ships/lib/backend/components/sendResponse.ts
+++ b/leaky-ships/lib/backend/components/sendResponse.ts
@@ -2,21 +2,19 @@ import { NextApiRequest, NextApiResponse } from "next"
import logging, { Logging } from "../logging"
export interface Result {
- message: string,
- statusCode?: number,
- body?: T,
- type?: Logging[],
+ message: string
+ statusCode?: number
+ body?: T
+ type?: Logging[]
}
export default function sendResponse(payload: {
- req: NextApiRequest,
- res: NextApiResponse,
- result: Result
+ req: NextApiRequest
+ res: NextApiResponse
+ result: Result
}) {
- const { req, res, result } = payload
- res.status(result.statusCode ?? 200)
- result.body ?
- res.json(result.body) :
- res.end()
- logging(result.message, result.type ?? ['debug'], req)
+ const { req, res, result } = payload
+ res.status(result.statusCode ?? 200)
+ result.body ? res.json(result.body) : res.end()
+ logging(result.message, result.type ?? ["debug"], req)
}
diff --git a/leaky-ships/lib/backend/jwtVerifyCatch.ts b/leaky-ships/lib/backend/jwtVerifyCatch.ts
index 2f89e8f..2354fe0 100644
--- a/leaky-ships/lib/backend/jwtVerifyCatch.ts
+++ b/leaky-ships/lib/backend/jwtVerifyCatch.ts
@@ -1,21 +1,36 @@
import { Token } from "@prisma/client"
export default async function jwtVerifyCatch(
- tokenType: Token['type'],
- err: Error
+ tokenType: Token["type"],
+ err: Error
) {
- switch (err.message) {
- case 'jwt expired':
- return { message: `JWT (${tokenType}) expired!`, statusCode: 403, solved: true, type: 'warn' }
+ switch (err.message) {
+ case "jwt expired":
+ return {
+ message: `JWT (${tokenType}) expired!`,
+ statusCode: 403,
+ solved: true,
+ type: "warn",
+ }
- case 'invalid signature':
- return { message: `Invalid JWT (${tokenType}) signature! Token: `, statusCode: 401, solved: true, type: 'error' }
+ case "invalid signature":
+ return {
+ message: `Invalid JWT (${tokenType}) signature! Token: `,
+ statusCode: 401,
+ solved: true,
+ type: "error",
+ }
- case 'jwt must be provided':
- return { message: `No JWT (${tokenType}) given.`, statusCode: 401, solved: true, type: 'warn' }
+ case "jwt must be provided":
+ return {
+ message: `No JWT (${tokenType}) given.`,
+ statusCode: 401,
+ solved: true,
+ type: "warn",
+ }
- default:
- console.log(err)
- return { message: `Unknown error on 'JWT.verify()'.`, solved: false }
- }
-}
\ No newline at end of file
+ default:
+ console.log(err)
+ return { message: `Unknown error on 'JWT.verify()'.`, solved: false }
+ }
+}
diff --git a/leaky-ships/lib/backend/logging.ts b/leaky-ships/lib/backend/logging.ts
index 9109d7c..2869641 100644
--- a/leaky-ships/lib/backend/logging.ts
+++ b/leaky-ships/lib/backend/logging.ts
@@ -1,17 +1,17 @@
-import fs from 'fs'
-import colors, { Color } from 'colors'
-import { NextApiRequest } from 'next'
-import { IncomingMessage } from 'http'
+import fs from "fs"
+import colors, { Color } from "colors"
+import { NextApiRequest } from "next"
+import { IncomingMessage } from "http"
colors.enable()
const loggingTemplates: { [key: string]: LoggingType } = {
- 'system': ['SYSTEM', 'green'],
- 'info.green': ['INFO', 'green'],
- 'info.cyan': ['INFO', 'cyan'],
- 'debug': ['Debug', 'grey'],
- 'post': ['Post', 'white'],
- 'warn': ['WARN', 'yellow'],
- 'error': ['ERROR', 'red']
+ system: ["SYSTEM", "green"],
+ "info.green": ["INFO", "green"],
+ "info.cyan": ["INFO", "cyan"],
+ debug: ["Debug", "grey"],
+ post: ["Post", "white"],
+ warn: ["WARN", "yellow"],
+ error: ["ERROR", "red"],
}
type LoggingType = [string, keyof Color]
@@ -20,32 +20,40 @@ export type Logging = keyof typeof loggingTemplates | LoggingType
let started: boolean = false
async function logStartup() {
- await fs.promises.stat('log').catch(async () => {
- await fs.promises.mkdir('log')
- await logging(`Created 'log' Folder.`, ['info.cyan', 'system'])
- })
- started = true
+ await fs.promises.stat("log").catch(async () => {
+ await fs.promises.mkdir("log")
+ await logging(`Created 'log' Folder.`, ["info.cyan", "system"])
+ })
+ started = true
}
-async function logging(message: string, types: Logging[], req?: NextApiRequest | IncomingMessage) {
- if (!started)
- await logStartup()
- const messages = { console: message, file: message }
- types.slice().reverse().forEach(async (type) => {
- const [name, color] = typeof type === 'object' ? type : loggingTemplates[type]
- messages.console = `[${name}] `[color] + messages.console
- messages.file = `[${name}] ` + messages.file
+async function logging(
+ message: string,
+ types: Logging[],
+ req?: NextApiRequest | IncomingMessage
+) {
+ if (!started) await logStartup()
+ const messages = { console: message, file: message }
+ types
+ .slice()
+ .reverse()
+ .forEach(async (type) => {
+ const [name, color] =
+ typeof type === "object" ? type : loggingTemplates[type]
+ messages.console = `[${name}] `[color] + messages.console
+ messages.file = `[${name}] ` + messages.file
})
- messages.console = `[${new Date().toString().slice(0, 33)}] ` + messages.console
- messages.file = `[${new Date().toString().slice(0, 33)}] ` + messages.file
- if (req) {
- const forwardedFor: any = req.headers['x-forwarded-for']
- const ip = (forwardedFor || '127.0.0.1, 192.168.178.1').split(',')
- messages.console = ip[0].yellow + ' - ' + messages.console
- messages.file = ip[0] + ' - ' + messages.file
- }
- await fs.promises.appendFile('log/log.txt', messages.file + '\n')
- console.log(messages.console)
+ messages.console =
+ `[${new Date().toString().slice(0, 33)}] ` + messages.console
+ messages.file = `[${new Date().toString().slice(0, 33)}] ` + messages.file
+ if (req) {
+ const forwardedFor: any = req.headers["x-forwarded-for"]
+ const ip = (forwardedFor || "127.0.0.1, 192.168.178.1").split(",")
+ messages.console = ip[0].yellow + " - " + messages.console
+ messages.file = ip[0] + " - " + messages.file
+ }
+ await fs.promises.appendFile("log/log.txt", messages.file + "\n")
+ console.log(messages.console)
}
-export default logging
\ No newline at end of file
+export default logging
diff --git a/leaky-ships/lib/frontend/checkIsLoggedIn.ts b/leaky-ships/lib/frontend/checkIsLoggedIn.ts
index a90efae..040a28e 100644
--- a/leaky-ships/lib/frontend/checkIsLoggedIn.ts
+++ b/leaky-ships/lib/frontend/checkIsLoggedIn.ts
@@ -6,18 +6,24 @@ import getTokenDB from "../backend/components/getTokenDB"
import getPlayerByIdDB from "../backend/components/getPlayerByIdDB"
import logging from "../backend/logging"
-export default async function checkIsLoggedIn(context: GetServerSidePropsContext) {
- const req: any = context.req
- const res: any = context.res
+export default async function checkIsLoggedIn(
+ context: GetServerSidePropsContext
+) {
+ const req: any = context.req
+ const res: any = context.res
- const isLoggedIn = await getTokenFromCookie({ req, res })
- .then(checkTokenIsValid)
- .then(getTokenDB)
- .then(getPlayerByIdDB)
- .then(({ player }) => !!player)
- .catch(() => false)
+ const isLoggedIn = await getTokenFromCookie({ req, res })
+ .then(checkTokenIsValid)
+ .then(getTokenDB)
+ .then(getPlayerByIdDB)
+ .then(({ player }) => !!player)
+ .catch(() => false)
- logging('loginCheck ' + (isLoggedIn ? true : '-> loggedIn: ' + false), ['debug', 'info.cyan'], req)
+ logging(
+ "loginCheck " + (isLoggedIn ? true : "-> loggedIn: " + false),
+ ["debug", "info.cyan"],
+ req
+ )
- return isLoggedIn
-}
\ No newline at end of file
+ return isLoggedIn
+}
diff --git a/leaky-ships/lib/frontend/getAccessToken.ts b/leaky-ships/lib/frontend/getAccessToken.ts
index 85919f3..00105ea 100644
--- a/leaky-ships/lib/frontend/getAccessToken.ts
+++ b/leaky-ships/lib/frontend/getAccessToken.ts
@@ -1,7 +1,7 @@
export default function getAccessToken(): Promise {
- return fetch('/api/auth', {
- method: 'GET',
- })
- .then(res => res.json())
- .then(res => res.newAccessToken)
-}
\ No newline at end of file
+ return fetch("/api/auth", {
+ method: "GET",
+ })
+ .then((res) => res.json())
+ .then((res) => res.newAccessToken)
+}
diff --git a/leaky-ships/lib/hooks/useGameEvent.ts b/leaky-ships/lib/hooks/useGameEvent.ts
index 31b5fd3..64f28cd 100644
--- a/leaky-ships/lib/hooks/useGameEvent.ts
+++ b/leaky-ships/lib/hooks/useGameEvent.ts
@@ -1,150 +1,222 @@
-import { useCallback, useEffect, useMemo, useReducer, useState } from 'react'
-import { hitReducer, initlialLastLeftTile, initlialTarget, initlialTargetPreview, initlialMouseCursor } from '../utils/helpers'
-import { Hit, Mode, MouseCursor, Target, Position } from '../../interfaces/frontend'
-import { PointerProps } from '../../components/GamefieldPointer'
+import { useCallback, useEffect, useMemo, useReducer, useState } from "react"
+import {
+ hitReducer,
+ initlialLastLeftTile,
+ initlialTarget,
+ initlialTargetPreview,
+ initlialMouseCursor,
+} from "../utils/helpers"
+import {
+ Hit,
+ Mode,
+ MouseCursor,
+ Target,
+ Position,
+} from "../../interfaces/frontend"
+import { PointerProps } from "../../components/GamefieldPointer"
const modes: Mode[] = [
- { pointerGrid: Array.from(Array(3), () => Array.from(Array(3))), type: 'radar' },
- { pointerGrid: Array.from(Array(3), () => Array.from(Array(1))), type: 'htorpedo' },
- { pointerGrid: Array.from(Array(1), () => Array.from(Array(3))), type: 'vtorpedo' },
- { pointerGrid: [[{ x: 0, y: 0 }]], type: 'missile' }
+ {
+ pointerGrid: Array.from(Array(3), () => Array.from(Array(3))),
+ type: "radar",
+ },
+ {
+ pointerGrid: Array.from(Array(3), () => Array.from(Array(1))),
+ type: "htorpedo",
+ },
+ {
+ pointerGrid: Array.from(Array(1), () => Array.from(Array(3))),
+ type: "vtorpedo",
+ },
+ { pointerGrid: [[{ x: 0, y: 0 }]], type: "missile" },
]
function useGameEvent(count: number) {
- const [lastLeftTile, setLastLeftTile] = useState(initlialLastLeftTile)
- const [target, setTarget] = useState(initlialTarget)
- const [eventReady, setEventReady] = useState(false)
- const [appearOK, setAppearOK] = useState(false)
- const [targetPreview, setTargetPreview] = useState(initlialTargetPreview)
- const [mouseCursor, setMouseCursor] = useState(initlialMouseCursor)
- const [hits, DispatchHits] = useReducer(hitReducer, [] as Hit[])
- const [mode, setMode] = useState(0)
+ const [lastLeftTile, setLastLeftTile] =
+ useState(initlialLastLeftTile)
+ const [target, setTarget] = useState(initlialTarget)
+ const [eventReady, setEventReady] = useState(false)
+ const [appearOK, setAppearOK] = useState(false)
+ const [targetPreview, setTargetPreview] = useState(
+ initlialTargetPreview
+ )
+ const [mouseCursor, setMouseCursor] =
+ useState(initlialMouseCursor)
+ const [hits, DispatchHits] = useReducer(hitReducer, [] as Hit[])
+ const [mode, setMode] = useState(0)
- const targetList = useCallback((target: Position) => {
- const { pointerGrid, type } = modes[mode]
- const xLength = pointerGrid.length
- const yLength = pointerGrid[0].length
- const { x: targetX, y: targetY } = target
- return pointerGrid.map((arr, i) => {
- return arr.map((_, i2) => {
- const relativeX = -Math.floor(xLength / 2) + i
- const relativeY = -Math.floor(yLength / 2) + i2
- const x = targetX + (relativeX ?? 0)
- const y = targetY + (relativeY ?? 0)
- return {
- x,
- y,
- type,
- edges: [
- i === 0 ? 'left' : '',
- i === xLength - 1 ? 'right' : '',
- i2 === 0 ? 'top' : '',
- i2 === yLength - 1 ? 'bottom' : '',
- ]
- }
- })
- })
- .reduce((prev, curr) => [...prev, ...curr], [])
- }, [mode])
-
- const isHit = useCallback((x: number, y: number) => {
- return hits.filter(h => h.x === x && h.y === y)
- }, [hits])
-
- const settingTarget = useCallback((isGameTile: boolean, x: number, y: number) => {
- if (!isGameTile || isHit(x, y).length)
- return
- setMouseCursor(e => ({ ...e, shouldShow: false }))
- setTarget(t => {
- if (t.x === x && t.y === y && t.show) {
- DispatchHits({ type: 'fireMissile', payload: { hit: (x + y) % 2 !== 0, x, y } })
- return { preview: false, show: false, x, y }
- } else {
- const target = { preview: false, show: true, x, y }
- const hasAnyBorder = targetList(target).filter(({ x, y }) => isBorder(x, y, count)).length
- if (hasAnyBorder)
- return t
- return target
-
- }
- })
- }, [count, isHit, targetList])
-
- const isSet = useCallback((x: number, y: number) => {
- return !!targetList(target).filter(field => x === field.x && y === field.y).length && target.show
- }, [target, targetList])
-
- const composeTargetTiles = useCallback((target: Target): PointerProps[] => {
- const { preview, show } = target
- const result = targetList(target).map(({ x, y, type, edges }) => {
+ const targetList = useCallback(
+ (target: Position) => {
+ const { pointerGrid, type } = modes[mode]
+ const xLength = pointerGrid.length
+ const yLength = pointerGrid[0].length
+ const { x: targetX, y: targetY } = target
+ return pointerGrid
+ .map((arr, i) => {
+ return arr.map((_, i2) => {
+ const relativeX = -Math.floor(xLength / 2) + i
+ const relativeY = -Math.floor(yLength / 2) + i2
+ const x = targetX + (relativeX ?? 0)
+ const y = targetY + (relativeY ?? 0)
return {
- preview,
- x,
- y,
- show,
- type,
- edges,
- imply: !!isHit(x, y).length || (!!isSet(x, y) && preview)
+ x,
+ y,
+ type,
+ edges: [
+ i === 0 ? "left" : "",
+ i === xLength - 1 ? "right" : "",
+ i2 === 0 ? "top" : "",
+ i2 === yLength - 1 ? "bottom" : "",
+ ],
}
+ })
})
- return result
- }, [isHit, isSet, targetList])
+ .reduce((prev, curr) => [...prev, ...curr], [])
+ },
+ [mode]
+ )
- // handle visibility and position change of targetPreview
- useEffect(() => {
- const { show, x, y } = targetPreview
- // if mouse has moved too quickly and last event was entering and leaving the same field, it must have gone outside the grid
- const hasLeft = x === lastLeftTile.x && y === lastLeftTile.y
- const isSet = x === target.x && y === target.y && target.show
+ const isHit = useCallback(
+ (x: number, y: number) => {
+ return hits.filter((h) => h.x === x && h.y === y)
+ },
+ [hits]
+ )
- if (show && !appearOK)
- setTargetPreview(e => ({ ...e, show: false }))
- if (!show && mouseCursor.shouldShow && eventReady && appearOK && !isHit(x, y).length && !isSet && !hasLeft)
- setTargetPreview(e => ({ ...e, show: true }))
- }, [targetPreview, mouseCursor.shouldShow, isHit, eventReady, appearOK, lastLeftTile, target])
-
- // enable targetPreview event again after 200 ms.
- useEffect(() => {
- setEventReady(false)
- const previewTarget = { x: mouseCursor.x, y: mouseCursor.y }
- const hasAnyBorder = targetList(previewTarget).filter(({ x, y }) => isBorder(x, y, count)).length
- if (targetPreview.show || !appearOK || hasAnyBorder)
- return
- const autoTimeout = setTimeout(() => {
- setTargetPreview(e => ({ ...e, ...previewTarget }))
- setEventReady(true)
- setAppearOK(true)
- }, 300)
-
- // or abort if state has changed early
- return () => {
- clearTimeout(autoTimeout)
+ const settingTarget = useCallback(
+ (isGameTile: boolean, x: number, y: number) => {
+ if (!isGameTile || isHit(x, y).length) return
+ setMouseCursor((e) => ({ ...e, shouldShow: false }))
+ setTarget((t) => {
+ if (t.x === x && t.y === y && t.show) {
+ DispatchHits({
+ type: "fireMissile",
+ payload: { hit: (x + y) % 2 !== 0, x, y },
+ })
+ return { preview: false, show: false, x, y }
+ } else {
+ const target = { preview: false, show: true, x, y }
+ const hasAnyBorder = targetList(target).filter(({ x, y }) =>
+ isBorder(x, y, count)
+ ).length
+ if (hasAnyBorder) return t
+ return target
}
- }, [appearOK, count, mouseCursor.x, mouseCursor.y, targetList, targetPreview.show])
+ })
+ },
+ [count, isHit, targetList]
+ )
- // approve targetPreview new position after 200 mil. sec.
- useEffect(() => {
- // early return to start cooldown only when about to show up
- const autoTimeout = setTimeout(() => {
- setAppearOK(!targetPreview.show)
- }, targetPreview.show ? 500 : 300)
+ const isSet = useCallback(
+ (x: number, y: number) => {
+ return (
+ !!targetList(target).filter((field) => x === field.x && y === field.y)
+ .length && target.show
+ )
+ },
+ [target, targetList]
+ )
- // or abort if movement is repeated early
- return () => {
- clearTimeout(autoTimeout)
+ const composeTargetTiles = useCallback(
+ (target: Target): PointerProps[] => {
+ const { preview, show } = target
+ const result = targetList(target).map(({ x, y, type, edges }) => {
+ return {
+ preview,
+ x,
+ y,
+ show,
+ type,
+ edges,
+ imply: !!isHit(x, y).length || (!!isSet(x, y) && preview),
}
- }, [targetPreview.show])
+ })
+ return result
+ },
+ [isHit, isSet, targetList]
+ )
- return {
- tilesProps: { count, settingTarget, setMouseCursor, setLastLeftTile },
- pointersProps: { composeTargetTiles, target, targetPreview },
- targetsProps: { setMode, setTarget },
- hits
+ // handle visibility and position change of targetPreview
+ useEffect(() => {
+ const { show, x, y } = targetPreview
+ // if mouse has moved too quickly and last event was entering and leaving the same field, it must have gone outside the grid
+ const hasLeft = x === lastLeftTile.x && y === lastLeftTile.y
+ const isSet = x === target.x && y === target.y && target.show
+
+ if (show && !appearOK) setTargetPreview((e) => ({ ...e, show: false }))
+ if (
+ !show &&
+ mouseCursor.shouldShow &&
+ eventReady &&
+ appearOK &&
+ !isHit(x, y).length &&
+ !isSet &&
+ !hasLeft
+ )
+ setTargetPreview((e) => ({ ...e, show: true }))
+ }, [
+ targetPreview,
+ mouseCursor.shouldShow,
+ isHit,
+ eventReady,
+ appearOK,
+ lastLeftTile,
+ target,
+ ])
+
+ // enable targetPreview event again after 200 ms.
+ useEffect(() => {
+ setEventReady(false)
+ const previewTarget = { x: mouseCursor.x, y: mouseCursor.y }
+ const hasAnyBorder = targetList(previewTarget).filter(({ x, y }) =>
+ isBorder(x, y, count)
+ ).length
+ if (targetPreview.show || !appearOK || hasAnyBorder) return
+ const autoTimeout = setTimeout(() => {
+ setTargetPreview((e) => ({ ...e, ...previewTarget }))
+ setEventReady(true)
+ setAppearOK(true)
+ }, 300)
+
+ // or abort if state has changed early
+ return () => {
+ clearTimeout(autoTimeout)
}
+ }, [
+ appearOK,
+ count,
+ mouseCursor.x,
+ mouseCursor.y,
+ targetList,
+ targetPreview.show,
+ ])
+
+ // approve targetPreview new position after 200 mil. sec.
+ useEffect(() => {
+ // early return to start cooldown only when about to show up
+ const autoTimeout = setTimeout(
+ () => {
+ setAppearOK(!targetPreview.show)
+ },
+ targetPreview.show ? 500 : 300
+ )
+
+ // or abort if movement is repeated early
+ return () => {
+ clearTimeout(autoTimeout)
+ }
+ }, [targetPreview.show])
+
+ return {
+ tilesProps: { count, settingTarget, setMouseCursor, setLastLeftTile },
+ pointersProps: { composeTargetTiles, target, targetPreview },
+ targetsProps: { setMode, setTarget },
+ hits,
+ }
}
function isBorder(x: number, y: number, count: number) {
- return x < 2 || x > count + 1 || y < 2 || y > count + 1
+ return x < 2 || x > count + 1 || y < 2 || y > count + 1
}
-export default useGameEvent
\ No newline at end of file
+export default useGameEvent
diff --git a/leaky-ships/lib/prisma.ts b/leaky-ships/lib/prisma.ts
index 42a3070..5f7a05b 100644
--- a/leaky-ships/lib/prisma.ts
+++ b/leaky-ships/lib/prisma.ts
@@ -1,15 +1,15 @@
// lib/prisma.ts
-import { PrismaClient } from '@prisma/client';
+import { PrismaClient } from "@prisma/client"
-let prisma: PrismaClient;
+let prisma: PrismaClient
-if (process.env.NODE_ENV === 'production') {
- prisma = new PrismaClient();
+if (process.env.NODE_ENV === "production") {
+ prisma = new PrismaClient()
} else {
- if (!global.prismaClient) {
- global.prismaClient = new PrismaClient();
- }
- prisma = global.prismaClient;
+ if (!global.prismaClient) {
+ global.prismaClient = new PrismaClient()
+ }
+ prisma = global.prismaClient
}
-export default prisma;
+export default prisma
diff --git a/leaky-ships/lib/utils/helpers.ts b/leaky-ships/lib/utils/helpers.ts
index a88dc5c..1c51fa7 100644
--- a/leaky-ships/lib/utils/helpers.ts
+++ b/leaky-ships/lib/utils/helpers.ts
@@ -1,60 +1,51 @@
import { Hit, HitDispatch } from "../../interfaces/frontend"
export function borderCN(count: number, x: number, y: number) {
- if (x === 0)
- return 'left'
- if (y === 0)
- return 'top'
- if (x === count + 1)
- return 'right'
- if (y === count + 1)
- return 'bottom'
- return ''
+ if (x === 0) return "left"
+ if (y === 0) return "top"
+ if (x === count + 1) return "right"
+ if (y === count + 1) return "bottom"
+ return ""
}
export function cornerCN(count: number, x: number, y: number) {
- if (x === 0 && y === 0)
- return 'left-top-corner'
- if (x === count + 1 && y === 0)
- return 'right-top-corner'
- if (x === 0 && y === count + 1)
- return 'left-bottom-corner'
- if (x === count + 1 && y === count + 1)
- return 'right-bottom-corner'
- return ''
+ if (x === 0 && y === 0) return "left-top-corner"
+ if (x === count + 1 && y === 0) return "right-top-corner"
+ if (x === 0 && y === count + 1) return "left-bottom-corner"
+ if (x === count + 1 && y === count + 1) return "right-bottom-corner"
+ return ""
}
export function fieldIndex(count: number, x: number, y: number) {
- return y * (count + 2) + x
+ return y * (count + 2) + x
}
export function hitReducer(formObject: Hit[], action: HitDispatch) {
- switch (action.type) {
-
- case 'fireMissile': {
- const result = [...formObject, action.payload]
- return result
- }
-
- default:
- return formObject
+ switch (action.type) {
+ case "fireMissile": {
+ const result = [...formObject, action.payload]
+ return result
}
+
+ default:
+ return formObject
+ }
}
export const initlialLastLeftTile = {
- x: 0,
- y: 0
+ x: 0,
+ y: 0,
}
export const initlialTarget = {
- preview: false,
- show: false,
- x: 2,
- y: 2
+ preview: false,
+ show: false,
+ x: 2,
+ y: 2,
}
export const initlialTargetPreview = {
- preview: true,
- show: false,
- x: 2,
- y: 2
+ preview: true,
+ show: false,
+ x: 2,
+ y: 2,
}
export const initlialMouseCursor = {
- shouldShow: false,
- x: 0,
- y: 0
+ shouldShow: false,
+ x: 0,
+ y: 0,
}
diff --git a/leaky-ships/package.json b/leaky-ships/package.json
index 51f210a..8f011dd 100644
--- a/leaky-ships/package.json
+++ b/leaky-ships/package.json
@@ -51,4 +51,4 @@
"sass": "^1.57.1",
"tailwindcss": "^3.2.4"
}
-}
\ No newline at end of file
+}
diff --git a/leaky-ships/pages/_app.tsx b/leaky-ships/pages/_app.tsx
index 8f7c337..b439e1a 100644
--- a/leaky-ships/pages/_app.tsx
+++ b/leaky-ships/pages/_app.tsx
@@ -1,9 +1,9 @@
-import '../styles/App.scss'
-import '../styles/grid.scss'
-import '../styles/grid2.scss'
-import '../styles/homepage.scss'
-import '../styles/globals.css'
-import type { AppProps } from 'next/app'
+import "../styles/App.scss"
+import "../styles/grid.scss"
+import "../styles/grid2.scss"
+import "../styles/homepage.scss"
+import "../styles/globals.css"
+import type { AppProps } from "next/app"
export default function App({ Component, pageProps }: AppProps) {
return
diff --git a/leaky-ships/pages/_document.tsx b/leaky-ships/pages/_document.tsx
index 54e8bf3..097cb7f 100644
--- a/leaky-ships/pages/_document.tsx
+++ b/leaky-ships/pages/_document.tsx
@@ -1,4 +1,4 @@
-import { Html, Head, Main, NextScript } from 'next/document'
+import { Html, Head, Main, NextScript } from "next/document"
export default function Document() {
return (
diff --git a/leaky-ships/pages/api/auth.ts b/leaky-ships/pages/api/auth.ts
index 502aafe..fefcdda 100644
--- a/leaky-ships/pages/api/auth.ts
+++ b/leaky-ships/pages/api/auth.ts
@@ -10,40 +10,48 @@ import { Logging } from "../../lib/backend/logging"
import { Token } from "@prisma/client"
interface Data {
- token: string
+ token: string
}
export default async function auth(
- req: NextApiRequest,
- res: NextApiResponse
+ req: NextApiRequest,
+ res: NextApiResponse
) {
- return getTokenFromCookie({ req, res, newTokenType: 'ACCESS' as Token['type'] })
- .then(checkTokenIsValid)
- .then(getTokenDB)
- .then(getPlayerByIdDB)
- .then(createTokenDB)
- .then(authResponse)
- .then(sendResponse)
- .catch(err => sendError(req, res, err))
+ return getTokenFromCookie({
+ req,
+ res,
+ newTokenType: "ACCESS" as Token["type"],
+ })
+ .then(checkTokenIsValid)
+ .then(getTokenDB)
+ .then(getPlayerByIdDB)
+ .then(createTokenDB)
+ .then(authResponse)
+ .then(sendResponse)
+ .catch((err) => sendError(req, res, err))
}
async function authResponse(payload: {
- newToken: string,
- newTokenDB: Token,
- tokenDB: Token,
- req: NextApiRequest,
- res: NextApiResponse
+ newToken: string
+ newTokenDB: Token
+ tokenDB: Token
+ req: NextApiRequest
+ res: NextApiResponse
}) {
- const { newToken, newTokenDB, tokenDB, req, res } = payload
+ const { newToken, newTokenDB, tokenDB, req, res } = payload
- // Successfull response
- return {
- req,
- res,
- result: {
- message: 'Access-Token generated: ' + newTokenDB.id + ' with Refreshtoken-Token: ' + tokenDB.id,
- body: { token: newToken },
- type: ['debug', 'info.cyan'] as Logging[]
- }
- }
-}
\ No newline at end of file
+ // Successfull response
+ return {
+ req,
+ res,
+ result: {
+ message:
+ "Access-Token generated: " +
+ newTokenDB.id +
+ " with Refreshtoken-Token: " +
+ tokenDB.id,
+ body: { token: newToken },
+ type: ["debug", "info.cyan"] as Logging[],
+ },
+ }
+}
diff --git a/leaky-ships/pages/api/data.ts b/leaky-ships/pages/api/data.ts
index 5a452ef..46c542a 100644
--- a/leaky-ships/pages/api/data.ts
+++ b/leaky-ships/pages/api/data.ts
@@ -9,40 +9,44 @@ import { Logging } from "../../lib/backend/logging"
import { Game, Player, Token } from "@prisma/client"
interface Data {
- games: Game[]
+ games: Game[]
}
export default async function data(
- req: NextApiRequest,
- res: NextApiResponse
+ req: NextApiRequest,
+ res: NextApiResponse
) {
- return getTokenFromBody({ req, res, tokenType: 'ACCESS' as Token['type'] })
- .then(checkTokenIsValid)
- .then(getTokenDB)
- .then(getPlayerByIdDB)
- .then(dataResponse)
- .then(sendResponse)
- .catch(err => sendError(req, res, err))
+ return getTokenFromBody({ req, res, tokenType: "ACCESS" as Token["type"] })
+ .then(checkTokenIsValid)
+ .then(getTokenDB)
+ .then(getPlayerByIdDB)
+ .then(dataResponse)
+ .then(sendResponse)
+ .catch((err) => sendError(req, res, err))
}
async function dataResponse(payload: {
- player: Player,
- tokenDB: Token,
- // games: Game[],
- req: NextApiRequest,
- res: NextApiResponse
+ player: Player
+ tokenDB: Token
+ // games: Game[],
+ req: NextApiRequest
+ res: NextApiResponse
}) {
- const { player, tokenDB, req, res } = payload
+ const { player, tokenDB, req, res } = payload
- const games: any = {}
- // Successfull response
- return {
- req,
- res,
- result: {
- message: 'Requested data of user: ' + player.id + ' with Access-Token: ' + tokenDB.id,
- body: { games },
- type: ['debug', 'info.cyan'] as Logging[]
- }
- }
-}
\ No newline at end of file
+ const games: any = {}
+ // Successfull response
+ return {
+ req,
+ res,
+ result: {
+ message:
+ "Requested data of user: " +
+ player.id +
+ " with Access-Token: " +
+ tokenDB.id,
+ body: { games },
+ type: ["debug", "info.cyan"] as Logging[],
+ },
+ }
+}
diff --git a/leaky-ships/pages/api/login.ts b/leaky-ships/pages/api/login.ts
index 34d7573..7662533 100644
--- a/leaky-ships/pages/api/login.ts
+++ b/leaky-ships/pages/api/login.ts
@@ -10,77 +10,89 @@ import { Player, Token } from "@prisma/client"
import prisma from "../../lib/prisma"
interface Data {
- loggedIn: boolean
+ loggedIn: boolean
}
export default async function login(
- req: NextApiRequest,
- res: NextApiResponse
+ req: NextApiRequest,
+ res: NextApiResponse
) {
- const { username, password } = req.body
- return preCheck({ req, res, username, password, newTokenType: 'REFRESH' as Token['type'] })
- .then(getPlayerByNameDB)
- .then(checkPasswordIsValid)
- .then(createTokenDB)
- .then(loginResponse)
- .then(sendResponse)
- .catch(err => sendError(req, res, err))
+ const { username, password } = req.body
+ return preCheck({
+ req,
+ res,
+ username,
+ password,
+ newTokenType: "REFRESH" as Token["type"],
+ })
+ .then(getPlayerByNameDB)
+ .then(checkPasswordIsValid)
+ .then(createTokenDB)
+ .then(loginResponse)
+ .then(sendResponse)
+ .catch((err) => sendError(req, res, err))
}
-async function preCheck(payload: T & {
- req: NextApiRequest,
+async function preCheck(
+ payload: T & {
+ req: NextApiRequest
res: NextApiResponse
-}) {
- const { req } = payload
- const oldRefreshToken = req.cookies.token
- // Check for old cookie, if unused invalidate it
- const oldDBToken = await prisma.token.findUnique({
- where: {
- token: oldRefreshToken
- }
+ }
+) {
+ const { req } = payload
+ const oldRefreshToken = req.cookies.token
+ // Check for old cookie, if unused invalidate it
+ const oldDBToken = await prisma.token.findUnique({
+ where: {
+ token: oldRefreshToken,
+ },
+ })
+ if (oldDBToken?.used) {
+ await prisma.token.update({
+ where: {
+ token: oldRefreshToken,
+ },
+ data: {
+ used: true,
+ },
})
- if (oldDBToken?.used) {
- await prisma.token.update({
- where: {
- token: oldRefreshToken
- },
- data: {
- used: true
- }
- })
- await logging('Old token has been invalidated.', ['debug'], req)
- }
- return { ...payload, noCookiePresent: true }
+ await logging("Old token has been invalidated.", ["debug"], req)
+ }
+ return { ...payload, noCookiePresent: true }
}
async function loginResponse(payload: {
- player: Player,
- passwordIsValid: boolean,
- refreshToken: string,
- refreshTokenDB: Token,
- req: NextApiRequest,
- res: NextApiResponse
+ player: Player
+ passwordIsValid: boolean
+ refreshToken: string
+ refreshTokenDB: Token
+ req: NextApiRequest
+ res: NextApiResponse
}) {
- const { player, refreshToken, refreshTokenDB, req, res } = payload
+ const { player, refreshToken, refreshTokenDB, req, res } = payload
- // Set login cookie
- setCookie('token', refreshToken, {
- req,
- res,
- maxAge: 172800000,
- httpOnly: true,
- sameSite: true,
- secure: true,
- })
+ // Set login cookie
+ setCookie("token", refreshToken, {
+ req,
+ res,
+ maxAge: 172800000,
+ httpOnly: true,
+ sameSite: true,
+ secure: true,
+ })
- // Successfull response
- return {
- req,
- res,
- result: {
- message: 'User ' + player.id + ' logged in and generated Refresh-Token: ' + refreshTokenDB.id,
- body: { loggedIn: true },
- type: ['debug', 'info.cyan'] as Logging[]
- }
- }
-}
\ No newline at end of file
+ // Successfull response
+ return {
+ req,
+ res,
+ result: {
+ message:
+ "User " +
+ player.id +
+ " logged in and generated Refresh-Token: " +
+ refreshTokenDB.id,
+ body: { loggedIn: true },
+ type: ["debug", "info.cyan"] as Logging[],
+ },
+ }
+}
diff --git a/leaky-ships/pages/api/logout.ts b/leaky-ships/pages/api/logout.ts
index c3e03db..98b010c 100644
--- a/leaky-ships/pages/api/logout.ts
+++ b/leaky-ships/pages/api/logout.ts
@@ -9,39 +9,39 @@ import getTokenFromCookie from "../../lib/backend/components/getTokenFromCookie"
import logging, { Logging } from "../../lib/backend/logging"
interface Data {
- loggedOut: boolean
+ loggedOut: boolean
}
export default async function logout(
- req: NextApiRequest,
- res: NextApiResponse
+ req: NextApiRequest,
+ res: NextApiResponse
) {
- return getTokenFromCookie({ req, res })
- .then(checkTokenIsValid)
- .then(getTokenDB)
- .then(logoutResponse)
- .then(sendResponse)
- .catch(err => sendError(req, res, err))
+ return getTokenFromCookie({ req, res })
+ .then(checkTokenIsValid)
+ .then(getTokenDB)
+ .then(logoutResponse)
+ .then(sendResponse)
+ .catch((err) => sendError(req, res, err))
}
async function logoutResponse(payload: {
- tokenDB: Token,
- req: NextApiRequest,
- res: NextApiResponse
+ tokenDB: Token
+ req: NextApiRequest
+ res: NextApiResponse
}) {
- const { tokenDB, req, res } = payload
+ const { tokenDB, req, res } = payload
- // Set login cookie
- deleteCookie('token', { req, res })
+ // Set login cookie
+ deleteCookie("token", { req, res })
- // Successfull response
- return {
- req,
- res,
- result: {
- message: 'User of Token ' + tokenDB.id + ' logged out.',
- body: { loggedOut: true },
- type: ['debug', 'info.cyan'] as Logging[]
- }
- }
-}
\ No newline at end of file
+ // Successfull response
+ return {
+ req,
+ res,
+ result: {
+ message: "User of Token " + tokenDB.id + " logged out.",
+ body: { loggedOut: true },
+ type: ["debug", "info.cyan"] as Logging[],
+ },
+ }
+}
diff --git a/leaky-ships/pages/api/register.ts b/leaky-ships/pages/api/register.ts
index 7895e33..d5e45e9 100644
--- a/leaky-ships/pages/api/register.ts
+++ b/leaky-ships/pages/api/register.ts
@@ -6,36 +6,36 @@ import { Logging } from "../../lib/backend/logging"
import { Player } from "@prisma/client"
interface Data {
- registered: boolean
+ registered: boolean
}
export default async function register(
- req: NextApiRequest,
- res: NextApiResponse
+ req: NextApiRequest,
+ res: NextApiResponse
) {
- const { username, password } = req.body
- return createPlayerDB({ req, res, username, password })
- .then(registerResponse)
- .then(sendResponse)
- .catch(err => sendError(req, res, err))
+ const { username, password } = req.body
+ return createPlayerDB({ req, res, username, password })
+ .then(registerResponse)
+ .then(sendResponse)
+ .catch((err) => sendError(req, res, err))
}
async function registerResponse(payload: {
- player: Player,
- req: NextApiRequest,
- res: NextApiResponse
+ player: Player
+ req: NextApiRequest
+ res: NextApiResponse
}) {
- const { player, req, res } = payload
+ const { player, req, res } = payload
- // Successfull response
- return {
- req,
- res,
- result: {
- message: 'Player created : ' + player.id,
- statusCode: 201,
- body: { registered: true },
- type: ['debug', 'info.cyan'] as Logging[]
- }
- }
-}
\ No newline at end of file
+ // Successfull response
+ return {
+ req,
+ res,
+ result: {
+ message: "Player created : " + player.id,
+ statusCode: 201,
+ body: { registered: true },
+ type: ["debug", "info.cyan"] as Logging[],
+ },
+ }
+}
diff --git a/leaky-ships/pages/api/ws.ts b/leaky-ships/pages/api/ws.ts
index 8b73f7d..f6f5a11 100644
--- a/leaky-ships/pages/api/ws.ts
+++ b/leaky-ships/pages/api/ws.ts
@@ -1,18 +1,18 @@
-import type { NextApiRequest } from 'next'
-import { Server } from 'socket.io'
-import { NextApiResponseWithSocket } from '../../interfaces/NextApiSocket'
+import type { NextApiRequest } from "next"
+import { Server } from "socket.io"
+import { NextApiResponseWithSocket } from "../../interfaces/NextApiSocket"
const SocketHandler = (req: NextApiRequest, res: NextApiResponseWithSocket) => {
if (res.socket.server.io) {
- console.log('Socket is already running ' + req.url)
+ console.log("Socket is already running " + req.url)
} else {
- console.log('Socket is initializing ' + req.url)
+ console.log("Socket is initializing " + req.url)
const io = new Server(res.socket.server)
res.socket.server.io = io
- io.on('connection', socket => {
- socket.on('input-change', msg => {
- socket.broadcast.emit('update-input', msg)
+ io.on("connection", (socket) => {
+ socket.on("input-change", (msg) => {
+ socket.broadcast.emit("update-input", msg)
})
// console.log(socket.id)
// console.log(socket)
@@ -23,10 +23,10 @@ const SocketHandler = (req: NextApiRequest, res: NextApiResponseWithSocket) => {
// ...
})
- socket.emit('test2', 'lol')
+ socket.emit("test2", "lol")
})
}
res.end()
}
-export default SocketHandler
\ No newline at end of file
+export default SocketHandler
diff --git a/leaky-ships/pages/dev/gamefield.tsx b/leaky-ships/pages/dev/gamefield.tsx
index b7abb82..b44a91d 100644
--- a/leaky-ships/pages/dev/gamefield.tsx
+++ b/leaky-ships/pages/dev/gamefield.tsx
@@ -1,5 +1,5 @@
-import Head from 'next/head'
-import Gamefield from '../../components/Gamefield'
+import Head from "next/head"
+import Gamefield from "../../components/Gamefield"
export default function Home() {
return (
diff --git a/leaky-ships/pages/dev/grid.tsx b/leaky-ships/pages/dev/grid.tsx
index b7b52a5..73d3b9f 100644
--- a/leaky-ships/pages/dev/grid.tsx
+++ b/leaky-ships/pages/dev/grid.tsx
@@ -1,5 +1,5 @@
-import Head from 'next/head'
-import Grid from '../../components/Grid'
+import Head from "next/head"
+import Grid from "../../components/Grid"
export default function Home() {
return (
diff --git a/leaky-ships/pages/dev/grid2.tsx b/leaky-ships/pages/dev/grid2.tsx
index 69afcf9..9e1b598 100644
--- a/leaky-ships/pages/dev/grid2.tsx
+++ b/leaky-ships/pages/dev/grid2.tsx
@@ -1,5 +1,5 @@
-import Head from 'next/head'
-import Grid2 from '../../components/Grid2'
+import Head from "next/head"
+import Grid2 from "../../components/Grid2"
export default function Home() {
return (
diff --git a/leaky-ships/pages/dev/index.tsx b/leaky-ships/pages/dev/index.tsx
index b7ff43d..2ee42c0 100644
--- a/leaky-ships/pages/dev/index.tsx
+++ b/leaky-ships/pages/dev/index.tsx
@@ -1,48 +1,52 @@
-import { faPlus, faUserPlus } from '@fortawesome/pro-solid-svg-icons'
-import { faEye, faLeftLong } from '@fortawesome/pro-regular-svg-icons'
-import { faCirclePlay } from '@fortawesome/pro-thin-svg-icons'
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
-import { useState } from 'react'
+import { faPlus, faUserPlus } from "@fortawesome/pro-solid-svg-icons"
+import { faEye, faLeftLong } from "@fortawesome/pro-regular-svg-icons"
+import { faCirclePlay } from "@fortawesome/pro-thin-svg-icons"
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
+import { useState } from "react"
export default function Home() {
- const [heWantsToPlay, setHeWantsToPlay] = useState(false)
- return (
-
-
+ )
}
diff --git a/leaky-ships/pages/dev/socket.tsx b/leaky-ships/pages/dev/socket.tsx
index 7b3d227..31e3be2 100644
--- a/leaky-ships/pages/dev/socket.tsx
+++ b/leaky-ships/pages/dev/socket.tsx
@@ -1,30 +1,30 @@
-import { ChangeEventHandler, useEffect, useState } from 'react'
-import { io } from 'socket.io-client'
+import { ChangeEventHandler, useEffect, useState } from "react"
+import { io } from "socket.io-client"
let socket: ReturnType
const Home = () => {
- const [input, setInput] = useState('')
+ const [input, setInput] = useState("")
useEffect(() => {
socketInitializer()
}, [])
const socketInitializer = async () => {
- await fetch('/api/ws')
+ await fetch("/api/ws")
socket = io()
- socket.on('connect', () => {
- console.log('connected')
+ socket.on("connect", () => {
+ console.log("connected")
})
- socket.on('update-input', msg => {
+ socket.on("update-input", (msg) => {
setInput(msg)
})
}
const onChangeHandler: ChangeEventHandler = (e) => {
setInput(e.target.value)
- socket.emit('input-change', e.target.value)
+ socket.emit("input-change", e.target.value)
}
return (
@@ -36,4 +36,4 @@ const Home = () => {
)
}
-export default Home
\ No newline at end of file
+export default Home
diff --git a/leaky-ships/pages/dev/socketio.tsx b/leaky-ships/pages/dev/socketio.tsx
index 12b7789..ac90b34 100644
--- a/leaky-ships/pages/dev/socketio.tsx
+++ b/leaky-ships/pages/dev/socketio.tsx
@@ -1,4 +1,4 @@
-import SocketIO from '../../components/SocketIO'
+import SocketIO from "../../components/SocketIO"
export default function Home() {
return (
diff --git a/leaky-ships/pages/index.tsx b/leaky-ships/pages/index.tsx
index 2a63814..755105b 100644
--- a/leaky-ships/pages/index.tsx
+++ b/leaky-ships/pages/index.tsx
@@ -1,5 +1,5 @@
-import Head from 'next/head'
-import Link from 'next/link'
+import Head from "next/head"
+import Link from "next/link"
export default function Home() {
return (
@@ -11,12 +11,36 @@ export default function Home() {
- Gamefield
- Homepage
- Grid Effect
- Grid Effect with Content
- Socket
- SocketIO
+
+
+ Gamefield
+
+
+
+
+ Homepage
+
+
+
+
+ Grid Effect
+
+
+
+
+ Grid Effect with Content
+
+
+
+
+ Socket
+
+
+
+
+ SocketIO
+
+
>
)
diff --git a/leaky-ships/styles/App.scss b/leaky-ships/styles/App.scss
index 00b66ac..e162bf7 100644
--- a/leaky-ships/styles/App.scss
+++ b/leaky-ships/styles/App.scss
@@ -1,6 +1,6 @@
-@use './mixins/display' as *;
-@use './mixins/effects' as *;
-@import './mixins/variables';
+@use "./mixins/display" as *;
+@use "./mixins/effects" as *;
+@import "./mixins/variables";
html,
body,
@@ -10,8 +10,8 @@ body,
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
+ "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
}
@@ -69,15 +69,15 @@ body {
display: grid;
align-items: center;
justify-items: center;
- grid-template-rows: .75fr repeat(12, 1fr) .75fr;
- grid-template-columns: .75fr repeat(12, 1fr) .75fr;
+ grid-template-rows: 0.75fr repeat(12, 1fr) 0.75fr;
+ grid-template-columns: 0.75fr repeat(12, 1fr) 0.75fr;
- >.label {
+ > .label {
grid-column: var(--x);
grid-row: var(--y);
}
- >.border-tile {
+ > .border-tile {
box-sizing: border-box;
border: 1px solid blue;
height: 100%;
@@ -96,7 +96,7 @@ body {
box-sizing: border-box;
}
- >span {
+ > span {
vertical-align: center;
user-select: none;
}
@@ -172,7 +172,7 @@ body {
&.preview {
opacity: 0;
- @include transition(.5s);
+ @include transition(0.5s);
}
&.radar {
@@ -184,7 +184,7 @@ body {
&:not(.left):not(.right):not(.top):not(.bottom) {
// border: 5px solid var(--color);
- grid-area: var(--y1) /var(--x1) /var(--y2) /var(--x2);
+ grid-area: var(--y1) / var(--x1) / var(--y2) / var(--x2);
svg {
opacity: 1;
@@ -207,7 +207,7 @@ body {
opacity: 1;
}
- &.imply>svg {
+ &.imply > svg {
opacity: 0;
}
@@ -300,7 +300,7 @@ body {
.item {
@include flex-col;
align-items: center;
- gap: .5rem;
+ gap: 0.5rem;
width: 128px;
.container {
@@ -332,8 +332,8 @@ body {
span {
color: black;
- font-size: .75em;
+ font-size: 0.75em;
font-weight: bold;
}
}
-}
\ No newline at end of file
+}
diff --git a/leaky-ships/styles/globals.css b/leaky-ships/styles/globals.css
index bd6213e..b5c61c9 100644
--- a/leaky-ships/styles/globals.css
+++ b/leaky-ships/styles/globals.css
@@ -1,3 +1,3 @@
@tailwind base;
@tailwind components;
-@tailwind utilities;
\ No newline at end of file
+@tailwind utilities;
diff --git a/leaky-ships/styles/grid.scss b/leaky-ships/styles/grid.scss
index 2177422..461dfac 100644
--- a/leaky-ships/styles/grid.scss
+++ b/leaky-ships/styles/grid.scss
@@ -1,36 +1,34 @@
-@use './mixins/effects' as *;
+@use "./mixins/effects" as *;
#tiles {
- height: 100vh;
- width: 100vw;
- display: grid;
- grid-template-columns: repeat(var(--columns), 1fr);
- grid-template-rows: repeat(var(--rows), 1fr);
+ height: 100vh;
+ width: 100vw;
+ display: grid;
+ grid-template-columns: repeat(var(--columns), 1fr);
+ grid-template-rows: repeat(var(--rows), 1fr);
- .tile {
- background-color: var(--bg-color-1);
+ .tile {
+ background-color: var(--bg-color-1);
- &.active {
- animation: bright .3s forwards;
- animation-delay: var(--delay);
- }
+ &.active {
+ animation: bright 0.3s forwards;
+ animation-delay: var(--delay);
}
+ }
}
@keyframes bright {
- 0% {
- background-color: var(--bg-color-1);
- }
+ 0% {
+ background-color: var(--bg-color-1);
+ }
- 50% {
+ 50% {
+ background-color: var(--bg-color-2);
+ filter: brightness(130%);
+ outline: 1px solid white;
+ }
- background-color: var(--bg-color-2);
- filter: brightness(130%);
- outline: 1px solid white;
- }
-
- 100% {
-
- background-color: var(--bg-color-2);
- }
-}
\ No newline at end of file
+ 100% {
+ background-color: var(--bg-color-2);
+ }
+}
diff --git a/leaky-ships/styles/grid2.scss b/leaky-ships/styles/grid2.scss
index b405784..2909df8 100644
--- a/leaky-ships/styles/grid2.scss
+++ b/leaky-ships/styles/grid2.scss
@@ -1,94 +1,94 @@
-@use './mixins/effects' as *;
+@use "./mixins/effects" as *;
$g1: rgb(98, 0, 234);
$g2: rgb(236, 64, 122);
#tiles {
+ height: 100vh;
+ width: 100vw;
+ display: grid;
+ grid-template-columns: repeat(var(--columns), 1fr);
+ grid-template-rows: repeat(var(--rows), 1fr);
+ background: linear-gradient(to right, $g1, $g2, $g1);
+ background-size: 200%;
+ animation: background-pan 10s linear infinite;
+
+ .tile {
+ position: relative;
+
+ &::before {
+ position: absolute;
+ content: "";
+ background-color: rgb(20, 20, 20);
+ inset: 1px;
+ }
+
+ &.active {
+ opacity: 1;
+ animation: hide 0.2s forwards;
+ animation-delay: var(--delay);
+ }
+
+ &.inactive {
+ opacity: 0;
+ animation: show 0.2s forwards;
+ animation-delay: var(--delay);
+ }
+ }
+
+ .center-div {
+ position: absolute;
height: 100vh;
width: 100vw;
- display: grid;
- grid-template-columns: repeat(var(--columns), 1fr);
- grid-template-rows: repeat(var(--rows), 1fr);
- background: linear-gradient(to right, $g1, $g2, $g1);
- background-size: 200%;
- animation: background-pan 10s linear infinite;
+ display: inherit;
- .tile {
- position: relative;
+ .headline {
+ margin: auto;
+ font-size: 5em;
+ background-color: rgba(20, 20, 20, 0.2);
+ padding: 0.25em 0.5em;
+ border-radius: 0.25em;
- &::before {
- position: absolute;
- content: '';
- background-color: rgb(20, 20, 20);
- inset: 1px;
- }
+ &.active {
+ opacity: 1;
+ animation: hide 2s forwards;
+ // animation-delay: 1s;
+ }
- &.active {
- opacity: 1;
- animation: hide .2s forwards;
- animation-delay: var(--delay);
- }
-
- &.inactive {
- opacity: 0;
- animation: show .2s forwards;
- animation-delay: var(--delay);
- }
- }
-
- .center-div {
- position: absolute;
- height: 100vh;
- width: 100vw;
- display: inherit;
-
- .headline {
- margin: auto;
- font-size: 5em;
- background-color: rgba(20, 20, 20, 0.2);
- padding: .25em .5em;
- border-radius: .25em;
-
- &.active {
- opacity: 1;
- animation: hide 2s forwards;
- // animation-delay: 1s;
- }
-
- &.inactive {
- opacity: 0;
- animation: show 2s forwards;
- // animation-delay: 1s;
- }
- }
+ &.inactive {
+ opacity: 0;
+ animation: show 2s forwards;
+ // animation-delay: 1s;
+ }
}
+ }
}
@keyframes background-pan {
- from {
- background-position: 0% center;
- }
+ from {
+ background-position: 0% center;
+ }
- to {
- background-position: -200% center;
- }
+ to {
+ background-position: -200% center;
+ }
}
@keyframes hide {
- 0% {
- opacity: 1;
- }
+ 0% {
+ opacity: 1;
+ }
- 100% {
- opacity: 0;
- }
+ 100% {
+ opacity: 0;
+ }
}
@keyframes show {
- 0% {
- opacity: 0;
- }
+ 0% {
+ opacity: 0;
+ }
- 100% {
- opacity: 1;
- }
-}
\ No newline at end of file
+ 100% {
+ opacity: 1;
+ }
+}
diff --git a/leaky-ships/styles/homepage.scss b/leaky-ships/styles/homepage.scss
index a84823d..d54cc1d 100644
--- a/leaky-ships/styles/homepage.scss
+++ b/leaky-ships/styles/homepage.scss
@@ -1,338 +1,330 @@
-@use './mixins/display' as *;
-@use './mixins/effects' as *;
-@use './mixins/CP_Font' as *;
-@import './mixins/variables';
+@use "./mixins/display" as *;
+@use "./mixins/effects" as *;
+@use "./mixins/CP_Font" as *;
+@import "./mixins/variables";
-
-@import url('https://fonts.googleapis.com/css2?family=Farro:wght@300;400;500;700&display=swap');
+@import url("https://fonts.googleapis.com/css2?family=Farro:wght@300;400;500;700&display=swap");
#box {
- min-height: 100%;
- background-color: #282c34;
- @include flex-col;
+ min-height: 100%;
+ background-color: #282c34;
+ @include flex-col;
+ align-items: center;
+ justify-content: space-around;
+
+ #navExpand {
+ @include flex;
align-items: center;
- justify-content: space-around;
+ justify-content: center;
+ position: absolute;
+ top: 64px;
+ left: 64px;
+ width: 96px;
+ height: 96px;
+ background-color: $grayish;
+ border-radius: 8px;
+ box-shadow: 0 0 2px 2px #0008 inset;
- #navExpand {
- @include flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- top: 64px;
- left: 64px;
- width: 96px;
- height: 96px;
- background-color: $grayish;
- border-radius: 8px;
- box-shadow: 0 0 2px 2px #0008 inset;
+ #burgerMenu {
+ @include pixelart;
+ height: 84px;
+ width: 84px;
+ }
+ }
- #burgerMenu {
- @include pixelart;
- height: 84px;
- width: 84px;
+ #shield {
+ @include flex-row;
+ justify-content: center;
+ height: 250px;
+ width: 700px;
+ background-image: url("/assets/shield.png");
+ background-repeat: no-repeat;
+ background-size: contain;
+
+ #width {
+ @include flex-col;
+ justify-content: space-between;
+
+ h1 {
+ @include CP_Font;
+ margin: 3%;
+ width: 100%;
+ text-align: center;
+ font-size: 5.8em;
+ letter-spacing: 6px;
+
+ &:first-child {
+ border-top: 5px solid black;
}
+
+ &:last-child {
+ border-bottom: 5px solid black;
+ }
+ }
+ }
+ }
+
+ #videoWrapper {
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 350px;
+ width: 700px;
+ background-color: #2227;
+ border: 4px solid black;
+ border-radius: 8px;
+
+ svg {
+ font-size: 6em;
+ color: #231f20;
+
+ path {
+ stroke: black;
+ stroke-width: 2px;
+ stroke-linejoin: round;
+ }
+ }
+ }
+
+ #startButton {
+ font-family: "Farro", sans-serif;
+ font-weight: bold;
+ font-size: 3em;
+ color: black;
+ background-color: $warn;
+ border: none;
+ border-radius: 8px;
+ padding: calc(2rem + 8px) 6rem 2rem 6rem;
+ }
+
+ #startBox {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background-color: $grayish;
+ box-shadow: 0 0 2px 2px #fffb inset, 0 0 2px 2px #fff2;
+ border: 4px solid black;
+ padding: 3rem;
+ border-radius: 8px;
+ min-width: 60vw;
+ gap: 2rem;
+
+ #back {
+ font-size: 3em;
+ color: $grayish;
+ align-self: flex-start;
+ background-color: #000c;
+ border: none;
+ border-radius: 8px;
+ padding: 0 0.5rem;
+ margin-top: -1.5rem;
+ width: 10rem;
+ box-shadow: 0 0 2px 2px #fff6 inset;
+ border: 2px solid #000c;
}
- #shield {
+ #sameWidth {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 3rem;
+
+ .optionButton {
@include flex-row;
- justify-content: center;
- height: 250px;
- width: 700px;
- background-image: url("/assets/shield.png");
- background-repeat: no-repeat;
- background-size: contain;
-
- #width {
- @include flex-col;
- justify-content: space-between;
-
- h1 {
- @include CP_Font;
- margin: 3%;
- width: 100%;
- text-align: center;
- font-size: 5.8em;
- letter-spacing: 6px;
-
- &:first-child {
- border-top: 5px solid black;
- }
-
- &:last-child {
- border-bottom: 5px solid black;
- }
- }
- }
- }
-
- #videoWrapper {
- position: relative;
- display: flex;
+ justify-content: space-between;
align-items: center;
- justify-content: center;
- height: 350px;
- width: 700px;
- background-color: #2227;
- border: 4px solid black;
- border-radius: 8px;
-
- svg {
- font-size: 6em;
- color: #231f20;
-
- path {
- stroke: black;
- stroke-width: 2px;
- stroke-linejoin: round;
- }
- }
- }
-
- #startButton {
- font-family: 'Farro', sans-serif;
- font-weight: bold;
- font-size: 3em;
- color: black;
- background-color: $warn;
+ font-size: 2.5em;
+ color: $grayish;
+ background-color: #000c;
border: none;
border-radius: 8px;
- padding: calc(2rem + 8px) 6rem 2rem 6rem;
- }
+ padding: 1rem 2rem 1rem 4rem;
+ width: 100%;
+ box-shadow: 0 0 2px 2px #fff6 inset;
+ border: 2px solid #000c;
- #startBox {
- display: flex;
- flex-direction: column;
- align-items: center;
- background-color: $grayish;
- box-shadow: 0 0 2px 2px #fffb inset, 0 0 2px 2px #fff2;
- border: 4px solid black;
- padding: 3rem;
- border-radius: 8px;
- min-width: 60vw;
- gap: 2rem;
-
- #back {
- font-size: 3em;
- color: $grayish;
- align-self: flex-start;
- background-color: #000C;
- border: none;
- border-radius: 8px;
- padding: 0 .5rem;
- margin-top: -1.5rem;
- width: 10rem;
- box-shadow: 0 0 2px 2px #fff6 inset;
- border: 2px solid #000C;
+ &:last-child {
+ margin-top: 2rem;
}
- #sameWidth {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 3rem;
-
- .optionButton {
- @include flex-row;
- justify-content: space-between;
- align-items: center;
- font-size: 2.5em;
- color: $grayish;
- background-color: #000C;
- border: none;
- border-radius: 8px;
- padding: 1rem 2rem 1rem 4rem;
- width: 100%;
- box-shadow: 0 0 2px 2px #fff6 inset;
- border: 2px solid #000C;
-
- &:last-child {
- margin-top: 2rem;
- }
-
- span {
- margin: 0 auto;
- }
-
- svg {
- margin-left: 3rem;
- font-size: 2em;
- width: 2.5rem;
- height: inherit;
- }
- }
-
+ span {
+ margin: 0 auto;
}
+ svg {
+ margin-left: 3rem;
+ font-size: 2em;
+ width: 2.5rem;
+ height: inherit;
+ }
+ }
}
+ }
}
@media (max-width: 2000px) {
- #box {
- #shield {
- height: 200px;
- width: 560px;
+ #box {
+ #shield {
+ height: 200px;
+ width: 560px;
- #width {
+ #width {
+ h1 {
+ font-size: 4.5em;
+ letter-spacing: 4px;
- h1 {
- font-size: 4.5em;
- letter-spacing: 4px;
+ &:first-child {
+ border-top: 4px solid black;
+ }
- &:first-child {
- border-top: 4px solid black;
- }
-
- &:last-child {
- border-bottom: 4px solid black;
- }
- }
- }
+ &:last-child {
+ border-bottom: 4px solid black;
+ }
}
+ }
}
+ }
}
@media (max-width: 1000px) {
- #box {
- #navExpand {
- top: 32px;
- left: 32px;
- width: 80px;
- height: 80px;
+ #box {
+ #navExpand {
+ top: 32px;
+ left: 32px;
+ width: 80px;
+ height: 80px;
- #burgerMenu {
- height: 64px;
- width: 64px;
- }
- }
-
- #shield {
- height: 160px;
- width: 450px;
-
- #width {
-
- h1 {
- font-size: 3.6em;
- letter-spacing: 3px;
-
- &:first-child {
- border-top: 3px solid black;
- }
-
- &:last-child {
- border-bottom: 3px solid black;
- }
- }
- }
- }
-
- #videoWrapper {
- height: 300px;
- width: 600px;
- }
+ #burgerMenu {
+ height: 64px;
+ width: 64px;
+ }
}
+
+ #shield {
+ height: 160px;
+ width: 450px;
+
+ #width {
+ h1 {
+ font-size: 3.6em;
+ letter-spacing: 3px;
+
+ &:first-child {
+ border-top: 3px solid black;
+ }
+
+ &:last-child {
+ border-bottom: 3px solid black;
+ }
+ }
+ }
+ }
+
+ #videoWrapper {
+ height: 300px;
+ width: 600px;
+ }
+ }
}
@media (max-width: 700px) {
- #box {
- justify-content: space-evenly;
+ #box {
+ justify-content: space-evenly;
- #navExpand {
- top: 16px;
- left: 16px;
- width: 64px;
- height: 64px;
+ #navExpand {
+ top: 16px;
+ left: 16px;
+ width: 64px;
+ height: 64px;
- #burgerMenu {
- height: 44px;
- width: 44px;
- }
- }
-
- #shield {
- height: 100px;
- width: 280px;
-
- #width {
-
- h1 {
- font-size: 2.2em;
- letter-spacing: 2px;
-
- &:first-child {
- border-top: 2px solid black;
- }
-
- &:last-child {
- border-bottom: 2px solid black;
- }
- }
- }
- }
-
- #videoWrapper {
- height: 250px;
- width: 450px;
-
- svg {
- font-size: 4em;
- }
- }
-
- #startButton {
- font-size: 2em;
- padding: calc(1rem + 8px) 3rem 1rem 3rem;
- }
-
- #startBox {
- max-width: 90vw;
- padding: 2rem;
-
- #back {
- margin-top: -1rem;
- font-size: 2em;
- width: 7rem;
- padding: .125rem;
- }
-
- #sameWidth {
- max-width: 100%;
-
- .optionButton {
- font-size: 2em;
- padding: 1rem 2rem;
-
- svg {
- margin-left: 2rem;
- font-size: 1.5em;
- width: 2rem;
- }
- }
- }
- }
+ #burgerMenu {
+ height: 44px;
+ width: 44px;
+ }
}
+
+ #shield {
+ height: 100px;
+ width: 280px;
+
+ #width {
+ h1 {
+ font-size: 2.2em;
+ letter-spacing: 2px;
+
+ &:first-child {
+ border-top: 2px solid black;
+ }
+
+ &:last-child {
+ border-bottom: 2px solid black;
+ }
+ }
+ }
+ }
+
+ #videoWrapper {
+ height: 250px;
+ width: 450px;
+
+ svg {
+ font-size: 4em;
+ }
+ }
+
+ #startButton {
+ font-size: 2em;
+ padding: calc(1rem + 8px) 3rem 1rem 3rem;
+ }
+
+ #startBox {
+ max-width: 90vw;
+ padding: 2rem;
+
+ #back {
+ margin-top: -1rem;
+ font-size: 2em;
+ width: 7rem;
+ padding: 0.125rem;
+ }
+
+ #sameWidth {
+ max-width: 100%;
+
+ .optionButton {
+ font-size: 2em;
+ padding: 1rem 2rem;
+
+ svg {
+ margin-left: 2rem;
+ font-size: 1.5em;
+ width: 2rem;
+ }
+ }
+ }
+ }
+ }
}
-
@media (max-width: 500px) {
- #box {
- #videoWrapper {
- height: 150px;
- width: 300px;
- }
-
- #startBox {
- #sameWidth {
-
- .optionButton {
- font-size: 1.5em;
-
- svg {
- margin-left: 1rem;
- font-size: 1em;
- }
- }
- }
- }
+ #box {
+ #videoWrapper {
+ height: 150px;
+ width: 300px;
}
-}
\ No newline at end of file
+
+ #startBox {
+ #sameWidth {
+ .optionButton {
+ font-size: 1.5em;
+
+ svg {
+ margin-left: 1rem;
+ font-size: 1em;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/leaky-ships/styles/mixins/CP_Font.scss b/leaky-ships/styles/mixins/CP_Font.scss
index 02cef59..cefb5a9 100644
--- a/leaky-ships/styles/mixins/CP_Font.scss
+++ b/leaky-ships/styles/mixins/CP_Font.scss
@@ -1,9 +1,8 @@
@font-face {
- font-family: "CP_Font";
- src: url("/fonts/cpfont_ote/CP Font.otf") format("opentype");
+ font-family: "CP_Font";
+ src: url("/fonts/cpfont_ote/CP Font.otf") format("opentype");
}
-
@mixin CP_Font {
- font-family: "CP_Font", sans-serif;
-}
\ No newline at end of file
+ font-family: "CP_Font", sans-serif;
+}
diff --git a/leaky-ships/styles/mixins/display.scss b/leaky-ships/styles/mixins/display.scss
index 6edb39c..9fe7df2 100644
--- a/leaky-ships/styles/mixins/display.scss
+++ b/leaky-ships/styles/mixins/display.scss
@@ -1,11 +1,11 @@
@mixin flex {
- display: flex;
+ display: flex;
}
@mixin flex-col {
- display: flex;
- flex-direction: column;
+ display: flex;
+ flex-direction: column;
}
@mixin flex-row {
- display: flex;
- flex-direction: row;
-}
\ No newline at end of file
+ display: flex;
+ flex-direction: row;
+}
diff --git a/leaky-ships/styles/mixins/effects.scss b/leaky-ships/styles/mixins/effects.scss
index 28598d0..82956ff 100644
--- a/leaky-ships/styles/mixins/effects.scss
+++ b/leaky-ships/styles/mixins/effects.scss
@@ -1,61 +1,157 @@
@mixin transition($timing) {
- -moz-transition: $timing;
- -webkit-transition: $timing;
- -o-transition: $timing;
- -ms-transition: $timing;
- transition: $timing;
+ -moz-transition: $timing;
+ -webkit-transition: $timing;
+ -o-transition: $timing;
+ -ms-transition: $timing;
+ transition: $timing;
}
@mixin appear($timing) {
- animation: appear $timing forwards;
+ animation: appear $timing forwards;
}
@keyframes appear {
- From {
- opacity: 0;
- }
- To {
- opacity: 1;
- }
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
}
@mixin gradient-edge {
- &.left-top-corner {
- mask-image: -webkit-gradient(linear, right bottom, left top, color-stop(0, rgba(0, 0, 0, 1)), color-stop(0.5, rgba(0, 0, 0, 0)));
- -webkit-mask-image: -webkit-gradient(linear, right bottom, left top, color-stop(0, rgba(0, 0, 0, 1)), color-stop(0.5, rgba(0, 0, 0, 0)));
- }
- &.right-top-corner {
- mask-image: -webkit-gradient(linear, left bottom, right top, color-stop(0, rgba(0, 0, 0, 1)), color-stop(0.5, rgba(0, 0, 0, 0)));
- -webkit-mask-image: -webkit-gradient(linear, left bottom, right top, color-stop(0, rgba(0, 0, 0, 1)), color-stop(0.5, rgba(0, 0, 0, 0)));
- }
- &.left-bottom-corner {
- mask-image: -webkit-gradient(linear, right top, left bottom, color-stop(0, rgba(0, 0, 0, 1)), color-stop(0.5, rgba(0, 0, 0, 0)));
- -webkit-mask-image: -webkit-gradient(linear, right top, left bottom, color-stop(0, rgba(0, 0, 0, 1)), color-stop(0.5, rgba(0, 0, 0, 0)));
- }
- &.right-bottom-corner {
- mask-image: -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(0, 0, 0, 1)), color-stop(0.5, rgba(0, 0, 0, 0)));
- -webkit-mask-image: -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(0, 0, 0, 1)), color-stop(0.5, rgba(0, 0, 0, 0)));
- }
+ &.left-top-corner {
+ mask-image: -webkit-gradient(
+ linear,
+ right bottom,
+ left top,
+ color-stop(0, rgba(0, 0, 0, 1)),
+ color-stop(0.5, rgba(0, 0, 0, 0))
+ );
+ -webkit-mask-image: -webkit-gradient(
+ linear,
+ right bottom,
+ left top,
+ color-stop(0, rgba(0, 0, 0, 1)),
+ color-stop(0.5, rgba(0, 0, 0, 0))
+ );
+ }
+ &.right-top-corner {
+ mask-image: -webkit-gradient(
+ linear,
+ left bottom,
+ right top,
+ color-stop(0, rgba(0, 0, 0, 1)),
+ color-stop(0.5, rgba(0, 0, 0, 0))
+ );
+ -webkit-mask-image: -webkit-gradient(
+ linear,
+ left bottom,
+ right top,
+ color-stop(0, rgba(0, 0, 0, 1)),
+ color-stop(0.5, rgba(0, 0, 0, 0))
+ );
+ }
+ &.left-bottom-corner {
+ mask-image: -webkit-gradient(
+ linear,
+ right top,
+ left bottom,
+ color-stop(0, rgba(0, 0, 0, 1)),
+ color-stop(0.5, rgba(0, 0, 0, 0))
+ );
+ -webkit-mask-image: -webkit-gradient(
+ linear,
+ right top,
+ left bottom,
+ color-stop(0, rgba(0, 0, 0, 1)),
+ color-stop(0.5, rgba(0, 0, 0, 0))
+ );
+ }
+ &.right-bottom-corner {
+ mask-image: -webkit-gradient(
+ linear,
+ left top,
+ right bottom,
+ color-stop(0, rgba(0, 0, 0, 1)),
+ color-stop(0.5, rgba(0, 0, 0, 0))
+ );
+ -webkit-mask-image: -webkit-gradient(
+ linear,
+ left top,
+ right bottom,
+ color-stop(0, rgba(0, 0, 0, 1)),
+ color-stop(0.5, rgba(0, 0, 0, 0))
+ );
+ }
- &.left {
- mask-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- -webkit-mask-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- }
- &.right {
- mask-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- -webkit-mask-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- }
- &.top {
- mask-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- -webkit-mask-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- }
- &.bottom {
- mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
- }
+ &.left {
+ mask-image: -webkit-gradient(
+ linear,
+ right top,
+ left top,
+ from(rgba(0, 0, 0, 1)),
+ to(rgba(0, 0, 0, 0))
+ );
+ -webkit-mask-image: -webkit-gradient(
+ linear,
+ right top,
+ left top,
+ from(rgba(0, 0, 0, 1)),
+ to(rgba(0, 0, 0, 0))
+ );
+ }
+ &.right {
+ mask-image: -webkit-gradient(
+ linear,
+ left top,
+ right top,
+ from(rgba(0, 0, 0, 1)),
+ to(rgba(0, 0, 0, 0))
+ );
+ -webkit-mask-image: -webkit-gradient(
+ linear,
+ left top,
+ right top,
+ from(rgba(0, 0, 0, 1)),
+ to(rgba(0, 0, 0, 0))
+ );
+ }
+ &.top {
+ mask-image: -webkit-gradient(
+ linear,
+ left bottom,
+ left top,
+ from(rgba(0, 0, 0, 1)),
+ to(rgba(0, 0, 0, 0))
+ );
+ -webkit-mask-image: -webkit-gradient(
+ linear,
+ left bottom,
+ left top,
+ from(rgba(0, 0, 0, 1)),
+ to(rgba(0, 0, 0, 0))
+ );
+ }
+ &.bottom {
+ mask-image: -webkit-gradient(
+ linear,
+ left top,
+ left bottom,
+ from(rgba(0, 0, 0, 1)),
+ to(rgba(0, 0, 0, 0))
+ );
+ -webkit-mask-image: -webkit-gradient(
+ linear,
+ left top,
+ left bottom,
+ from(rgba(0, 0, 0, 1)),
+ to(rgba(0, 0, 0, 0))
+ );
+ }
}
// Pixelart sharpness (no interpolation)
// https://css-tricks.com/keep-pixelated-images-pixelated-as-they-scale/
@mixin pixelart {
- image-rendering: pixelated;
- image-rendering: -moz-crisp-edges;
- image-rendering: crisp-edges;
-}
\ No newline at end of file
+ image-rendering: pixelated;
+ image-rendering: -moz-crisp-edges;
+ image-rendering: crisp-edges;
+}
diff --git a/leaky-ships/styles/mixins/variables.scss b/leaky-ships/styles/mixins/variables.scss
index a29f8c6..e8d7033 100644
--- a/leaky-ships/styles/mixins/variables.scss
+++ b/leaky-ships/styles/mixins/variables.scss
@@ -1,3 +1,3 @@
$theme: #282c34;
-$grayish: #B1B2B5CC;
-$warn: #fabd04;
\ No newline at end of file
+$grayish: #b1b2b5cc;
+$warn: #fabd04;
diff --git a/leaky-ships/tailwind.config.js b/leaky-ships/tailwind.config.js
index 812b8ed..f8ecd2c 100644
--- a/leaky-ships/tailwind.config.js
+++ b/leaky-ships/tailwind.config.js
@@ -8,4 +8,4 @@ module.exports = {
extend: {},
},
plugins: [],
-}
\ No newline at end of file
+}