Skip to content
Snippets Groups Projects
Commit 5f894c03 authored by atm2g19's avatar atm2g19
Browse files

Initial commit.

adding all current work
parents
No related branches found
No related tags found
No related merge requests found
Showing with 644 additions and 0 deletions
dbconf.json
dst/
node_modules/
log/
\ No newline at end of file
This diff is collapsed.
{
"name": "web-games",
"version": "1.0.0",
"description": "node-based backend and frontend for web-games",
"main": "server.js",
"scripts": {
"run": "export PORT=80; node server.js",
"test": "export PORT=8080; export DEBUG=1; node server.js"
},
"author": "Alex Mansfield",
"license": "ISC",
"dependencies": {
"@types/express": "^4.17.3",
"@types/mysql": "^2.15.9",
"@types/node": "^13.9.8",
"@types/socket.io": "^2.1.4",
"express": "^4.17.1",
"mysql": "^2.18.1",
"path": "^0.12.7",
"socket.io": "^2.3.0",
"ts": "^0.2.2"
},
"devDependencies": {
"typescript": "^3.8.3"
}
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>
Error 404
</h1><br>
<p>
oops
</p><br>
<h3>
Page not found!
</h3><br>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>
Error 500
</h1><br>
<p>
oops
</p><br>
<h3>
Server error!
</h3><br>
</body>
</html>
\ No newline at end of file
let socket;
function setup(){
socket = io.connect("http://localhost:8080");
}
function draw(){
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script>
<script src="./battleships.js"></script>
</head>
<body>
<h1>
Battleships game
</h1>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>
Game listing
</h1>
<p>
<li>
<a href="./cah/">
Cards against humanity
</a>
</li>
<li>
<a href="./battleships/">
Battleships
</a>
</li>
</p>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>
Test web-server
</h1>
</body>
</html>
\ No newline at end of file
dst/server.js
\ No newline at end of file
import * as express from "express";
function Auth(req : express.Request, res : express.Response, next : express.NextFunction){
next();
}
import * as express from "express"
import {debug} from "./debug";
function AutoRedirect(req : express.Request, res : express.Response, next : express.NextFunction){
//get last character of req string.
let lastchar : string = req.path.substr(req.path.length-1, 1);
debug(`Last character: '${lastchar}' : ${req.path}`);
if(lastchar == '/'){
res.redirect(req.path + "index.html");
res.end();
// }else if(req.path.lastIndexOf('.') < req.path.lastIndexOf('/')){
// res.redirect(req.path + ".html");
// res.end();
}else
next();
}
export {AutoRedirect};
\ No newline at end of file
const DEBUG : boolean = process.env.DEBUG ? true : false;
function debug(input: any){
if(!DEBUG) return;
console.log("DEBUG: ");
console.log(input);
}
export {debug};
\ No newline at end of file
import * as express from "express";
import { sendFile } from "./sendFile";
// import * as fs from "fs";
function _404(req : express.Request, res : express.Response, next : express.NextFunction){
res.status(404);
if(req.path.substr(req.path.lastIndexOf('.')) != ".html"){
res.end();
}else{
sendFile("public/errors/404.html", req, res, next);
// next();
}
}
function error(err : any, req : express.Request, res : express.Response, next : express.NextFunction){
if(typeof(err) == 'string'){
res.status(parseInt(err));
}else if(typeof(err) == 'number'){
res.status(err);
}
sendFile(`public/errors/${err}.html`, req, res, next);
// next();
}
function handled_error(err : express.Errback, req : express.Request, res : express.Response, next : express.NextFunction){
res.status(500);
sendFile(`public/errors/500.html`, req, res, next);
// next();
}
function unhandled_error(err : express.Errback, req : express.Request, res : express.Response, next : express.NextFunction){
res.status(500);
res.send("Serious unexpected server issue. This will be resolved as soon as possible. please bear with.");
res.end();
}
export {_404, error, handled_error, unhandled_error};
\ No newline at end of file
import * as mysql from "mysql";
interface DB {
};
export interface QueryResults {
err? : mysql.MysqlError;
results? : any;
fields? : mysql.FieldInfo[];
}
export class GameDB{
pool : mysql.Pool;
constructor(config : mysql.ConnectionConfig){
this.pool = mysql.createPool(config).on("connection", (con) => {
console.log("mysql DB connected!");
});
}
query(sql : string, values? : any) : Promise<QueryResults>{
return new Promise((resolve, reject) => {
this.pool.query(sql, values, (err : mysql.MysqlError, results : any[], fields : mysql.FieldInfo[]) => {
resolve({err, results, fields} as QueryResults);
})
})
}
}
\ No newline at end of file
import * as express from "express";
import * as mysql from "mysql";
import * as io from "socket.io";
import { Server } from "http";
import { debug } from "./debug";
import { Game, GameConstructor } from "./games/game";
import { resolve } from "dns";
import { GameDB } from "./gamedb";
const DB = {
active_games : {
table : "active_games",
active_game_id : {
column : "active_games.active_game_id",
},
active_game_type_id : {
column : "active_games.active_game_type_id",
},
active_game_idle : {
column : "active_games.active_game_idle",
}
},
game_data : {
table : "game_data",
game_id : {
column : "game_data.game_id",
},
data_key : {
column : "game_data.data_key",
},
data_value : {
column : "game_data.data_value",
}
},
games : {
table : "games",
game_id : {
column : "games.game_id",
},
game_name : {
column : "games.game_name",
}
}
}
const MYSQL_CONFIG : mysql.ConnectionConfig = {
host : "localhost",
user : "web-games",
password : "web-games-password",
database : "web_games_db"
}
const Games : GameDB = new GameDB(MYSQL_CONFIG);
// POOL.getConnection((err) => {
// if(err){
// console.log("NOT connected to sql server");
// }else{
// console.log("Connected to sql server");
// }
// });
let socket;
function joinGame(socket : io.Socket, args : any){
console.log(`Join game request : ${args}`);
//check game id exists
Games.query(`SELECT active_games.active_game_id, active_games.active_game_type_id, active_games.active_game_idle, game_data.data_value FROM active_games, game_data WHERE active_game_id = ? AND game_data.data_key = 0;`, [args.id])
.then(res => {
if(res.err){
console.log(res.err);
return;
}
console.log(res.results);
if(res.results.length == 0){
socket.disconnect(true);
}
});
}
function API(req : express.Request, res : express.Response, next : express.NextFunction){
if(!/^\/games\/api\/.+/.test(req.path)) {
next();
return;
}
console.log(req.path);
let paths : string[] = req.path.split('/');
paths = paths.slice(paths.lastIndexOf("api")+1);
console.log(paths);
switch(paths[0]){
case "list":
listGames(paths[1], res, next);
return;
break;
case "create":
createGame(paths[1], req, res, next);
return;
break;
default:
break;
}
next();
}
function game_api(app : Server){
socket = io(app);
socket.sockets.on("connection", (socket : io.Socket) => {
console.log(`New connection : ${socket.id}`);
socket.on("join", (data : any) => joinGame(socket, data));
socket.on("disconnect", (args) => {
console.log(`Socket disconnected : ${socket.id}`);
});
});
return {API};
}
function listGames(game : string, response : express.Response, next : express.NextFunction){
//get all active games by game name/id
console.log(`Listing games for : ${game}`);
let query : string
if(/^[0-9]+$/.test(game)){
query = `SELECT ${DB.active_games.active_game_id.column},${DB.game_data.data_value.column} FROM ${DB.active_games.table}, ${DB.game_data.table}, ${DB.games.table} WHERE ${DB.games.game_id.column} = ${game} AND ${DB.active_games.active_game_id.column} = ${DB.game_data.game_id.column};`
}else{
query = `SELECT ${DB.active_games.active_game_id.column},${DB.game_data.data_value.column} FROM ${DB.active_games.table}, ${DB.game_data.table}, ${DB.games.table} WHERE ${DB.games.game_name.column} = ${mysql.escape(game)} AND ${DB.active_games.active_game_id.column} = ${DB.game_data.game_id.column};`
}
Games.query(query)
.then(results => {
if(results.err){
console.log(results.err);
next();
return;
}
// console.log(res);
// console.log(fields);
let data = [];
for(let key in results.results){
let row = results.results[key];
let data_value = JSON.parse(row.data_value);
data_value.id = row.active_game_id;
debug(data_value);
data.push(data_value);
// data[row.active_game_id] = data_value;
}
// console.log(JSON.parse(res));
response.type('application/json');
response.send(data);
response.end();
}).catch(next)
// next();
}
let loadedGames : Game[] = [];
function createGame(game : string ,req : express.Request, res : express.Response, next : express.NextFunction){
if(req.method != "POST") {
next();
return;
}
let query : string
if(/^[0-9]+$/.test(game)){
query = `SELECT ${DB.games.game_id.column}, ${DB.games.game_name.column} FROM ${DB.games.table} WHERE ${DB.games.game_id.column} = ${game};`;
}else{
query = `SELECT ${DB.games.game_id.column}, ${DB.games.game_name.column} FROM ${DB.games.table} WHERE ${DB.games.game_name.column} = ${mysql.escape(game)};`;
}
// let query_cb : mysql.queryCallback = (err : mysql.MysqlError, results : any, fields : mysql.FieldInfo[]) => {
// //got game name and ID, now create new game from that info
// let game_id : number = results[0].game_id;
// let game_name : string = results[0].game_name;
// let game_prom : Promise<Game>;
// if(!loadedGames[game_id]){
// game_prom = new Promise((resolve, reject) => {
// let import_prom : Promise<any>;
// import_prom = import(`./games/${game_name}`)
// .then((_game : any) => {
// let game : Game = _game.game;
// loadedGames[game_id] = game;
// console.log(game);
// game.init(Games);
// resolve(loadedGames[game_id]);
// }).catch(reject);
// })
// }else{
// game_prom = new Promise((resolve, reject) => {
// resolve(loadedGames[game_id]);
// })
// }
// game_prom.then((game : Game) => {
// debug(`Creating game by Alex. CHANGE`);
// game.create("Alex").then(active_game_id => {
// res.send(`Created new ${game_name} game by ${"Alex"} with id ${active_game_id}`);
// res.end();
// });
// }).catch(err => {
// //game does not exist
// console.log(`Game ${game_name}:${game_id} does not exist!`);
// next(500);
// });
// };
Games.query(query)
.then(results => {
let game_id : number = results.results[0].game_id;
let game_name : string = results.results[0].game_name;
let game_prom : Promise<Game>;
if(!loadedGames[game_id]){
game_prom = new Promise((resolve, reject) => {
let import_prom : Promise<any>;
import_prom = import(`./games/${game_name}`)
.then((_game : any) => {
let game : GameConstructor = _game.game;
loadedGames[game_id] = new game(Games);
console.log(loadedGames[game_id]);
// game.init(Games);
resolve(loadedGames[game_id]);
}).catch(reject);
})
}else{
game_prom = new Promise(resolve => {
resolve(loadedGames[game_id]);
})
}
game_prom.then((game : Game) => {
debug(`Creating game by Alex. CHANGE`);
game.create("Alex").then(active_game_id => {
res.send(`Created new ${game_name} game by ${"Alex"} with id ${active_game_id}`);
res.end();
});
}).catch(err => {
//game does not exist
console.log(`Game ${game_name}:${game_id} does not exist!`);
next(500);
});
}).catch(next)
}
export {game_api};
\ No newline at end of file
import {Game, GameInitFunction, GameCreateFunction, GameDestroyFunction, GameConstructor} from "./game";
import { debug } from "../debug";
import { GameDB } from "../gamedb";
import { rejects } from "assert";
const battleships : GameConstructor = class battleships implements Game{
public id : number = 1;
public name : string = "battleships";
protected db : GameDB;
constructor(db_server : GameDB){
this.db = db_server;
}
// init(){}
create(creator : string, password? : string) : Promise<number>{
debug(`Battleships creating game by ${creator}`);
return new Promise<number>((resolve, reject) => {
this.db.query(`INSERT INTO active_games(active_game_type_id, active_game_idle) VALUES (${this.id}, now());`) //
.then(results => {
console.log(results.results);
resolve(results.results.insertId || -1);
let json_data : any = {name: "Alex's battleships V2", players : []};
if(password){
json_data.password = password;
}
return this.db.query(`INSERT INTO game_data(game_id, data_key, data_value) VALUES (${results.results.insertId}, 0, ?);`, JSON.stringify(json_data));
})
.then(results => {
console.log(results);
}).catch(err => {
console.log(err);
reject(err);
});
})
}
destroy(){
}
}
export {battleships as game};
\ No newline at end of file
import * as mysql from "mysql"
import { GameDB } from "../gamedb";
export type GameInitFunction = (db_server : GameDB) => void;
export type GameCreateFunction = (creator : string, password? : string) => Promise<number>;
export type GameDestroyFunction = (game_id : number) => void;
export interface GameConstructor {
new (db_server : GameDB) : Game;
}
export interface Game{
create : GameCreateFunction;
destroy : GameDestroyFunction;
name : string;
id : number;
[key : string] : any;
}
\ No newline at end of file
import * as express from "express";
import * as fs from "fs";
function Log(req : express.Request, res : express.Response, next : express.NextFunction){
let log_data = `${req.method} : ${req.ip} : ${req.path}`
console.log(log_data);
let timestr : string = new Date(Date.now()).toString();
let path : string = `log/${timestr.substr(0, 18).replace(' ', '_')}`
fs.appendFile(path, timestr.substr(16, 9) + log_data + '\n', ()=>{});
next();
}
export {Log};
\ No newline at end of file
import * as express from "express";
import * as fs from "fs";
function staticServe(root : string){
return function (req : express.Request, res : express.Response, next : express.NextFunction){
let fullpath = root+req.path;
sendFile(fullpath, req, res, next);
}
}
function sendFile(path : string, req : express.Request, res : express.Response, next : express.NextFunction){
fs.exists(path, (exists : boolean) => {
if(!exists){
next(404);
return;
}
let rs = fs.createReadStream(path);
res.type(path.substr(path.lastIndexOf(".")));
rs.on("data", (data : Buffer) => {
res.write(data);
});
rs.on("end", () => {
res.end();
rs.close();
});
})
}
export {sendFile, staticServe};
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment