SotM_Playfield/server.js

203 lines
5.2 KiB
JavaScript
Raw Normal View History

// jshint node:true
// jshint esversion:6
"use strict";
const http = require('http'),
fs = require('fs'),
path = require('path'),
url = require('url'),
phantom = require('phantom'),
port = 8080;
const server = http.createServer((req, res) => {
const uri = url.parse(req.url);
2017-09-20 18:10:37 -04:00
let pathParts = uri.pathname.split("/");
switch (pathParts[1]) {
case '':
case 'index.html':
sendIndex(res);
break;
case 'style.css':
sendFile(res, 'style.css', 'text/css');
break;
case 'js':
2017-09-28 12:58:28 -04:00
switch (pathParts[2]) {
case 'playfield.js':
sendFile(res, 'js/playfield.js', 'application/javascript');
break;
case 'editor.js':
sendFile(res, 'js/editor.js', 'application/javascript');
break;
case 'interact.js':
sendFile(res, 'interact.js', 'application/javascript');
break;
default:
send404(res, uri);
}
2017-09-20 18:10:37 -04:00
break;
case 'template':
pathParts.splice(0, 2); // remove first two elements
let item = pathParts.join("/");
console.log("template/" + item);
switch (item) {
case "card.json":
case "deck.json":
sendFile(res, "template/" + item, 'application/json');
break;
case "environment/card.svg":
case "hero/card.svg":
case "hero/charBack.svg":
case "hero/charFront.svg":
case "villain/card.svg":
case "villain/character.svg":
case "villain/instructions.svg":
sendFile(res, "template/" + item, 'image/svg+xml');
break;
default:
send404(res, uri);
}
break;
2017-09-20 18:10:37 -04:00
case 'deck':
if (pathParts.length === 3) {
2017-10-01 00:30:07 -04:00
let deckName = decodeURI(pathParts[2]);
2017-09-20 18:10:37 -04:00
sendDeckIndex(res, deckName);
}
else if (pathParts.length === 4) {
2017-10-01 00:30:07 -04:00
let deckName = decodeURI(pathParts[2]);
2017-09-20 18:10:37 -04:00
switch (pathParts[3]) {
case 'play':
sendFile(res, 'html/playfield.html');
2017-09-20 18:10:37 -04:00
break;
case 'editor':
sendFile(res, 'html/editor.html');
break;
2017-09-20 18:10:37 -04:00
case 'deck.png':
sendFile(res, deckName + '.png', 'image/png');
break;
case 'deck.json':
sendFileJSON(res, deckName);
break;
case 'upload':
handleUpload(res, req, deckName);
2017-09-20 18:10:37 -04:00
break;
default:
send404(res, uri);
}
}
2017-09-20 18:10:37 -04:00
break;
default:
send404(res, uri);
}
});
server.listen(process.env.PORT || port);
console.log('listening on 8080');
function sendIndex(res) {
let decks = ["the_Unholy_Priest_update_2", "NZoths_Invasion_1.1"];
2017-09-28 12:58:28 -04:00
const html = `
2017-09-20 18:10:37 -04:00
<html>
<head>
<link rel="stylesheet" type="text/css" href="/style.css">
2017-09-28 14:01:22 -04:00
<title>Index</title>
2017-09-20 18:10:37 -04:00
</head>
<body>
<ul>
${(decks.map(d => `<li><a href="deck/${d}">${d}</a></li>`).join(' '))}
2017-09-20 18:10:37 -04:00
</ul>
</body>
</html>`;
2017-09-20 22:57:15 -04:00
res.writeHead(200, {'Content-type': 'text/html; charset=utf-8'});
2017-09-20 18:10:37 -04:00
res.end(html, 'utf-8');
}
function sendDeckIndex(res, deckName) {
const html = `
<html>
<head>
<link rel="stylesheet" type="text/css" href="/style.css">
2017-09-28 14:01:22 -04:00
<title>${deckName}</title>
2017-09-20 18:10:37 -04:00
</head>
<body>
<ul>
<li><a href="${deckName}/play">Play!</a></li>
<li><a href="${deckName}/editor">Editor</a></li>
</ul>
2017-09-20 18:10:37 -04:00
</body>
</html>`;
2017-09-20 22:57:15 -04:00
res.writeHead(200, {'Content-type': 'text/html; charset=utf-8'});
2017-09-20 18:10:37 -04:00
res.end(html, 'utf-8');
}
function sendFileJSON(res, deckName) {
fs.readFile(deckName + '.json', (error, content) => {
console.log(JSON.parse(content));
res.writeHead(200, {'Content-type': 'application/json; charset=utf-8'});
res.end(JSON.stringify(JSON.parse(content).ObjectStates[0]), 'utf-8');
if (error) {
console.error(error);
}
});
}
function handleUpload(res, req) {
let body = '';
req.on('data', data => {
body += data;
// check for file > 100MB
if (body.length > 1e8) {
req.connection.destroy();
console.log('upload too big');
}
});
req.on('end', () => {
let json = JSON.parse(body);
console.log("making page");
phantom.create().then(
ph => ph.createPage().then(
page => {
page.on('onLoadFinished', status => {
if (status !== 'success') {
console.log('Failed to load page');
ph.exit(1);
}
else {
page.render("dest.png");
page.close().then(() => ph.exit());
}
});
page.property('zoomFactor', 2); // pretty arbitrary
page.property('content', json.body);
}));
});
}
2017-09-20 18:10:37 -04:00
function send404(res, uri) {
res.writeHead(404, {'Content-type': "text/html; charset=utf-8"});
const html = `
<head>
<title>404 Not Found</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>Error 404: Path ${uri.pathname} not found</h1>
You seem to have gone to the wrong place, would you like to go
back to the <a href="/">main page</a>?
</body>`;
res.end(html, 'utf-8');
}
function sendFile(res, filename, contentType='text/html; charset=utf-8') {
fs.readFile(filename, (error, content) => {
res.writeHead(200, {'Content-type': contentType});
res.end(content, 'utf-8');
if (error) {
console.error(error);
}
});
}