HydrantHunter

gateBuddy 2.0

Jul 13th, 2015
1,401
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 49.81 KB | None | 0 0
  1. --[[  LanteaCraft      ]]--
  2. --[[      and SGCraft  ]]--
  3. --[[    Gate Buddy     ]]--
  4. --[[      by Dog       ]]--
  5. --[[ aka HydrantHunter ]]--
  6. --[[ pastebin B81kt39c ]]--
  7. local gbVer = "2.0.00"
  8. --[[
  9. Tested with/requires:
  10.   - Minecraft 1.7.10+ AND ComputerCraft 1.75+ || LanteaCraft LC2-16+ | OR | SGCraft1.11.x-mc1.7.10+
  11.   For setup and usage instructions, please visit http://tinyurl.com/jf3rjr7
  12.  
  13. Special thanks to: SquidDev     (AES encryption/decryption)
  14.                    Alex Kloss   (base64 encoder/decoder)
  15.  
  16. IMPORTANT NOTE:
  17.   - all of the following variables are set by the program as necessary
  18.   - editing any of them below will most likely cause unexpected results
  19. ]]--
  20. local tArgs, clients = { ... }, { }
  21. local gate, thisGate, dialAddress, pingTimer
  22. local chevronNumber, clientCount, thisCC = 0, 0, tostring(os.getComputerID())
  23. local modemSide, callDirection, gateStatus, remoteIrisStatus = "none", "none", "QRY", "unk"
  24. local lcGate, continueDialing, spinTime, irisState, allowIrisClose, logging = false, false, false, false, false, false
  25. local sgStates = {
  26.   Idle = "Idle";
  27.   Dialing = "Dialing";
  28.   Dialling = "Dialing";
  29.   Opening = "Dialing";
  30.   Connected = "Connected";
  31.   Closing = "Disconnecting";
  32.   Offline = "Offline";
  33. }
  34.  
  35. -- Lua 5.1+ base64 v3.0 (c) 2009 by Alex Kloss <alexthkloss@web.de>
  36. -- licensed under the terms of the LGPL2
  37. -- http://lua-users.org/wiki/BaseSixtyFour
  38. -- character table string
  39. local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  40. -- encoding
  41. local function encode(data)
  42.   return ((data:gsub('.', function(x)
  43.     local r,b='',x:byte()
  44.     for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
  45.     return r;
  46.   end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
  47.     if (#x < 6) then return '' end
  48.     local c=0
  49.     for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
  50.     return b:sub(c+1,c+1)
  51.   end)..({ '', '==', '=' })[#data%3+1])
  52. end
  53. -- decoding
  54. local function decode(data)
  55.   data = string.gsub(data, '[^'..b..'=]', '')
  56.   return (data:gsub('.', function(x)
  57.     if (x == '=') then return '' end
  58.     local r,f='',(b:find(x)-1)
  59.     for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
  60.     return r;
  61.   end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
  62.     if (#x ~= 8) then return '' end
  63.     local c=0
  64.     for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
  65.     return string.char(c)
  66.   end))
  67. end
  68.  
  69. -- AES Lua implementation by SquidDev
  70. -- https://gist.github.com/SquidDev/86925e07cbabd70773e53d781bd8b2fe
  71. -- http://pastebin.com/DMx8M0LP
  72. local encrypt, decrypt
  73. do
  74.   local function _W(f) local e=setmetatable({}, {__index = _ENV or getfenv()}) if setfenv then setfenv(f, e) end return f(e) or e end
  75.   local bit=_W(function(_ENV, ...)
  76.   --[[
  77.     This bit API is designed to cope with unsigned integers instead of normal integers
  78.     To do this we add checks for overflows: (x > 2^31 ? x - 2 ^ 32 : x)
  79.     These are written in long form because no constant folding.
  80.   ]]
  81.   local floor = math.floor
  82.   local lshift, rshift
  83.  
  84.   rshift = function(a,disp)
  85.     return floor(a % 4294967296 / 2^disp)
  86.   end
  87.  
  88.   lshift = function(a,disp)
  89.     return (a * 2^disp) % 4294967296
  90.   end
  91.  
  92.   return {
  93.     -- bit operations
  94.     bnot = bit32 and bit32.bnot or bit.bnot,
  95.     band = bit32 and bit32.band or bit.band,
  96.     bor  = bit32 and bit32.bor or bit.bor,
  97.     bxor = bit32 and bit32.bxor or bit.bxor,
  98.     rshift = rshift,
  99.     lshift = lshift,
  100.   }
  101.   end)
  102.  
  103.   local gf=_W(function(_ENV, ...)
  104.   -- finite field with base 2 and modulo irreducible polynom x^8+x^4+x^3+x+1 = 0x11d
  105.   local bxor = bit32 and bit32.bxor or bit.bxor
  106.   local lshift = bit.lshift
  107.   -- private data of gf
  108.   local n = 0x100
  109.   local ord = 0xff
  110.   local irrPolynom = 0x11b
  111.   local exp, log = {}, {}
  112.   --
  113.   -- add two polynoms (its simply xor)
  114.   --
  115.   local function add(operand1, operand2)
  116.     return bxor(operand1,operand2)
  117.   end
  118.   --
  119.   -- subtract two polynoms (same as addition)
  120.   --
  121.   local function sub(operand1, operand2)
  122.     return bxor(operand1,operand2)
  123.   end
  124.   --
  125.   -- inverts element
  126.   -- a^(-1) = g^(order - log(a))
  127.   --
  128.   local function invert(operand)
  129.     -- special case for 1 or normal invert
  130.     return operand == 1 and 1 or exp[ord - log[operand]]
  131.   end
  132.   --
  133.   -- multiply two elements using a logarithm table
  134.   -- a*b = g^(log(a)+log(b))
  135.   --
  136.   local function mul(operand1, operand2)
  137.     if (operand1 == 0 or operand2 == 0) then
  138.       return 0
  139.     end
  140.     local exponent = log[operand1] + log[operand2]
  141.     if (exponent >= ord) then
  142.       exponent = exponent - ord
  143.     end
  144.     return exp[exponent]
  145.   end
  146.   --
  147.   -- divide two elements
  148.   -- a/b = g^(log(a)-log(b))
  149.   --
  150.   local function div(operand1, operand2)
  151.     if (operand1 == 0)  then
  152.       return 0
  153.     end
  154.     -- TODO: exception if operand2 == 0
  155.     local exponent = log[operand1] - log[operand2]
  156.     if (exponent < 0) then
  157.       exponent = exponent + ord
  158.     end
  159.     return exp[exponent]
  160.   end
  161.   --
  162.   -- print logarithmic table
  163.   --
  164.   local function printLog()
  165.     for i = 1, n do
  166.       print("log(", i-1, ")=", log[i-1])
  167.     end
  168.   end
  169.   --
  170.   -- print exponentiation table
  171.   --
  172.   local function printExp()
  173.     for i = 1, n do
  174.       print("exp(", i-1, ")=", exp[i-1])
  175.     end
  176.   end
  177.   --
  178.   -- calculate logarithmic and exponentiation table
  179.   --
  180.   local function initMulTable()
  181.     local a = 1
  182.     for i = 0,ord-1 do
  183.       exp[i] = a
  184.       log[a] = i
  185.       -- multiply with generator x+1 -> left shift + 1
  186.       a = bxor(lshift(a, 1), a)
  187.       -- if a gets larger than order, reduce modulo irreducible polynom
  188.       if a > ord then
  189.         a = sub(a, irrPolynom)
  190.       end
  191.     end
  192.   end
  193.  
  194.   initMulTable()
  195.  
  196.   return {
  197.     add = add,
  198.     sub = sub,
  199.     invert = invert,
  200.     mul = mul,
  201.     div = div,
  202.     printLog = printLog,
  203.     printExp = printExp,
  204.   }
  205.   end)
  206.  
  207.   util=_W(function(_ENV, ...)
  208.   -- Cache some bit operators
  209.   local bxor = bit.bxor
  210.   local rshift = bit.rshift
  211.   local band = bit.band
  212.   local lshift = bit.lshift
  213.   local sleepCheckIn
  214.   --
  215.   -- calculate the parity of one byte
  216.   --
  217.   local function byteParity(byte)
  218.     byte = bxor(byte, rshift(byte, 4))
  219.     byte = bxor(byte, rshift(byte, 2))
  220.     byte = bxor(byte, rshift(byte, 1))
  221.     return band(byte, 1)
  222.   end
  223.   --
  224.   -- get byte at position index
  225.   --
  226.   local function getByte(number, index)
  227.     return index == 0 and band(number,0xff) or band(rshift(number, index*8),0xff)
  228.   end
  229.   --
  230.   -- put number into int at position index
  231.   --
  232.   local function putByte(number, index)
  233.     return index == 0 and band(number,0xff) or lshift(band(number,0xff),index*8)
  234.   end
  235.   --
  236.   -- convert byte array to int array
  237.   --
  238.   local function bytesToInts(bytes, start, n)
  239.     local ints = {}
  240.     for i = 0, n - 1 do
  241.       ints[i + 1] =
  242.           putByte(bytes[start + (i*4)], 3) +
  243.           putByte(bytes[start + (i*4) + 1], 2) +
  244.           putByte(bytes[start + (i*4) + 2], 1) +
  245.           putByte(bytes[start + (i*4) + 3], 0)
  246.       if n % 10000 == 0 then sleepCheckIn() end
  247.     end
  248.     return ints
  249.   end
  250.   --
  251.   -- convert int array to byte array
  252.   --
  253.   local function intsToBytes(ints, output, outputOffset, n)
  254.     n = n or #ints
  255.     for i = 0, n - 1 do
  256.       for j = 0,3 do
  257.         output[outputOffset + i*4 + (3 - j)] = getByte(ints[i + 1], j)
  258.       end
  259.       if n % 10000 == 0 then sleepCheckIn() end
  260.     end
  261.     return output
  262.   end
  263.   --
  264.   -- convert bytes to hexString
  265.   --
  266.   local function bytesToHex(bytes)
  267.     local hexBytes = ""
  268.     for i,byte in ipairs(bytes) do
  269.       hexBytes = hexBytes .. string.format("%02x ", byte)
  270.     end
  271.     return hexBytes
  272.   end
  273.  
  274.   local function hexToBytes(bytes)
  275.     local out = {}
  276.     for i = 1, #bytes, 2 do
  277.       out[#out + 1] = tonumber(bytes:sub(i, i + 1), 16)
  278.     end
  279.     return out
  280.   end
  281.   --
  282.   -- convert data to hex string
  283.   --
  284.   local function toHexString(data)
  285.     local type = type(data)
  286.     if (type == "number") then
  287.       return string.format("%08x",data)
  288.     elseif (type == "table") then
  289.       return bytesToHex(data)
  290.     elseif (type == "string") then
  291.       local bytes = {string.byte(data, 1, #data)}
  292.       return bytesToHex(bytes)
  293.     else
  294.       return data
  295.     end
  296.   end
  297.  
  298.   local function padByteString(data)
  299.     local dataLength = #data
  300.     local random1 = math.random(0,255)
  301.     local random2 = math.random(0,255)
  302.     local prefix = string.char(random1,
  303.       random2,
  304.       random1,
  305.       random2,
  306.       getByte(dataLength, 3),
  307.       getByte(dataLength, 2),
  308.       getByte(dataLength, 1),
  309.       getByte(dataLength, 0)
  310.     )
  311.     data = prefix .. data
  312.     local padding, paddingLength = "", math.ceil(#data/16)*16 - #data
  313.     for i=1,paddingLength do
  314.       padding = padding .. string.char(math.random(0,255))
  315.     end
  316.     return data .. padding
  317.   end
  318.  
  319.   local function properlyDecrypted(data)
  320.     local random = {string.byte(data,1,4)}
  321.     if (random[1] == random[3] and random[2] == random[4]) then
  322.       return true
  323.     end
  324.     return false
  325.   end
  326.  
  327.   local function unpadByteString(data)
  328.     if (not properlyDecrypted(data)) then
  329.       return nil
  330.     end
  331.     local dataLength = putByte(string.byte(data,5), 3)
  332.              + putByte(string.byte(data,6), 2)
  333.              + putByte(string.byte(data,7), 1)
  334.              + putByte(string.byte(data,8), 0)
  335.     return string.sub(data,9,8+dataLength)
  336.   end
  337.  
  338.   local function xorIV(data, iv)
  339.     for i = 1,16 do
  340.       data[i] = bxor(data[i], iv[i])
  341.     end
  342.   end
  343.  
  344.   local function increment(data)
  345.     local i = 16
  346.     while true do
  347.       local value = data[i] + 1
  348.       if value >= 256 then
  349.         data[i] = value - 256
  350.         i = (i - 2) % 16 + 1
  351.       else
  352.         data[i] = value
  353.         break
  354.       end
  355.     end
  356.   end
  357.  
  358.   -- Called every encryption cycle
  359.   local push, pull, time = os.queueEvent, coroutine.yield, os.time
  360.   local oldTime = time()
  361.   local function sleepCheckIn()
  362.     local newTime = time()
  363.     if newTime - oldTime >= 0.03 then -- (0.020 * 1.5)
  364.       oldTime = newTime
  365.       push("sleep")
  366.       pull("sleep")
  367.     end
  368.   end
  369.  
  370.   local function getRandomData(bytes)
  371.     local char, random, sleep, insert = string.char, math.random, sleepCheckIn, table.insert
  372.     local result = {}
  373.     for i=1,bytes do
  374.       insert(result, random(0,255))
  375.       if i % 10240 == 0 then sleep() end
  376.     end
  377.     return result
  378.   end
  379.  
  380.   local function getRandomString(bytes)
  381.     local char, random, sleep, insert = string.char, math.random, sleepCheckIn, table.insert
  382.     local result = {}
  383.     for i=1,bytes do
  384.       insert(result, char(random(0,255)))
  385.       if i % 10240 == 0 then sleep() end
  386.     end
  387.     return table.concat(result)
  388.   end
  389.  
  390.   return {
  391.     byteParity = byteParity,
  392.     getByte = getByte,
  393.     putByte = putByte,
  394.     bytesToInts = bytesToInts,
  395.     intsToBytes = intsToBytes,
  396.     bytesToHex = bytesToHex,
  397.     hexToBytes = hexToBytes,
  398.     toHexString = toHexString,
  399.     padByteString = padByteString,
  400.     properlyDecrypted = properlyDecrypted,
  401.     unpadByteString = unpadByteString,
  402.     xorIV = xorIV,
  403.     increment = increment,
  404.     sleepCheckIn = sleepCheckIn,
  405.     getRandomData = getRandomData,
  406.     getRandomString = getRandomString,
  407.   }
  408.   end)
  409.  
  410.   aes=_W(function(_ENV, ...)
  411.   -- Implementation of AES with nearly pure lua
  412.   -- AES with lua is slow, really slow :-)
  413.   local putByte = util.putByte
  414.   local getByte = util.getByte
  415.   -- some constants
  416.   local ROUNDS = 'rounds'
  417.   local KEY_TYPE = "type"
  418.   local ENCRYPTION_KEY=1
  419.   local DECRYPTION_KEY=2
  420.   -- aes SBOX
  421.   local SBox = {}
  422.   local iSBox = {}
  423.   -- aes tables
  424.   local table0 = {}
  425.   local table1 = {}
  426.   local table2 = {}
  427.   local table3 = {}
  428.   local tableInv0 = {}
  429.   local tableInv1 = {}
  430.   local tableInv2 = {}
  431.   local tableInv3 = {}
  432.   -- round constants
  433.   local rCon = {
  434.     0x01000000,
  435.     0x02000000,
  436.     0x04000000,
  437.     0x08000000,
  438.     0x10000000,
  439.     0x20000000,
  440.     0x40000000,
  441.     0x80000000,
  442.     0x1b000000,
  443.     0x36000000,
  444.     0x6c000000,
  445.     0xd8000000,
  446.     0xab000000,
  447.     0x4d000000,
  448.     0x9a000000,
  449.     0x2f000000,
  450.   }
  451.   --
  452.   -- affine transformation for calculating the S-Box of AES
  453.   --
  454.   local function affinMap(byte)
  455.     mask = 0xf8
  456.     result = 0
  457.     for i = 1,8 do
  458.       result = bit.lshift(result,1)
  459.       parity = util.byteParity(bit.band(byte,mask))
  460.       result = result + parity
  461.       -- simulate roll
  462.       lastbit = bit.band(mask, 1)
  463.       mask = bit.band(bit.rshift(mask, 1),0xff)
  464.       mask = lastbit ~= 0 and bit.bor(mask, 0x80) or bit.band(mask, 0x7f)
  465.     end
  466.     return bit.bxor(result, 0x63)
  467.   end
  468.   --
  469.   -- calculate S-Box and inverse S-Box of AES
  470.   -- apply affine transformation to inverse in finite field 2^8
  471.   --
  472.   local function calcSBox()
  473.     for i = 0, 255 do
  474.       inverse = i ~= 0 and gf.invert(i) or 0
  475.       mapped = affinMap(inverse)
  476.       SBox[i] = mapped
  477.       iSBox[mapped] = i
  478.     end
  479.   end
  480.   --
  481.   -- Calculate round tables
  482.   -- round tables are used to calculate shiftRow, MixColumn and SubBytes
  483.   -- with 4 table lookups and 4 xor operations.
  484.   --
  485.   local function calcRoundTables()
  486.     for x = 0,255 do
  487.       byte = SBox[x]
  488.       table0[x] = putByte(gf.mul(0x03, byte), 0)
  489.                 + putByte(             byte , 1)
  490.                 + putByte(             byte , 2)
  491.                 + putByte(gf.mul(0x02, byte), 3)
  492.       table1[x] = putByte(             byte , 0)
  493.                 + putByte(             byte , 1)
  494.                 + putByte(gf.mul(0x02, byte), 2)
  495.                 + putByte(gf.mul(0x03, byte), 3)
  496.       table2[x] = putByte(             byte , 0)
  497.                 + putByte(gf.mul(0x02, byte), 1)
  498.                 + putByte(gf.mul(0x03, byte), 2)
  499.                 + putByte(             byte , 3)
  500.       table3[x] = putByte(gf.mul(0x02, byte), 0)
  501.                 + putByte(gf.mul(0x03, byte), 1)
  502.                 + putByte(             byte , 2)
  503.                 + putByte(             byte , 3)
  504.     end
  505.   end
  506.   --
  507.   -- Calculate inverse round tables
  508.   -- does the inverse of the normal roundtables for the equivalent
  509.   -- decryption algorithm.
  510.   --
  511.   local function calcInvRoundTables()
  512.     for x = 0,255 do
  513.       byte = iSBox[x]
  514.       tableInv0[x] = putByte(gf.mul(0x0b, byte), 0)
  515.                  + putByte(gf.mul(0x0d, byte), 1)
  516.                  + putByte(gf.mul(0x09, byte), 2)
  517.                  + putByte(gf.mul(0x0e, byte), 3)
  518.       tableInv1[x] = putByte(gf.mul(0x0d, byte), 0)
  519.                  + putByte(gf.mul(0x09, byte), 1)
  520.                  + putByte(gf.mul(0x0e, byte), 2)
  521.                  + putByte(gf.mul(0x0b, byte), 3)
  522.       tableInv2[x] = putByte(gf.mul(0x09, byte), 0)
  523.                  + putByte(gf.mul(0x0e, byte), 1)
  524.                  + putByte(gf.mul(0x0b, byte), 2)
  525.                  + putByte(gf.mul(0x0d, byte), 3)
  526.       tableInv3[x] = putByte(gf.mul(0x0e, byte), 0)
  527.                  + putByte(gf.mul(0x0b, byte), 1)
  528.                  + putByte(gf.mul(0x0d, byte), 2)
  529.                  + putByte(gf.mul(0x09, byte), 3)
  530.     end
  531.   end
  532.   --
  533.   -- rotate word: 0xaabbccdd gets 0xbbccddaa
  534.   -- used for key schedule
  535.   --
  536.   local function rotWord(word)
  537.     local tmp = bit.band(word,0xff000000)
  538.     return (bit.lshift(word,8) + bit.rshift(tmp,24))
  539.   end
  540.   --
  541.   -- replace all bytes in a word with the SBox.
  542.   -- used for key schedule
  543.   --
  544.   local function subWord(word)
  545.     return putByte(SBox[getByte(word,0)],0)
  546.       + putByte(SBox[getByte(word,1)],1)
  547.       + putByte(SBox[getByte(word,2)],2)
  548.       + putByte(SBox[getByte(word,3)],3)
  549.   end
  550.   --
  551.   -- generate key schedule for aes encryption
  552.   --
  553.   -- returns table with all round keys and
  554.   -- the necessary number of rounds saved in [ROUNDS]
  555.   --
  556.   local function expandEncryptionKey(key)
  557.     local keySchedule = {}
  558.     local keyWords = math.floor(#key / 4)
  559.     if ((keyWords ~= 4 and keyWords ~= 6 and keyWords ~= 8) or (keyWords * 4 ~= #key)) then
  560.       error("Invalid key size: " .. tostring(keyWords))
  561.       return nil
  562.     end
  563.     keySchedule[ROUNDS] = keyWords + 6
  564.     keySchedule[KEY_TYPE] = ENCRYPTION_KEY
  565.     for i = 0,keyWords - 1 do
  566.       keySchedule[i] = putByte(key[i*4+1], 3)
  567.                + putByte(key[i*4+2], 2)
  568.                + putByte(key[i*4+3], 1)
  569.                + putByte(key[i*4+4], 0)
  570.     end
  571.     for i = keyWords, (keySchedule[ROUNDS] + 1)*4 - 1 do
  572.       local tmp = keySchedule[i-1]
  573.       if ( i % keyWords == 0) then
  574.         tmp = rotWord(tmp)
  575.         tmp = subWord(tmp)
  576.         local index = math.floor(i/keyWords)
  577.         tmp = bit.bxor(tmp,rCon[index])
  578.       elseif (keyWords > 6 and i % keyWords == 4) then
  579.         tmp = subWord(tmp)
  580.       end
  581.       keySchedule[i] = bit.bxor(keySchedule[(i-keyWords)],tmp)
  582.     end
  583.     return keySchedule
  584.   end
  585.   --
  586.   -- Inverse mix column
  587.   -- used for key schedule of decryption key
  588.   --
  589.   local function invMixColumnOld(word)
  590.     local b0 = getByte(word,3)
  591.     local b1 = getByte(word,2)
  592.     local b2 = getByte(word,1)
  593.     local b3 = getByte(word,0)
  594.     return putByte(gf.add(gf.add(gf.add(gf.mul(0x0b, b1),
  595.                          gf.mul(0x0d, b2)),
  596.                          gf.mul(0x09, b3)),
  597.                          gf.mul(0x0e, b0)),3)
  598.        + putByte(gf.add(gf.add(gf.add(gf.mul(0x0b, b2),
  599.                          gf.mul(0x0d, b3)),
  600.                          gf.mul(0x09, b0)),
  601.                          gf.mul(0x0e, b1)),2)
  602.        + putByte(gf.add(gf.add(gf.add(gf.mul(0x0b, b3),
  603.                          gf.mul(0x0d, b0)),
  604.                          gf.mul(0x09, b1)),
  605.                          gf.mul(0x0e, b2)),1)
  606.        + putByte(gf.add(gf.add(gf.add(gf.mul(0x0b, b0),
  607.                          gf.mul(0x0d, b1)),
  608.                          gf.mul(0x09, b2)),
  609.                          gf.mul(0x0e, b3)),0)
  610.   end
  611.   --
  612.   -- Optimized inverse mix column
  613.   -- look at http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
  614.   -- TODO: make it work
  615.   --
  616.   local function invMixColumn(word)
  617.     local b0 = getByte(word,3)
  618.     local b1 = getByte(word,2)
  619.     local b2 = getByte(word,1)
  620.     local b3 = getByte(word,0)
  621.     local t = bit.bxor(b3,b2)
  622.     local u = bit.bxor(b1,b0)
  623.     local v = bit.bxor(t,u)
  624.     v = bit.bxor(v,gf.mul(0x08,v))
  625.     w = bit.bxor(v,gf.mul(0x04, bit.bxor(b2,b0)))
  626.     v = bit.bxor(v,gf.mul(0x04, bit.bxor(b3,b1)))
  627.     return putByte( bit.bxor(bit.bxor(b3,v), gf.mul(0x02, bit.bxor(b0,b3))), 0)
  628.        + putByte( bit.bxor(bit.bxor(b2,w), gf.mul(0x02, t              )), 1)
  629.        + putByte( bit.bxor(bit.bxor(b1,v), gf.mul(0x02, bit.bxor(b0,b3))), 2)
  630.        + putByte( bit.bxor(bit.bxor(b0,w), gf.mul(0x02, u              )), 3)
  631.   end
  632.   --
  633.   -- generate key schedule for aes decryption
  634.   --
  635.   -- uses key schedule for aes encryption and transforms each
  636.   -- key by inverse mix column.
  637.   --
  638.   local function expandDecryptionKey(key)
  639.     local keySchedule = expandEncryptionKey(key)
  640.     if (keySchedule == nil) then
  641.       return nil
  642.     end
  643.     keySchedule[KEY_TYPE] = DECRYPTION_KEY
  644.     for i = 4, (keySchedule[ROUNDS] + 1)*4 - 5 do
  645.       keySchedule[i] = invMixColumnOld(keySchedule[i])
  646.     end
  647.     return keySchedule
  648.   end
  649.   --
  650.   -- xor round key to state
  651.   --
  652.   local function addRoundKey(state, key, round)
  653.     for i = 0, 3 do
  654.       state[i + 1] = bit.bxor(state[i + 1], key[round*4+i])
  655.     end
  656.   end
  657.   --
  658.   -- do encryption round (ShiftRow, SubBytes, MixColumn together)
  659.   --
  660.   local function doRound(origState, dstState)
  661.     dstState[1] =  bit.bxor(bit.bxor(bit.bxor(
  662.           table0[getByte(origState[1],3)],
  663.           table1[getByte(origState[2],2)]),
  664.           table2[getByte(origState[3],1)]),
  665.           table3[getByte(origState[4],0)])
  666.     dstState[2] =  bit.bxor(bit.bxor(bit.bxor(
  667.           table0[getByte(origState[2],3)],
  668.           table1[getByte(origState[3],2)]),
  669.           table2[getByte(origState[4],1)]),
  670.           table3[getByte(origState[1],0)])
  671.     dstState[3] =  bit.bxor(bit.bxor(bit.bxor(
  672.           table0[getByte(origState[3],3)],
  673.           table1[getByte(origState[4],2)]),
  674.           table2[getByte(origState[1],1)]),
  675.           table3[getByte(origState[2],0)])
  676.     dstState[4] =  bit.bxor(bit.bxor(bit.bxor(
  677.           table0[getByte(origState[4],3)],
  678.           table1[getByte(origState[1],2)]),
  679.           table2[getByte(origState[2],1)]),
  680.           table3[getByte(origState[3],0)])
  681.   end
  682.   --
  683.   -- do last encryption round (ShiftRow and SubBytes)
  684.   --
  685.   local function doLastRound(origState, dstState)
  686.     dstState[1] = putByte(SBox[getByte(origState[1],3)], 3)
  687.           + putByte(SBox[getByte(origState[2],2)], 2)
  688.           + putByte(SBox[getByte(origState[3],1)], 1)
  689.           + putByte(SBox[getByte(origState[4],0)], 0)
  690.     dstState[2] = putByte(SBox[getByte(origState[2],3)], 3)
  691.           + putByte(SBox[getByte(origState[3],2)], 2)
  692.           + putByte(SBox[getByte(origState[4],1)], 1)
  693.           + putByte(SBox[getByte(origState[1],0)], 0)
  694.     dstState[3] = putByte(SBox[getByte(origState[3],3)], 3)
  695.           + putByte(SBox[getByte(origState[4],2)], 2)
  696.           + putByte(SBox[getByte(origState[1],1)], 1)
  697.           + putByte(SBox[getByte(origState[2],0)], 0)
  698.     dstState[4] = putByte(SBox[getByte(origState[4],3)], 3)
  699.           + putByte(SBox[getByte(origState[1],2)], 2)
  700.           + putByte(SBox[getByte(origState[2],1)], 1)
  701.           + putByte(SBox[getByte(origState[3],0)], 0)
  702.   end
  703.   --
  704.   -- do decryption round
  705.   --
  706.   local function doInvRound(origState, dstState)
  707.     dstState[1] =  bit.bxor(bit.bxor(bit.bxor(
  708.           tableInv0[getByte(origState[1],3)],
  709.           tableInv1[getByte(origState[4],2)]),
  710.           tableInv2[getByte(origState[3],1)]),
  711.           tableInv3[getByte(origState[2],0)])
  712.     dstState[2] =  bit.bxor(bit.bxor(bit.bxor(
  713.           tableInv0[getByte(origState[2],3)],
  714.           tableInv1[getByte(origState[1],2)]),
  715.           tableInv2[getByte(origState[4],1)]),
  716.           tableInv3[getByte(origState[3],0)])
  717.     dstState[3] =  bit.bxor(bit.bxor(bit.bxor(
  718.           tableInv0[getByte(origState[3],3)],
  719.           tableInv1[getByte(origState[2],2)]),
  720.           tableInv2[getByte(origState[1],1)]),
  721.           tableInv3[getByte(origState[4],0)])
  722.     dstState[4] =  bit.bxor(bit.bxor(bit.bxor(
  723.           tableInv0[getByte(origState[4],3)],
  724.           tableInv1[getByte(origState[3],2)]),
  725.           tableInv2[getByte(origState[2],1)]),
  726.           tableInv3[getByte(origState[1],0)])
  727.   end
  728.   --
  729.   -- do last decryption round
  730.   --
  731.   local function doInvLastRound(origState, dstState)
  732.     dstState[1] = putByte(iSBox[getByte(origState[1],3)], 3)
  733.           + putByte(iSBox[getByte(origState[4],2)], 2)
  734.           + putByte(iSBox[getByte(origState[3],1)], 1)
  735.           + putByte(iSBox[getByte(origState[2],0)], 0)
  736.     dstState[2] = putByte(iSBox[getByte(origState[2],3)], 3)
  737.           + putByte(iSBox[getByte(origState[1],2)], 2)
  738.           + putByte(iSBox[getByte(origState[4],1)], 1)
  739.           + putByte(iSBox[getByte(origState[3],0)], 0)
  740.     dstState[3] = putByte(iSBox[getByte(origState[3],3)], 3)
  741.           + putByte(iSBox[getByte(origState[2],2)], 2)
  742.           + putByte(iSBox[getByte(origState[1],1)], 1)
  743.           + putByte(iSBox[getByte(origState[4],0)], 0)
  744.     dstState[4] = putByte(iSBox[getByte(origState[4],3)], 3)
  745.           + putByte(iSBox[getByte(origState[3],2)], 2)
  746.           + putByte(iSBox[getByte(origState[2],1)], 1)
  747.           + putByte(iSBox[getByte(origState[1],0)], 0)
  748.   end
  749.   --
  750.   -- encrypts 16 Bytes
  751.   -- key           encryption key schedule
  752.   -- input         array with input data
  753.   -- inputOffset   start index for input
  754.   -- output        array for encrypted data
  755.   -- outputOffset  start index for output
  756.   --
  757.   local function encrypt(key, input, inputOffset, output, outputOffset)
  758.     --default parameters
  759.     inputOffset = inputOffset or 1
  760.     output = output or {}
  761.     outputOffset = outputOffset or 1
  762.     local state, tmpState = {}, {}
  763.     if (key[KEY_TYPE] ~= ENCRYPTION_KEY) then
  764.       error("No encryption key: " .. tostring(key[KEY_TYPE]) .. ", expected " .. ENCRYPTION_KEY)
  765.       return
  766.     end
  767.     state = util.bytesToInts(input, inputOffset, 4)
  768.     addRoundKey(state, key, 0)
  769.     local round = 1
  770.     while (round < key[ROUNDS] - 1) do
  771.       -- do a double round to save temporary assignments
  772.       doRound(state, tmpState)
  773.       addRoundKey(tmpState, key, round)
  774.       round = round + 1
  775.       doRound(tmpState, state)
  776.       addRoundKey(state, key, round)
  777.       round = round + 1
  778.     end
  779.     doRound(state, tmpState)
  780.     addRoundKey(tmpState, key, round)
  781.     round = round +1
  782.     doLastRound(tmpState, state)
  783.     addRoundKey(state, key, round)
  784.     util.sleepCheckIn()
  785.     return util.intsToBytes(state, output, outputOffset)
  786.   end
  787.   --
  788.   -- decrypt 16 bytes
  789.   -- key           decryption key schedule
  790.   -- input         array with input data
  791.   -- inputOffset   start index for input
  792.   -- output        array for decrypted data
  793.   -- outputOffset  start index for output
  794.   ---
  795.   local function decrypt(key, input, inputOffset, output, outputOffset)
  796.     -- default arguments
  797.     inputOffset = inputOffset or 1
  798.     output = output or {}
  799.     outputOffset = outputOffset or 1
  800.     local state, tmpState = {}, {}
  801.     if (key[KEY_TYPE] ~= DECRYPTION_KEY) then
  802.       error("No decryption key: " .. tostring(key[KEY_TYPE]))
  803.       return
  804.     end
  805.     state = util.bytesToInts(input, inputOffset, 4)
  806.     addRoundKey(state, key, key[ROUNDS])
  807.     local round = key[ROUNDS] - 1
  808.     while (round > 2) do
  809.       -- do a double round to save temporary assignments
  810.       doInvRound(state, tmpState)
  811.       addRoundKey(tmpState, key, round)
  812.       round = round - 1
  813.       doInvRound(tmpState, state)
  814.       addRoundKey(state, key, round)
  815.       round = round - 1
  816.     end
  817.     doInvRound(state, tmpState)
  818.     addRoundKey(tmpState, key, round)
  819.     round = round - 1
  820.     doInvLastRound(tmpState, state)
  821.     addRoundKey(state, key, round)
  822.     util.sleepCheckIn()
  823.     return util.intsToBytes(state, output, outputOffset)
  824.   end
  825.  
  826.   -- calculate all tables when loading this file
  827.   calcSBox()
  828.   calcRoundTables()
  829.   calcInvRoundTables()
  830.  
  831.   return {
  832.     ROUNDS = ROUNDS,
  833.     KEY_TYPE = KEY_TYPE,
  834.     ENCRYPTION_KEY = ENCRYPTION_KEY,
  835.     DECRYPTION_KEY = DECRYPTION_KEY,
  836.     expandEncryptionKey = expandEncryptionKey,
  837.     expandDecryptionKey = expandDecryptionKey,
  838.     encrypt = encrypt,
  839.     decrypt = decrypt,
  840.   }
  841.   end)
  842.  
  843.   local buffer=_W(function(_ENV, ...)
  844.   local function new()
  845.     return {}
  846.   end
  847.  
  848.   local function addString(stack, s)
  849.     table.insert(stack, s)
  850.   end
  851.  
  852.   local function toString(stack)
  853.     return table.concat(stack)
  854.   end
  855.  
  856.   return {
  857.     new = new,
  858.     addString = addString,
  859.     toString = toString,
  860.   }
  861.   end)
  862.  
  863.   ciphermode=_W(function(_ENV, ...)
  864.   local public = {}
  865.   --
  866.   -- Encrypt strings
  867.   -- key - byte array with key
  868.   -- string - string to encrypt
  869.   -- modefunction - function for cipher mode to use
  870.   --
  871.   local random, unpack = math.random, unpack or table.unpack
  872.   function public.encryptString(key, data, modeFunction, iv)
  873.     if iv then
  874.       local ivCopy = {}
  875.       for i = 1, 16 do ivCopy[i] = iv[i] end
  876.       iv = ivCopy
  877.     else
  878.       iv = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  879.     end
  880.     local keySched = aes.expandEncryptionKey(key)
  881.     local encryptedData = buffer.new()
  882.     for i = 1, #data/16 do
  883.       local offset = (i-1)*16 + 1
  884.       local byteData = {string.byte(data,offset,offset +15)}
  885.       iv = modeFunction(keySched, byteData, iv)
  886.       buffer.addString(encryptedData, string.char(unpack(byteData)))
  887.     end
  888.     return buffer.toString(encryptedData)
  889.   end
  890.   --
  891.   -- the following 4 functions can be used as
  892.   -- modefunction for encryptString
  893.   --
  894.   -- Electronic code book mode encrypt function
  895.   function public.encryptECB(keySched, byteData, iv)
  896.     aes.encrypt(keySched, byteData, 1, byteData, 1)
  897.   end
  898.  
  899.   -- Cipher block chaining mode encrypt function
  900.   function public.encryptCBC(keySched, byteData, iv)
  901.     util.xorIV(byteData, iv)
  902.     aes.encrypt(keySched, byteData, 1, byteData, 1)
  903.     return byteData
  904.   end
  905.  
  906.   -- Output feedback mode encrypt function
  907.   function public.encryptOFB(keySched, byteData, iv)
  908.     aes.encrypt(keySched, iv, 1, iv, 1)
  909.     util.xorIV(byteData, iv)
  910.     return iv
  911.   end
  912.  
  913.   -- Cipher feedback mode encrypt function
  914.   function public.encryptCFB(keySched, byteData, iv)
  915.     aes.encrypt(keySched, iv, 1, iv, 1)
  916.     util.xorIV(byteData, iv)
  917.     return byteData
  918.   end
  919.  
  920.   function public.encryptCTR(keySched, byteData, iv)
  921.     local nextIV = {}
  922.     for j = 1, 16 do nextIV[j] = iv[j] end
  923.     aes.encrypt(keySched, iv, 1, iv, 1)
  924.     util.xorIV(byteData, iv)
  925.     util.increment(nextIV)
  926.     return nextIV
  927.   end
  928.   --
  929.   -- Decrypt strings
  930.   -- key - byte array with key
  931.   -- string - string to decrypt
  932.   -- modefunction - function for cipher mode to use
  933.   --
  934.   function public.decryptString(key, data, modeFunction, iv)
  935.     if iv then
  936.       local ivCopy = {}
  937.       for i = 1, 16 do ivCopy[i] = iv[i] end
  938.       iv = ivCopy
  939.     else
  940.       iv = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  941.     end
  942.     local keySched
  943.     if modeFunction == public.decryptOFB or modeFunction == public.decryptCFB or modeFunction == public.decryptCTR then
  944.       keySched = aes.expandEncryptionKey(key)
  945.     else
  946.       keySched = aes.expandDecryptionKey(key)
  947.     end
  948.     local decryptedData = buffer.new()
  949.     for i = 1, #data/16 do
  950.       local offset = (i-1)*16 + 1
  951.       local byteData = {string.byte(data,offset,offset +15)}
  952.       iv = modeFunction(keySched, byteData, iv)
  953.       buffer.addString(decryptedData, string.char(unpack(byteData)))
  954.     end
  955.     return buffer.toString(decryptedData)
  956.   end
  957.   --
  958.   -- the following 4 functions can be used as
  959.   -- modefunction for decryptString
  960.   --
  961.   -- Electronic code book mode decrypt function
  962.   function public.decryptECB(keySched, byteData, iv)
  963.     aes.decrypt(keySched, byteData, 1, byteData, 1)
  964.     return iv
  965.   end
  966.  
  967.   -- Cipher block chaining mode decrypt function
  968.   function public.decryptCBC(keySched, byteData, iv)
  969.     local nextIV = {}
  970.     for j = 1, 16 do nextIV[j] = byteData[j] end
  971.     aes.decrypt(keySched, byteData, 1, byteData, 1)
  972.     util.xorIV(byteData, iv)
  973.     return nextIV
  974.   end
  975.  
  976.   -- Output feedback mode decrypt function
  977.   function public.decryptOFB(keySched, byteData, iv)
  978.     aes.encrypt(keySched, iv, 1, iv, 1)
  979.     util.xorIV(byteData, iv)
  980.     return iv
  981.   end
  982.  
  983.   -- Cipher feedback mode decrypt function
  984.   function public.decryptCFB(keySched, byteData, iv)
  985.     local nextIV = {}
  986.     for j = 1, 16 do nextIV[j] = byteData[j] end
  987.     aes.encrypt(keySched, iv, 1, iv, 1)
  988.     util.xorIV(byteData, iv)
  989.     return nextIV
  990.   end
  991.  
  992.   public.decryptCTR = public.encryptCTR
  993.   return public
  994.   end)
  995.  
  996.   -- Simple API for encrypting strings.
  997.   --
  998.   AES128 = 16
  999.   AES192 = 24
  1000.   AES256 = 32
  1001.   ECBMODE = 1
  1002.   CBCMODE = 2
  1003.   OFBMODE = 3
  1004.   CFBMODE = 4
  1005.   CTRMODE = 4
  1006.  
  1007.   local function pwToKey(password, keyLength, iv)
  1008.     local padLength = keyLength
  1009.     if (keyLength == AES192) then
  1010.       padLength = 32
  1011.     end
  1012.     if (padLength > #password) then
  1013.       local postfix = ""
  1014.       for i = 1,padLength - #password do
  1015.         postfix = postfix .. string.char(0)
  1016.       end
  1017.       password = password .. postfix
  1018.     else
  1019.       password = string.sub(password, 1, padLength)
  1020.     end
  1021.     local pwBytes = {string.byte(password,1,#password)}
  1022.     password = ciphermode.encryptString(pwBytes, password, ciphermode.encryptCBC, iv)
  1023.     password = string.sub(password, 1, keyLength)
  1024.     return {string.byte(password,1,#password)}
  1025.   end
  1026.   --
  1027.   -- Encrypts string data with password password.
  1028.   -- password  - the encryption key is generated from this string
  1029.   -- data      - string to encrypt (must not be too large)
  1030.   -- keyLength - length of aes key: 128(default), 192 or 256 Bit
  1031.   -- mode      - mode of encryption: ecb, cbc(default), ofb, cfb
  1032.   --
  1033.   -- mode and keyLength must be the same for encryption and decryption.
  1034.   --
  1035.   function encrypt(password, data, keyLength, mode, iv)
  1036.     assert(password ~= nil, "Empty password.")
  1037.     assert(data ~= nil, "Empty data.")
  1038.     local mode = mode or CBCMODE
  1039.     local keyLength = keyLength or AES128
  1040.     local key = pwToKey(password, keyLength, iv)
  1041.     local paddedData = util.padByteString(data)
  1042.     if mode == ECBMODE then
  1043.       return ciphermode.encryptString(key, paddedData, ciphermode.encryptECB, iv)
  1044.     elseif mode == CBCMODE then
  1045.       return ciphermode.encryptString(key, paddedData, ciphermode.encryptCBC, iv)
  1046.     elseif mode == OFBMODE then
  1047.       return ciphermode.encryptString(key, paddedData, ciphermode.encryptOFB, iv)
  1048.     elseif mode == CFBMODE then
  1049.       return ciphermode.encryptString(key, paddedData, ciphermode.encryptCFB, iv)
  1050.     elseif mode == CTRMODE then
  1051.       return ciphermode.encryptString(key, paddedData, ciphermode.encryptCTR, iv)
  1052.     else
  1053.       error("Unknown mode", 2)
  1054.     end
  1055.   end
  1056.   --
  1057.   -- Decrypts string data with password password.
  1058.   -- password  - the decryption key is generated from this string
  1059.   -- data      - string to encrypt
  1060.   -- keyLength - length of aes key: 128(default), 192 or 256 Bit
  1061.   -- mode      - mode of decryption: ecb, cbc(default), ofb, cfb
  1062.   --
  1063.   -- mode and keyLength must be the same for encryption and decryption.
  1064.   --
  1065.   function decrypt(password, data, keyLength, mode, iv)
  1066.     local mode = mode or CBCMODE
  1067.     local keyLength = keyLength or AES128
  1068.     local key = pwToKey(password, keyLength, iv)
  1069.     local plain
  1070.     if mode == ECBMODE then
  1071.       plain = ciphermode.decryptString(key, data, ciphermode.decryptECB, iv)
  1072.     elseif mode == CBCMODE then
  1073.       plain = ciphermode.decryptString(key, data, ciphermode.decryptCBC, iv)
  1074.     elseif mode == OFBMODE then
  1075.       plain = ciphermode.decryptString(key, data, ciphermode.decryptOFB, iv)
  1076.     elseif mode == CFBMODE then
  1077.       plain = ciphermode.decryptString(key, data, ciphermode.decryptCFB, iv)
  1078.     elseif mode == CTRMODE then
  1079.       plain = ciphermode.decryptString(key, data, ciphermode.decryptCTR, iv)
  1080.     else
  1081.       error("Unknown mode", 2)
  1082.     end
  1083.     result = util.unpadByteString(plain)
  1084.     if (result == nil) then
  1085.       return nil
  1086.     end
  1087.     return result
  1088.   end
  1089. end
  1090.  
  1091. local function netSend(id, data)
  1092.   local encKey, encryptedDataPack
  1093.   if not rednet.isOpen(modemSide) then rednet.open(modemSide) end
  1094.   if clients[id] then
  1095.     encKey = tostring(id) .. "ccDHD!General_Comms*Key" .. thisCC
  1096.     encryptedDataPack = encode(encrypt(encKey, textutils.serialize({ program = "ccDialer", data = data, ccDHD = false, gStatus = gateStatus, iris = remoteIrisStatus })))
  1097.     rednet.send(id, encryptedDataPack, "ccDialerWiFi")
  1098.   end
  1099. end
  1100.  
  1101. local function netSendAll(data)
  1102.   if not rednet.isOpen(modemSide) then rednet.open(modemSide) end
  1103.   if clientCount < 1 then return end
  1104.   local encKey, encryptedDataPack
  1105.   for id in pairs(clients) do
  1106.     encKey = tostring(id) .. "ccDHD!General_Comms*Key" .. thisCC
  1107.     encryptedDataPack = encode(encrypt(encKey, textutils.serialize({ program = "ccDialer", data = data, ccDHD = false, gStatus = gateStatus, iris = remoteIrisStatus })))
  1108.     rednet.send(id, encryptedDataPack, "ccDialerWiFi")
  1109.   end
  1110. end
  1111.  
  1112. local function recordSessionData()                        --# Human readable log files (last gate & history)
  1113.   local logAddress = dialAddress or "N/A"                 --# set logAddress
  1114.   if callDirection == "none" then callDirection = "Incoming" end
  1115.   local callTime = textutils.formatTime(os.time(), false) --# format the time
  1116.   if not fs.exists("/data") then fs.makeDir("/data") end
  1117.   local previousCall = fs.open("/data/lastCall", "w")     --# record last call
  1118.   previousCall.writeLine(tostring(os.day()) .. " @ " .. callTime .. " <" .. callDirection .. "> " .. logAddress)
  1119.   previousCall.close()
  1120. end
  1121.  
  1122. local function updateTerminal()
  1123.   term.setCursorPos(2, 5)
  1124.   term.write("Local / Target: " .. thisGate .. " / " .. (dialAddress or "none     "))
  1125.   term.setCursorPos(14, 7)
  1126.   term.write(string.rep(" ", 20))
  1127.   term.setCursorPos(14, 7)
  1128.   term.write(gateStatus .. " " .. ((gateStatus == "Dialing" or gateStatus == "Connected") and callDirection or " "))
  1129. end
  1130.  
  1131. local function hangUp() --# LanteaCraft & SGCraft
  1132.   if gateStatus == "Idle" or gateStatus == "Offline" then return end
  1133.   if lcGate then
  1134.     continueDialing = false
  1135.     while spinTime do
  1136.       os.queueEvent("spinWait")
  1137.       os.pullEvent("spinWait")
  1138.     end
  1139.     pcall(gate.disengageStargate)
  1140.     chevronNumber = gate.getActivatedChevrons()
  1141.     if chevronNumber > 0 then
  1142.       for i = 1, chevronNumber do
  1143.         --[[
  1144.         local onHook = pcall(gate.deactivateChevron)
  1145.         if onHook then
  1146.           chevronNumber = chevronNumber - 1
  1147.         else
  1148.           break
  1149.         end
  1150.         ]]--
  1151.         pcall(gate.deactivateChevron)
  1152.         chevronNumber = chevronNumber - 1
  1153.       end
  1154.     end
  1155.     if chevronNumber == 0 then
  1156.       dialAddress = nil
  1157.       gateStatus = "Idle"
  1158.       remoteIrisStatus = "unk"
  1159.       netSendAll("Idle")
  1160.       updateTerminal()
  1161.     end
  1162.   else
  1163.     gate.disconnect()
  1164.   end
  1165. end
  1166.  
  1167. local function lockChevron(num) --# LanteaCraft
  1168.   if continueDialing then
  1169.     --[[
  1170.     local dialGate = pcall(gate.selectGlyph, dialAddress:sub(num, num))
  1171.     if not dialGate then return false end
  1172.     dialGate = pcall(gate.activateChevron)
  1173.     if not dialGate then return false end
  1174.     ]]--
  1175.     pcall(gate.selectGlyph, dialAddress:sub(num, num))
  1176.     pcall(gate.activateChevron)
  1177.     gateStatus = "Dialing"
  1178.     return true
  1179.   else
  1180.     gateStatus = "Paused"
  1181.     return false
  1182.   end
  1183. end
  1184.  
  1185. local function lcIrisMonitor() --# LanteaCraft
  1186.   local event --, irisStatus, dataPack
  1187.   while true do
  1188.     event = os.pullEvent()
  1189.     if event == "irisOpened" or event == "irisDestroyed" or event == "irisClosed" then
  1190.       irisState = event == "irisClosed"
  1191.       term.setCursorPos(14, 9)
  1192.       term.write(irisState and "Closed" or "Open  ")
  1193.       --if gateStatus == "Connected" then
  1194.         --irisStatus = irisState and "closed" or "open"
  1195.         --dataPack = textutils.serialize({ irisState = irisStatus })
  1196.         --pcall(gate.sendMessage, dataPack)
  1197.       --end
  1198.     end
  1199.   end
  1200. end
  1201.  
  1202. local function lcGateMonitor() --# LanteaCraft
  1203.   local event --, irisStatus, dataPack, establishWormhole
  1204.   while true do
  1205.     event = os.pullEvent()
  1206.     if event == "spinToGlyph" or event == "engageGlyph" or event == "connect" or event == "disconnect" then
  1207.       if event == "spinToGlyph" then
  1208.         spinTime = true
  1209.         callDirection = dialAddress and "Outgoing" or "Incoming"
  1210.       elseif event == "engageGlyph" then
  1211.         spinTime = false
  1212.         if dialAddress then
  1213.           chevronNumber = chevronNumber + 1
  1214.           if chevronNumber == #dialAddress then
  1215.             continueDialing = false
  1216.             --establishWormhole = pcall(gate.engageStargate)
  1217.             --if not establishWormhole then hangUp() end
  1218.             pcall(gate.engageStargate)
  1219.           else
  1220.             if continueDialing and not lockChevron(chevronNumber + 1) then
  1221.               continueDialing = false
  1222.               gateStatus = "Paused"
  1223.             end
  1224.           end
  1225.           netSendAll(gateStatus == "Dialing" and "Dialing" or "Paused")
  1226.         end
  1227.       elseif event == "connect" then
  1228.         gateStatus = "Connected"
  1229.         spinTime = false
  1230.         if logging then recordSessionData() end
  1231.         --irisStatus = irisState and "closed" or "open"
  1232.         --dataPack = textutils.serialize({ irisState = irisStatus })
  1233.         --pcall(gate.sendMessage, dataPack)
  1234.         netSendAll("Connected")
  1235.       elseif event == "disconnect" then
  1236.         gateStatus = "Idle"
  1237.         remoteIrisStatus = "unk"
  1238.         spinTime = false
  1239.         dialAddress = nil
  1240.         callDirection = "none"
  1241.         chevronNumber = 0
  1242.         netSendAll("Idle")
  1243.       end
  1244.       updateTerminal()
  1245.     end
  1246.   end
  1247. end
  1248.  
  1249. local function sgIrisMonitor() --# SGCraft
  1250.   local irisEvent, _, newState, oldState, irisStatus
  1251.   while true do
  1252.     irisEvent, _, newState, oldState = os.pullEvent("sgIrisStateChange")
  1253.     if newState == "Closed" or newState == "Open" or newState == "Offline" then
  1254.       irisState = newState == "Closed"
  1255.       term.setCursorPos(14, 9)
  1256.       term.write(irisState and "Closed" or "Open  ")
  1257.       if gateStatus == "Connected" then
  1258.         irisStatus = irisState and "closed" or "open"
  1259.         gate.sendMessage(textutils.serialize({ irisState = irisStatus }))
  1260.       end
  1261.     end
  1262.   end
  1263. end
  1264.  
  1265. local function sgGateMonitor() --# SGCraft
  1266.   local sgEvent, _, newState, oldState, irisStatus
  1267.   while true do
  1268.     sgEvent, _, newState, oldState = os.pullEvent("sgStargateStateChange")
  1269.     gateStatus = sgStates[newState] or "Unknown"
  1270.     if gateStatus == "Connected" then
  1271.       if not dialAddress then
  1272.         dialAddress = gate.remoteAddress()
  1273.         _, chevronNumber, callDirection = gate.stargateState()
  1274.       end
  1275.       if logging and newState ~= oldState then recordSessionData() end
  1276.       irisStatus = irisState and "closed" or "open"
  1277.       gate.sendMessage(textutils.serialize({ irisState = irisStatus }))
  1278.       netSendAll("Connected")
  1279.     elseif gateStatus == "Idle" or gateStatus == "Offline" then
  1280.       dialAddress = nil
  1281.       callDirection = "none"
  1282.       remoteIrisStatus = "unk"
  1283.       chevronNumber = 0
  1284.       netSendAll("Idle")
  1285.     end
  1286.     updateTerminal()
  1287.   end
  1288. end
  1289.  
  1290. local function outgoingCall() --# LanteaCraft & SGCraft
  1291.   local _, sgEvent, outgoingAddress
  1292.   while true do
  1293.     if lcGate then
  1294.       sgEvent, chevronNumber = os.pullEvent("sgChevronEncode")
  1295.     else
  1296.       sgEvent, _, outgoingAddress = os.pullEvent("sgDialOut")
  1297.     end
  1298.     gateStatus = "Dialing"
  1299.     callDirection = "Outgoing"
  1300.     updateTerminal()
  1301.     netSendAll("Dialing")
  1302.   end
  1303. end
  1304.  
  1305. local function incomingCall() --# LanteaCraft & SGCraft
  1306.   local _, incomingChevron, incomingAddress, sgEvent
  1307.   while true do
  1308.     if lcGate then
  1309.       _, incomingChevron = os.pullEvent("sgIncoming")
  1310.     else
  1311.       sgEvent, _, incomingAddress = os.pullEvent("sgDialIn")
  1312.     end
  1313.     gateStatus = "Dialing"
  1314.     callDirection = "Incoming"
  1315.     --if lcGate then incomingAddress = incomingAddress and incomingAddress .. incomingChevron or incomingChevron end
  1316.     dialAddress = lcGate and "N/A" or gate.remoteAddress()
  1317.     updateTerminal()
  1318.     netSendAll("Dialing")
  1319.   end
  1320. end
  1321.  
  1322. local function gateReceive() --# LanteaCraft & SGCraft
  1323.   local _, src, message, success, data
  1324.   while true do
  1325.     if lcGate then
  1326.       _, message = os.pullEvent("receive")
  1327.     else
  1328.       _, src, message = os.pullEvent("sgMessageReceived")
  1329.     end
  1330.     success, data = pcall(textutils.unserialize, message)
  1331.     if success and type(data) == "table" then
  1332.       if data.password then
  1333.         if irisState then
  1334.           pcall(gate.openIris)
  1335.         elseif not irisState and allowIrisClose then
  1336.           pcall(gate.closeIris)
  1337.         end
  1338.       elseif data.irisState then
  1339.         remoteIrisStatus = data.irisState
  1340.         netSendAll(remoteIrisStatus)
  1341.       end
  1342.     end
  1343.   end
  1344. end
  1345.  
  1346. local function netReceive()
  1347.   local id, encryptedMessage, decryptedMesesage, encodedMessage, message, success, mCommand, mcLen, dataPack
  1348.   while true do
  1349.     if not rednet.isOpen(modemSide) then rednet.open(modemSide) end
  1350.     id, encodedMessage = rednet.receive("ccDialerWiFi")
  1351.     if type(encodedMessage) == "string" then
  1352.       success, encryptedMessage = pcall(decode, encodedMessage)
  1353.       if success then
  1354.         encKey = thisCC .. "ccDHD!General_Comms*Key" .. tostring(id)
  1355.         success, decryptedMessage = pcall(decrypt, encKey, encryptedMessage)
  1356.         if success then
  1357.           success, message = pcall(textutils.unserialize, decryptedMessage)
  1358.           if success and type(message) == "table" and message.program and message.program == "ccDialer" and message.gate then
  1359.             if message.gate == "NO HOST" and message.command and message.command == "QRY" then
  1360.               if not clients[id] then clientCount = clientCount + 1 end
  1361.               clients[id] = 0
  1362.               netSend(id, thisGate)
  1363.             elseif message.gate == thisGate then
  1364.               if message.password and clients[id] and gateStatus == "Connected" then
  1365.                 dataPack = textutils.serialize({ password = message.password })
  1366.                 pcall(gate.sendMessage, dataPack)
  1367.               elseif message.command and clients[id] then
  1368.                 mCommand = message.command
  1369.                 if mCommand == "ping" then
  1370.                   netSend(id, "pong")
  1371.                 elseif mCommand == "pong" then
  1372.                   clients[id] = 0
  1373.                 elseif mCommand == "endCall" then
  1374.                   hangUp()
  1375.                 elseif mCommand == "logout" then
  1376.                   clients[id] = nil
  1377.                   clientCount = math.max(0, clientCount - 1)
  1378.                 else
  1379.                   mcLen = #tostring(mCommand)
  1380.                   if (mcLen == 7 or mcLen == 9) and mCommand ~= thisGate then
  1381.                     if lcGate then
  1382.                       if gateStatus == "Dialing" and mCommand == dialAddress then
  1383.                         continueDialing = false
  1384.                         gateStatus = "Paused"
  1385.                       elseif gateStatus == "Paused" and mCommand == dialAddress then
  1386.                         continueDialing = true
  1387.                         if not lockChevron(chevronNumber + 1) then
  1388.                           continueDialing = false
  1389.                           gateStatus = "Paused"
  1390.                         end
  1391.                       elseif gateStatus == "Idle" then
  1392.                         if gate.getActivatedChevrons() > 0 then hangUp() end
  1393.                         dialAddress = mCommand
  1394.                         continueDialing = true
  1395.                         if not lockChevron(1) then hangUp() end
  1396.                       end
  1397.                     else
  1398.                       if gateStatus == "Idle" then
  1399.                         dialAddress = mCommand
  1400.                         if not gate.dial(dialAddress) then dialAddress = nil end
  1401.                       end
  1402.                     end
  1403.                   end
  1404.                 end
  1405.               end
  1406.             end
  1407.           end
  1408.         end
  1409.       end
  1410.     end
  1411.   end
  1412. end
  1413.  
  1414. local function charInput()
  1415.   while true do
  1416.     local _, char = os.pullEvent("char")
  1417.     if string.lower(char) == "q" then
  1418.       netSendAll("Offline")
  1419.       rednet.unhost("ccDialerWiFi", thisGate)
  1420.       if rednet.isOpen(modemSide) then rednet.close(modemSide) end
  1421.       term.clear()
  1422.       term.setCursorPos(1, 1)
  1423.       term.write("gateBuddy is OFFLINE")
  1424.       term.setCursorPos(1, 3)
  1425.       return
  1426.     end
  1427.   end
  1428. end
  1429.  
  1430. local function dataPoller()
  1431.   local _, timer
  1432.   while true do
  1433.     _, timer = os.pullEvent("timer")
  1434.     if timer == pingTimer then
  1435.       if clientCount > 0 then
  1436.         for id, timeout in pairs(clients) do
  1437.           clients[id] = timeout + 1
  1438.           if clients[id] > 2 then
  1439.             clients[id] = nil
  1440.             clientCount = math.max(0, clientCount - 1)
  1441.           else
  1442.             netSend(id, "ping")
  1443.           end
  1444.         end
  1445.       end
  1446.       pingTimer = os.startTimer(5)
  1447.     end
  1448.   end
  1449. end
  1450.  
  1451. local function initError(device)
  1452.   term.clear()
  1453.   term.setCursorPos(1, 1)
  1454.   term.write("No " .. device .. " detected!")
  1455.   term.setCursorPos(1, 3)
  1456.   term.write("gateBuddy is OFFLINE")
  1457.   term.setCursorPos(1, 5)
  1458. end
  1459.  
  1460. term.setBackgroundColor(colors.black)
  1461. term.setTextColor(colors.white)
  1462. term.clear()
  1463. term.setCursorPos(2, 2)
  1464. if pocket then error("Computer or turtle required.", 0) end
  1465. term.write("gateBuddy initializing...")
  1466. if not os.getComputerLabel() then os.setComputerLabel("gateBuddy.cc#" .. thisCC) end
  1467. gate = peripheral.find("stargate")
  1468. if not gate then
  1469.   lcGate = true
  1470.   gate = peripheral.find("StargateBase")
  1471.   if gate and not gate.isValid() then gate = nil end
  1472. end
  1473. if not gate then return initError("STARGATE") end
  1474. thisGate = lcGate and gate.getStargateAddressString() or gate.localAddress()
  1475. local irisStatus
  1476. if lcGate then
  1477.   local glyphs = gate.getActivatedGlyphs()  --# returns a string
  1478.   local chevs = gate.getActivatedChevrons() --# returns a number
  1479.   if glyphs and chevs > 0 then              --# this can be confused - if the gate is hanging up, there will be chevrons encoded, but the status is "Disconnecting" not "Dialing"
  1480.     dialAddress = chevs == 9 and glyphs or glyphs .. string.rep("?", 9 - chevs)
  1481.     gateStatus = chevs == 9 and "Connected" or "Dialing"
  1482.     chevronNumber = chevs
  1483.     callDirection = "Unknown"
  1484.   else
  1485.     gateStatus = "Idle"
  1486.     callDirection = "none"
  1487.   end
  1488.   irisStatus = gate.getIrisState()
  1489.   irisState = irisStatus == "CLOSED"
  1490. else
  1491.   local gateState
  1492.   gateState, chevronNumber, callDirection = gate.stargateState()
  1493.   if gateState == "Offline" then return initError("STARGATE") end
  1494.   gateStatus = sgStates[gateState] or "Unknown"
  1495.   if gateStatus ~= "Idle" then dialAddress = gate.remoteAddress() end
  1496.   irisStatus = gate.irisState()
  1497.   irisState = irisStatus == "Closed"
  1498. end
  1499. for _, side in pairs(rs.getSides()) do
  1500.   if peripheral.isPresent(side) and peripheral.getType(side) == "modem" and peripheral.call(side, "isWireless") then
  1501.     modemSide = side
  1502.     rednet.open(side)
  1503.     rednet.host("ccDialerWiFi", thisGate)
  1504.     break
  1505.   end
  1506. end
  1507. if modemSide == "none" then return initError("WIRELESS MODEM") end
  1508. if tArgs[1] then
  1509.   for i = 1, #tArgs do
  1510.     if tArgs[i] == "log" then
  1511.       logging = true
  1512.     elseif tArgs[i] == "iris" and irisStatus ~= "Offline" and irisStatus ~= "NONE" then
  1513.       allowIrisClose = true
  1514.     end
  1515.   end
  1516. end
  1517. pingTimer = os.startTimer(5)
  1518. term.clear()
  1519. term.setCursorPos(2, 2)
  1520. term.write("gateBuddy " .. gbVer .. " is ONLINE")
  1521. term.setCursorPos(2, 5)
  1522. term.write("Local / Target: " .. thisGate .. " / " .. (dialAddress or "none"))
  1523. term.setCursorPos(2, 7)
  1524. term.write("Gate State: ")
  1525. term.write(gateStatus .. " " .. ((gateStatus == "Dialing" or gateStatus == "Connected") and callDirection or " "))
  1526. term.setCursorPos(2, 9)
  1527. term.write("Iris State: " .. (irisState and "Closed" or "Open"))
  1528. term.setCursorPos(2, 12)
  1529. term.write("press 'q' to quit")
  1530. if lcGate then
  1531.   parallel.waitForAny(gateReceive, netReceive, lcGateMonitor, lcIrisMonitor, charInput, dataPoller) --incomingCall, outgoingCall,
  1532. else
  1533.   parallel.waitForAny(gateReceive, netReceive, sgGateMonitor, sgIrisMonitor, incomingCall, outgoingCall, charInput, dataPoller)
  1534. end
Add Comment
Please, Sign In to add comment