Created
June 21, 2021 06:33
-
-
Save phoboslab/0bf09acb2ea4912d621ae80c439a4bba to your computer and use it in GitHub Desktop.
Impact2 Weltmeister Server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
let http = require('http'), | |
url = require('url'), | |
querystring = require('querystring'), | |
fs = require('fs'), | |
editorIndex = 'editor/editor.html', | |
port = parseInt(process.argv[2] || 8080, 10); | |
let API = { | |
glob: function(params, body, callback) { | |
let dir = params.dir ? params.dir.replace(/\/$/, '') : ''; | |
fs.readdir('./' + dir, function(err, files){ | |
if (err) { | |
return callback('dir listing failed for ./' + dir); | |
} | |
let parent = dir.replace(/\/?[^\/]*$/,''); | |
let ret = {current: dir, parent: parent, dirs: [], files: []}, | |
typeMatch = params.type | |
? new RegExp('\\.' + params.type + '$') | |
: null; | |
for (let i = 0; i < files.length; i++) { | |
let fileName = files[i], | |
filePath = (dir && dir+'/') + fileName; | |
if (fileName.match(/^\./)) { | |
continue; | |
} | |
if (fs.statSync('./' + filePath).isDirectory()) { | |
ret.dirs.push({name: fileName, path: filePath}); | |
} | |
else if (!params.type || fileName.match(typeMatch)) { | |
ret.files.push({name: fileName, path: filePath}); | |
} | |
} | |
callback(null, ret); | |
}); | |
}, | |
save: function(params, body, callback) { | |
if (!params.path) { | |
return callback('no path specified'); | |
} | |
fs.writeFile(params.path, body, {flag: 'w'}, function(err) { | |
if (err) { | |
return callback('error writing file ' + params.path); | |
} | |
callback(null, {saved: true}); | |
}); | |
} | |
}; | |
let utf8 = '; charset=utf-8'; | |
let mime = { | |
html: 'text/html' + utf8, | |
htm: 'text/html' + utf8, | |
json: 'application/json' + utf8, | |
js: 'application/javascript' + utf8, | |
jpeg: 'image/jpeg', | |
jpg: 'image/jpeg', | |
gif: 'image/gif', | |
png: 'image/png', | |
ogg: 'audio/ogg', | |
mp3: 'audio/mp3', | |
aac: 'audio/aac', | |
css: 'text/css' + utf8, | |
bin: 'application/octet-stream' | |
}; | |
let serveAPI = function(request, response, name) { | |
let uri = url.parse(request.url, true), | |
apiFunc = API[name]; | |
if (!apiFunc) { | |
return writeError(request, response, 404, 'no such API function: ' + name); | |
} | |
console.log('API:', name, uri.query); | |
let bodyChunks = []; | |
request.on('data', function(chunk){ | |
bodyChunks.push(chunk); | |
}); | |
request.on('end', function(){ | |
let body = Buffer.concat(bodyChunks); | |
apiFunc(uri.query, body, function(err, data){ | |
if (err) { | |
writeError(request, response, 500, err); | |
} | |
else { | |
response.writeHead(200, {'Content-Type': mime.json}); | |
response.write(JSON.stringify(data)); | |
response.end(); | |
} | |
}); | |
}); | |
}; | |
let serveStaticFile = function(request, response) { | |
let uri = querystring.unescape(url.parse(request.url).pathname), | |
fileName = './' + uri; | |
if (uri === '/editor') { | |
fileName = editorIndex; | |
} | |
fs.stat(fileName, function(err, stat) { | |
if (err) { | |
return writeError(request, response, 404, 'not found'); | |
} | |
if (stat.isDirectory()) { | |
fileName += '/index.html'; | |
} | |
fs.readFile(fileName, 'binary', function(err, file) { | |
if (err) { | |
return writeError(request, response, 500, 'internal error'); | |
} | |
let ext = fileName.match(/\.(\w+)$/); | |
console.log('200: ' + uri); | |
response.writeHead(200, {'content-type': (ext && mime[ext[1]]) || mime.bin}); | |
response.write(file, 'binary'); | |
response.end(); | |
}); | |
}); | |
}; | |
let writeError = function(request, response, code, message) { | |
console.log(code+': ' + request.url); | |
response.writeHead(code, {'Content-Type': mime.json}); | |
response.write(JSON.stringify({error: {code: code, message: message}})); | |
response.end(); | |
}; | |
http.createServer(function(request, response) { | |
let apiMatch = null; | |
if (apiMatch = request.url.match(/^\/api\/(\w+)/)) { | |
serveAPI(request, response, apiMatch[1]); | |
} | |
else { | |
serveStaticFile(request, response); | |
} | |
}).listen(port); | |
console.log( | |
'Impact editor running at: http://localhost:' + port + '/editor\n' + | |
'CTRL + C to shutdown' | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment