Ledger Nano X - The secure hardware wallet
SHARE
TWEET

BioPup

HydrantHunter Jan 11th, 2014 (edited) 715 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[    BioPup     ]]--
  2. --[[    by Dog     ]]--
  3. --[[     aka       ]]--
  4. --[[ HydrantHunter ]]--
  5. --[[   pastebin    ]]--
  6. --[[   H8LKg8kS    ]]--
  7. local bVer = "2.0.00"
  8. --[[
  9. Tested with/requires:
  10.   - Minecraft            1.6.4 | 1.7.10
  11.   - ComputerCraft        1.58+ | 1.73+
  12.   - Gopher's Peripherals 2.13  | 2.2
  13.   - An advanced computer
  14.   - One or more biolocks
  15. ]]--
  16. -- "biolock", IDprint, attachName, learnedName, accessLevel
  17. local screen = "main"
  18. local accountName, accountPrint, accountAccess
  19. local kernelState, dataChanged, newAccount, scanned = true, false, false, false
  20. local accountNames, scanners, scannerSides, scannerLock = { }, { }, { }, { }
  21. local accountPage, accountPages, scannerPage, scannerPages, numPerPage, thisScanner = 1, 1, 1, 1, 14, 0
  22. local termX, termY = term.getSize()
  23.  
  24. -- custom read function courtesy of theoriginalbit (modified by Dog)
  25. local function read(_mask, _history, _limit, _noTerminate, _noMouse)
  26.   if _mask and type(_mask) ~= "string" then
  27.     error("Invalid parameter #1: Expected string, got " .. type(_mask), 2)
  28.   end
  29.   if _history and type(_history) ~= "table" then
  30.     error("Invalid parameter #2: Expected table, got " .. type(_history), 2)
  31.   end
  32.   if _limit and type(_limit) ~= "number" then
  33.     error("Invalid parameter #3: Expected number, got " .. type(_limit), 2)
  34.   end
  35.   if _noTerminate and type(_noTerminate) ~= "boolean" then
  36.     error("Invalid argument #4: Expected boolean, got " .. nativeType(_noTerminate), 2)
  37.   end
  38.   if _noMouse and type(_noMouse) ~= "boolean" then
  39.     error("Invalid argument #5: Expected boolean, got " .. nativeType(_noMouse), 2)
  40.   end
  41.   term.setCursorBlink(true)
  42.   local mouseLimit = _limit or 0
  43.   local input = ""
  44.   local pos = 0
  45.   local historyPos = nil
  46.   local pullEvent = _noTerminate and os.pullEventRaw or os.pullEvent
  47.   local sw, sh = term.getSize()
  48.   local sx, sy = term.getCursorPos()
  49.   local function redraw(_special)
  50.     local scroll = (sx + pos >= sw and (sx + pos) - sw or 0)
  51.     local replace = _special or _mask
  52.     local output = replace and (string.rep(replace, math.ceil(#input / #replace) - scroll)):sub(1, #input) or input:sub(scroll + 1)
  53.     term.setCursorPos(sx, sy)
  54.     term.write(output)
  55.     term.setCursorPos(sx + pos - scroll, sy)
  56.   end
  57.   local nativeScroll = term.scroll
  58.   term.scroll = function(_n) local ok, err = pcall(function() return nativeScroll(_n) end) if ok then sy = sy - _n return err end error(err, 2) end
  59.   while true do
  60.     local event, code, mX, mY = pullEvent()
  61.     if event == "char" and (not _limit or #input < _limit) then
  62.       input = input:sub(1, pos) .. code .. input:sub(pos + 1)
  63.       pos = pos + 1
  64.       if not _limit then mouseLimit = math.min(mouseLimit + 1, sw - (sw - sx)) end
  65.     elseif event == "paste" and (not _limit or #input < _limit) then
  66.       if _limit and #input + #code > _limit then
  67.         code = code:sub(1, _limit - #input)
  68.       end
  69.       input = input:sub(1, pos) .. code .. input:sub(pos + 1)
  70.       pos = pos + #code
  71.       if not _limit then mouseLimit = math.min(mouseLimit + #code, sw - (sw - sx)) end
  72.     elseif event == "key" then
  73.       if code == keys.enter or code == keys.numPadEnter then
  74.         break
  75.       elseif code == keys.backspace and pos > 0 then
  76.         redraw(' ')
  77.         input = input:sub(1, math.max(pos - 1, 0)) .. input:sub(pos + 1)
  78.         pos = math.max(pos - 1, 0)
  79.         if not _limit then mouseLimit = math.max(mouseLimit - 1, 0) end
  80.       elseif code == keys.delete and pos < #input then
  81.         redraw(' ')
  82.         input = input:sub(1, pos) .. input:sub(pos + 2)
  83.         if not _limit then mouseLimit = math.max(mouseLimit - 1, 0) end
  84.       elseif code == keys.home then
  85.         pos = 0
  86.       elseif code == keys["end"] then
  87.         pos = #input
  88.       elseif code == keys.left and pos > 0 then
  89.         pos = math.max(pos - 1, 0)
  90.       elseif code == keys.right and pos < #input then
  91.         pos = math.min(pos + 1, #input)
  92.       elseif _history and code == keys.up or code == keys.down then
  93.         redraw(' ')
  94.         if code == keys.up then
  95.           if not historyPos then
  96.             historyPos = #_history
  97.           elseif historyPos > 1 then
  98.             historyPos = historyPos - 1
  99.           end
  100.         else
  101.           if historyPos ~= nil and historyPos < #_history then
  102.             historyPos = math.max(historyPos + 1, #_history)
  103.           elseif historyPos == #_history then
  104.             historyPos = nil
  105.           end
  106.         end
  107.         if historyPos and #_history > 0 then
  108.           input = string.sub(_history[historyPos], 1, _limit) or ""
  109.           pos = #input
  110.           if not _limit then mouseLimit = pos end
  111.         else
  112.           input = ""
  113.           pos = 0
  114.           if not _limit then mouseLimit = 0 end
  115.         end
  116.       end
  117.     elseif event == "mouse_click" and not _noMouse and ((mX < sx or mX >= sx + mouseLimit) or (mY ~= sy)) then
  118.       break
  119.     end
  120.     redraw(_mask)
  121.   end
  122.   term.scroll = nativeScroll
  123.   term.setCursorBlink(false)
  124.   if sy + 1 > sh then
  125.     term.scroll(sy + 1 - sh)
  126.     term.setCursorPos(1, sy)
  127.   else
  128.     term.setCursorPos(1, sy + 1)
  129.   end
  130.   return input
  131. end
  132.  
  133. local function clearScreen()
  134.  term.setBackgroundColor(colors.black)
  135.  term.clear()
  136. end
  137.  
  138. local function clearDataArea()
  139.   term.setBackgroundColor(colors.black)
  140.   local line = string.rep(" ", 33)
  141.   for i = 5, termY - 1 do
  142.     term.setCursorPos(18, i)
  143.     term.write(line)
  144.   end
  145. end
  146.  
  147. local function header()
  148.   term.setTextColor(colors.white)
  149.   local line = string.rep(" ", termX - 6)
  150.   local new = { " N ", " E ", " W " }
  151.   for i = 1, 3 do                         --# header body
  152.     term.setCursorPos(1, i)
  153.     if screen == "scanner" and not scannerLock[thisScanner] then
  154.       term.setBackgroundColor(colors.green)
  155.       term.write(new[i])
  156.     else
  157.       term.setBackgroundColor(colors.blue)
  158.       term.write("   ")
  159.     end
  160.     term.setBackgroundColor(colors.blue)
  161.     term.write(line)
  162.     term.setBackgroundColor(colors.red)
  163.     term.write(i == 2 and " X " or "   ") --# exit button
  164.   end
  165.   term.setBackgroundColor(colors.blue)
  166.   term.setTextColor(colors.lightBlue)
  167.   local title = "BioScanner Account Manager"
  168.   term.setCursorPos(math.ceil(termX / 2) - math.floor(#title / 2), 2)
  169.   term.write(title)                       --# draw title
  170. end
  171.  
  172. local function infoFrame()
  173.   term.setBackgroundColor(colors.lightGray)
  174.   local line = string.rep(" ", 16)
  175.   for i = 4, 8 do
  176.     term.setCursorPos(1, i)
  177.     term.write(line)
  178.   end
  179.   term.setTextColor(colors.gray)
  180.   term.setCursorPos(2, screen == "main" and 6 or 7)
  181.   term.write(screen == "main" and "Scanners: " or "Accounts: ")
  182.   term.setTextColor(colors.black)
  183.   if screen == "main" then
  184.     term.write(#scanners > 9 and tostring(#scanners) or " " .. tostring(#scanners))
  185.   elseif screen == "scanner" then
  186.     term.write(#accountNames > 9 and tostring(#accountNames) or " " .. tostring(#accountNames))
  187.     term.setBackgroundColor(colors.gray)
  188.     term.setTextColor(colors.black)
  189.     term.setCursorPos(2, 5)
  190.     term.write(string.rep(" ", 14))
  191.     if #scannerSides[thisScanner] == 10 then
  192.       term.setCursorPos(9 - math.floor(#scannerSides[thisScanner] / 2), 5)
  193.     else
  194.       term.setCursorPos(8 - math.floor(#scannerSides[thisScanner] / 2), 5)
  195.     end
  196.     term.write(scannerSides[thisScanner])
  197.   end
  198. end
  199.  
  200. local function actionFrame()
  201.   term.setTextColor(colors.white)
  202.   term.setBackgroundColor(colors.cyan)
  203.   local line = string.rep(" ", 16)
  204.   for i = 10, 13 do
  205.     term.setCursorPos(1, i)
  206.     term.write(line)
  207.   end
  208.   if screen == "main" then
  209.     term.setBackgroundColor(colors.red)
  210.     term.setCursorPos(2, 11)
  211.     term.write(" LOCK ")
  212.     term.setBackgroundColor(colors.green)
  213.     term.setCursorPos(9, 11)
  214.     term.write("UNLOCK")
  215.     term.setBackgroundColor(colors.red)
  216.     term.setCursorPos(2, 12)
  217.     term.write(" *ALL ")
  218.     term.setBackgroundColor(colors.green)
  219.     term.setCursorPos(9, 12)
  220.     term.write(" *ALL ")
  221.   elseif screen == "scanner" then
  222.     term.setBackgroundColor(scannerLock[thisScanner] and colors.green or colors.red)
  223.     term.setCursorPos(2, 11)
  224.     term.write(scannerLock[thisScanner] and "    UNLOCK    " or "     LOCK     ")
  225.     term.setCursorPos(2, 12)
  226.     term.write(" This scanner ")
  227.   end
  228. end
  229.  
  230. local function pageFrame()
  231.   term.setBackgroundColor(colors.lightGray)
  232.   local line = string.rep(" ", 16)
  233.   for i = 15, 19 do
  234.     term.setCursorPos(1, i)
  235.     term.write(line)
  236.   end
  237.   term.setTextColor(colors.gray)
  238.   term.setCursorPos(2, 16)
  239.   term.write("(scroll mouse)")
  240.   term.setCursorPos(2, 18)
  241.   term.setTextColor(colors.gray)
  242.   term.write("Page: ")
  243.   term.setTextColor(colors.black)
  244.   term.write(screen == "main" and tostring(scannerPage) or tostring(accountPage))
  245.   term.setTextColor(colors.gray)
  246.   term.write(" of ")
  247.   term.setTextColor(colors.black)
  248.   term.write(screen == "main" and tostring(scannerPages) or tostring(accountPages))
  249. end
  250.  
  251. local function leftPane()
  252.   term.setBackgroundColor(colors.gray)
  253.   local line = string.rep(" ", 17)
  254.   for i = 4, termY do --# sidebar body
  255.     term.setCursorPos(1, i)
  256.     term.write(line)
  257.   end
  258.   infoFrame()         --# show scanner count or account count and selected scanner
  259.   actionFrame()       --# lock/unlock button(s)
  260.   pageFrame()         --# scannerPage of scannerPages or accountPage of accountPages
  261. end
  262.  
  263. local function accountInfoButtons()
  264.   term.setCursorPos(20, 13)
  265.   term.setTextColor((dataChanged or newAccount) and colors.white or colors.gray)
  266.   term.setBackgroundColor(colors.green)
  267.   term.write(" Save ")
  268.   term.setCursorPos(28, 13)
  269.   term.setBackgroundColor(colors.red)
  270.   term.setTextColor(newAccount and colors.gray or colors.white)
  271.   term.write(" Delete ")
  272.   term.setCursorPos(38, 13)
  273.   term.setTextColor(colors.white)
  274.   term.setBackgroundColor(colors.orange)
  275.   term.write(" Cancel ")
  276.   term.setBackgroundColor(colors.gray)
  277. end
  278.  
  279. local function accountInfo(accountNum)
  280.   screen = "account"
  281.   term.setTextColor(colors.lightBlue)
  282.   term.setBackgroundColor(colors.blue)
  283.   term.setCursorPos(15, 5)
  284.   term.write(string.rep(" ", 36))
  285.   term.setCursorPos(16, 5)
  286.   term.write(newAccount and "New Account" or "Edit Account") --# Dialogue title
  287.   if not newAccount then
  288.     term.setCursorPos(49 - #tostring(accountNum), 5)
  289.     term.write("#" .. tostring(accountNum))
  290.   end
  291.   term.setBackgroundColor(colors.lightGray)
  292.   local line = string.rep(" ", 36)
  293.   for i = 6, 14 do                                  --# Dialogue body
  294.     term.setCursorPos(15, i)
  295.     term.write(line)
  296.   end
  297.   term.setBackgroundColor(colors.gray)
  298.   term.setCursorPos(23, 7)
  299.   term.write(string.rep(" ", 27))                   --# 'Name' input box
  300.   term.setCursorPos(23, 9)
  301.   term.write(string.rep(" ", 27))                   --# 'idPrint' input box
  302.   term.setBackgroundColor(colors.lightGray)
  303.   term.setTextColor(colors.black)
  304.   term.setCursorPos(16, 7)
  305.   term.write("Name:  ")
  306.   term.setTextColor(colors.white)
  307.   term.setBackgroundColor(colors.gray)
  308.   term.write(" " .. accountName:sub(1, 25))         --# Name
  309.   term.setBackgroundColor(colors.lightGray)
  310.   term.setTextColor(colors.black)
  311.   term.setCursorPos(16, 9)
  312.   term.write("Print: ")
  313.   term.setTextColor(((newAccount and not scanned) or accountPrint:find("idPrint-")) and colors.white or colors.lightGray)
  314.   term.setBackgroundColor(colors.gray)
  315.   term.write(" " .. accountPrint:sub(1, 25))        --# idPrint
  316.   term.setBackgroundColor(colors.lightGray)
  317.   term.setTextColor(colors.black)
  318.   term.setCursorPos(16, 11)
  319.   term.write("Access Level: ")
  320.   term.setTextColor(colors.white)
  321.   term.setBackgroundColor(colors.gray)
  322.   term.write(" " .. tostring(accountAccess) .. " ") --# Access Level
  323.   accountInfoButtons()
  324. end
  325.  
  326. local function clearAccountList()
  327.   for i = #accountNames, 1, -1 do
  328.     accountNames[i] = nil
  329.   end
  330. end
  331.  
  332. local function accountList()
  333.   if accountNames[1] then
  334.     local currentTop = ((accountPage - 1) * numPerPage) + 1
  335.     local tmpY = 4
  336.     term.setBackgroundColor(colors.black)
  337.     for i = currentTop, currentTop + numPerPage - 1 do
  338.       tmpY = tmpY + 1
  339.       term.setCursorPos(20, tmpY)
  340.       term.setTextColor(colors.gray)
  341.       term.write("Acct " .. tostring(i) .. ": ")
  342.       term.setCursorPos(29, tmpY)
  343.       term.setTextColor(colors.blue)
  344.       term.write(accountNames[i]:sub(1, 20) .. string.rep(" ", 20 - #accountNames[i]:sub(1, 20))) --# Account name
  345.       if i >= #accountNames then break end
  346.     end
  347.   end
  348. end
  349.  
  350. local function viewAccounts()
  351.   clearDataArea()
  352.   if scannerLock[thisScanner] then
  353.     term.setTextColor(colors.orange)
  354.     term.setCursorPos(21, 5)
  355.     term.write("This scanner is locked")
  356.   else
  357.     accountNames = { scanners[thisScanner].getLearnedNames() } --# get account list from bioscanner
  358.     if accountNames[1] then                                    --# if there are accounts, list them
  359.       accountPages = math.ceil(#accountNames / numPerPage)
  360.       accountPage = math.min(math.max(1, accountPage), accountPages)
  361.       accountList()
  362.     else
  363.       term.setTextColor(colors.lightBlue)
  364.       term.setCursorPos(21, 5)
  365.       term.write("No accounts on this scanner")
  366.     end
  367.   end
  368. end
  369.  
  370. local function scannerList()
  371.   local magicNumber = ((scannerPage - 1) * numPerPage) + 1
  372.   local tmpY = 4
  373.   term.setBackgroundColor(colors.black)
  374.   for i = magicNumber, math.min(magicNumber + numPerPage - 1, #scanners) do
  375.     tmpY = tmpY + 1
  376.     term.setTextColor(scannerLock[i] and colors.red or colors.green)
  377.     term.setCursorPos(21, tmpY)
  378.     term.write(scannerSides[i]:sub(1, 13) .. string.rep(" ", 13 - #scannerSides[i]:sub(1, 13)))
  379.     term.setTextColor(colors.gray)
  380.     term.setCursorPos(36, tmpY)
  381.     if scannerLock[i] then
  382.       term.write("Scanner locked")
  383.     else
  384.       local sNames = { scanners[i].getLearnedNames() }
  385.       term.write(tostring(#sNames))
  386.       term.write(#sNames == 1 and " account     " or " accounts    ")
  387.     end
  388.   end
  389. end
  390.  
  391. local function newAccountHelp()
  392.   clearDataArea()
  393.   term.setTextColor(colors.cyan)
  394.   term.setCursorPos(20, 6)
  395.   term.write("The best way to add a new")
  396.   term.setCursorPos(20, 7)
  397.   term.write("account is to instruct the")
  398.   term.setCursorPos(20, 8)
  399.   term.write("user to swipe the scanner. If")
  400.   term.setCursorPos(20, 9)
  401.   term.write("you prefer to manually create")
  402.   term.setCursorPos(20, 10)
  403.   term.write("an account select ")
  404.   term.setTextColor(colors.orange)
  405.   term.write("Manual Entry")
  406.   term.setTextColor(colors.cyan)
  407.   term.write(".")
  408.   term.setTextColor(colors.lightGray)
  409.   term.setCursorPos(20, 12)
  410.   term.write("Manually entered names/prints")
  411.   term.setCursorPos(20, 13)
  412.   term.write("are limited to 25 characters.")
  413.   term.setTextColor(colors.white)
  414.   term.setBackgroundColor(colors.green)
  415.   term.setCursorPos(28, 15)
  416.   term.write("  Scan  User  ")
  417.   term.setBackgroundColor(colors.orange)
  418.   term.setCursorPos(28, 17)
  419.   term.write(" Manual Entry ")
  420. end
  421.  
  422. local function editAccountName()
  423.   term.setTextColor(colors.lightGray)
  424.   term.setCursorPos(24, 7)
  425.   term.write(accountName:sub(1, 25))
  426.   term.setBackgroundColor(colors.gray)
  427.   term.setTextColor(colors.yellow)
  428.   term.setCursorPos(24, 7)
  429.   local newName = read(nil, nil, 25)
  430.   if newName ~= "" then
  431.     accountName = newName
  432.     dataChanged = true
  433.   end
  434.   term.setCursorPos(23, 7)
  435.   term.write(string.rep(" ", 27))
  436.   term.setTextColor(colors.white)
  437.   term.setCursorPos(24, 7)
  438.   term.write(accountName:sub(1, 25))
  439.   accountInfoButtons()
  440. end
  441.  
  442. local function editAccountPrint()
  443.   term.setCursorPos(24, 9)
  444.   term.setTextColor(colors.lightGray)
  445.   term.write(accountPrint:sub(1, 25))
  446.   term.setCursorPos(24, 9)
  447.   term.setBackgroundColor(colors.gray)
  448.   term.setTextColor(colors.white)
  449.   local newPrint = read(nil, nil, 25)
  450.   if newPrint ~= "" then
  451.     accountPrint = newPrint
  452.     dataChanged = true
  453.   end
  454.   term.setCursorPos(23, 9)
  455.   term.write(string.rep(" ", 27))
  456.   term.setCursorPos(24, 9)
  457.   term.setTextColor(colors.white)
  458.   term.write(accountPrint:sub(1, 25))
  459.   accountInfoButtons()
  460. end
  461.  
  462. local function editAccountAccess()
  463.   term.setCursorPos(31, 11)
  464.   term.setTextColor(colors.lightGray)
  465.   term.write(tostring(accountAccess))
  466.   term.setCursorPos(31, 11)
  467.   term.setBackgroundColor(colors.gray)
  468.   term.setTextColor(colors.yellow)
  469.   local newAccess = tonumber(read(nil, nil, 1))
  470.   if newAccess and newAccess ~= accountAccess and newAccess > 0 and newAccess < 6 then dataChanged = true end
  471.   accountAccess = (newAccess and newAccess > 0 and newAccess < 6) and newAccess or accountAccess
  472.   term.setCursorPos(31, 11)
  473.   term.setTextColor(colors.white)
  474.   term.write(tostring(accountAccess))
  475.   accountInfoButtons()
  476. end
  477.  
  478. local function postAccountMgt()
  479.   dataChanged, newAccount, scanned = false, false, false
  480.   clearAccountList()
  481.   screen = "scanner"
  482.   viewAccounts()
  483.   leftPane()
  484. end
  485.  
  486. local function getPassword()
  487.   term.setBackgroundColor(colors.lightGray)
  488.   term.setTextColor(colors.white)
  489.   term.setCursorPos(22, 9)
  490.   return read("*", nil, 25)
  491. end
  492.  
  493. local function lockUnlockBox()
  494.   local line = string.rep(" ", 29)
  495.   term.setBackgroundColor(colors.blue)
  496.   term.setCursorPos(20, 5)
  497.   term.write(line)
  498.   term.setBackgroundColor(colors.gray)
  499.   term.setTextColor(colors.lightGray)
  500.   for i = 6, 10 do
  501.     term.setCursorPos(20, i)
  502.     term.write(line)
  503.   end
  504.   term.setCursorPos(21, 7)
  505.   term.write("Password")
  506.   term.setBackgroundColor(colors.lightGray)
  507.   term.setCursorPos(21, 9)
  508.   term.write(string.rep(" ", 27))
  509.   term.setBackgroundColor(colors.blue)
  510.   term.setCursorPos(21, 5)
  511. end
  512.  
  513. local function lockUnlockScanner()
  514.   lockUnlockBox()
  515.   term.write("Scanner ")
  516.   term.write(scannerLock[thisScanner] and "Locked" or "Unlocked")
  517.   local newPass = getPassword()
  518.   if newPass and newPass ~= "" then
  519.     if scannerLock[thisScanner] then
  520.       if scanners[thisScanner].unlock(newPass) then
  521.         scannerLock[thisScanner] = false
  522.       end
  523.     else
  524.       if scanners[thisScanner].lock(newPass) then
  525.         accountPage, accountPages = 1, 1
  526.         clearAccountList()
  527.         scannerLock[thisScanner] = true
  528.       end
  529.     end
  530.   end
  531.   header()
  532.   viewAccounts()
  533.   infoFrame()
  534.   actionFrame()
  535.   pageFrame()
  536. end
  537.  
  538. local function lockUnlockAllScanners(_lock)
  539.   lockUnlockBox()
  540.   term.write(_lock and "Lock" or "Unlock")
  541.   term.write(" ALL Scanners")
  542.   local newPass = getPassword()
  543.   if newPass and newPass ~= "" then
  544.     for i = 1, #scanners do
  545.       if _lock then
  546.         if scanners[i].lock(newPass) then
  547.           scannerLock[i] = true
  548.         end
  549.       else
  550.         if scanners[i].unlock(newPass) then
  551.           scannerLock[i] = false
  552.         end
  553.       end
  554.     end
  555.   end
  556.   clearDataArea()
  557.   scannerList()
  558. end
  559.  
  560. local function bioKernel() -- "biolock", IDprint, attachName, learnedName, accessLevel
  561.   while kernelState do
  562.     local event, data, x, y, z = os.pullEvent()
  563.     if event == "biolock" and (screen == "account" or screen == "scanner") and x == scannerSides[thisScanner] and not scannerLock[thisScanner] then
  564.       if screen == "account" and ((newAccount and not scanned) or accountPrint:find("idPrint-")) then --# if the account dialogue is already open (manual entry)
  565.         accountPrint = data
  566.         scanned = true
  567.         accountInfo()
  568.       elseif screen == "scanner" then    --# if the account dialogue is not already open (scanned entry)
  569.         accountPrint = data
  570.         scanned = true
  571.         local thisAccount
  572.         for i = 1, #accountNames do      --# check to see if the accountName is already recorded
  573.           if accountNames[i] == y then
  574.             accountName = y
  575.             accountAccess = z
  576.             thisAccount = i
  577.             break
  578.           end
  579.         end
  580.         if not thisAccount then          --# if the account doesn't already exist then create a new account
  581.           newAccount = true
  582.           accountName = data
  583.           accountAccess = 1
  584.         end
  585.         accountInfo(thisAccount)         --# display the account info dialogue
  586.       end
  587.     elseif event == "mouse_click" and data == 1 then
  588.       if screen == "main" then
  589.         if x > termX - 3 and y < 4 then                             --# X / Quit
  590.           kernelState = false
  591.           clearScreen()
  592.           term.setTextColor(colors.white)
  593.           term.setCursorPos(1, 1)
  594.           break
  595.         elseif x > 1 and x < 8 and (y == 11 or y == 12) then
  596.           lockUnlockAllScanners(true)
  597.         elseif x > 8 and x < 15 and (y == 11 or y == 12) then
  598.           lockUnlockAllScanners()
  599.         elseif x > 20 and x < 36 and y > 4 and y < termY then       --# select a scanner
  600.           local magicNumber = ((scannerPage - 1) * (numPerPage - 1)) + scannerPage + y - 5
  601.           if #scanners >= magicNumber and x < 21 + #scannerSides[magicNumber] then
  602.             thisScanner = magicNumber
  603.             screen = "scanner"
  604.             header()
  605.             viewAccounts()
  606.             leftPane()
  607.           end
  608.         end
  609.       elseif screen == "scanner" then
  610.         if x > termX - 3 and y < 4 then                              --# X / Exit scanner screen to main screen
  611.           screen = "main"
  612.           clearAccountList()
  613.           clearDataArea()
  614.           header()
  615.           scannerList()
  616.           leftPane()
  617.         elseif x < 4 and y < 4 and not scannerLock[thisScanner] then --# manual new account help
  618.           screen = "accountHelp"
  619.           newAccountHelp()
  620.         elseif x > 1 and x < 16 and (y == 11 or y == 12) then        --# lock/unlock scanner
  621.           lockUnlockScanner()
  622.         elseif x > 28 and x < 49 and y > 4 and y < termY then        --# select an account
  623.           local magicNumber = ((accountPage - 1) * (numPerPage - 1)) + accountPage + y - 5
  624.           if #accountNames >= magicNumber and x < 33 + #accountNames[magicNumber] then
  625.             accountName = accountNames[magicNumber]
  626.             accountPrint = scanners[thisScanner].getPrint(accountName)
  627.             accountAccess = scanners[thisScanner].getAccessLevel(accountName)
  628.             accountInfo(magicNumber)
  629.           end
  630.         end
  631.       elseif screen == "account" then
  632.         if y == 7 and x > 22 and x < 50 then                         --# Account Name
  633.           editAccountName()
  634.         elseif y == 9 and x > 22 and x < 50 and ((newAccount and not scanned) or accountPrint:find("idPrint-")) then --# Account idPrint
  635.           editAccountPrint()
  636.         elseif y == 11 and x > 29 and x < 33 then                    --# Account Access level
  637.           editAccountAccess()
  638.         elseif y == 13 then
  639.           if x > 19 and x < 26 and (newAccount or dataChanged) then  --# Save
  640.             scanners[thisScanner].learn(accountName, accountPrint, accountAccess)
  641.             postAccountMgt()
  642.           elseif x > 27 and x < 36 and not newAccount then           --# Delete
  643.             scanners[thisScanner].forget(accountName)
  644.             postAccountMgt()
  645.           elseif x > 37 and x < 46 then                              --# Cancel
  646.             postAccountMgt()
  647.           end
  648.         end
  649.       elseif screen == "accountHelp" then
  650.         if (x > termX - 3 and y < 4) or (x > 27 and x < 42) then
  651.           if y == 15 or (x > termX - 3 and y < 4) then --# scan in new account / return to main screen
  652.             screen = "scanner"
  653.             clearDataArea()
  654.             accountList()
  655.           elseif y == 17 then            --# manually input new account
  656.             clearDataArea()
  657.             accountName = "User-" .. tostring(#accountNames + 1) .. "-" .. tostring(math.random(1000, 9999))
  658.             accountPrint = "idPrint-" .. tostring(#accountNames + 1) .. "-" .. tostring(math.random(1000, 9999))
  659.             accountAccess = 1
  660.             newAccount = true
  661.             accountInfo()
  662.           end
  663.         end
  664.       end
  665.     elseif event == "mouse_scroll" and (screen == "main" or screen == "scanner") then
  666.       if screen == "main" then
  667.         scannerPage = data == 1 and math.min(scannerPage + 1, scannerPages) or math.max(scannerPage - 1, 1)
  668.         if scannerPage == scannerPages and scannerPages > 1 then clearDataArea() end
  669.         scannerList()
  670.       else
  671.         accountPage = data == 1 and math.min(accountPage + 1, accountPages) or math.max(accountPage - 1, 1)
  672.         if accountPage == accountPages and accountPages > 1 then clearDataArea() end
  673.         accountList()
  674.       end
  675.       pageFrame()
  676.     elseif event == "key" and (screen == "main" or screen == "scanner") then
  677.       if data == keys.home or data == keys["end"] then --# Home/End
  678.         if screen == "main" then
  679.           scannerPage = data == keys.home and 1 or scannerPages
  680.           if scannerPage == scannerPages and scannerPages > 1 then clearDataArea() end
  681.           scannerList()
  682.         else
  683.           accountPage = data == keys.home and 1 or accountPages
  684.           if accountPage == accountPages and accountPages > 1 then clearDataArea() end
  685.           accountList()
  686.         end
  687.         pageFrame()
  688.       elseif data == keys.pageUp or data == keys.pageDown then --# Page forward/back
  689.         if screen == "main" then
  690.           scannerPage = data == keys.pageUp and math.min(scannerPage + 1, scannerPages) or math.max(1, scannerPage - 1)
  691.           if scannerPage == scannerPages and scannerPages > 1 then clearDataArea() end
  692.           scannerList()
  693.         else
  694.           accountPage = data == keys.pageUp and math.min(accountPage + 1, accountPages) or math.max(1, accountpage - 1)
  695.           if accountPage == accountPages and accountPages > 1 then clearDataArea() end
  696.           accountList()
  697.         end
  698.         pageFrame()
  699.       end
  700.     end
  701.   end
  702. end
  703.  
  704. local function initError(device)
  705.   clearScreen()
  706.   term.setTextColor(colors.white)
  707.   term.setCursorPos(2, 2)
  708.   write("BioPup requires " .. device)
  709.   term.setCursorPos(1, 5)
  710. end
  711.  
  712. if not os.getComputerLabel() then os.setComputerLabel("Computer " .. tostring(os.getComputerID())) end
  713. if not term.isColor() or pocket or turtle then return initError("an Advanced Computer") end
  714. if termX < 51 or termY < 19 then return initError("full screen") end
  715. for _, side in pairs(rs.getSides()) do
  716.   if peripheral.getType(side) == "biolock" then
  717.     scanners[#scanners + 1] = peripheral.wrap(side)
  718.     scannerSides[#scannerSides + 1] = side
  719.     if scanners[#scanners].lock("test") then
  720.       scanners[#scanners].unlock("test")
  721.       scannerLock[#scannerLock + 1] = false
  722.     else
  723.       scannerLock[#scannerLock + 1] = true
  724.     end
  725.   elseif peripheral.getType(side) == "modem" and not peripheral.call(side, "isWireless") then
  726.     for _, name in pairs(peripheral.call(side, "getNamesRemote")) do
  727.       if peripheral.getType(name) == "biolock" then
  728.         scanners[#scanners + 1] = peripheral.wrap(name)
  729.         scannerSides[#scannerSides + 1] = name
  730.         if scanners[#scanners].lock("test") then
  731.           scanners[#scanners].unlock("test")
  732.           scannerLock[#scannerLock + 1] = false
  733.         else
  734.           scannerLock[#scannerLock + 1] = true
  735.         end
  736.       end
  737.     end
  738.   end
  739. end
  740. if not scanners[1] then return initError("a Biometric Scanner") end
  741. scannerPages = math.ceil(#scanners / numPerPage)
  742. clearScreen()
  743. header()
  744. leftPane()
  745. scannerList()
  746. bioKernel() --# main loop
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top