webcommands: bidirectional

master
rnd 2018-12-24 21:10:26 +01:00
parent b85ac575ba
commit 0a7c5d33d8
2 changed files with 82 additions and 17 deletions

View File

@ -1,31 +1,68 @@
// listen to web request and pass it to minetest, rnd 2018
// listen to web request and pass it to minetest or back to web, rnd 2018
// INSTRUCTIONS. url options:
// 1./mtmsg/msg will store msg as message received from minetest ( minetest_message). note that msg cant contain spaces or newlines
// 2./getwebmsg/ will reply = IP + ' ' + webmessage
// 3./webmsg/msg will store message as webmessage
// 4./getmtmsg will reply with minetest_message
// NOTES: 1. avoids the need to deal with POST nastyness and complications like
// https://stackoverflow.com/questions/4295782/how-do-you-extract-post-data-in-node-js
const http = require('http');
const hostname = '192.168.0.10' //write address of your router (it will be accessible from internet then if you open firewall for nodejs process)
const port = 80;
var webreq = ""
var webreq = "" // message from web
var mtreq = "" // message from mt
// take request from web and pass it to minetest
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
if (req.url == '/favicon.ico') return // prevent passing this as request
var pos = (req.url).indexOf("/MT");
if (pos >=0) { // did request come from minetest? then answer with latest request
res.write(webreq);webreq = "";res.end();return
}
//process web request and store it
var msg = req.url;
if (msg == '/favicon.ico') return // prevent passing this as request
var pos = msg.indexOf("/",1); // gets the 2nd / in /part1/part2/...
var cmd = msg.substring(1,pos);
var response = ""
var ip = req.connection.remoteAddress;
webreq = ip + ' ' + req.url
res.write('request received: ' + webreq);res.end(); // acknowledge request
switch(cmd)
{
case "mtmsg":
response = msg.substring(pos+1);
mtreq = response
break
case "getmtmsg":
response = mtreq; mtreq = ''
break
case "getwebmsg":
response = webreq; webreq = ''
break
case "webmsg":
webreq = ip + ' ' + msg.substring(pos+1);
response = 'request received: ' + webreq + '\nuse /getmtmsg to view response from minetest'
break
default:
response = 'INSTRUCTIONS. url options:\n'+
'1./mtmsg/msg will store msg as message received from minetest ( minetest_message). note that msg cant contain spaces or newlines\n'+
'2./getwebmsg/ will reply = IP + " " + webmessage\n'+
'3./webmsg/msg will store message as webmessage\n'+
'4./getmtmsg will reply with minetest_message\n'
}
if (msg!='' && cmd != 'getwebmsg') console.log('ip ' + ip + ', msg ' + msg)
res.write(response); res.end()
return
});
// make server listen
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});

View File

@ -5,13 +5,14 @@
https://nodejs.org/dist/v10.14.2/node-v10.14.2-win-x86.zip
2. run nodejs server using run.bat
:loop
node --inspect myprogs/minetest_webcommands.js
node $path/minetest_webcommands.js
goto loop
3. run robot and type 'http://192.168.0.10:80/hello this is a test' into browser
3. run robot and type 'http://192.168.0.10/webmsg/hello this is a test' into browser
(you need to write your router address here, i.e. ip accessible from internet OR lan address)
--]]
if not fetch then
address = "192.168.0.10";
fetch = _G.basic_robot.http_api.fetch;
state = 0 -- ready to fetch new command
-- WARNING: this is run outside pcall and can crash server if errors!
@ -20,12 +21,39 @@ if not fetch then
if not res.succeeded then self.label("#ERROR: data couldn't be downloaded :\n" .. minetest.serialize(res) ) return end
if res.data == "" then return end
local req = res.data; req = string.gsub(req,"%%20"," ")
if res.data then self.label(os.clock() .. ' received cmd : ' .. req) end
if res.data then
self.label(os.date("%X") ..', cmd : ' .. req)
local i = string.find(req," !")
if i then
run_commmand(string.sub(req,i+2))
end
end
end
admin = minetest.setting_get("name")
run_commmand = function(message)
local cmd, param = _G.string.match(message, "([^ ]+) *(.*)")
if not param then
param = ""
end
local cmd_def = minetest.chatcommands[cmd]
if cmd_def then
cmd_def.func(admin, param)
else
minetest.chat_send_all(admin..": "..message)
end
end
MT2web = function(message)
message = string.gsub(message," ","%%20") -- NOTE: if you send request that has 'space' in it there will be error 400!
fetch({url = "http://".. address .. "/mtmsg/"..message, timeout = 5}, result)
end
MT2web("minetest robot started and listening.")
end
if state == 0 then
fetch({url = "http://192.168.0.10/MT", timeout = 30}, result)
fetch({url = "http://"..address.."/getwebmsg/", timeout = 5}, result)
state = 1
end