Browse Source

working on coderskin upload

master
poikilos 6 years ago
committed by Jacob Gustafson
parent
commit
02f2fe74e9
  1. 84
      webapp/.gitignore
  2. 29
      webapp/README.md
  3. 14
      webapp/install-mts.sh
  4. 93
      webapp/package-lock.json
  5. 1
      webapp/package.json
  6. 86
      webapp/server.js

84
webapp/.gitignore

@ -0,0 +1,84 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/

29
webapp/README.md

@ -1,14 +1,29 @@
# EnlivenMinetest webapp
EnlivenMinetest Node.js webapp for web management of minetest
* Must run as same user as minetestserver, and neither as root
* Must run as same user as minetestserver, and neither should be root!
## Install
* Using Terminal, cd to your EnlivenMinetest/webapp diretory, then:
```bash
npm install
```
## Usage
* start like:
`node server.js`
* then it will listen on port 3000
* change skin at localhost:3000/skin-form
* for security, no overwrite is allowed
Uses passport
see <https://code.tutsplus.com/tutorials/authenticating-nodejs-applications-with-passport--cms-21619>
Replaces the "write" (stdout) method of the minetest process:
see <https://stackoverflow.com/questions/18543047/mocha-monitor-application-output>
## Planned Features
* Replace the "write" (stdout) method of the minetestserver process (see
<https://stackoverflow.com/questions/18543047/mocha-monitor-application-output>)
## Developer Notes
* Uses passport (see <https://code.tutsplus.com/tutorials/authenticating-nodejs-applications-with-passport--cms-21619>
### Things webapp should deprecate
* mtanalyze/web
* /home/owner/GitHub/EnlivenMinetest/etc/change_hardcoded_world_name_first/eauth
@ -48,8 +63,8 @@ fi
cd "$target_dir"
npm init
#except changed jade to pug
npm install express static-favicon morgan cookie-parser body-parser debug pug passport passport-local mongoose
npm install express static-favicon morgan cookie-parser body-parser debug pug passport passport-local mongoose formidable
#NOTE: multiparty has streaming like busboy, but is non-trivial to implement
```
### Old (Unused)

14
webapp/install-mts.sh

@ -43,12 +43,12 @@ if [ ! -f "$flag_file" ]; then
echo "ERROR: Build did not complete--missing '$flag_file'"
exit 1
fi
flag_file="$HOME/minetest/bin/minetestserver"
if [ -f "$flag_file" ]; then
mv -f "$flag_file" "$flag_file.bak"
dest_flag_file="$HOME/$flag_file"
if [ -f "$dest_flag_file" ]; then
mv -f "$dest_flag_file" "$dest_flag_file.bak"
fi
if [ -f "$flag_file" ]; then
echo "ERROR: not complete since can't move old '$flag_file'"
if [ -f "$dest_flag_file" ]; then
echo "ERROR: not complete since can't move old '$dest_flag_file'"
exit 1
fi
if [ ! -d minetest ]; then
@ -57,8 +57,8 @@ if [ ! -d minetest ]; then
fi
echo "Installing minetest to '$HOME'..."
rsync -rt minetest $HOME
if [ ! -f "$flag_file" ]; then
echo "ERROR: not complete--couldn't create '$flag_file'"
if [ ! -f "$dest_flag_file" ]; then
echo "ERROR: not complete--couldn't create '$dest_flag_file'"
exit 1
fi
flag_dir="$HOME/minetest/games/Bucket_Game"

93
webapp/package-lock.json

@ -9,7 +9,7 @@
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
"requires": {
"mime-types": "2.1.18",
"mime-types": "~2.1.18",
"negotiator": "0.6.1"
}
},
@ -24,15 +24,15 @@
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
"requires": {
"bytes": "3.0.0",
"content-type": "1.0.4",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "1.1.2",
"http-errors": "1.6.3",
"depd": "~1.1.1",
"http-errors": "~1.6.2",
"iconv-lite": "0.4.19",
"on-finished": "2.3.0",
"on-finished": "~2.3.0",
"qs": "6.5.1",
"raw-body": "2.3.2",
"type-is": "1.6.16"
"type-is": "~1.6.15"
}
},
"bytes": {
@ -112,36 +112,36 @@
"resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
"requires": {
"accepts": "1.3.5",
"accepts": "~1.3.5",
"array-flatten": "1.1.1",
"body-parser": "1.18.2",
"content-disposition": "0.5.2",
"content-type": "1.0.4",
"content-type": "~1.0.4",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "1.1.2",
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"etag": "1.8.1",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.1.1",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "1.1.2",
"on-finished": "2.3.0",
"parseurl": "1.3.2",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"path-to-regexp": "0.1.7",
"proxy-addr": "2.0.3",
"proxy-addr": "~2.0.3",
"qs": "6.5.1",
"range-parser": "1.2.0",
"range-parser": "~1.2.0",
"safe-buffer": "5.1.1",
"send": "0.16.2",
"serve-static": "1.13.2",
"setprototypeof": "1.1.0",
"statuses": "1.4.0",
"type-is": "1.6.16",
"statuses": "~1.4.0",
"type-is": "~1.6.16",
"utils-merge": "1.0.1",
"vary": "1.1.2"
"vary": "~1.1.2"
}
},
"finalhandler": {
@ -150,14 +150,19 @@
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"requires": {
"debug": "2.6.9",
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"on-finished": "2.3.0",
"parseurl": "1.3.2",
"statuses": "1.4.0",
"unpipe": "1.0.0"
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"statuses": "~1.4.0",
"unpipe": "~1.0.0"
}
},
"formidable": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz",
"integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg=="
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
@ -173,10 +178,10 @@
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"requires": {
"depd": "1.1.2",
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.0",
"statuses": "1.4.0"
"statuses": ">= 1.4.0 < 2"
}
},
"iconv-lite": {
@ -224,7 +229,7 @@
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"requires": {
"mime-db": "1.33.0"
"mime-db": "~1.33.0"
}
},
"ms": {
@ -265,7 +270,7 @@
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
"integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
"requires": {
"forwarded": "0.1.2",
"forwarded": "~0.1.2",
"ipaddr.js": "1.6.0"
}
},
@ -303,7 +308,7 @@
"depd": "1.1.1",
"inherits": "2.0.3",
"setprototypeof": "1.0.3",
"statuses": "1.4.0"
"statuses": ">= 1.3.1 < 2"
}
},
"setprototypeof": {
@ -324,18 +329,18 @@
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
"requires": {
"debug": "2.6.9",
"depd": "1.1.2",
"destroy": "1.0.4",
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"etag": "1.8.1",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "1.6.3",
"http-errors": "~1.6.2",
"mime": "1.4.1",
"ms": "2.0.0",
"on-finished": "2.3.0",
"range-parser": "1.2.0",
"statuses": "1.4.0"
"on-finished": "~2.3.0",
"range-parser": "~1.2.0",
"statuses": "~1.4.0"
}
},
"serve-static": {
@ -343,9 +348,9 @@
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
"requires": {
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"parseurl": "1.3.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.2",
"send": "0.16.2"
}
},
@ -365,7 +370,7 @@
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "2.1.18"
"mime-types": "~2.1.18"
}
},
"unpipe": {

1
webapp/package.json

@ -14,6 +14,7 @@
"body-parser": "^1.18.2",
"cookie-parser": "^1.4.3",
"express": "^4.7.2",
"formidable": "^1.2.1",
"n-readlines": "^0.2.8"
}
}

86
webapp/server.js

@ -1,5 +1,13 @@
'use strict';
// Howto: see README.md
//function getUserHome() {
//return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
//}
const profilePath = require('os').homedir();
var skinDir = profilePath + "/minetest/games/ENLIVEN/mods/codercore/coderskins/textures";
var tz_offset = 240; //subtract this from server time to get local time; 4hrs is 240; 5hrs is 300
//TODO: handle tz_offset not divisible by 60
//var selected_date_s = null;
@ -14,6 +22,10 @@ var express = require('express'),
fs = require('fs'),
readlines = require('n-readlines');
const os = require('os');
var formidable = require('formidable')
var querystring = require("querystring"); // built-in
// var util = require('util')
var app = express();
//app.engine('handlebars', exphbs({defaultLayout: 'main'}));
//app.set('view engine', 'handlebars');
@ -267,6 +279,8 @@ function read_log() {
}
}
app.get('/get-players', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(players));
@ -286,6 +300,71 @@ app.get('/announce', function (req, res) {
res.send();
});
app.get('/skin-form', function (req, res) {
var ret = "";
ret += '<html><body style="font-family:calibri,sans">'+"\n";
ret += '<form action="/set-skin" method="post" enctype="multipart/form-data">'+"\n";
ret += 'User Name (case-sensitive): <input type="text" name="userName" id="userName">'+"\n";
ret += 'Select image to upload:'+"\n";
ret += '<input type="file" name="upload" id="upload">'+"\n";
ret += '<input type="submit" value="Upload Image" name="submit">'+"\n";
ret += '</form>'+"\n";
ret += '</body></html>';
res.send(ret);
//res.render('home');
});
//using express & formidable:
app.post('/set-skin', function (req, res){
var form = new formidable.IncomingForm();
// from coderskins/readme.txt:
//To install a specific skin for a specific player, name the PNG file
//to be used as follows:
//player_NAME.png
//where NAME is the player's in-game nick. Then copy the PNG file into
//the mod's "textures" directory.
//The PNG file should be a standard Minetest 64x32 or Minecraft 64x64
//"skin" file.
//Or, if you prefer, create a text file, in the mod's "textures" direc-
//tory with a similar filename:
//player_NAME.skin
//(OldCoder, 2019)
var directPath = "";
var indirectPath = "";
var msg = "Uploading...";
form.parse(req, function(err, fields, files) {
if (err) next(err);
directPath = skinDir + "/player_" + fields.userName + ".png";
indirectPath = skinDir + "/player_" + fields.userName + ".skin";
// TODO: make sure my_file and project_id values are present
var originalPath = files.my_file.path;
fs.rename(files.my_file.path, directPath, function(err) {
if (err) {
msg = "Failed to rename " + originalPath
+ " to " + directPath + "<br/>\n";
console.log(msg);
next(err);
}
res.end();
});
});
//form.on('fileBegin', function (name, file){
////file.path = __dirname + '/uploads/' + file.name;
//// file.path = skinDir + "/" + file.name;
//// manual_path = "player_" +
//});
form.on('file', function (name, file){
msg = 'Uploaded ' + file.name + "<br/>\n";
console.log(msg);
});
//res.sendFile(__dirname + '/index.html');
res.redirect("/?msg=" + querystring.stringify(msg));
});
app.get('/', function (req, res) {
var ret = "";
ret += '<html><body style="font-family:calibri,sans">';
@ -298,6 +377,11 @@ app.get('/', function (req, res) {
//
var selected_date_s = null;
if (req.query.date) selected_date_s = req.query.date
if (req.query.msg != undefined) {
ret += "<br/>\n";
ret += "<b>" + querystring.parse(msg) + "</b><br>\n";
ret += "<br/>\n";
}
ret += "assuming minetestserver ran as: " + os.homedir() + "<br/>\n";
ret += "timezone (tz_offset/60*-1): " + (Math.floor(tz_offset/60)*-1) + '<span name="tzArea" id="tzArea"></span><br/>\n';
ret += 'date: <span id="dateArea" name="dateArea">' + selected_date_s + '</span><br/>'+"\n";
@ -339,5 +423,5 @@ var server = app.listen(3000, function () {
var port = server.address().port;
console.log("reading log...");
read_log();
console.log("EnlivenMinetest webapp listening at http://%s:%s", host, port);
console.log("EnlivenMinetest webapp is listening at http://%s:%s", host, port);
});

Loading…
Cancel
Save