scripts update

master
rnd 2018-05-04 10:58:50 +02:00
parent 17657dacbb
commit 633ef44ac0
13 changed files with 198 additions and 375 deletions

View File

@ -6,7 +6,7 @@ instructions:
1. unpack in "minetest DIR"/clientmods/
2. enable client mods in advanced settings menu or in minetest.conf
3. inside /clientmods/mods.conf there should be line: load_mod_basic_robot_csm = true
4. while playing say .bot
4. while playing say .b to open gui. say .b 1 to run current tab program.
5. there are 2 example programs in /scripts,
you can see commands in init.lua, function getSandboxEnv() or for more available commands
https://github.com/minetest/minetest/blob/master/doc/client_lua_api.md

14
scripts/calculator.lua Normal file
View File

@ -0,0 +1,14 @@
--calculator by rnd
--say ,2+3 in chat
if not init then
init = true
self.msg_filter("",false)
end
msg = self.sent_msg()
if msg and msg~="" then
result = _G.loadstring("return "..msg)();
result = tonumber(result)
if result then say(minetest.colorize("lawngreen",msg .. " = " .. result)) else say("error in formula") end
end

View File

@ -1,4 +1,4 @@
-- colored text: string.char(27) .."(c@red)"..text
-- colored chat
if not colors then
colors = {"red","blue","violet", "lawngreen","brown","yellow","orange","pink"}
end

View File

@ -0,0 +1,115 @@
--authentication with zero knowledge proof by rnd
-- instructions: change target name and hold w+s to send identity challenge
if not init then
target = "qtest" -- player you want to authenticate with
targetidentity = "qtest" -- other player identity - you want to check he is real
myidentity = "rnd" -- your identity - you want other to believe to be this
shared_secrets = { -- SHARED SECRETS: {name1, name2, secret}
{"qtest","rnd","lekT$#J?434ijaakk4fa??_lDFg"}, -- shared secret between qtest and rnd
}
auth = {};
for i=1,#shared_secrets do
local name1 = shared_secrets[i][1];
local name2 = shared_secrets[i][2];
local tname = ""
if name1<name2 then tname = name1..name2 else tname = name2..name1 end
auth[tname] = shared_secrets[i][3]
end
teamname = "";
if myidentity<targetidentity then teamname = myidentity .. targetidentity else teamname = targetidentity..myidentity end
chatchar = "@@";
challenge = 0
init = true
self.msg_filter(chatchar)
-- rnd experimental hash ( min 256 bit output )
rndm = 2^31 1; --C++11's minstd_rand
rnda = 48271; -- generator
rndseed = 0;
random = function(n)
rndseed = (rnda*rndseed)% rndm;
return rndseed % n
end
local hash_ = function(input,seed)
local n = 128-32+1; -- Z_97, 97 prime
local m = 32;
local ret = {};input = input or "";
rndseed = seed;
local key = {};
local out = {};
for i=1, string.len(input) do
key[i] = random(n) -- generate keys from password
out[i] = string.byte(input,i)-m
if out[i] == -6 then out[i] = 96 end -- conversion back
end
local c0 = 1; -- this serves as accumulator too
for i=1, string.len(input) do
local offset=key[i]
local c = out[i];
for j = 1,string.len(input) do c0 = c0 + (out[j])^3; c0 = c0 % n end
c = (c+c0+offset) % n;
out[i] = c
end
rndseed = rndseed+c0
for i = 1, string.len(input) do
if out[i] == 96 then out[i]=-6 end -- 32 + 96 = 128 (bad char)
ret[#ret+1] = string.char(m+out[i])
end
return table.concat(ret,""),rndseed
end
rndhash = function(text)
local length = string.len(text);
if length<32 then text = text .. string.rep(" ", 32-length) end
local seed = 0; -- accumulator
local ret = text; for i = 1, 10 do ret,seed = hash_(ret,seed) end
return ret
end
say(minetest.colorize("red","#AUTHENTICATION: press w+s to send challenge to " .. target .. " or wait for one."))
local msg = ""; while msg do msg = self.listen_msg() end
end
if minetest.localplayer:get_key_pressed() == 3 then
rndseed = os.time();challenge = rndhash(random(2^31));
say("/msg " .. target .. " " .. chatchar .. " " .. challenge,true)
say(minetest.colorize("orange","#CHALLENGE SENT."))
end
msg = self.listen_msg()
if msg and msg~= "" then
msg = minetest.strip_colors(msg)
local i = string.find(msg,chatchar)
local cstring = string.sub(msg,i+2);
if string.sub(cstring,1,1) == " " then -- send back response
say(minetest.colorize("orange","#SENDING RESPONSE"))
local response = rndhash(string.sub(cstring,2) .. auth[teamname] ) --os.date("%x")
say("/msg " .. target .. " " .. chatchar .. response, true)
else
say(minetest.colorize("orange","#VERIFYING RESPONSE "))
local cresponse = rndhash(challenge .. auth[teamname] )
if cresponse == cstring then
say(minetest.colorize("lawngreen","#IDENTITY OF " .. target .. " CONFIRMED AS " .. targetidentity))
else
say(minetest.colorize("red","#FAKE IDENTITY OF " .. target .. " DETECTED - IS NOT " .. targetidentity))
end
end
end

View File

@ -0,0 +1,55 @@
-- rnd experimental hash ( min 256 bit output )
if not rndhash then
rndm = 2^31 1; --C++11's minstd_rand
rnda = 48271; -- generator
rndseed = 0;
random = function(n)
rndseed = (rnda*rndseed)% rndm;
return rndseed % n
end
local hash_ = function(input,seed)
local n = 128-32+1; -- Z_97, 97 prime
local m = 32;
local ret = {};input = input or "";
rndseed = seed;
local key = {};
local out = {};
for i=1, string.len(input) do
key[i] = random(n) -- generate keys from password
out[i] = string.byte(input,i)-m
if out[i] == -6 then out[i] = 96 end -- conversion back
end
local c0 = 1; -- this serves as accumulator too
for i=1, string.len(input) do
local offset=key[i]
local c = out[i];
for j = 1,string.len(input) do c0 = c0 + (out[j])^3; c0 = c0 % n end
c = (c+c0+offset) % n;
out[i] = c
end
rndseed = rndseed+c0
for i = 1, string.len(input) do
if out[i] == 96 then out[i]=-6 end -- 32 + 96 = 128 (bad char)
ret[#ret+1] = string.char(m+out[i])
end
return table.concat(ret,""),rndseed
end
rndhash = function(text)
local length = string.len(text);
if length<32 then text = text .. string.rep(" ", 32-length) end
local seed = 0; -- accumulator
local ret = text; for i = 1, 10 do ret,seed = hash_(ret,seed) end
return ret
end
for i = 1, 32 do
say(i .. " -> " .. rndhash(i))
end
end

View File

@ -1,252 +0,0 @@
--MSGER by rnd
--[[
INSTRUCTIONS:
1. set target player name bellow and encryption = true ( otherwise not encrypted)
2. start program and wait for session key or send one (hold W+S)
3. to send message just write: ,hello
--]]
if not init then
msgversion = "05012018a"
--- S E T T I N G S ---------------------------------------
target = "test" --write name of player you want to talk to
privatemsg = true -- false to chat, true for private msg
encryption = true; -- target player must use same settings
mode = 0; -- 1 to show window when message receiverd
send_timeout = 2; -- stop sending session key after so many tries
state = 0; -- if sendkey: 0: sending key, 1: key receipt aknowledged, ready. if receieve key: 0: waiting for key, 1: ready
chatchar = "''" -- some servers end msg announce with :, some with %)
password = { -- ~30 bits per row, 10x ~ 300 bit, 2 consecutive passwords should be different!
1050060370,
1301007001,
1000050002,
1040000003,
1000000004,
1000600005,
1080000006,
1000001203,
1000100008,
1080500609,
}
password0 = {}; for i=1,#password do password0[i] = password[i] end
-- each password can be up to 10^10, plus random session key 4*10^13 for total 64*10^43 ~ 148.8 bits
-----------------------------------------------------------
init = true
say(minetest.colorize("lawngreen","#MESSENGER ".. msgversion .. " STARTED. Starting conversation with " .. target))
if encryption then say(minetest.colorize("orange","wait for receipt of session key or hold W+S to send session key!")) end
self.msg_filter(chatchar) -- only records messages that contain chatchar to prevent skipping if too many messages from server!
empty_chat_buffer = function()
local msg = ""; while msg do msg = self.listen_msg() end
end
empty_chat_buffer();
maxn = 1000000000;
rndm = 2^31 1; --C++11's minstd_rand
rnda = 48271; -- generator
random = function(n)
rndseed = (rnda*rndseed)% rndm;
return rndseed % n
end
rndseed = os.time(); session_key = random(maxn) -- derive session key
send_session_key = false
state = -1
if not encryption then state = 1 end
scount = 0
wtime = 0
encrypt_ = function(input,password,sgn)
local n = 128-32+1; -- Z_97, 97 prime
local m = 32;
local ret = {};input = input or "";
rndseed = password;
local key = {};
local out = {};
for i=1, string.len(input) do
key[i] = random(n) -- generate keys from password
out[i] = string.byte(input,i)-m
if out[i] == -6 then out[i] = 96 end -- conversion back
end
if sgn > 0 then -- encrypt
for i=1, string.len(input) do
local offset=key[i]
local c = out[i];
local c0 = 0;
for j = 1,i-1 do c0 = c0 + (out[j])^3; c0 = c0 % n end
for j = i+1,string.len(input) do c0 = c0 + (out[j])^3; c0 = c0 % n end
c = (c+(c0+offset)*sgn) % n;
out[i] = c
end
else -- decrypt
local c0 = 0
for i = string.len(input),1,-1 do
local offset=key[i];
local c = out[i];
local c0 = 0;
for j = 1,i-1 do c0 = c0 + (out[j])^3; c0 = c0 % n end
for j = i+1,string.len(input) do c0 = c0 + (out[j])^3; c0 = c0 % n end
c = (c+(c0+offset)*sgn) % n;
out[i] = c
end
end
for i = 1, string.len(input) do
if out[i] == 96 then out[i]=-6 end -- 32 + 96 = 128 (bad char)
ret[#ret+1] = string.char(m+out[i])
end
return table.concat(ret,"")
end
encrypt = function(text,password)
local input = text;
local out = "";
for i = 1, #password do
input = encrypt_(input,password[i], (i%1)*2-1)
end
return input
end
decrypt = function(text, password)
local input = text;
local out = "";
for i = #password,1,-1 do
input = encrypt_(input,password[i], -(i%1)*2+1)
end
return input
end
unit_test = function()
local text = "Hello encrypted world! 12345 ..."
--local password = {1,2,session_key}
local enc = encrypt(text,password)
local dec = decrypt(enc,password)
say(text .. " -> " .. enc .. " -> " .. dec)
self.remove()
end
--unit_test()
end
if state == -1 then -- idle
msg = self.listen_msg()
if msg then
if string.find(msg,target) and string.find(msg,chatchar) then
msg = minetest.strip_colors(msg)
local i = string.find(msg, chatchar)
if i then -- ready to chat
msg = string.sub(msg,i+string.len(chatchar))
session_key = tonumber(decrypt(msg,password0))
if not session_key then
say(minetest.colorize("red","#MESSENGER: target uses wrong password! restarting...")) init = false
else
msg = encrypt("OK " .. session_key, password0)
say("/msg " .. target .. " " .. chatchar .. msg,true) -- send confirmation of receipt
msg = false
state = 1 scount = 1
say(minetest.colorize("lawngreen","#MESSENGER: RECEIVED SESSION KEY " .. session_key))
password[1] = session_key;password[#password] = password0[#password0] - session_key;
--say(password1 .. " " .. password2)
end
end
end
end
if not msg and minetest.localplayer:get_key_pressed() == 3 then
say(minetest.colorize("red","SENDING SESSION KEY TO " .. target))
state = 0;
end
else -- receive/send
msg = self.listen_msg()
if state == 0 then
if minetest.localplayer:get_key_pressed() == 3 then scount = 0 wtime = 0 end
if scount == 0 then msg = "" end -- trigger sending key at start
wtime = wtime + 1
if wtime > 10 then say(minetest.colorize("red","#MESSENGER: timeout while waiting for response from target. resetting")); init = false end
end
if msg then
if state == 0 then
-- SENDING KEY, listening for confirmation
if string.find(msg,target) and string.find(msg,chatchar) then -- did we receive confirmation?
msg = minetest.strip_colors(msg)
local i = string.find(msg, chatchar)
if i then
msg = string.sub(msg,i+string.len(chatchar))
msg = decrypt(msg,password0)
if msg == "OK " .. session_key then -- ready to chat
state = 1
say(minetest.colorize("lawngreen","#MESSENGER: TARGET CONFIRMS RECEIPT OF SESSION KEY " .. session_key))
password[1] = session_key;password[#password] = password0[#password0] - session_key;
--say(password1 .. " " .. password2)
end
end
elseif scount == 0 then -- send session key
scount = 1
msg = encrypt(session_key, password0)
say("/msg " .. target .. " " .. chatchar .. msg,true)
say(minetest.colorize("red","#MESSENGER: waiting for " .. target .. " to respond ..."))
wtime = 0
end
elseif state == 1 then -- NORMAL OPERATION: DECRYPT INCOMMING MESSAGES, SEND ENCRYPTED MESSAGES
if string.find(msg,target) and string.find(msg,chatchar) then
--say("D1")
msg = minetest.strip_colors(msg)
local i = string.find(msg, chatchar)
if i then
msg = string.sub(msg,i+string.len(chatchar))
--say("ENCRYPTED :" .. msg)
if encryption then
msg = decrypt(msg,password);
if string.byte(msg,1)~=32 then
say(minetest.colorize("red","#MESSENGER: DECRYPTION ERROR. TARGET USING DIFFERENT PASSWORD. RESTARTING MESSENGER."))
init = false
end
msg = minetest.colorize("LawnGreen","DECRYPTED from " .. target .. ">") .. minetest.colorize("yellow", msg)
end
form = "size[5,5] textarea[0,0;6,6;MSG;MESSAGE FROM " .. target .. "> " .. minetest.formspec_escape(msg) .. "]"
if mode == 1 then minetest.show_formspec("robot", form) else say(msg) end
end
end
end
end
end
msg = self.sent_msg() -- is there message to send?
if msg then
say(minetest.colorize("Pink", "MESSAGE SENT to " .. target .. "> " .. msg))
if encryption then msg = encrypt(" " .. msg, password) end
if privatemsg then
say("/msg " .. target .. " " .. chatchar .. msg,true)
else
say(chatchar .. msg,true)
end
end

View File

@ -40,6 +40,7 @@ end
msg = self.listen_msg()
if msg and msg~= "" then
msg = minetest.strip_colors(msg)
i = string.find(msg,">")
if i then
msg = decode(string.sub(msg,i+2))

View File

@ -1,117 +0,0 @@
--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

View File

@ -1,7 +1,8 @@
--triangulation by rnd
if not init then
get_inter = function(x1,y1,a1,b1,x2,y2,a2,b2)
local s = (b1*x1-a1*y1-b1*x2+a1*y2)/(a2*b1-b2*a1); return x2+a2*s,y2+b2*s
local an = a2*b1-b2*a1;
local s = (b1*x1-a1*y1-b1*x2+a1*y2)/an; return x2+a2*s,y2+b2*s,math.abs(an)
end
init = true; state = 1; pos = {{{0,0,0},{0,0,0}},{{0,0,0},{0,0,0}}};
say(minetest.colorize("red", "LOOK AT TARGET FROM 2 DIFFERENT POSITIONS. press shift to advance to next step."))
@ -13,9 +14,15 @@ if minetest.localplayer:get_key_pressed() == 64 then
local p = minetest.localplayer:get_pos(); local view = minetest.camera:get_look_dir()
pos[state] = {p,view}; state = state +1
if state == 3 then
local x1,z1,x2,y2;init = false
x1,z1 = get_inter(pos[1][1].x,pos[1][1].z,pos[1][2].x,pos[1][2].z,pos[2][1].x,pos[2][1].z,pos[2][2].x,pos[2][2].z)
x2,y2 = get_inter(pos[1][1].x,pos[1][1].y,pos[1][2].x,pos[1][2].y,pos[2][1].x,pos[2][1].y,pos[2][2].x,pos[2][2].y)
local x1,z1,x2,y2,y3,z3,an1,an2,an3;init = false
x1,z1,an1 = get_inter(pos[1][1].x,pos[1][1].z,pos[1][2].x,pos[1][2].z,pos[2][1].x,pos[2][1].z,pos[2][2].x,pos[2][2].z)
x2,y2,an2 = get_inter(pos[1][1].x,pos[1][1].y,pos[1][2].x,pos[1][2].y,pos[2][1].x,pos[2][1].y,pos[2][2].x,pos[2][2].y)
y3,z3,an3 = get_inter(pos[1][1].y,pos[1][1].z,pos[1][2].y,pos[1][2].z,pos[2][1].y,pos[2][1].z,pos[2][2].y,pos[2][2].z)
if an2>an1 then x1 = x2 end
if an3>an2 then y2 = y3 end
if an3>an1 then z1 = z3 end
local dist = math.floor(math.sqrt((p.x-x1)^2+(p.y-y2)^2+(p.z-z1)^2))
x1 = math.floor(10*x1)/10;y2 = math.floor(10*y2)/10;z1 = math.floor(10*z1)/10
say(minetest.colorize("lawngreen","TARGET IS AT " .. x1.. " " .. y2 .. " " .. z1 .. " (dist = " .. dist ..")"))