2017-09-18 12:04:55 -04:00
|
|
|
// jshint node:true
|
|
|
|
// jshint esversion:6
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const http = require('http'),
|
|
|
|
fs = require('fs'),
|
2017-10-02 03:24:13 -04:00
|
|
|
path = require('path'),
|
2017-09-18 12:04:55 -04:00
|
|
|
url = require('url'),
|
2017-10-02 03:24:13 -04:00
|
|
|
phantom = require('phantom'),
|
2017-09-18 12:04:55 -04:00
|
|
|
port = 8080;
|
|
|
|
|
2017-10-02 14:37:56 -04:00
|
|
|
const decks = ["the_Unholy_Priest_update_2", "NZoths_Invasion_1.2", "Puffer_Fish_input_1.3"];
|
|
|
|
|
2017-09-18 12:04:55 -04:00
|
|
|
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;
|
2017-10-09 03:28:54 -04:00
|
|
|
case 'css':
|
|
|
|
switch (pathParts[2]) {
|
|
|
|
case 'playfield.css':
|
|
|
|
case 'editor.css':
|
2017-10-09 12:48:04 -04:00
|
|
|
case 'common.css':
|
2017-10-09 03:28:54 -04:00
|
|
|
sendFile(res, 'css/' + pathParts[2], 'text/css');
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
send404(res, uri);
|
|
|
|
}
|
2017-09-20 18:10:37 -04:00
|
|
|
break;
|
2017-09-23 21:31:06 -04:00
|
|
|
case 'js':
|
2017-09-28 12:58:28 -04:00
|
|
|
switch (pathParts[2]) {
|
2017-09-23 21:31:06 -04:00
|
|
|
case 'playfield.js':
|
2017-09-24 16:45:51 -04:00
|
|
|
case 'editor.js':
|
2017-09-23 21:31:06 -04:00
|
|
|
case 'interact.js':
|
2017-10-02 14:37:56 -04:00
|
|
|
sendFile(res, 'js/' + pathParts[2], 'application/javascript');
|
2017-09-23 21:31:06 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
send404(res, uri);
|
|
|
|
}
|
2017-09-20 18:10:37 -04:00
|
|
|
break;
|
2017-09-24 16:45:51 -04:00
|
|
|
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":
|
2017-10-08 22:07:22 -04:00
|
|
|
case "environment/input.json":
|
2017-10-12 02:27:17 -04:00
|
|
|
case "hero/input.json":
|
|
|
|
case "villain/input.json":
|
2017-09-24 16:45:51 -04:00
|
|
|
sendFile(res, "template/" + item, 'application/json');
|
|
|
|
break;
|
2017-10-08 22:07:22 -04:00
|
|
|
case "environment/deck.svg":
|
2017-10-11 18:19:08 -04:00
|
|
|
case "hero/deck.svg":
|
|
|
|
case "hero/character-back.svg":
|
2017-10-12 02:27:17 -04:00
|
|
|
case "hero/character.svg":
|
2017-10-11 18:19:08 -04:00
|
|
|
case "villain/deck.svg":
|
2017-09-24 16:45:51 -04:00
|
|
|
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':
|
2017-10-02 14:37:56 -04:00
|
|
|
if (pathParts.length < 3 || pathParts[2] === '') {
|
|
|
|
sendIndex(res);
|
|
|
|
break;
|
2017-09-20 18:10:37 -04:00
|
|
|
}
|
2017-10-02 14:37:56 -04:00
|
|
|
let deckName = decodeURI(pathParts[2]);
|
|
|
|
switch (pathParts[3] || '') {
|
|
|
|
case '':
|
|
|
|
sendDeckIndex(res, deckName);
|
|
|
|
break;
|
|
|
|
case 'play':
|
|
|
|
sendFile(res, 'html/playfield.html');
|
|
|
|
break;
|
|
|
|
case 'editor':
|
|
|
|
sendFile(res, 'html/editor.html');
|
|
|
|
break;
|
|
|
|
case 'deck.png':
|
2017-10-09 03:26:52 -04:00
|
|
|
sendFile(res, `decks/${deckName}.png`, 'image/png');
|
2017-10-02 14:37:56 -04:00
|
|
|
break;
|
|
|
|
case 'deck.json':
|
|
|
|
sendFileJSON(res, deckName);
|
|
|
|
break;
|
2017-12-03 00:50:05 -05:00
|
|
|
case 'deck.tts.json':
|
|
|
|
sendFile(res, `decks/${deckName}.json`, 'application/json');
|
|
|
|
break;
|
2017-10-08 18:21:24 -04:00
|
|
|
case 'deck.input.json':
|
2017-10-09 03:26:52 -04:00
|
|
|
sendFile(res, `decks/${deckName}.input.json`, 'application/json');
|
2017-10-08 18:21:24 -04:00
|
|
|
break;
|
2017-10-02 14:37:56 -04:00
|
|
|
case 'upload':
|
2017-10-12 03:13:01 -04:00
|
|
|
handleUpload(res, req);
|
2017-10-02 14:37:56 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
send404(res, uri);
|
2017-09-18 12:04:55 -04:00
|
|
|
}
|
2017-09-20 18:10:37 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
send404(res, uri);
|
2017-09-18 12:04:55 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
server.listen(process.env.PORT || port);
|
|
|
|
console.log('listening on 8080');
|
|
|
|
|
|
|
|
function sendIndex(res) {
|
2017-09-28 12:58:28 -04:00
|
|
|
const html = `
|
2017-09-20 18:10:37 -04:00
|
|
|
<html>
|
|
|
|
<head>
|
2017-10-09 12:48:04 -04:00
|
|
|
<link rel="stylesheet" type="text/css" href="/css/common.css">
|
2017-09-28 14:01:22 -04:00
|
|
|
<title>Index</title>
|
2017-09-20 18:10:37 -04:00
|
|
|
</head>
|
|
|
|
<body>
|
2017-10-09 12:48:04 -04:00
|
|
|
<label>Create New Deck: <input type="text" onchange="window.location='/deck/' + event.target.value + '/editor'"></label>
|
2017-09-20 18:10:37 -04:00
|
|
|
<ul>
|
2017-10-02 14:37:56 -04:00
|
|
|
${(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>
|
2017-10-09 12:48:04 -04:00
|
|
|
<link rel="stylesheet" type="text/css" href="/css/common.css">
|
2017-09-28 14:01:22 -04:00
|
|
|
<title>${deckName}</title>
|
2017-09-20 18:10:37 -04:00
|
|
|
</head>
|
|
|
|
<body>
|
2017-09-24 16:45:51 -04:00
|
|
|
<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');
|
|
|
|
}
|
|
|
|
|
2017-10-02 03:29:53 -04:00
|
|
|
function sendFileJSON(res, deckName) {
|
2017-10-09 03:26:52 -04:00
|
|
|
fs.readFile(`decks/${deckName}.json`, (error, content) => {
|
2017-10-02 03:29:53 -04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-10-02 03:24:13 -04:00
|
|
|
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', () => {
|
2017-10-02 14:41:42 -04:00
|
|
|
const json = JSON.parse(body);
|
|
|
|
const deckJSON = json.json;
|
|
|
|
const cardTemplate = fs.readFileSync('template/card.json');
|
2017-10-12 03:41:16 -04:00
|
|
|
const template = JSON.parse(fs.readFileSync(`template/${deckJSON.type}/input.json`));
|
|
|
|
const cardCount = Object.entries(template.cardTypes)
|
|
|
|
.map(ct => deckJSON[ct[0]].length * (ct[1].back ? 2 : 1))
|
|
|
|
.reduce((sum, current) => sum + current, 0);
|
2017-10-02 14:41:42 -04:00
|
|
|
|
|
|
|
let deckOut = JSON.parse(fs.readFileSync('template/deck.json'));
|
|
|
|
deckOut.ObjectStates[0].Nickname = deckJSON.name;
|
2017-10-12 03:13:01 -04:00
|
|
|
|
2017-10-02 14:41:42 -04:00
|
|
|
Object.assign(deckOut.ObjectStates[0].CustomDeck['1'],
|
2017-10-12 03:13:01 -04:00
|
|
|
{NumWidth: Math.ceil(Math.sqrt(cardCount)),
|
|
|
|
NumHeight: Math.ceil(Math.sqrt(cardCount)),
|
|
|
|
FaceURL: `http://${req.headers.host}/deck/${deckJSON.name}/deck.png`,
|
2017-10-02 14:41:42 -04:00
|
|
|
BackURL: "http://cloud-3.steamusercontent.com/ugc/156906385556221451/CE2C3AFE1759790CB0B532FFD636D05A99EC91F4/"});
|
|
|
|
|
2017-10-12 03:13:01 -04:00
|
|
|
let index = 100;
|
|
|
|
deckOut.ObjectStates[0].ContainedObjects =
|
|
|
|
Object.entries(template.cardTypes).map(
|
|
|
|
cardType => deckJSON[cardType[0]].map(cardIn => {
|
|
|
|
let cardOut = JSON.parse(cardTemplate);
|
|
|
|
Object.assign(cardOut, {Nickname: cardIn.name,
|
|
|
|
Description: cardIn.keywords,
|
|
|
|
CardID: index});
|
2017-10-12 03:41:16 -04:00
|
|
|
|
|
|
|
for (let ii=0; ii<(cardIn.count || 1); ii++) {
|
|
|
|
deckOut.ObjectStates[0].DeckIDs.push(index);
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
|
2017-10-12 03:13:01 -04:00
|
|
|
if(cardType[1].back) {
|
|
|
|
let cardBack = JSON.parse(cardTemplate);
|
|
|
|
Object.assign(cardBack, {Nickname: cardIn.back.name,
|
|
|
|
Description: cardIn.back.keywords,
|
|
|
|
CardID: index});
|
|
|
|
cardOut.States = {"2": cardBack};
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
return cardOut;
|
2017-10-12 03:41:16 -04:00
|
|
|
}))
|
|
|
|
.reduce((sum, cur) => sum.concat(cur), []);
|
2017-10-02 14:41:42 -04:00
|
|
|
|
2017-10-09 03:26:52 -04:00
|
|
|
fs.writeFileSync(`decks/${deckJSON.name}.json`, JSON.stringify(deckOut));
|
|
|
|
fs.writeFileSync(`decks/${deckJSON.name}.input.json`, JSON.stringify(deckJSON));
|
2017-10-02 03:24:13 -04:00
|
|
|
|
|
|
|
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 {
|
2017-10-09 03:26:52 -04:00
|
|
|
page.render(`decks/${deckJSON.name}.png`);
|
2017-10-02 03:24:13 -04:00
|
|
|
page.close().then(() => ph.exit());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
page.property('zoomFactor', 2); // pretty arbitrary
|
2017-10-12 03:12:00 -04:00
|
|
|
page.property('content', '<body style="margin:0;">' + json.body + '</body>');
|
2017-10-02 14:41:42 -04:00
|
|
|
}));
|
|
|
|
decks.push(deckJSON.name);
|
2017-10-02 03:24:13 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
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>
|
2017-10-09 12:48:04 -04:00
|
|
|
<link rel="stylesheet" href="/css/common.css">
|
2017-09-20 18:10:37 -04:00
|
|
|
</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');
|
|
|
|
}
|
|
|
|
|
2017-09-18 12:04:55 -04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|