var url = require('url'), http = require('http'), mime = require('mime-types'), fs = require('fs'); module.exports = class WebserverController { handleRequest(config, request, response) { switch(request.method.toLowerCase()) { case "post": this.handlePostRequest(config, request, response); break; case "get": default: this.handleGetRequest(config, request, response); break; } } handlePostRequest(config, request, response) { var body = ''; var self = this; request.on('data', function(chunk) { body += chunk.toString(); }); request.on('end', function() { var keyValuePairs = body.split("&"); var postData = {}; for(var i in keyValuePairs) { var block = keyValuePairs[i].split("="); postData[block[0]] = block[1]; } self.handleRoutes(config, request, response, postData); }); } handleRoutes(config, request, response, body) { var parsedUrl = url.parse(request.url, true); var pathname = parsedUrl.pathname; var pathParts = pathname.replace(/^\/+/gm, '').split("/"); if(pathParts[0] == "api") { pathParts.shift(); //drop api var responseData = null; switch(pathParts.shift()) { case "current": this.current(config, request, response); break; case "register": this.register(config, request, response, body); break; default: this.help(request, response); break; } return; } var filename = config.websitePath; if(config.routes.hasOwnProperty(pathname)) { filename += config.routes[pathname]; } else { filename += pathname; } fs.stat(filename, function(err, stat) { if(err != null) { if(err.code == 'ENOENT') { response.writeHead(404, {'Content-Type': 'text/html'}); response.write("404 Page Not Found"); } else { response.writeHead(500, {'Content-Type': 'text/html'}); response.write("500 Server Error"); } response.end(); return; } fs.readFile(filename, function(err, data) { var mimeType = mime.lookup(filename); response.writeHead(200, {'Content-Type': mimeType}); response.write(data); response.end(); }); }); } handleGetRequest(config, request, response) { this.handleRoutes(config, request, response, {}); } current(config, request, response) { var responseData = {}; var activePlayers = []; for(var i in session.players) { var player = session.players[i]; activePlayers.push(player.name); } responseData.players = activePlayers; response.writeHead(200, {'Content-Type': 'application/json'}); response.write(JSON.stringify(responseData, null, '\t')); response.end(); } register(config, request, response, body) { if(!config.allowRegistration) { response.writeHead(200, {'Content-Type': 'application/json'}); response.write(JSON.stringify({"status": "error", "error": "Registration is not enabled at this time."}, null, '\t')); response.end(); return; } //TODO: make sure username is valid and not already claimed if(!this.isValidUsername(config, body.username)) { response.writeHead(200, {'Content-Type': 'application/json'}); response.write(JSON.stringify({"status": "error", "error": "That username is not available."}, null, '\t')); response.end(); return; } var newPlayer = builder.mud_spawnMobile("PlayerMobile"); newPlayer.password = world.mud_generateHash(body.username.toLowerCase() + body.password); var playerName = JSON.stringify(body.username).replace( /[_\W]/g , ''); playerName = playerName.substring(0,1).toUpperCase() + playerName.substring(1); newPlayer.name = playerName; world.mud_playerSave(newPlayer); world.mud_destroyMobile(newPlayer.id); response.writeHead(200, {'Content-Type': 'application/json'}); response.write(JSON.stringify({"status": "ok"}, null, '\t')); response.end(); } isValidUsername(config, username) { var cleanName = JSON.stringify(username).replace( /[_\W]/g , ''); if(config.usernameBlacklist.indexOf(cleanName) != -1) { return false; } var playerFilename = config.playerDataPath+ "/"+cleanName+".json"; if (fs.existsSync(playerFilename)) { return false; } return cleanName == username; } help(request, response) { var helpData = {"description": "This is the API for accessing or writing data to the Starmire MUD.", "commands" : [ {"path": "/api/current", "method": "get", "description": "Returns the current players"}, {"path": "/api/register", "method": "post", "fields": "username, password", "description": "Will create a new character with the username and password specified if valid."}, ]}; response.writeHead(200, {'Content-Type': 'application/json'}); response.write(JSON.stringify(helpData, null, '\t')); response.end(); } };