diff --git a/src/main/files/test-aes.lua b/src/main/files/test-aes.lua new file mode 100755 index 0000000..ce49764 --- /dev/null +++ b/src/main/files/test-aes.lua @@ -0,0 +1,15 @@ +os.loadAPI("bos/lib/aes.lua") +--aes = require("lib.aes") + + +local encMessage = aes.encrypt("MyKey", "My Message") + +print("encMessage: " .. encMessage) +sleep(2) + +local decMessage = aes.decrypt("MyKey", encMessage) +print("decMessage: " .. decMessage) +sleep(2) + + + diff --git a/src/main/files/test-hash.lua b/src/main/files/test-hash.lua new file mode 100755 index 0000000..173422d --- /dev/null +++ b/src/main/files/test-hash.lua @@ -0,0 +1,20 @@ +os.loadAPI("brammeros/programs/cryptography/hash.lua") + + +while true do + write("Eingabe: ") + message = read() + + hashedMessage = hash.digestStr(message) + print("") + print("Hashed Stuff: " .. hashedMessage) + print("") + print("") +end + + + + + + + diff --git a/src/main/lib/aes.lua b/src/main/lib/aes.lua new file mode 100755 index 0000000..38b9f5e --- /dev/null +++ b/src/main/lib/aes.lua @@ -0,0 +1,218 @@ +local function e(n) +local s=setmetatable({},{__index=_ENV or getfenv()})if setfenv then setfenv(n,s)end;return n(s)or s end +local t=e(function(n,...)local s=math.floor;local h,r +r=function(d,l)return s(d%4294967296/2^l)end +h=function(d,l)return(d*2^l)%4294967296 end +return{bnot=bit.bnot,band=bit.band,bor=bit.bor,bxor=bit.bxor,rshift=r,lshift=h}end) +local a=e(function(n,...)local s=t.bxor;local h=t.lshift;local r=0x100;local d=0xff;local l=0x11b;local u={}local c={} +local function m(k,q)return s(k,q)end;local function f(k,q)return s(k,q)end +local function w(k)if(k==1)then return 1 end;local q=d-c[k]return u[q]end;local function y(k,q)if(k==0 or q==0)then return 0 end;local j=c[k]+c[q] +if(j>=d)then j=j-d end;return u[j]end +local function p(k,q) +if(k==0)then return 0 end;local j=c[k]-c[q]if(j<0)then j=j+d end;return u[j]end +local function v()for k=1,r do print("log(",k-1,")=",c[k-1])end end +local function b()for k=1,r do print("exp(",k-1,")=",u[k-1])end end;local function g()local k=1 +for q=0,d-1 do u[q]=k;c[k]=q;k=s(h(k,1),k)if k>d then k=f(k,l)end end end;g()return +{add=m,sub=f,invert=w,mul=y,div=dib,printLog=v,printExp=b}end) +util=e(function(n,...)local s=t.bxor;local h=t.rshift;local r=t.band;local d=t.lshift;local l;local function u(O)O=s(O,h(O,4)) +O=s(O,h(O,2))O=s(O,h(O,1))return r(O,1)end +local function c(O,I)if(I==0)then return +r(O,0xff)else return r(h(O,I*8),0xff)end end;local function m(O,I) +if(I==0)then return r(O,0xff)else return d(r(O,0xff),I*8)end end +local function f(O,I,N)local S={} +for H=0,N-1 do +S[H+1]= +m(O[I+ (H*4)],3)+m(O[I+ (H*4)+1],2)+ +m(O[I+ (H*4)+2],1)+m(O[I+ (H*4)+3],0)if N%10000 ==0 then l()end end;return S end;local function w(O,I,N,S)S=S or#O;for H=0,S-1 do +for R=0,3 do I[N+H*4+ (3-R)]=c(O[H+1],R)end;if S%10000 ==0 then l()end end +return I end;local function y(O)local I="" +for N,S in +ipairs(O)do I=I..string.format("%02x ",S)end;return I end +local function p(O)local I={}for N=1,#O,2 do I[#I+1]=tonumber(O:sub(N, +N+1),16)end;return I end +local function v(O)local I=type(O) +if(I=="number")then return string.format("%08x",O)elseif +(I=="table")then return y(O)elseif(I=="string")then local N={string.byte(O,1,#O)} +return y(N)else return O end end +local function b(O)local I=#O;local N=math.random(0,255)local S=math.random(0,255) +local H=string.char(N,S,N,S,c(I,3),c(I,2),c(I,1),c(I,0))O=H..O;local R=math.ceil(#O/16)*16-#O;local D=""for L=1,R do D=D.. +string.char(math.random(0,255))end;return O..D end +local function g(O)local I={string.byte(O,1,4)}if +(I[1]==I[3]and I[2]==I[4])then return true end;return false end +local function k(O)if(not g(O))then return nil end +local I= +m(string.byte(O,5),3)+ +m(string.byte(O,6),2)+m(string.byte(O,7),1)+m(string.byte(O,8),0)return string.sub(O,9,8+I)end;local function q(O,I)for N=1,16 do O[N]=s(O[N],I[N])end end +local function j(O) +local I=16;while true do local N=O[I]+1 +if N>=256 then O[I]=N-256;I=(I-2)%16+1 else O[I]=N;break end end end;local x,z,_=os.queueEvent,coroutine.yield,os.time;local E=_() +local function l()local O=_()if O-E>=0.03 then E=O +x("sleep")z("sleep")end end +local function T(O)local I,N,S,H=string.char,math.random,l,table.insert;local R={}for D=1,O do +H(R,N(0,255))if D%10240 ==0 then S()end end;return R end +local function A(O)local I,N,S,H=string.char,math.random,l,table.insert;local R={}for D=1,O do +H(R,I(N(0,255)))if D%10240 ==0 then S()end end +return table.concat(R)end +return +{byteParity=u,getByte=c,putByte=m,bytesToInts=f,intsToBytes=w,bytesToHex=y,hexToBytes=p,toHexString=v,padByteString=b,properlyDecrypted=g,unpadByteString=k,xorIV=q,increment=j,sleepCheckIn=l,getRandomData=T,getRandomString=A}end) +aes=e(function(n,...)local s=util.putByte;local h=util.getByte;local r='rounds'local d="type"local l=1;local u=2 +local c={}local m={}local f={}local w={}local y={}local p={}local v={}local b={}local g={}local k={} +local q={0x01000000,0x02000000,0x04000000,0x08000000,0x10000000,0x20000000,0x40000000,0x80000000,0x1b000000,0x36000000,0x6c000000,0xd8000000,0xab000000,0x4d000000,0x9a000000,0x2f000000} +local function j(M)mask=0xf8;result=0 +for F=1,8 do result=t.lshift(result,1) +parity=util.byteParity(t.band(M,mask))result=result+parity;lastbit=t.band(mask,1) +mask=t.band(t.rshift(mask,1),0xff) +if(lastbit~=0)then mask=t.bor(mask,0x80)else mask=t.band(mask,0x7f)end end;return t.bxor(result,0x63)end;local function x() +for M=0,255 do if(M~=0)then inverse=a.invert(M)else inverse=M end +mapped=j(inverse)c[M]=mapped;m[mapped]=M end end +local function z() +for M=0,255 do +byte=c[M] +f[M]= +s(a.mul(0x03,byte),0)+s(byte,1)+s(byte,2)+s(a.mul(0x02,byte),3)w[M]=s(byte,0)+s(byte,1)+s(a.mul(0x02,byte),2)+ +s(a.mul(0x03,byte),3)y[M]= + +s(byte,0)+s(a.mul(0x02,byte),1)+s(a.mul(0x03,byte),2)+s(byte,3)p[M]= + +s(a.mul(0x02,byte),0)+s(a.mul(0x03,byte),1)+s(byte,2)+s(byte,3)end end +local function _() +for M=0,255 do byte=m[M] +v[M]= +s(a.mul(0x0b,byte),0)+s(a.mul(0x0d,byte),1)+s(a.mul(0x09,byte),2)+ +s(a.mul(0x0e,byte),3) +b[M]= +s(a.mul(0x0d,byte),0)+s(a.mul(0x09,byte),1)+s(a.mul(0x0e,byte),2)+ +s(a.mul(0x0b,byte),3) +g[M]= +s(a.mul(0x09,byte),0)+s(a.mul(0x0e,byte),1)+s(a.mul(0x0b,byte),2)+ +s(a.mul(0x0d,byte),3) +k[M]= +s(a.mul(0x0e,byte),0)+s(a.mul(0x0b,byte),1)+s(a.mul(0x0d,byte),2)+ +s(a.mul(0x09,byte),3)end end;local function E(M)local F=t.band(M,0xff000000)return +(t.lshift(M,8)+t.rshift(F,24))end +local function T(M)return +s(c[h(M,0)],0)+s(c[h(M,1)],1)+s(c[h(M,2)],2)+ +s(c[h(M,3)],3)end +local function A(M)local F={}local W=math.floor(#M/4)if( +(W~=4 and W~=6 and W~=8)or(W*4 ~=#M))then +error("Invalid key size: "..tostring(W))return nil end;F[r]=W+6;F[d]=l;for Y=0,W-1 +do +F[Y]= +s(M[Y*4+1],3)+s(M[Y*4+2],2)+s(M[Y*4+3],1)+s(M[Y*4+4],0)end +for Y=W,(F[r]+1)*4-1 do +local P=F[Y-1] +if(Y%W==0)then P=E(P)P=T(P)local V=math.floor(Y/W)P=t.bxor(P,q[V])elseif( +W>6 and Y%W==4)then P=T(P)end;F[Y]=t.bxor(F[(Y-W)],P)end;return F end +local function O(M)local F=h(M,3)local W=h(M,2)local Y=h(M,1)local P=h(M,0) +return + + + +s(a.add(a.add(a.add(a.mul(0x0b,W),a.mul(0x0d,Y)),a.mul(0x09,P)),a.mul(0x0e,F)),3)+ +s(a.add(a.add(a.add(a.mul(0x0b,Y),a.mul(0x0d,P)),a.mul(0x09,F)),a.mul(0x0e,W)),2)+ +s(a.add(a.add(a.add(a.mul(0x0b,P),a.mul(0x0d,F)),a.mul(0x09,W)),a.mul(0x0e,Y)),1)+ +s(a.add(a.add(a.add(a.mul(0x0b,F),a.mul(0x0d,W)),a.mul(0x09,Y)),a.mul(0x0e,P)),0)end +local function I(M)local F=h(M,3)local W=h(M,2)local Y=h(M,1)local P=h(M,0)local V=t.bxor(P,Y) +local B=t.bxor(W,F)local G=t.bxor(V,B)G=t.bxor(G,a.mul(0x08,G)) +w=t.bxor(G,a.mul(0x04,t.bxor(Y,F)))G=t.bxor(G,a.mul(0x04,t.bxor(P,W))) +return + + +s(t.bxor(t.bxor(P,G),a.mul(0x02,t.bxor(F,P))),0)+s(t.bxor(t.bxor(Y,w),a.mul(0x02,V)),1)+ +s(t.bxor(t.bxor(W,G),a.mul(0x02,t.bxor(F,P))),2)+ +s(t.bxor(t.bxor(F,w),a.mul(0x02,B)),3)end +local function N(M)local F=A(M)if(F==nil)then return nil end;F[d]=u;for W=4,(F[r]+1)*4-5 do +F[W]=O(F[W])end;return F end;local function S(M,F,W) +for Y=0,3 do M[Y+1]=t.bxor(M[Y+1],F[W*4+Y])end end +local function H(M,F) +F[1]=t.bxor(t.bxor(t.bxor(f[h(M[1],3)],w[h(M[2],2)]),y[h(M[3],1)]),p[h(M[4],0)]) +F[2]=t.bxor(t.bxor(t.bxor(f[h(M[2],3)],w[h(M[3],2)]),y[h(M[4],1)]),p[h(M[1],0)]) +F[3]=t.bxor(t.bxor(t.bxor(f[h(M[3],3)],w[h(M[4],2)]),y[h(M[1],1)]),p[h(M[2],0)]) +F[4]=t.bxor(t.bxor(t.bxor(f[h(M[4],3)],w[h(M[1],2)]),y[h(M[2],1)]),p[h(M[3],0)])end +local function R(M,F) +F[1]=s(c[h(M[1],3)],3)+s(c[h(M[2],2)],2)+ +s(c[h(M[3],1)],1)+s(c[h(M[4],0)],0) +F[2]=s(c[h(M[2],3)],3)+s(c[h(M[3],2)],2)+ +s(c[h(M[4],1)],1)+s(c[h(M[1],0)],0) +F[3]=s(c[h(M[3],3)],3)+s(c[h(M[4],2)],2)+ +s(c[h(M[1],1)],1)+s(c[h(M[2],0)],0) +F[4]=s(c[h(M[4],3)],3)+s(c[h(M[1],2)],2)+ +s(c[h(M[2],1)],1)+s(c[h(M[3],0)],0)end +local function D(M,F) +F[1]=t.bxor(t.bxor(t.bxor(v[h(M[1],3)],b[h(M[4],2)]),g[h(M[3],1)]),k[h(M[2],0)]) +F[2]=t.bxor(t.bxor(t.bxor(v[h(M[2],3)],b[h(M[1],2)]),g[h(M[4],1)]),k[h(M[3],0)]) +F[3]=t.bxor(t.bxor(t.bxor(v[h(M[3],3)],b[h(M[2],2)]),g[h(M[1],1)]),k[h(M[4],0)]) +F[4]=t.bxor(t.bxor(t.bxor(v[h(M[4],3)],b[h(M[3],2)]),g[h(M[2],1)]),k[h(M[1],0)])end +local function L(M,F) +F[1]=s(m[h(M[1],3)],3)+s(m[h(M[4],2)],2)+ +s(m[h(M[3],1)],1)+s(m[h(M[2],0)],0) +F[2]=s(m[h(M[2],3)],3)+s(m[h(M[1],2)],2)+ +s(m[h(M[4],1)],1)+s(m[h(M[3],0)],0) +F[3]=s(m[h(M[3],3)],3)+s(m[h(M[2],2)],2)+ +s(m[h(M[1],1)],1)+s(m[h(M[4],0)],0) +F[4]=s(m[h(M[4],3)],3)+s(m[h(M[3],2)],2)+ +s(m[h(M[2],1)],1)+s(m[h(M[1],0)],0)end +local function U(M,F,W,Y,P)W=W or 1;Y=Y or{}P=P or 1;local V={}local B={}if(M[d]~=l)then +error("No encryption key: ".. +tostring(M[d])..", expected "..l)return end +V=util.bytesToInts(F,W,4)S(V,M,0)local G=1;while(G2)do +D(V,B)S(B,M,G)G=G-1;D(B,V)S(V,M,G)G=G-1 end;D(V,B) +S(B,M,G)G=G-1;L(B,V)S(V,M,G)util.sleepCheckIn()return +util.intsToBytes(V,Y,P)end;x()z()_() +return{ROUNDS=r,KEY_TYPE=d,ENCRYPTION_KEY=l,DECRYPTION_KEY=u,expandEncryptionKey=A,expandDecryptionKey=N,encrypt=U,decrypt=C}end) +local o=e(function(n,...)local function s()return{}end;local function h(d,l)table.insert(d,l)end;local function r(d)return +table.concat(d)end;return{new=s,addString=h,toString=r}end) +ciphermode=e(function(n,...)local s={}local h=math.random +function s.encryptString(r,d,l,u)if u then local f={}for w=1,16 do f[w]=u[w]end;u=f else +u={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}end +local c=aes.expandEncryptionKey(r)local m=o.new()for f=1,#d/16 do local w=(f-1)*16+1 +local y={string.byte(d,w,w+15)}u=l(c,y,u) +o.addString(m,string.char(unpack(y)))end +return o.toString(m)end;function s.encryptECB(r,d,l)aes.encrypt(r,d,1,d,1)end;function s.encryptCBC(r,d,l) +util.xorIV(d,l)aes.encrypt(r,d,1,d,1)return d end;function s.encryptOFB(r,d,l) +aes.encrypt(r,l,1,l,1)util.xorIV(d,l)return l end;function s.encryptCFB(r,d,l) +aes.encrypt(r,l,1,l,1)util.xorIV(d,l)return d end +function s.encryptCTR(r,d,l) +local u={}for c=1,16 do u[c]=l[c]end;aes.encrypt(r,l,1,l,1) +util.xorIV(d,l)util.increment(u)return u end +function s.decryptString(r,d,l,u)if u then local f={}for w=1,16 do f[w]=u[w]end;u=f else +u={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}end;local c +if l==s.decryptOFB or +l==s.decryptCFB or l==s.decryptCTR then +c=aes.expandEncryptionKey(r)else c=aes.expandDecryptionKey(r)end;local m=o.new()for f=1,#d/16 do local w=(f-1)*16+1 +local y={string.byte(d,w,w+15)}u=l(c,y,u) +o.addString(m,string.char(unpack(y)))end +return o.toString(m)end;function s.decryptECB(r,d,l)aes.decrypt(r,d,1,d,1)return l end;function s.decryptCBC(r,d,l) +local u={}for c=1,16 do u[c]=d[c]end;aes.decrypt(r,d,1,d,1) +util.xorIV(d,l)return u end;function s.decryptOFB(r,d,l) +aes.encrypt(r,l,1,l,1)util.xorIV(d,l)return l end;function s.decryptCFB(r,d,l) +local u={}for c=1,16 do u[c]=d[c]end;aes.encrypt(r,l,1,l,1) +util.xorIV(d,l)return u end +s.decryptCTR=s.encryptCTR;return s end)AES128=16;AES192=24;AES256=32;ECBMODE=1;CBCMODE=2;OFBMODE=3;CFBMODE=4;CTRMODE=4 +local function i(n,s,h)local r=s;if(s== +AES192)then r=32 end +if(r>#n)then local l=""for u=1,r-#n do +l=l..string.char(0)end;n=n..l else n=string.sub(n,1,r)end;local d={string.byte(n,1,#n)} +n=ciphermode.encryptString(d,n,ciphermode.encryptCBC,h)n=string.sub(n,1,s)return{string.byte(n,1,#n)}end +function encrypt(n,s,h,r,d)assert(n~=nil,"Empty password.") +assert(n~=nil,"Empty data.")local r=r or CBCMODE;local h=h or AES128;local l=i(n,h,d) +local u=util.padByteString(s) +if r==ECBMODE then +return ciphermode.encryptString(l,u,ciphermode.encryptECB,d)elseif r==CBCMODE then +return ciphermode.encryptString(l,u,ciphermode.encryptCBC,d)elseif r==OFBMODE then +return ciphermode.encryptString(l,u,ciphermode.encryptOFB,d)elseif r==CFBMODE then +return ciphermode.encryptString(l,u,ciphermode.encryptCFB,d)elseif r==CTRMODE then +return ciphermode.encryptString(l,u,ciphermode.encryptCTR,d)else error("Unknown mode",2)end end +function decrypt(n,s,h,r,d)local r=r or CBCMODE;local h=h or AES128;local l=i(n,h,d)local u +if r==ECBMODE then +u=ciphermode.decryptString(l,s,ciphermode.decryptECB,d)elseif r==CBCMODE then +u=ciphermode.decryptString(l,s,ciphermode.decryptCBC,d)elseif r==OFBMODE then +u=ciphermode.decryptString(l,s,ciphermode.decryptOFB,d)elseif r==CFBMODE then +u=ciphermode.decryptString(l,s,ciphermode.decryptCFB,d)elseif r==CTRMODE then +u=ciphermode.decryptString(l,s,ciphermode.decryptCTR,d)else error("Unknown mode",2)end;result=util.unpadByteString(u) +if(result==nil)then return nil end;return result end \ No newline at end of file diff --git a/src/main/lib/basic-functions.lua b/src/main/lib/basic-functions.lua new file mode 100755 index 0000000..93a40a3 --- /dev/null +++ b/src/main/lib/basic-functions.lua @@ -0,0 +1,62 @@ +function clear_display() + term.clear() + term.setCursorPos(1,1) +end + +function write_to_file(file, content) + file = fs.open(file, "w") + file.write(content) + file.close() +end + +function append_to_file(file, content) + file = fs.open(file, "a") + file.write(content) + file.close() +end + +function append_to_file_nl(file, content) + file = fs.open(file, "a") + file.writeLine(content) + file.close() +end + +function read_file_oneline(file) + file = fs.open(file, "r") + data = file.readLine() + file.close() + if (data == "true") then data = true elseif data == "false" then data = false end + return data +end + +function read_file_all(file) + file = fs.open(file, "r") + if (file == nil) then + print("File does not exist.") + else + data = file.readAll() + file.close() + end + return data +end + +function split_string_to_array(input_str) + table = {} + i = 0 + for str in string.gmatch(input_str, "([^"..",".."]+)") do + table[i] = str + i = i + 1 + end + return table +end + +return +{ + clear_display=clear_display, + write_to_file=write_to_file, + append_to_file=append_to_file, + append_to_file_nl=append_to_file_nl, + read_file_oneline=read_file_oneline, + read_file_all=read_file_all, + split_string_to_array=split_string_to_array, +} \ No newline at end of file diff --git a/src/main/lib/hash.lua b/src/main/lib/hash.lua new file mode 100755 index 0000000..34da3f9 --- /dev/null +++ b/src/main/lib/hash.lua @@ -0,0 +1,206 @@ +-- SHA-256 +-- By KillaVanilla + +k = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +} + +local function generateShiftBitmask(bits) + local bitmask = 0 + for i=1, bits do + bit.bor(bitmask, 0x8000000) + bit.brshift(bitmask, 1) + end + return bitmask +end + +local function rrotate(input, shiftAmount) + if input > (2^32) then + input = input % (2^32) + end + return bit.bor( bit.brshift(input, shiftAmount), bit.blshift(input, 32-shiftAmount) ) +end + +local function Preprocessing(message) + local len = #message*8 + local bits = #message*8 + table.insert(message, 1) + while true do + if bits % 512 == 448 then + break + else + table.insert(message, 0) + bits = #message*8 + end + end + table.insert(message, len) + return message +end + +local function breakMsg(message) + local chunks = {} + local chunk = 1 + for word=1, #message, 16 do + chunks[chunk] = {} + table.insert(chunks[chunk], message[word] or 0) + table.insert(chunks[chunk], message[word+1] or 0) + table.insert(chunks[chunk], message[word+2] or 0) + table.insert(chunks[chunk], message[word+3] or 0) + table.insert(chunks[chunk], message[word+4] or 0) + table.insert(chunks[chunk], message[word+5] or 0) + table.insert(chunks[chunk], message[word+6] or 0) + table.insert(chunks[chunk], message[word+7] or 0) + table.insert(chunks[chunk], message[word+8] or 0) + table.insert(chunks[chunk], message[word+9] or 0) + table.insert(chunks[chunk], message[word+10] or 0) + table.insert(chunks[chunk], message[word+11] or 0) + table.insert(chunks[chunk], message[word+12] or 0) + table.insert(chunks[chunk], message[word+13] or 0) + table.insert(chunks[chunk], message[word+14] or 0) + table.insert(chunks[chunk], message[word+15] or 0) + chunk = chunk+1 + end + return chunks +end + +local function digestChunk(chunk, hash) + for i=17, 64 do + local s0 = bit.bxor( bit.brshift(chunk[i-15], 3), bit.bxor( rrotate(chunk[i-15], 7), rrotate(chunk[i-15], 18) ) ) + local s1 = bit.bxor( bit.brshift(chunk[i-2], 10), bit.bxor( rrotate(chunk[i-2], 17), rrotate(chunk[i-2], 19) ) ) + chunk[i] = (chunk[i-16] + s0 + chunk[i-7] + s1) % (2^32) + end + + local a = hash[1] + local b = hash[2] + local c = hash[3] + local d = hash[4] + local e = hash[5] + local f = hash[6] + local g = hash[7] + local h = hash[8] + + for i=1, 64 do + local S1 = bit.bxor(rrotate(e, 6), bit.bxor(rrotate(e,11),rrotate(e,25))) + local ch = bit.bxor( bit.band(e, f), bit.band(bit.bnot(e), g) ) + local t1 = h + S1 + ch + k[i] + chunk[i] + --d = d+h + S0 = bit.bxor(rrotate(a,2), bit.bxor( rrotate(a,13), rrotate(a,22) )) + local maj = bit.bxor( bit.band( a, bit.bxor(b, c) ), bit.band(b, c) ) + local t2 = S0 + maj + + h = g + g = f + f = e + e = d + t1 + d = c + c = b + b = a + a = t1 + t2 + + a = a % (2^32) + b = b % (2^32) + c = c % (2^32) + d = d % (2^32) + e = e % (2^32) + f = f % (2^32) + g = g % (2^32) + h = h % (2^32) + + end + + hash[1] = (hash[1] + a) % (2^32) + hash[2] = (hash[2] + b) % (2^32) + hash[3] = (hash[3] + c) % (2^32) + hash[4] = (hash[4] + d) % (2^32) + hash[5] = (hash[5] + e) % (2^32) + hash[6] = (hash[6] + f) % (2^32) + hash[7] = (hash[7] + g) % (2^32) + hash[8] = (hash[8] + h) % (2^32) + + return hash +end + +function digest(msg) + msg = Preprocessing(msg) + local hash = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19} + local chunks = breakMsg(msg) + for i=1, #chunks do + hash = digestChunk(chunks[i], hash) + end + return hash +end + +function digestStr(input) + -- transform the input into a table of ints: + local output = {} + local outputStr = "" + for i=1, #input do + output[i] = string.byte(input, i, i) + end + output = digest(output) + for i=1, #output do + outputStr = outputStr..string.format("%X", output[i]) + end + return outputStr, output +end + +function hashToBytes(hash) + local bytes = {} + for i=1, 8 do + table.insert(bytes, bit.band(bit.brshift(bit.band(hash[i], 0xFF000000), 24), 0xFF)) + table.insert(bytes, bit.band(bit.brshift(bit.band(hash[i], 0xFF0000), 16), 0xFF)) + table.insert(bytes, bit.band(bit.brshift(bit.band(hash[i], 0xFF00), 8), 0xFF)) + table.insert(bytes, bit.band(hash[i], 0xFF)) + end + return bytes +end + +function hmac(input, key) + -- HMAC(H,K,m) = H( (K opad) .. H((K ipad) .. m)) + -- Where: + -- H - cryptographic hash function. In this case, H is SHA-256. + -- K - The secret key. + -- if length(K) > 256 bits or 32 bytes, then K = H(K) + -- if length(K) < 256 bits or 32 bytes, then pad K to the right with zeroes. (i.e pad(K) = K .. repeat(0, 32 - byte_length(K))) + -- m - The message to be authenticated. + -- .. - byte concentration + -- eXclusive OR. + -- opad - Outer Padding, equal to repeat(0x5C, 32). + -- ipad - Inner Padding, equal to repeat(0x36, 32). + if #key > 32 then + local keyDigest = digest(key) + key = keyDigest + elseif #key < 32 then + for i=#key, 32 do + key[i] = 0 + end + end + local opad = {} + local ipad = {} + for i=1, 32 do + opad[i] = bit.bxor(0x5C, key[i] or 0) + ipad[i] = bit.bxor(0x36, key[i] or 0) + end + local padded_key = {} + for i=1, #input do + ipad[32+i] = input[i] + end + local ipadHash = hashToBytes(digest(ipad)) + ipad = ipadHash + for i=1, 32 do + padded_key[i] = opad[i] + padded_key[32+i] = ipad[i] + end + return digest(padded_key) +end + +return { + digestStr=digestStr +} \ No newline at end of file diff --git a/src/main/lib/networking.lua b/src/main/lib/networking.lua new file mode 100755 index 0000000..04def91 --- /dev/null +++ b/src/main/lib/networking.lua @@ -0,0 +1,110 @@ + +basic_functions = require("lib.basic-functions") +hash = require("lib.hash") +--aes = require("lib.aes") --aes does not yet work with require +os.loadAPI("bos/lib/aes.lua") + +function create_keyfile() + basic_functions.clear_display() + write("Please enter shared secret for networking: ") + local pw_hash = hash.digestStr(read("*") .. "salty salt") + basic_functions.write_to_file("bos/files/networking-key.txt", pw_hash) + basic_functions.clear_display() +end + +local function get_keyfile() + local pw_hash = basic_functions.read_file_oneline("bos/files/networking-key.txt") + return pw_hash +end + +local function setup() + own_label = os.computerLabel() + peripheral.find("modem", rednet.open) + if not fs.exists "bos/files/networking-key.txt" then + create_keyfile() + end +end + +--[[ +String target ist label des Computers. zb "computer1", "miner1", "farmer1", etc +String message ist einfach der Text der Übertragen werden soll +]] +function send_message(to, what, payload) + setup() + local keyfile = get_keyfile() + local msg_table = {} + msg_table[0] = own_label + msg_table[1] = to + msg_table[2] = what + msg_table[3] = payload + + local enc_msg = aes.encrypt(keyfile, textutils.serialize(msg_table)) + rednet.broadcast(enc_msg) +end + +function send_file(to, origin_path, target_path) + setup() + local keyfile = get_keyfile() + local payload_table = {} + + print("sending " .. origin_path .. " to " .. to) + + local file_content = basic_functions.read_file_all(origin_path) + payload_table[0] = target_path + payload_table[1] = file_content + + send_message(to, "file_transfer", payload_table) + sleep(0.5) +end + +function receive_message() + setup() + local keyfile = get_keyfile() + local id, rec_msg, prot = rednet.receive() + local pcall_success, decr_msg = pcall(aes.decrypt, keyfile, rec_msg) + + if pcall_success and decr_msg ~= nil then + local rec_table = textutils.unserialize(decr_msg) + + local from = rec_table[0] + local to = rec_table[1] + local what = rec_table[2] + local payload = rec_table[3] + + if to == own_label or to == "all" then + if what == "file_transfer" then + basic_functions.write_to_file(payload[0], payload[1]) + return "event: file transfer received" + elseif what == "execute_script" then + shell.run(payload) + return + elseif what == "script_command" then + return rec_table[3] + end + + return rec_table + end + else + return "event: unencrypted message" + end +end + +return { + send_message = send_message, + send_file = send_file, + receive_message = receive_message, +} + + + + + + + + + + + + + + diff --git a/src/main/lib/test-aes.lua b/src/main/lib/test-aes.lua new file mode 100755 index 0000000..ce49764 --- /dev/null +++ b/src/main/lib/test-aes.lua @@ -0,0 +1,15 @@ +os.loadAPI("bos/lib/aes.lua") +--aes = require("lib.aes") + + +local encMessage = aes.encrypt("MyKey", "My Message") + +print("encMessage: " .. encMessage) +sleep(2) + +local decMessage = aes.decrypt("MyKey", encMessage) +print("decMessage: " .. decMessage) +sleep(2) + + + diff --git a/src/main/lib/test-hash.lua b/src/main/lib/test-hash.lua new file mode 100755 index 0000000..173422d --- /dev/null +++ b/src/main/lib/test-hash.lua @@ -0,0 +1,20 @@ +os.loadAPI("brammeros/programs/cryptography/hash.lua") + + +while true do + write("Eingabe: ") + message = read() + + hashedMessage = hash.digestStr(message) + print("") + print("Hashed Stuff: " .. hashedMessage) + print("") + print("") +end + + + + + + + diff --git a/src/main/programs/open_staircase.lua b/src/main/programs/open_staircase.lua new file mode 100755 index 0000000..58182ab --- /dev/null +++ b/src/main/programs/open_staircase.lua @@ -0,0 +1,11 @@ +basic_functions = require("lib.basic-functions") +networking = require("lib.networking") + +function send_open_command() + networking.send_message("Door Panel", "script_command", "open_staircase") +end + + +send_open_command() + + diff --git a/src/main/programs/stairs.lua b/src/main/programs/stairs.lua new file mode 100755 index 0000000..005a37e --- /dev/null +++ b/src/main/programs/stairs.lua @@ -0,0 +1,18 @@ +function open_stair() + redstone.setOutput("bottom", true) + print("Stairs opened") +end + +function close_stairs() + redstone.setOutput("bottom", false) + print("Stairs closed") +end + + + +while true do + open_stairs() + sleep(5) + close_stairs() + sleep(5) +end diff --git a/src/main/programs/sync-client.lua b/src/main/programs/sync-client.lua new file mode 100644 index 0000000..632ff86 --- /dev/null +++ b/src/main/programs/sync-client.lua @@ -0,0 +1,93 @@ +if not fs.exists "bos/lib/aes.lua" then + shell.run("pastebin get bkege8fc bos/lib/aes.lua") +end +--aes = require("bos.lib.aes") --aes does not yet work with require +os.loadAPI("bos/lib/aes.lua") + +if not fs.exists "bos/lib/hash.lua" then + shell.run("pastebin get DVLAZ4K7 bos/lib/hash.lua") +end +hash = require("bos.lib.hash") + +local function write_to_file(file, content) + file = fs.open(file, "w") + file.write(content) + file.close() +end + +local function read_file_oneline(file) + file = fs.open(file, "r") + data = file.readLine() + file.close() + if (data == "true") then data = true elseif data == "false" then data = false end + return data +end + +local function clear_display() + term.clear() + term.setCursorPos(1,1) +end + +local function create_keyfile() + clear_display() + write("Please enter shared secret for networking: ") + local pw_hash = hash.digestStr(read("*") .. "salty salt") + write_to_file("bos/files/networking-key.txt", pw_hash) + clear_display() +end + +local function setup() + print(">starting sync-client-setup") + from = os.computerLabel() + peripheral.find("modem", rednet.open) + if not fs.exists "bos/files/networking-key.txt" then + create_keyfile() + end + print(">sync-client-setup finished") + sleep(2) +end + +local function get_keyfile() + pw_hash = read_file_oneline("bos/files/networking-key.txt") + return pw_hash +end + +local function receive_message() + keyfile = get_keyfile() + id, rec_msg, prot = rednet.receive() + pcall_success, decr_msg = pcall(aes.decrypt, keyfile, rec_msg) + + if pcall_success and decr_msg ~= nil then + rec_table = textutils.unserialize(decr_msg) + + if rec_table[1] == from then + if rec_table[2] == "file_transfer" then + write_to_file(rec_table[3][0], rec_table[3][1]) + return "event: received " .. rec_table[3][0] + end + + return rec_table + end + else + return "event: unencrypted message" + end +end + +function send_message(to, what, payload) + setup() + keyfile = get_keyfile() + local msg_table = {} + msg_table[0] = from + msg_table[1] = to + msg_table[2] = what + msg_table[3] = payload + + enc_msg = aes.encrypt(keyfile, textutils.serialize(msg_table)) + rednet.broadcast(enc_msg) +end + +setup() +print(">modem required") +while true do + print(receive_message()) +end diff --git a/src/main/programs/sync-server.lua b/src/main/programs/sync-server.lua new file mode 100755 index 0000000..bbc438e --- /dev/null +++ b/src/main/programs/sync-server.lua @@ -0,0 +1,45 @@ +--os.loadAPI("brammeros/programs/system/basic_functions.lua") +--basic_functions.load_apis() +basic_functions = require("lib.basic-functions") +networking = require("lib.networking") + +function setup() + print(">starting netwroking setup") + sleep(1) + if not fs.exists "bos/files/sync-targets.txt" then + sync_targets = {} + sync_targets[0] = "placeholder" + basic_functions.write_to_file("bos/files/sync-targets.txt", textutils.serialize(sync_targets)) + end + + if not fs.exists "bos/files/sync-filelist.txt" then + sync_filelist = {} + sync_filelist[0] = "placeholder" + basic_functions.write_to_file("bos/files/sync-filelist.txt", textutils.serialize(sync_filelist)) + end +end + +function sync_files() + for i=0, #sync_filelist do + for j=0, #sync_targets do + networking.send_file(sync_targets[j], sync_filelist[i], sync_filelist[i]) + end + end +end + +local function get_sync_targets() + sync_targets = basic_functions.read_file_all("bos/files/sync-targets.txt") + sync_targets = textutils.unserialize(sync_targets) + return sync_targets +end + +local function get_sync_filelist() + local sync_filelist = basic_functions.read_file_all("bos/files/sync-filelist.txt") + sync_filelist = textutils.unserialize(sync_filelist) + return sync_filelist +end + +setup() +sync_targets = get_sync_targets() +sync_filelist = get_sync_filelist() +sync_files() diff --git a/src/main/programs/system-lock.lua b/src/main/programs/system-lock.lua new file mode 100755 index 0000000..6426fad --- /dev/null +++ b/src/main/programs/system-lock.lua @@ -0,0 +1,66 @@ +basic_functions = require("lib.basic-functions") +hash = require("lib.hash") + +local function create_new_bos_pw() + basic_functions.clear_display() + print("Enter a new Password for bos: ") + local input = read("*") + local pw_hash = hash.digestStr(input .. os.getComputerID()) + basic_functions.write_to_file("bos/files/bos-pw-hash.txt", pw_hash) +end + +local function pw_prompt() + write("Enter Password: ") + pw_input = hash.digestStr(read("*") .. os.getComputerID()) +end + +local function timeout_check() + sleep(10) + timeout_event = true +end + +local function pw_check(pw_input) + local correct_pw = basic_functions.read_file_oneline("bos/files/bos-pw-hash.txt") + return (pw_input == correct_pw) +end + +local function main() + --oldEvent = os.pullEvent + --os.pullEvent = os.pullEventRaw + if not (fs.exists("bos/files/bos-pw-hash.txt")) then + create_new_bos_pw() + end + + while (true) do + basic_functions.clear_display() + pw_input = nil + timeout_event = false + parallel.waitForAny(pw_prompt, timeout_check) + local pw_check_passed = pw_check(pw_input) + + if (pw_check_passed) then + basic_functions.clear_display() + basic_functions.write_to_file("bos/files/system-lock-status.txt", false) + print("Correct.") + sleep(0.2) + basic_functions.clear_display() + return + elseif timeout_event then + basic_functions.clear_display() + basic_functions.write_to_file("bos/files/system-lock-status.txt", true) + print("Timeout...") + sleep(1) + return + else + basic_functions.clear_display() + basic_functions.write_to_file("bos/files/system-lock-status.txt", true) + print("Sorry that was not correct...") + sleep(1) + print("rebooting...") + sleep(1) + return + end + end +end + +main() diff --git a/src/main/programs/turtle-build.lua b/src/main/programs/turtle-build.lua new file mode 100755 index 0000000..1d80237 --- /dev/null +++ b/src/main/programs/turtle-build.lua @@ -0,0 +1,20 @@ +function build_platform(width, depth) + for i=0, width-1 do + for j=0, depth-1 do + turtle.placeDown() + turtle.forward() + end + for j=0, depth-1 do + turtle.back() + end + turtle.turnRight() + turtle.forward() + turtle.turnLeft() + end + turtle.turnLeft() + for i=0, width-1 do + turtle.forward() + end +end + +build_platform(8, 8) \ No newline at end of file diff --git a/src/main/programs/turtle-logistic.lua b/src/main/programs/turtle-logistic.lua new file mode 100755 index 0000000..b0b3c96 --- /dev/null +++ b/src/main/programs/turtle-logistic.lua @@ -0,0 +1,274 @@ +function error() + print(Error) + read() +end + +function getStartPosition() + + local file = fs.open("logistics/startPosition","r") + local data = file.readLine() + file.close() + startPosition = data +end + + +function saveStartPosition(startPosition) + + local file = fs.open("logistics/startPosition","w") + file.write(startPosition) + file.close() +end + + + + +function getStorageContent() + + local file = fs.open("logistics/storageContent","r") + local data = file.readAll() + file.close() + storageContent = textutils.unserialize(data) +end + + +function saveStorageContent() + + local file = fs.open("logistics/storageContent","w") + file.write(textutils.serialize(storageContent)) + file.close() +end + +function createStorageContentMatrix(d,w,h) + + storageContent = {} + + for i=1, d do + storageContent[i] = {} + + for j=1, w do + storageContent[i][j] = {} + + for k=1, h do + storageContent[i][j][k] = {"empty", 0} + end + end + end +end + + + + + + +function chooseChestToGoTo() + + if not exist "logistics/storageContent" then + + createStorageContentMatrix() + else + + getStorageContent() + end + + + for i=1, #storageContent do + for j=1, #storageContent[i] do + for k=1, #storageContent[i][j] do + + if (storageContent[i][j][k][1] == itemDetail.name) and (storageContent[i][j][k][2] < 1664) then + return i,j,k + end + end + end + end + + + for i=1, #storageContent do + for j=1, #storageContent[i] do + for k=1, #storageContent[i][j] do + + if (storageContent[i][j][k][1] == "empty") and (storageContent[i][j][k][2] == 0) then + return i,j,k + + print("Lagerplatz nicht ausreichend.") + error() + end + end + end + end +end + + + + + + +function goToChosenChest(d,w,h) + + -- d + turtle.left() + turtle.left() + + for x=1, d do + + turtle.forward() + turtle.forward() + end + + turtle.back() + turtle.back() + + -- w + turtle.right() + + for y=1, w do + + turtle.forward() + end + + -- h + turtle.left() + + for z=1, h do + + turtle.up() + end +end + + + + + + +function goToStartChest() + + turtle.left() + while not (turtl.detect()) do + turtle.forward() + end + turtle.left() + while not (turtl.detect()) do + turtle.forward() + end + while not (turtl.detectDown()) do + turtle.down() + end + if (turtlePosition ~= startPosition) then + print("Turtle nicht bei Startposition.") + error() + end +end + + + + + + +function sortSlotInStorage() + + d,w,h = chooseChestToGoTo() + goToChosenChest(d,w,h) + + + local spaceInChest == 1728 - storageContent[d][w][h][2] + + if (spaceInChest > 0) then + + itemDetailCount = itemDetail.count + + turtle.drop() + + storageContent[d][w][h][1] = itemDetail.name + storageContent[d][w][h][2] = storageContent[d][w][h][2] + itemDetailCount + saveStorageContent() + end + + goToStartChest() +end + + + + + + +function sortChestInStorage() + + for i=1, 16 do + + turtle.suck(64) + end + + for i=1, 16 do + + turtle.select(i) + itemDetail = turtle.getItemDetail() + + if itemDetail then + sortSlotInStorage() + end + end +end + + + + + + +function refuelIfNeeded() + + while (turtle.getFuelLevel() <= 1000) do + + print("Wenig Treibstoff. Items werden nicht wegsortiert.") + write("Wenn die Turtle sich nachfüllen soll, dann gebe \"refuel all\" ein: ") + doRefuel = read() + if (doRefuel == "refuel all") then + for i=1, 16 do + turtle.select(i) + turtle.refuel(64) + end + end + end +end + + + + + + + + +--##########-- +--##########-- +--[[ Main ]]-- +--##########-- +--##########-- + +if not (fs.exists("logistics/startPosition")) then + + write("Start Position der Turtle: ") + startPosition = read() + saveStartPosition(startPosition) +end + +turtlePosition = gps.locate() + +while true do + + if (turtlePosition ~= startPosition) then + + goToStartChest() + + else + + refuelIfNeeded() + + while (turtle.suck()) do + + sortChestInStorage() + + end + end + + print("Waiting for Items") + sleep(60) +end \ No newline at end of file diff --git a/src/main/programs/turtle-miner-enderchest.lua b/src/main/programs/turtle-miner-enderchest.lua new file mode 100755 index 0000000..a94b389 --- /dev/null +++ b/src/main/programs/turtle-miner-enderchest.lua @@ -0,0 +1,297 @@ +basic_functions = require("lib.basic-functions") + +ore_list = { + [0] = "minecraft:gold_ore", + [1] = "minecraft:deepslate_gold_ore", + [2] = "minecraft:iron_ore", + [3] = "minecraft:deepslate_iron_ore", + [4] = "minecraft:coal_ore", + [5] = "minecraft:deepslate_coal_ore", + [6] = "minecraft:lapis_ore", + [7] = "minecraft:deepslate_lapis_ore", + [8] = "minecraft:diamond_ore", + [9] = "minecraft:deepslate_diamond_ore", + [10] = "minecraft:redstone_ore", + [11] = "minecraft:deepslate_redstone_ore", + [12] = "minecraft:emerald_ore", + [13] = "minecraft:deepslate_emerald_ore", + [14] = "minecraft:quartz_ore", + [15] = "minecraft:deepslate_quartz_ore", + [16] = "minecraft:copper_ore", + [17] = "minecraft:deepslate_copper_ore", + [18] = "minecraft:ancient_debris", +} + +throw_away_list = { + [0] = "minecraft:cobblestone", + [1] = "minecraft:dirt", + [2] = "minecraft:gravel", + [3] = "minecraft:andesite", + [4] = "minecraft:cobbled_deepslate", + [5] = "minecraft:diorite", + [6] = "minecraft:tuff", + [7] = "minecraft:netherrack", +} + +local function get_fuel_level() + fuel_level = turtle.getFuelLevel() + return fuel_level +end + + + +local function save_state() + basic_functions.write_to_file("bos/files/turtle-state.txt", textutils.serialize(state)) +end + + + +local function get_state() + if not fs.exists "bos/files/turtle-state.txt" then + turtle_state = {} + turtle_state["script"] = "bos/turtle-miner.lua" + turtle_state["info"] = "" + turtle_state["fuel_level"] = get_fuel_level() + turtle_state["data_goal_rows"] = 0 + turtle_state["data_goal_path_progress"] = 0 + turtle_state["data_current_row"] = 0 + turtle_state["data_current_path_progress"] = 0 + basic_functions.write_to_file("bos/files/turtle-state.txt", textutils.serialize(turtle_state)) + else + turtle_state = basic_functions.read_file_all("bos/files/turtle-state.txt") + turtle_state = textutils.unserialize(turtle_state) + end + return turtle_state +end + +local function clear_inventory() + for i=1, 16 do + turtle.select(i) + item_datail = turtle.getItemDetail() + + for j=0, #throw_away_list do + item_detail = turtle.getItemDetail() + if item_detail ~= nil then + if item_detail.name == throw_away_list[j] then + turtle.dropDown() + end + end + end + end + turtle.select(1) +end + +local function store_items() + --check inv for chest and place it + chest_available = false + for i=1, 16 do + turtle.select(i) + item_detail = turtle.getItemDetail() + if item_detail ~= nil then + if item_detail.name == "enderstorage:ender_chest" then + turtle.placeDown() + chest_available = true + break + elseif i == 16 then + --TODO save in state that no chests are available + end + end + end + + --drop items in chest + if chest_available then + for i=1, 16 do + turtle.select(i) + item_detail = turtle.getItemDetail() + if item_detail ~= nil then + if item_detail.name ~= "minecraft:torch" and item_detail.name ~= "enderstorage:ender_chest" then + turtle.dropDown() + end + end + end + turtle.digDown() --pickup enderchest + end +end + + + +local function check_inventory() + for i=1, 16 do + turtle.select(i) + item_count = turtle.getItemCount() + if item_count == 0 then + turtle.select(1) + return + end + end + + store_items() + turtle.select(1) +end + + + +local function is_ore(block_data) + for i=0, #ore_list do + if block_data["name"] == ore_list[i] then + return true + end + end + return false +end + +local function check_for_ore() + for i=0, 3 do + turtle.turnLeft() + block_found, block_data = turtle.inspect() + if is_ore(block_data) then + turtle.dig() + turtle.forward() + check_for_ore() + turtle.back() + end + end + + block_found, block_data = turtle.inspectUp() + if is_ore(block_data) then + turtle.digUp() + turtle.up() + check_for_ore() + turtle.down() + end + + block_found, block_data = turtle.inspectDown() + if is_ore(block_data) then + turtle.digDown() + turtle.down() + check_for_ore() + turtle.up() + end +end + +local function place_torch() + for i=1, 16 do + turtle.select(i) + item_detail = turtle.getItemDetail() + + if item_detail ~= nil then + if item_detail.name == "minecraft:torch" then + turtle.placeDown() + end + end + + --pcall_success, item_detail_name = pcall(place_torch_zwei) + + --if pcall_success and item_detail_name == "minecraft:torch" then + -- turtle.placeDown() + -- return true + --end + end +end + + + +function mine_forward(distance) + --mine a 3 Block high Tunnel for Blocks + for i=state["data_current_path_progress"], distance-2 do + + print("row: " .. state["data_current_row"]+1 .. "/" .. state["data_goal_rows"] .. ", path_progress: " .. state["data_current_path_progress"]+1 .. "/" .. state["data_goal_path_progress"]) + + turtle.dig() + turtle.forward() + turtle.digUp() + turtle.digDown() + + --check current mining step for ore + turtle.up() + check_for_ore() + turtle.down() + check_for_ore() + turtle.down() + check_for_ore() + turtle.up() + + if i%8 == 0 then + place_torch() + end + + --clear_inventory() + check_inventory() + clear_inventory() + + --save path progress + state["data_current_path_progress"] = i+1 + state["fuel_level"] = get_fuel_level() + save_state(state) + end + print("row: " .. state["data_current_row"]+1 .. "/" .. state["data_goal_rows"] .. ", path_progress: " .. state["data_current_path_progress"]+1 .. "/" .. state["data_goal_path_progress"]) +end + +function strip_mine(rows, path_progress) + print(">starting strip mining") + sleep(5) + + state = get_state() + + --save rows and path_length as state goal + state["data_goal_rows"] = rows + state["data_goal_path_progress"] = path_progress + save_state() + + if state["fuel_level"] == 0 then + print("OUT OF FUEL") + else + --main for loop + for i=state["data_current_row"], rows-1 do + mine_forward(path_progress) + turtle.turnLeft() + turtle.turnLeft() + + while not turtle.detect() do + turtle.forward() + end + + turtle.turnLeft() + + for j=0, 2 do + turtle.dig() + turtle.forward() + turtle.digUp() + turtle.digDown() + end + + turtle.turnLeft() + turtle.dig() + turtle.forward() + + state["data_current_row"] = i+1 + state["data_current_path_progress"] = 0 + save_state(state) + end + end +end + + + +function mine_stairs_down(length) + for i=0, length do + turtle.dig() + turtle.forward() + turtle.digUp() + turtle.digDown() + turtle.down() + turtle.digDown() + end +end + +state = get_state() +--print(textutils.serialize(state)) + +--store_items() +strip_mine(50, 250) + +--check_for_ore() +--mine_forward(50) +--mine_forward_fast(20) +--mine_stairs_down(50) +--stairs_up(60) diff --git a/src/main/programs/turtle-miner-enderchest2.lua b/src/main/programs/turtle-miner-enderchest2.lua new file mode 100755 index 0000000..55ce3f8 --- /dev/null +++ b/src/main/programs/turtle-miner-enderchest2.lua @@ -0,0 +1,339 @@ +basic_functions = require("lib.basic-functions") + +ore_list = { + [0] = "minecraft:gold_ore", + [1] = "minecraft:deepslate_gold_ore", + [2] = "minecraft:iron_ore", + [3] = "minecraft:deepslate_iron_ore", + [4] = "minecraft:coal_ore", + [5] = "minecraft:deepslate_coal_ore", + [6] = "minecraft:lapis_ore", + [7] = "minecraft:deepslate_lapis_ore", + [8] = "minecraft:diamond_ore", + [9] = "minecraft:deepslate_diamond_ore", + [10] = "minecraft:redstone_ore", + [11] = "minecraft:deepslate_redstone_ore", + [12] = "minecraft:emerald_ore", + [13] = "minecraft:deepslate_emerald_ore", + [14] = "minecraft:quartz_ore", + [15] = "minecraft:deepslate_quartz_ore", + [16] = "minecraft:copper_ore", + [17] = "minecraft:deepslate_copper_ore", + [18] = "minecraft:ancient_debris", +} + +throw_away_list = { + [0] = "minecraft:cobblestone", + [1] = "minecraft:dirt", + [2] = "minecraft:gravel", + [3] = "minecraft:andesite", + [4] = "minecraft:cobbled_deepslate", + [5] = "minecraft:diorite", + [6] = "minecraft:tuff", + [7] = "minecraft:netherrack", +} + +local function get_fuel_level() + fuel_level = turtle.getFuelLevel() + return fuel_level +end + + + +local function save_state() + basic_functions.write_to_file("bos/files/turtle-state.txt", textutils.serialize(state)) +end + + + +local function get_state() + if not fs.exists "bos/files/turtle-state.txt" then + turtle_state = {} + turtle_state["script"] = "bos/turtle-miner.lua" + turtle_state["info"] = "" + turtle_state["fuel_level"] = get_fuel_level() + turtle_state["data_goal_rows"] = 0 + turtle_state["data_goal_path_progress"] = 0 + turtle_state["data_current_row"] = 0 + turtle_state["data_current_path_progress"] = 0 + basic_functions.write_to_file("bos/files/turtle-state.txt", textutils.serialize(turtle_state)) + else + turtle_state = basic_functions.read_file_all("bos/files/turtle-state.txt") + turtle_state = textutils.unserialize(turtle_state) + end + return turtle_state +end + +local function clear_inventory() + for i=1, 16 do + turtle.select(i) + item_datail = turtle.getItemDetail() + + for j=0, #throw_away_list do + item_detail = turtle.getItemDetail() + if item_detail ~= nil then + if item_detail.name == throw_away_list[j] then + turtle.dropDown() + end + end + end + end + turtle.select(1) +end + +-- Chest on slot 1 for storing items away +-- Chest on slot 2 for getting fuel + +local function store_items() + --check inv for chest and place it + chest_available = false + for i=1, 16 do + turtle.select(i) + item_detail = turtle.getItemDetail() + if item_detail ~= nil then + if item_detail.name == "enderstorage:ender_chest" then + turtle.placeDown() + chest_available = true + break + elseif i == 16 then + --TODO save in state that no chests are available + end + end + end + + --drop items in chest + if chest_available then + for i=1, 16 do + turtle.select(i) + item_detail = turtle.getItemDetail() + if item_detail ~= nil then + if item_detail.name ~= "minecraft:torch" and item_detail.name ~= "enderstorage:ender_chest" then + turtle.dropDown() + end + end + end + turtle.digDown() --pickup enderchest + end +end + +local function store_items_to_enderchest() + turtle.select(1) + turtle.digDown() + turtle.placeDown() + + for i=3, 16 do + turtle.select(i) + item_detail = turtle.getItemDetail() + if item_detail ~= nil then + turtle.dropDown() + end + end + + turtle.select(1) + turtle.digDown() --pickup enderchest +end + +local function refuel_from_enderchest() -- should only be done if inventory (slots 3-16) are empty + turtle.select(2) + turtle.digDown() + turtle.placeDown() + + for i=3, 16 do + turtle.select(i) + turtle.suckDown() + end + + for i=3, 16 do + turtle.select(i) + turtle.refuel(64) + end + + turtle.select(2) + turtle.digDown() +end + + +local function check_inventory() + for i=1, 16 do + turtle.select(i) + item_count = turtle.getItemCount() + if item_count == 0 then + turtle.select(1) + return + end + end + + --store_items() + store_items_to_enderchest() + turtle.select(1) +end + + + +local function is_ore(block_data) + for i=0, #ore_list do + if block_data["name"] == ore_list[i] then + return true + end + end + return false +end + +local function check_for_ore() + for i=0, 3 do + turtle.turnLeft() + block_found, block_data = turtle.inspect() + if is_ore(block_data) then + turtle.dig() + turtle.forward() + check_for_ore() + turtle.back() + end + end + + block_found, block_data = turtle.inspectUp() + if is_ore(block_data) then + turtle.digUp() + turtle.up() + check_for_ore() + turtle.down() + end + + block_found, block_data = turtle.inspectDown() + if is_ore(block_data) then + turtle.digDown() + turtle.down() + check_for_ore() + turtle.up() + end +end + +local function place_torch() + for i=1, 16 do + turtle.select(i) + item_detail = turtle.getItemDetail() + + if item_detail ~= nil then + if item_detail.name == "minecraft:torch" then + turtle.placeDown() + end + end + + --pcall_success, item_detail_name = pcall(place_torch_zwei) + + --if pcall_success and item_detail_name == "minecraft:torch" then + -- turtle.placeDown() + -- return true + --end + end +end + + + +function mine_forward(distance) + --mine a 3 Block high Tunnel for Blocks + for i=state["data_current_path_progress"], distance-2 do + + print("row: " .. state["data_current_row"]+1 .. "/" .. state["data_goal_rows"] .. ", path_progress: " .. state["data_current_path_progress"]+1 .. "/" .. state["data_goal_path_progress"]) + + turtle.dig() + turtle.forward() + turtle.digUp() + turtle.digDown() + + --check current mining step for ore + turtle.up() + check_for_ore() + turtle.down() + check_for_ore() + turtle.down() + check_for_ore() + turtle.up() + + --if i%8 == 0 then + -- place_torch() + --end + + --clear_inventory() + check_inventory() + clear_inventory() + + --save path progress + state["data_current_path_progress"] = i+1 + state["fuel_level"] = get_fuel_level() + save_state(state) + end + print("row: " .. state["data_current_row"]+1 .. "/" .. state["data_goal_rows"] .. ", path_progress: " .. state["data_current_path_progress"]+1 .. "/" .. state["data_goal_path_progress"]) +end + +function strip_mine(rows, path_progress) + print(">starting strip mining") + sleep(5) + + state = get_state() + + --save rows and path_length as state goal + state["data_goal_rows"] = rows + state["data_goal_path_progress"] = path_progress + save_state() + + if get_fuel_level() < 10 then + print("OUT OF FUEL") + clear_inventory() + store_items_to_enderchest() + refuel_from_enderchest() + else + --main for loop + for i=state["data_current_row"], rows-1 do + mine_forward(path_progress) + turtle.turnLeft() + turtle.turnLeft() + + while not turtle.detect() do + turtle.forward() + end + + turtle.turnLeft() + + for j=0, 2 do + turtle.dig() + turtle.forward() + turtle.digUp() + turtle.digDown() + end + + turtle.turnLeft() + turtle.dig() + turtle.forward() + + state["data_current_row"] = i+1 + state["data_current_path_progress"] = 0 + save_state(state) + end + end +end + + + +function mine_stairs_down(length) + for i=0, length do + turtle.dig() + turtle.forward() + turtle.digUp() + turtle.digDown() + turtle.down() + turtle.digDown() + end +end + +state = get_state() +--print(textutils.serialize(state)) + +--store_items() +strip_mine(500, 500) + +--check_for_ore() +--mine_forward(50) +--mine_forward_fast(20) +--mine_stairs_down(50) +--stairs_up(60) diff --git a/src/main/programs/turtle-wood.lua b/src/main/programs/turtle-wood.lua new file mode 100755 index 0000000..72db789 --- /dev/null +++ b/src/main/programs/turtle-wood.lua @@ -0,0 +1,99 @@ + +wood_list = { + [0] = "minecraft:oak_log", + [1] = "minecraft:dark_oak_log", + [2] = "minecraft:spruce_log", +} + +local function is_wood(block_data) + for i=0, #wood_list do + if block_data["name"] == wood_list[i] then + return true + end + end + return false +end + +local function check_for_wood() + for i=0, 3 do + turtle.turnLeft() + block_found, block_data = turtle.inspect() + if is_wood(block_data) then + turtle.dig() + turtle.forward() + check_for_wood() + turtle.back() + end + end + + block_found, block_data = turtle.inspectUp() + if is_wood(block_data) then + turtle.digUp() + turtle.up() + check_for_wood() + turtle.down() + end + + block_found, block_data = turtle.inspectDown() + if is_wood(block_data) then + turtle.digDown() + turtle.down() + check_for_wood() + turtle.up() + end +end + +function place_tree() + local has_block, block_data = turtle.inspect() + if has_block then + print("sapling already planted") + else + for i=1, 16 do + turtle.select(i) + local item_detail = turtle.getItemDetail() + if item_detail ~= nil then + if item_detail.name == "minecraft:spruce_sapling" then + local has_block, block_data = turtle.inspect() + if not has_block then + turtle.up() + turtle.forward() + for i=0, 3 do + turtle.placeDown() + turtle.forward() + turtle.turnRight() + end + turtle.back() + turtle.down() + end + end + end + end + end +end + +--print(textutils.serialise(block_data)) +while true do + for k=0, 100 do + print(k) + local has_block, block_data = turtle.inspect() + if has_block then + if block_data.name == "minecraft:spruce_sapling" then + print("found sapling") + elseif block_data.name == "minecraft:spruce_log" then + print("found tree") + check_for_wood() + for j=1, 16 do + turtle.select(j) + item_detail = turtle.getItemDetail() + if item_detail ~= nil then + place_tree() + if item_detail.name == "minecraft:spruce_log" or item_detail.name == "minecraft:bamboo" then + turtle.dropDown() + end + end + end + end + end + sleep(5) + end +end