Compare commits

...

10 commits

Author SHA1 Message Date
KGrzeg
b6f81f94f4 docker-compose 2023-03-03 16:18:46 +01:00
KGrzeg
cd50ab17b3 Random secret when run, not when build 2023-03-03 16:06:16 +01:00
KGrzeg
697836579b Upload docker image, update instructions 2023-03-01 05:13:09 +01:00
KGrzeg
e1c46e7ba0 Smaller docker image 2023-03-01 04:50:49 +01:00
KGrzeg
90d2257c17 Dockify app 2023-03-01 04:31:25 +01:00
KGrzeg
1c9de06b66 RIP my english 2023-03-01 03:40:28 +01:00
KGrzeg
94e85e04d5 Optionally server static files 2023-03-01 03:36:49 +01:00
KGrzeg
000b62fd40 Broken regex in newer Node 2023-03-01 03:36:30 +01:00
KGrzeg
23dc908344 Set API path as env var 2023-03-01 03:36:09 +01:00
KGrzeg
89e2f52063 Readme update 2021-10-18 04:40:07 +02:00
17 changed files with 181 additions and 162 deletions

6
.dockerignore Normal file
View file

@ -0,0 +1,6 @@
**/node_modules
**/.cache
**/.DS_Store
**/storage
**/dist
**/.env

33
Dockerfile Normal file
View file

@ -0,0 +1,33 @@
FROM node:18-alpine
RUN apk add g++ make py3-pip
RUN mkdir -p /usr/app
WORKDIR /usr/app
ENV API_PATH="/api"
COPY game/package*.json ./
RUN npm install --quite
COPY game .
RUN npm run build
FROM node:18-alpine
RUN mkdir -p /usr/app/public
WORKDIR /usr/app
ENV STATIC="/usr/app/public"
ENV PORT=80
EXPOSE 80/tcp
COPY --from=0 /usr/app/dist ./public
COPY server/package*.json ./
RUN npm install --quite
COPY server .
COPY ./run.sh .
CMD ./run.sh

View file

@ -2,9 +2,67 @@
Tested on node `v14.17.3`
You can play the game [here](#)
You can play the game [here](https://mystifying-hypatia-4b1cef.netlify.app/) (unfortunelly I can not setup server, so this instance does not provide a ranking 😥).
Please be patient waiting for the game to load. My crappy, free hosting need some time to load assets.
In the `game` directory there game client.
In the `server` directory there are authentiaction and ranking server.
The game was created for the first edition of [Hackerspace Trójmiasto's Community](https://github.com/hs3city/hs3-jam) Jam.
To start the app locally, you need... *TODO* :)
![Screenshot](ss.jpg)
## How to start a game
You need the [NodeJS](https://nodejs.org/en/) installed.
~~The game's server do not serve game client's files. They are separately apps.~~
The server is responsible for authentication and storing records.
Data is stored as plain JSON files in `server/storage` directory.
You do not have to setup any external database :)
The game *should* work without server, with some limitations.
Space Smasher works fine on desktop, and not on mobile at all.
Keys: `WSAD + Mouse`
## Use Docker
### LETS GO
```sh
# run as a daemon
🐧 docker run -d -p 80:80 --restart=always --name smasher ghcr.io/kgrzeg/space-smasher-9001:latest
# or run in foreground
🐧 docker run -ti -p 80:80 --rm --name smasher ghcr.io/kgrzeg/space-smasher-9001:latest
```
### Build image locally
```sh
🐧 docker build -t space-smasher-9001:latest .
# run as a daemon
🐧 docker run -d -p 80:80 --restart=always --name smasher space-smasher-9001
# or run in foreground
🐧 docker run -ti -p 80:80 --rm --name smasher space-smasher-9001
```
## Setup for development
### run server
```sh
🐧 cd server
🐧 npm install # install dependencies
🐧 cp .env.example .env
🐧 # edit .env file - UPDATE THE SECRET!
🐧 npm start # the server listening on port 3000.
```
### Setup and run client
```sh
🐧 cd .. # only if your cwd is server directory
🐧 cd game
🐧 npm install # install dependencies
🐧 # edit first line of src/api.ts to match your server
🐧 npm start # to run in Dev mode (hot reloading and recompilling)
🐧 npm run build
🐧 # your app is in dist directory, you need to serve it via www server
```
The most knowledge you can get by reading the sources or dockerfile. I will fill the readme one day... maybe.
## Enjoy!

10
docker-compose.yml Normal file
View file

@ -0,0 +1,10 @@
version: '3'
services:
smasher:
image: ghcr.io/kgrzeg/space-smasher-9001:latest
# build: .
container_name: space-smasher-9001
ports:
- "80:80"
restart: always

5
game/README.md Normal file
View file

@ -0,0 +1,5 @@
# Start Game Client
For more info look at main README.md
I used [phaser3-typescript-parcel-template](https://github.com/ourcade/phaser3-typescript-parcel-template) as startup project (but typescript config was messed up)

13
game/package-lock.json generated
View file

@ -12,6 +12,7 @@
"phaser": "^3.55.2"
},
"devDependencies": {
"@types/node": "^18.14.2",
"@typescript-eslint/eslint-plugin": "^2.29.0",
"@typescript-eslint/parser": "^2.29.0",
"eslint": "^6.8.0",
@ -1790,6 +1791,12 @@
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
"dev": true
},
"node_modules/@types/node": {
"version": "18.14.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz",
"integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==",
"dev": true
},
"node_modules/@types/q": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
@ -11286,6 +11293,12 @@
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
"dev": true
},
"@types/node": {
"version": "18.14.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz",
"integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==",
"dev": true
},
"@types/q": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",

View file

@ -4,9 +4,7 @@
"description": "Simple Phaser 3 game for the Hackerspace Trójmiasto's little game jam",
"scripts": {
"start": "parcel src/index.html -p 8000",
"build": "parcel build src/index.html --out-dir dist --no-source-maps",
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint ./src --ext .js,.jsx,.ts,.tsx"
"build": "parcel build src/index.html --out-dir dist --no-source-maps"
},
"author": "Grzegorz Kupczyk",
"license": "MIT",
@ -16,6 +14,7 @@
},
"homepage": "https://github.com/ourcade/phaser3-parcel-template",
"devDependencies": {
"@types/node": "^18.14.2",
"@typescript-eslint/eslint-plugin": "^2.29.0",
"@typescript-eslint/parser": "^2.29.0",
"eslint": "^6.8.0",

View file

@ -1,138 +0,0 @@
This is a fork of [phaser3-typescript-parcel-template](https://github.com/ourcade/phaser3-typescript-parcel-template)
![phaser3-parceljs-template](https://user-images.githubusercontent.com/2236153/71606463-37a0da80-2b2e-11ea-9b5f-5d26ccc84f91.png)
# Phaser 3 + TypeScript + Parcel Template
> For people who want to spend time making Phaser 3 games in TypeScript instead of configuring build tools.
![License](https://img.shields.io/badge/license-MIT-green)
This is a TypeScript specific fork of [phaser3-parcel-template](https://github.com/ourcade/phaser3-parcel-template).
## Prerequisites
You'll need [Node.js](https://nodejs.org/en/), [npm](https://www.npmjs.com/), and [Parcel](https://parceljs.org/) installed.
It is highly recommended to use [Node Version Manager](https://github.com/nvm-sh/nvm) (nvm) to install Node.js and npm.
For Windows users there is [Node Version Manager for Windows](https://github.com/coreybutler/nvm-windows).
Install Node.js and `npm` with `nvm`:
```bash
nvm install node
nvm use node
```
Replace 'node' with 'latest' for `nvm-windows`.
Then install Parcel:
```bash
npm install -g parcel-bundler
```
## Getting Started
Clone this repository to your local machine:
```bash
git clone https://github.com/ourcade/phaser3-typescript-parcel-template.git
```
This will create a folder named `phaser3-typescript-parcel-template`. You can specify a different folder name like this:
```bash
git clone https://github.com/ourcade/phaser3-typescript-parcel-template.git my-folder-name
```
Go into your new project folder and install dependencies:
```bash
cd phaser3-typescript-parcel-template # or 'my-folder-name'
npm install
```
Start development server:
```
npm run start
```
To create a production build:
```
npm run build
```
Production files will be placed in the `dist` folder. Then upload those files to a web server. 🎉
## Project Structure
```
.
├── dist
├── node_modules
├── public
├── src
│ ├── scenes
│ │ ├── HelloWorldScene.ts
│ ├── index.html
│ ├── main.ts
├── package.json
```
The contents of this template is the basic [Phaser 3 getting started example](http://phaser.io/tutorials/getting-started-phaser3/part5).
This template assumes you will want to organize your code into multiple files and use TypeScript.
TypeScript files are intended for the `src` folder. `main.ts` is the entry point referenced by `index.html`.
Other than that there is no opinion on how you should structure your project. There is a `scenes` folder in `src` where the `HelloWorldScene.ts` lives but you can do whatever you want.
## Static Assets
Any static assets like images or audio files should be placed in the `public` folder. It'll then be served at http://localhost:8000/images/my-image.png
Example `public` structure:
```
public
├── images
│ ├── my-image.png
├── music
│ ├── ...
├── sfx
│ ├── ...
```
They can then be loaded by Phaser with `this.image.load('my-image', 'images/my-image.png')`.
## TypeScript ESLint
This template uses a basic `typescript-eslint` set up for code linting.
It does not aim to be opinionated.
## Dev Server Port
You can change the dev server's port number by modifying the `start` script in `package.json`. We use Parcel's `-p` option to specify the port number.
The script looks like this:
```
parcel src/index.html -p 8000
```
Change 8000 to whatever you want.
## Other Notes
[parcel-plugin-clean-easy](https://github.com/lifuzhao100/parcel-plugin-clean-easy) is used to ensure only the latest files are in the `dist` folder. You can modify this behavior by changing `parcelCleanPaths` in `package.json`.
[parcel-plugin-static-files](https://github.com/elwin013/parcel-plugin-static-files-copy#readme) is used to copy static files from `public` into the output directory and serve it. You can add additional paths by modifying `staticFiles` in `package.json`.
## License
[MIT License](https://github.com/ourcade/phaser3-typescript-parcel-template/blob/master/LICENSE)

View file

@ -1,4 +1,4 @@
const baseApiPath = "http://localhost:3000"
const baseApiPath = process.env.API_PATH ?? "http://localhost:3000"
export default {
async post(path: string, data?: any) {

View file

@ -140,8 +140,8 @@ declare global {
function logout() {
const sure = confirm("Are you sure you want to log out? " +
"You won't be able to login again without #key. " +
"Make sure you copied #key before log out!\n\n" +
"You won't be able to login again without the #key. " +
"Make sure you have copied the #key before log out!\n\n" +
"The #key: " + window.myStuff.key)
if (!sure)

11
run.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/sh
mkdir -p storage
if [ ! -f ".env" ]; then
cp .env.example .env
sed -i "s#HVuwh1dmaFhg4q1fef7xI4D6UeV7ImGK6NTp7i9eH6qiyJ9kxsvqPu29JXnhNGQY#$(head -c 12 /dev/random | base64)#" .env
fi
npm run start

View file

@ -1,2 +1,3 @@
secret = oIMzR4YvM9x9NoPrQfk4
secret = HVuwh1dmaFhg4q1fef7xI4D6UeV7ImGK6NTp7i9eH6qiyJ9kxsvqPu29JXnhNGQY
enableJusticeGuard = 1
PORT = 3001

View file

@ -9,7 +9,7 @@ export default {
error: "Incorrect name"
}
const re = /^[a-zA-z0-9_$][a-zA-z0-9 _$]{,15}$/
const re = /^[a-zA-Z0-9_$][a-zA-Z0-9 _$]{1,15}$/
if (!re.test(name))
return {
error: "Incorrect name"

5
server/README.md Normal file
View file

@ -0,0 +1,5 @@
# Start Game Server
For more info look at main README.md
I used [phaser3-typescript-parcel-template](https://github.com/ourcade/phaser3-typescript-parcel-template) as startup project (but typescript config was messed up)

View file

@ -4,7 +4,8 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon --ignore ./storage/ --exec babel-node server.js"
"dedv": "nodemon --ignore ./storage/ --exec babel-node server.js",
"start": "babel-node server.js"
},
"type": "module",
"keywords": [],

View file

@ -9,6 +9,8 @@ import auth from './Auth.js'
import db from './Database.js'
import jg from './JusticeGuard.js'
const router = express.Router();
const protect = (req, res, next) => {
const authHeader = req.headers.authorization;
@ -42,19 +44,21 @@ const neededArguments = (args) => {
const app = express()
app.use(morgan('combined'))
app.use(express.json())
app.use(cors())
app.get("/", (_, res) => {
router.use(express.json())
router.get("/", (_, res) => {
res.json({ message: "Hello! API here" })
});
app.get("/secured", protect, (req, res) => {
router.get("/secured", protect, (req, res) => {
res.json({ message: "You can see it!", payload: req.user })
})
app.post("/signup", neededArguments(['name']), async (req, res) => {
router.post("/signup", neededArguments(['name']), async (req, res) => {
const user = await auth.createAccount(req.body.name)
if (user.error)
@ -65,7 +69,7 @@ app.post("/signup", neededArguments(['name']), async (req, res) => {
res.json(user)
})
app.post("/login", neededArguments(['key']), async (req, res) => {
router.post("/login", neededArguments(['key']), async (req, res) => {
const user = auth.login(req.body.key)
if (user.error)
@ -76,7 +80,7 @@ app.post("/login", neededArguments(['key']), async (req, res) => {
res.json(user)
})
app.post("/record", protect, neededArguments(['points', 'shoots', 'time']), jg, async (req, res) => {
router.post("/record", protect, neededArguments(['points', 'shoots', 'time']), jg, async (req, res) => {
db.updateRecord(req.user.name, req.body.points)
const rank = db.getRank(req.user.name)
@ -88,14 +92,14 @@ app.post("/record", protect, neededArguments(['points', 'shoots', 'time']), jg,
})
})
app.get("/top", (req, res) => {
router.get("/top", (req, res) => {
res.json({
status: "ok",
records: db.getTop()
})
})
app.get("/start", protect, async (req, res) => {
router.get("/start", protect, async (req, res) => {
await db.setLastPlayedToNow(req.user.name)
res.json({
@ -103,11 +107,22 @@ app.get("/start", protect, async (req, res) => {
})
})
if (process.env.STATIC) {
app.use(express.static(process.env.STATIC));
app.use("/api", router);
} else {
app.use("/", router);
}
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401).send('invalid token...');
}
});
await db.read()
app.listen(3000)
(async function () { await db.read() })()
const port = process.env.PORT || 3000
app.listen(port, () => {
console.log(`Server listening on port ${port}!`);
})

BIN
ss.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB