basic_robot_csm/scripts/transfer_file.lua
2018-05-04 11:13:00 +02:00

117 lines
3.8 KiB
Lua

--TRANSFER FILE by rnd v05012018a
-- write target name. hold w and s simultaneously to start send data in robot code 8.
-- DESCRIPTION: sends program 8 using pm chat (encoded, broken in pieces).
-- both players can talk during transfer with no problems
if not init then
target = "test"; -- who to receive from
chunksize = 450; -- maxlength that server supports
chatchar = ": " -- used to trigger listener, change to what server uses, normally pm chat looks like: 'PM from NAME: TEXT'
msgchar = "@" -- what to insert to message, so it will be like '... NAME: @TEXT'
state = 0; -- dont edit
mode = 0; -- 1 send, 0: idle(2 receive)
idx = 0; -- current index
maxids = 0; -- total number of chunks
t = {os.time(),0}; -- timings
data = {};
if mode == 0 then say(minetest.colorize("red","#TRANSFER: wait to receive from '" .. target .. "' or hold w & s to start sending")) end
init = true
read_data = function(data,inputfile)
sdata = minetest.encode_base64(_G.basic_robot.data["code"..8]) -- data to send, robot code 8
local length = string.len(sdata);
local chunks = math.ceil(length/chunksize);
for i = 1, chunks do -- break data into smaller pieces with stamps
data[i] = string.format("%05d",i) .. " " .. string.sub(sdata,1+(i-1)*chunksize,i*chunksize)
end
maxidx = chunks;
end
self.msg_filter(target.. chatchar .. msgchar, true); -- ignore all other receives
local msg = ""
while msg do msg = self.listen_msg() end -- reset msg buffer
read_data(data,inputfile)
end
t[2] = os.time();
if mode == 0 then -- IDLE
msg = self.listen_msg();
-- press w and s simultaneously to start 'send'
if minetest.localplayer:get_key_pressed() == 3 then
say(minetest.colorize("red","SENDING DATA STREAM TO " .. target))
mode = 1; msg = false
end
if msg then
msg = minetest.strip_colors(msg)
local i = string.find(msg, msgchar);
local ridx = tonumber(string.sub(msg,i+1,i+5));
if ridx == 0 then -- initial packet
say("INIT PACKET RECEIVED")
chunksize = tonumber(string.sub(msg,i+7,i+9))
maxidx = tonumber(string.sub(msg,i+11))
t[1] = t[2]
mode = 2 -- receiver!
say("/msg " .. target .. " " .. msgchar.. ridx, true) -- confirmation
end
end
elseif mode == 1 then -- SENDER/SERVER
if state == 0 then
say("/msg " .. target .. " ".. msgchar .. "00000" .. " " .. string.format("%03d",chunksize) .. " " .. maxidx, true) -- send init
state = 1
t[1] = t[2];
elseif state == 1 then
msg = self.listen_msg();
if msg then
msg = minetest.strip_colors(msg)
local i = string.find(msg, msgchar);
idx = tonumber(string.sub(msg,i+1,i+5));
if not idx then say("restart. wrong message: " .. msg); self.remove() end
idx= idx+1
if idx>maxidx then
state = 2
say(minetest.colorize("red","END."))
else
if idx % 5 == 1 then -- less spam
say("SENDING " .. idx.."/" .. maxidx .. ", " .. chunksize/(t[2]-t[1]) .. " b/s")
end
say("/msg " .. target .. " ".. msgchar .. data[idx], true)
t[1] = t[2]
end
end
end
elseif mode == 2 then -- RECEIVER/CLIENT
if state == 0 then
msg = self.listen_msg();
if msg then
msg = minetest.strip_colors(msg)
--say("RECEIVED : " .. msg)
local i = string.find(msg, msgchar);
if not i then say("restart. wrong message " .. msg ) self.remove() end
local ridx = tonumber(string.sub(msg,i+1,i+5));
say("/msg " .. target .. " " .. msgchar.. ridx, true) -- confirmation
local rdata = string.sub(msg, i+7)
data[ridx] = rdata;
if ridx % 5 == 1 then -- less spam
say(minetest.colorize("red","received " .. ridx .. "/" .. maxidx .. ", " .. chunksize/(t[2]-t[1]) .. " b/s"))
end
t[1] = t[2]
if ridx == maxidx then
state = 1
local sdata = minetest.decode_base64(table.concat(data));
_G.basic_robot.data["code"..8] = sdata
say(minetest.colorize("red","END. RECEIVED DATA SAVED AS CODE 8!"))
end
end
end
end