Advertisement
realrivals

Ultimate door lock

Jun 22nd, 2014
272
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 40.75 KB | None | 0 0
  1. tArgs = {...}
  2.  
  3. colourMode = (term.isColor and term.isColor())
  4.  
  5. if OneOS then
  6.     --running under OneOS
  7.     OneOS.ToolBarColour = colours.white
  8.     OneOS.ToolBarTextColour = colours.grey
  9. end
  10.  
  11. local _w, _h = term.getSize()
  12.  
  13. local round = function(num, idp)
  14.     local mult = 10^(idp or 0)
  15.     return math.floor(num * mult + 0.5) / mult
  16. end
  17.  
  18. InterfaceElements = {}
  19.  
  20. Drawing = {
  21.    
  22.     Screen = {
  23.         Width = _w,
  24.         Height = _h
  25.     },
  26.  
  27.     DrawCharacters = function (x, y, characters, textColour,bgColour)
  28.         Drawing.WriteStringToBuffer(x, y, characters, textColour, bgColour)
  29.     end,
  30.    
  31.     DrawBlankArea = function (x, y, w, h, colour)
  32.         Drawing.DrawArea (x, y, w, h, " ", 1, colour)
  33.     end,
  34.  
  35.     DrawArea = function (x, y, w, h, character, textColour, bgColour)
  36.         --width must be greater than 1, other wise we get a stack overflow
  37.         if w < 0 then
  38.             w = w * -1
  39.         elseif w == 0 then
  40.             w = 1
  41.         end
  42.  
  43.         for ix = 1, w do
  44.             local currX = x + ix - 1
  45.             for iy = 1, h do
  46.                 local currY = y + iy - 1
  47.                 Drawing.WriteToBuffer(currX, currY, character, textColour, bgColour)
  48.             end
  49.         end
  50.     end,
  51.  
  52.     DrawImage = function(_x,_y,tImage, w, h)
  53.         if tImage then
  54.             for y = 1, h do
  55.                 if not tImage[y] then
  56.                     break
  57.                 end
  58.                 for x = 1, w do
  59.                     if not tImage[y][x] then
  60.                         break
  61.                     end
  62.                     local bgColour = tImage[y][x]
  63.                     local textColour = tImage.textcol[y][x] or colours.white
  64.                     local char = tImage.text[y][x]
  65.                     Drawing.WriteToBuffer(x+_x-1, y+_y-1, char, textColour, bgColour)
  66.                 end
  67.             end
  68.         elseif w and h then
  69.             Drawing.DrawBlankArea(x, y, w, h, colours.green)
  70.         end
  71.     end,
  72.     --using .nft
  73.     LoadImage = function(path)
  74.         local image = {
  75.             text = {},
  76.             textcol = {}
  77.         }
  78.         local fs = fs
  79.         if OneOS then
  80.             fs = OneOS.FS
  81.         end
  82.         if fs.exists(path) then
  83.             local _open = io.open
  84.             if OneOS then
  85.                 _open = OneOS.IO.open
  86.             end
  87.             local file = _open(path, "r")
  88.             local sLine = file:read()
  89.             local num = 1
  90.             while sLine do  
  91.                     table.insert(image, num, {})
  92.                     table.insert(image.text, num, {})
  93.                     table.insert(image.textcol, num, {})
  94.                                                
  95.                     --As we're no longer 1-1, we keep track of what index to write to
  96.                     local writeIndex = 1
  97.                     --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour
  98.                     local bgNext, fgNext = false, false
  99.                     --The current background and foreground colours
  100.                     local currBG, currFG = nil,nil
  101.                     for i=1,#sLine do
  102.                             local nextChar = string.sub(sLine, i, i)
  103.                             if nextChar:byte() == 30 then
  104.                                 bgNext = true
  105.                             elseif nextChar:byte() == 31 then
  106.                                 fgNext = true
  107.                             elseif bgNext then
  108.                                 currBG = Drawing.GetColour(nextChar)
  109.                                 bgNext = false
  110.                             elseif fgNext then
  111.                                 currFG = Drawing.GetColour(nextChar)
  112.                                 fgNext = false
  113.                             else
  114.                                 if nextChar ~= " " and currFG == nil then
  115.                                        currFG = colours.white
  116.                                 end
  117.                                 image[num][writeIndex] = currBG
  118.                                 image.textcol[num][writeIndex] = currFG
  119.                                 image.text[num][writeIndex] = nextChar
  120.                                 writeIndex = writeIndex + 1
  121.                             end
  122.                     end
  123.                     num = num+1
  124.                     sLine = file:read()
  125.             end
  126.             file:close()
  127.         end
  128.         return image
  129.     end,
  130.  
  131.     DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour)
  132.         w = w or Drawing.Screen.Width
  133.         h = h or Drawing.Screen.Height
  134.         x = x or 0
  135.         y = y or 0
  136.         x = math.ceil((w - #characters) / 2) + x
  137.         y = math.floor(h / 2) + y
  138.  
  139.         Drawing.DrawCharacters(x, y, characters, textColour, bgColour)
  140.     end,
  141.  
  142.     GetColour = function(hex)
  143.         if hex == ' ' then
  144.             return colours.transparent
  145.         end
  146.         local value = tonumber(hex, 16)
  147.         if not value then return nil end
  148.         value = math.pow(2,value)
  149.         return value
  150.     end,
  151.  
  152.     Clear = function (_colour)
  153.         _colour = _colour or colours.black
  154.         Drawing.ClearBuffer()
  155.         Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, Drawing.Screen.Height, _colour)
  156.     end,
  157.  
  158.     Buffer = {},
  159.     BackBuffer = {},
  160.  
  161.     DrawBuffer = function()
  162.         for y,row in pairs(Drawing.Buffer) do
  163.             for x,pixel in pairs(row) do
  164.                 local shouldDraw = true
  165.                 local hasBackBuffer = true
  166.                 if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then
  167.                     hasBackBuffer = false
  168.                 end
  169.                 if hasBackBuffer and Drawing.BackBuffer[y][x][1] == Drawing.Buffer[y][x][1] and Drawing.BackBuffer[y][x][2] == Drawing.Buffer[y][x][2] and Drawing.BackBuffer[y][x][3] == Drawing.Buffer[y][x][3] then
  170.                     shouldDraw = false
  171.                 end
  172.                 if shouldDraw then
  173.                     term.setBackgroundColour(pixel[3])
  174.                     term.setTextColour(pixel[2])
  175.                     term.setCursorPos(x, y)
  176.                     term.write(pixel[1])
  177.                 end
  178.             end
  179.         end
  180.         Drawing.BackBuffer = Drawing.Buffer
  181.         Drawing.Buffer = {}
  182.         term.setCursorPos(1,1)
  183.     end,
  184.  
  185.     ClearBuffer = function()
  186.         Drawing.Buffer = {}
  187.     end,
  188.  
  189.     WriteStringToBuffer = function (x, y, characters, textColour,bgColour)
  190.         for i = 1, #characters do
  191.             local character = characters:sub(i,i)
  192.             Drawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour)
  193.         end
  194.     end,
  195.  
  196.     WriteToBuffer = function(x, y, character, textColour,bgColour)
  197.         if not colourMode then
  198.             if textColour ~= colours.white then
  199.                 textColour = colours.black
  200.             end
  201.             if bgColour ~= colours.white then
  202.                 bgColour = colours.black
  203.             end
  204.         end
  205.         x = round(x)
  206.         y = round(y)
  207.         if bgColour == colours.transparent then
  208.             Drawing.Buffer[y] = Drawing.Buffer[y] or {}
  209.             Drawing.Buffer[y][x] = Drawing.Buffer[y][x] or {"", colours.white, colours.black}
  210.             Drawing.Buffer[y][x][1] = character
  211.             Drawing.Buffer[y][x][2] = textColour
  212.         else
  213.             Drawing.Buffer[y] = Drawing.Buffer[y] or {}
  214.             Drawing.Buffer[y][x] = {character, textColour, bgColour}
  215.         end
  216.     end,
  217. }
  218.  
  219. Current = {
  220.     Document = nil,
  221.     TextInput = nil,
  222.     CursorPos = {1,1},
  223.     CursorColour = colours.black,
  224.     Selection = {8, 36},
  225.     Window = nil,
  226.     HeaderText = '',
  227.     StatusText = '',
  228.     StatusColour = colours.grey,
  229.     StatusScreen = true,
  230.     ButtonOne = nil,
  231.     ButtonTwo = nil,
  232.     Locked = false,
  233.     Page = '',
  234.     PageControls = {}
  235. }
  236.  
  237. isRunning = true
  238.  
  239. Events = {}
  240.  
  241. Button = {
  242.     X = 1,
  243.     Y = 1,
  244.     Width = 0,
  245.     Height = 0,
  246.     BackgroundColour = colours.lightGrey,
  247.     TextColour = colours.white,
  248.     ActiveBackgroundColour = colours.lightGrey,
  249.     Text = "",
  250.     Parent = nil,
  251.     _Click = nil,
  252.     Toggle = nil,
  253.  
  254.     AbsolutePosition = function(self)
  255.         return self.Parent:AbsolutePosition()
  256.     end,
  257.  
  258.     Draw = function(self)
  259.         local bg = self.BackgroundColour
  260.         local tc = self.TextColour
  261.         if type(bg) == 'function' then
  262.             bg = bg()
  263.         end
  264.  
  265.         if self.Toggle then
  266.             tc = colours.white
  267.             bg = self.ActiveBackgroundColour
  268.         end
  269.  
  270.         local pos = GetAbsolutePosition(self)
  271.         Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, bg)
  272.         Drawing.DrawCharactersCenter(pos.X, pos.Y, self.Width, self.Height, self.Text, tc, bg)
  273.     end,
  274.  
  275.     Initialise = function(self, x, y, width, height, backgroundColour, parent, click, text, textColour, toggle, activeBackgroundColour)
  276.         local new = {}    -- the new instance
  277.         setmetatable( new, {__index = self} )
  278.         height = height or 1
  279.         new.Width = width or #text + 2
  280.         new.Height = height
  281.         new.Y = y
  282.         new.X = x
  283.         new.Text = text or ""
  284.         if colourMode then
  285.             new.BackgroundColour = backgroundColour or colours.lightGrey
  286.             new.TextColour = textColour or colours.white
  287.             new.ActiveBackgroundColour = activeBackgroundColour or colours.lightBlue
  288.         else
  289.             new.BackgroundColour = colours.white
  290.             new.TextColour = colours.black
  291.             new.ActiveBackgroundColour = colours.black
  292.         end
  293.         new.Parent = parent
  294.         new._Click = click
  295.         new.Toggle = toggle
  296.         return new
  297.     end,
  298.  
  299.     Click = function(self, side, x, y)
  300.         if self._Click then
  301.             if self:_Click(side, x, y, not self.Toggle) ~= false and self.Toggle ~= nil then
  302.                 self.Toggle = not self.Toggle
  303.                 Draw()
  304.             end
  305.             return true
  306.         else
  307.             return false
  308.         end
  309.     end
  310. }
  311.  
  312. Label = {
  313.     X = 1,
  314.     Y = 1,
  315.     Width = 0,
  316.     Height = 0,
  317.     BackgroundColour = colours.lightGrey,
  318.     TextColour = colours.white,
  319.     Text = "",
  320.     Parent = nil,
  321.  
  322.     AbsolutePosition = function(self)
  323.         return self.Parent:AbsolutePosition()
  324.     end,
  325.  
  326.     Draw = function(self)
  327.         local bg = self.BackgroundColour
  328.         local tc = self.TextColour
  329.  
  330.         if self.Toggle then
  331.             tc = UIColours.MenuBarActive
  332.             bg = self.ActiveBackgroundColour
  333.         end
  334.  
  335.         local pos = GetAbsolutePosition(self)
  336.         Drawing.DrawCharacters(pos.X, pos.Y, self.Text, self.TextColour, self.BackgroundColour)
  337.     end,
  338.  
  339.     Initialise = function(self, x, y, text, textColour, backgroundColour, parent)
  340.         local new = {}    -- the new instance
  341.         setmetatable( new, {__index = self} )
  342.         height = height or 1
  343.         new.Width = width or #text + 2
  344.         new.Height = height
  345.         new.Y = y
  346.         new.X = x
  347.         new.Text = text or ""
  348.         new.BackgroundColour = backgroundColour or colours.white
  349.         new.TextColour = textColour or colours.black
  350.         new.Parent = parent
  351.         return new
  352.     end,
  353.  
  354.     Click = function(self, side, x, y)
  355.         return false
  356.     end
  357. }
  358.  
  359. TextBox = {
  360.     X = 1,
  361.     Y = 1,
  362.     Width = 0,
  363.     Height = 0,
  364.     BackgroundColour = colours.lightGrey,
  365.     TextColour = colours.black,
  366.     Parent = nil,
  367.     TextInput = nil,
  368.     Placeholder = '',
  369.  
  370.     AbsolutePosition = function(self)
  371.         return self.Parent:AbsolutePosition()
  372.     end,
  373.  
  374.     Draw = function(self)      
  375.         local pos = GetAbsolutePosition(self)
  376.         Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, self.BackgroundColour)
  377.         local text = self.TextInput.Value
  378.         if #tostring(text) > (self.Width - 2) then
  379.             text = text:sub(#text-(self.Width - 3))
  380.             if Current.TextInput == self.TextInput then
  381.                 Current.CursorPos = {pos.X + 1 + self.Width-2, pos.Y}
  382.             end
  383.         else
  384.             if Current.TextInput == self.TextInput then
  385.                 Current.CursorPos = {pos.X + 1 + self.TextInput.CursorPos, pos.Y}
  386.             end
  387.         end
  388.        
  389.         if #tostring(text) == 0 then
  390.             Drawing.DrawCharacters(pos.X + 1, pos.Y, self.Placeholder, colours.lightGrey, self.BackgroundColour)
  391.         else
  392.             Drawing.DrawCharacters(pos.X + 1, pos.Y, text, self.TextColour, self.BackgroundColour)
  393.         end
  394.  
  395.         term.setCursorBlink(true)
  396.        
  397.         Current.CursorColour = self.TextColour
  398.     end,
  399.  
  400.     Initialise = function(self, x, y, width, height, parent, text, backgroundColour, textColour, done, numerical)
  401.         local new = {}    -- the new instance
  402.         setmetatable( new, {__index = self} )
  403.         height = height or 1
  404.         new.Width = width or #text + 2
  405.         new.Height = height
  406.         new.Y = y
  407.         new.X = x
  408.         new.TextInput = TextInput:Initialise(text or '', function(key)
  409.             if done then
  410.                 done(key)
  411.             end
  412.             Draw()
  413.         end, numerical)
  414.         new.BackgroundColour = backgroundColour or colours.lightGrey
  415.         new.TextColour = textColour or colours.black
  416.         new.Parent = parent
  417.         return new
  418.     end,
  419.  
  420.     Click = function(self, side, x, y)
  421.         Current.Input = self.TextInput
  422.         self:Draw()
  423.     end
  424. }
  425.  
  426. TextInput = {
  427.     Value = "",
  428.     Change = nil,
  429.     CursorPos = nil,
  430.     Numerical = false,
  431.     IsDocument = nil,
  432.  
  433.     Initialise = function(self, value, change, numerical, isDocument)
  434.         local new = {}    -- the new instance
  435.         setmetatable( new, {__index = self} )
  436.         new.Value = tostring(value)
  437.         new.Change = change
  438.         new.CursorPos = #tostring(value)
  439.         new.Numerical = numerical
  440.         new.IsDocument = isDocument or false
  441.         return new
  442.     end,
  443.  
  444.     Insert = function(self, str)
  445.         if self.Numerical then
  446.             str = tostring(tonumber(str))
  447.         end
  448.  
  449.         local selection = OrderSelection()
  450.  
  451.         if self.IsDocument and selection then
  452.             self.Value = string.sub(self.Value, 1, selection[1]-1) .. str .. string.sub( self.Value, selection[2]+2)
  453.             self.CursorPos = selection[1]
  454.             Current.Selection = nil
  455.         else
  456.             local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','')
  457.  
  458.             self.Value = string.sub(self.Value, 1, self.CursorPos + newLineAdjust) .. str .. string.sub( self.Value, self.CursorPos + 1  + newLineAdjust)
  459.             self.CursorPos = self.CursorPos + 1
  460.         end
  461.        
  462.         self.Change(key)
  463.     end,
  464.  
  465.     Extract = function(self, remove)
  466.         local selection = OrderSelection()
  467.         if self.IsDocument and selection then
  468.             local _, newLineAdjust = string.gsub(self.Value:sub(selection[1], selection[2]), '\n','')
  469.             local str = string.sub(self.Value, selection[1], selection[2]+1+newLineAdjust)
  470.             if remove then
  471.                 self.Value = string.sub(self.Value, 1, selection[1]-1) .. string.sub( self.Value, selection[2]+2+newLineAdjust)
  472.                 self.CursorPos = selection[1] - 1
  473.                 Current.Selection = nil
  474.             end
  475.             return str
  476.         end
  477.     end,
  478.  
  479.     Char = function(self, char)
  480.         if char == 'nil' then
  481.             return
  482.         end
  483.         self:Insert(char)
  484.     end,
  485.  
  486.     Key = function(self, key)
  487.         if key == keys.enter then
  488.             if self.IsDocument then
  489.                 self.Value = string.sub(self.Value, 1, self.CursorPos ) .. '\n' .. string.sub( self.Value, self.CursorPos + 1 )
  490.                 self.CursorPos = self.CursorPos + 1
  491.             end
  492.             self.Change(key)       
  493.         elseif key == keys.left then
  494.             -- Left
  495.             if self.CursorPos > 0 then
  496.                 local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos))
  497.                 self.CursorPos = self.CursorPos - 1 - colShift
  498.                 self.Change(key)
  499.             end
  500.            
  501.         elseif key == keys.right then
  502.             -- Right               
  503.             if self.CursorPos < string.len(self.Value) then
  504.                 local colShift = FindColours(string.sub( self.Value, self.CursorPos+1, self.CursorPos+1))
  505.                 self.CursorPos = self.CursorPos + 1 + colShift
  506.                 self.Change(key)
  507.             end
  508.        
  509.         elseif key == keys.backspace then
  510.             -- Backspace
  511.             if self.IsDocument and Current.Selection then
  512.                 self:Extract(true)
  513.                 self.Change(key)
  514.             elseif self.CursorPos > 0 then
  515.                 local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos))
  516.                 local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','')
  517.  
  518.                 self.Value = string.sub( self.Value, 1, self.CursorPos - 1 - colShift + newLineAdjust) .. string.sub( self.Value, self.CursorPos + 1 - colShift + newLineAdjust)
  519.                 self.CursorPos = self.CursorPos - 1 - colShift
  520.                 self.Change(key)
  521.             end
  522.         elseif key == keys.home then
  523.             -- Home
  524.             self.CursorPos = 0
  525.             self.Change(key)
  526.         elseif key == keys.delete then
  527.             if self.IsDocument and Current.Selection then
  528.                 self:Extract(true)
  529.                 self.Change(key)
  530.             elseif self.CursorPos < string.len(self.Value) then
  531.                 self.Value = string.sub( self.Value, 1, self.CursorPos ) .. string.sub( self.Value, self.CursorPos + 2 )               
  532.                 self.Change(key)
  533.             end
  534.         elseif key == keys["end"] then
  535.             -- End
  536.             self.CursorPos = string.len(self.Value)
  537.             self.Change(key)
  538.         elseif key == keys.up and self.IsDocument then
  539.             -- Up
  540.             if Current.Document.CursorPos then
  541.                 local page = Current.Document.Pages[Current.Document.CursorPos.Page]
  542.                 self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY - 1 + Current.Document.ScrollBar.Scroll, true)
  543.                 self.Change(key)
  544.             end
  545.         elseif key == keys.down and self.IsDocument then
  546.             -- Down
  547.             if Current.Document.CursorPos then
  548.                 local page = Current.Document.Pages[Current.Document.CursorPos.Page]
  549.                 self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY + 1 + Current.Document.ScrollBar.Scroll, true)
  550.                 self.Change(key)
  551.             end
  552.         end
  553.     end
  554. }
  555.  
  556. local Capitalise = function(str)
  557.     return str:sub(1, 1):upper() .. str:sub(2, -1)
  558. end
  559.  
  560. Peripheral = {
  561.     GetPeripheral = function(_type)
  562.         for i, p in ipairs(Peripheral.GetPeripherals()) do
  563.             if p.Type == _type then
  564.                 return p
  565.             end
  566.         end
  567.     end,
  568.  
  569.     Call = function(type, ...)
  570.         local tArgs = {...}
  571.         local p = GetPeripheral(type)
  572.         peripheral.call(p.Side, unpack(tArgs))
  573.     end,
  574.  
  575.     GetPeripherals = function(filterType)
  576.         local peripherals = {}
  577.         for i, side in ipairs(peripheral.getNames()) do
  578.             local name = peripheral.getType(side):gsub("^%l", string.upper)
  579.             local code = string.upper(side:sub(1,1))
  580.             if side:find('_') then
  581.                 code = side:sub(side:find('_')+1)
  582.             end
  583.  
  584.             local dupe = false
  585.             for i, v in ipairs(peripherals) do
  586.                 if v[1] == name .. ' ' .. code then
  587.                     dupe = true
  588.                 end
  589.             end
  590.  
  591.             if not dupe then
  592.                 local _type = peripheral.getType(side)
  593.                 local isWireless = false
  594.                 if _type == 'modem' then
  595.                     if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then
  596.                         isWireless = true
  597.                     end    
  598.                     if isWireless then
  599.                         _type = 'wireless_modem'
  600.                         name = 'W '..name
  601.                     end
  602.                 end
  603.                 if not filterType or _type == filterType then
  604.                     table.insert(peripherals, {Name = name:sub(1,8) .. ' '..code, Fullname = name .. ' ('..Capitalise(side)..')', Side = side, Type = _type, Wireless = isWireless})
  605.                 end
  606.             end
  607.         end
  608.         return peripherals
  609.     end,
  610.  
  611.     GetPeripheral = function(_type)
  612.         for i, p in ipairs(Peripheral.GetPeripherals()) do
  613.             if p.Type == _type then
  614.                 return p
  615.             end
  616.         end
  617.     end,
  618.  
  619.     PresentNamed = function(name)
  620.         return peripheral.isPresent(name)
  621.     end,
  622.  
  623.     CallType = function(type, ...)
  624.         local tArgs = {...}
  625.         local p = Peripheral.GetPeripheral(type)
  626.         return peripheral.call(p.Side, unpack(tArgs))
  627.     end,
  628.  
  629.     CallNamed = function(name, ...)
  630.         local tArgs = {...}
  631.         return peripheral.call(name, unpack(tArgs))
  632.     end
  633. }
  634.  
  635. Wireless = {
  636.     Channels = {
  637.         UltimateDoorlockPing = 4210,
  638.         UltimateDoorlockRequest = 4211,
  639.         UltimateDoorlockRequestReply = 4212,
  640.     },
  641.  
  642.     isOpen = function(channel)
  643.         return Peripheral.CallType('wireless_modem', 'isOpen', channel)
  644.     end,
  645.  
  646.     Open = function(channel)
  647.         if not Wireless.isOpen(channel) then
  648.             Peripheral.CallType('wireless_modem', 'open', channel)
  649.         end
  650.     end,
  651.  
  652.     close = function(channel)
  653.         Peripheral.CallType('wireless_modem', 'close', channel)
  654.     end,
  655.  
  656.     closeAll = function()
  657.         Peripheral.CallType('wireless_modem', 'closeAll')
  658.     end,
  659.  
  660.     transmit = function(channel, replyChannel, message)
  661.         Peripheral.CallType('wireless_modem', 'transmit', channel, replyChannel, textutils.serialize(message))
  662.     end,
  663.  
  664.     Present = function()
  665.         if Peripheral.GetPeripheral('wireless_modem') == nil then
  666.             return false
  667.         else
  668.             return true
  669.         end
  670.     end,
  671.  
  672.     FormatMessage = function(message, messageID, destinationID)
  673.         return {
  674.             content = textutils.serialize(message),
  675.             senderID = os.getComputerID(),
  676.             senderName = os.getComputerLabel(),
  677.             channel = channel,
  678.             replyChannel = reply,
  679.             messageID = messageID or math.random(10000),
  680.             destinationID = destinationID
  681.         }
  682.     end,
  683.  
  684.     Timeout = function(func, time)
  685.         time = time or 1
  686.         parallel.waitForAny(func, function()
  687.             sleep(time)
  688.             --log('Timeout!'..time)
  689.         end)
  690.     end,
  691.  
  692.     RecieveMessage = function(_channel, messageID, timeout)
  693.         open(_channel)
  694.         local done = false
  695.         local event, side, channel, replyChannel, message = nil
  696.         Timeout(function()
  697.             while not done do
  698.                 event, side, channel, replyChannel, message = os.pullEvent('modem_message')
  699.                 if channel ~= _channel then
  700.                     event, side, channel, replyChannel, message = nil
  701.                 else
  702.                     message = textutils.unserialize(message)
  703.                     message.content = textutils.unserialize(message.content)
  704.                     if messageID and messageID ~= message.messageID or (message.destinationID ~= nil and message.destinationID ~= os.getComputerID()) then
  705.                         event, side, channel, replyChannel, message = nil
  706.                     else
  707.                         done = true
  708.                     end
  709.                 end
  710.             end
  711.         end,
  712.         timeout)
  713.         return event, side, channel, replyChannel, message
  714.     end,
  715.  
  716.     Initialise = function()
  717.         if Wireless.Present() then
  718.             for i, c in pairs(Wireless.Channels) do
  719.                 Wireless.Open(c)
  720.             end
  721.         end
  722.     end,
  723.  
  724.     HandleMessage = function(event, side, channel, replyChannel, message, distance)
  725.         message = textutils.unserialize(message)
  726.         message.content = textutils.unserialize(message.content)
  727.  
  728.         if channel == Wireless.Channels.Ping then
  729.             if message.content == 'Ping!' then
  730.                 SendMessage(replyChannel, 'Pong!', nil, message.messageID)
  731.             end
  732.         elseif message.destinationID ~= nil and message.destinationID ~= os.getComputerID() then
  733.         elseif Wireless.Responder then
  734.             Wireless.Responder(event, side, channel, replyChannel, message, distance)
  735.         end
  736.     end,
  737.  
  738.     SendMessage = function(channel, message, reply, messageID, destinationID)
  739.         reply = reply or channel + 1
  740.         Wireless.Open(channel)
  741.         Wireless.Open(reply)
  742.         local _message = Wireless.FormatMessage(message, messageID, destinationID)
  743.         Wireless.transmit(channel, reply, _message)
  744.         return _message
  745.     end,
  746.  
  747.     Ping = function()
  748.         local message = SendMessage(Channels.Ping, 'Ping!', Channels.PingReply)
  749.         RecieveMessage(Channels.PingReply, message.messageID)
  750.     end
  751. }
  752.  
  753. function GetAbsolutePosition(object)
  754.     local obj = object
  755.     local i = 0
  756.     local x = 1
  757.     local y = 1
  758.     while true do
  759.         x = x + obj.X - 1
  760.         y = y + obj.Y - 1
  761.  
  762.         if not obj.Parent then
  763.             return {X = x, Y = y}
  764.         end
  765.  
  766.         obj = obj.Parent
  767.  
  768.         if i > 32 then
  769.             return {X = 1, Y = 1}
  770.         end
  771.  
  772.         i = i + 1
  773.     end
  774.  
  775. end
  776.  
  777. function Draw()
  778.     Drawing.Clear(colours.white)
  779.  
  780.     if Current.StatusScreen then
  781.         local headerCol = colours.blue
  782.         local byCol = colours.lightGrey
  783.         if not colourMode then
  784.             headerCol = colours.black
  785.         end
  786.         Drawing.DrawCharactersCenter(1, -2, nil, nil, Current.HeaderText, headerCol, colours.white)
  787.         Drawing.DrawCharactersCenter(1, -1, nil, nil, 'by oeed', byCol, colours.white)
  788.         Drawing.DrawCharactersCenter(1, 1, nil, nil, Current.StatusText, Current.StatusColour, colours.white)
  789.     end
  790.  
  791.     if Current.ButtonOne then
  792.         if colourMode then
  793.             Current.ButtonOne:Draw()
  794.         else
  795.             Drawing.DrawCharacters(1, Drawing.Screen.Height-1, Current.ButtonOne.Text, colours.black, colours.white)
  796.             Drawing.DrawCharacters(1, Drawing.Screen.Height, '[DELETE]', colours.black, colours.white)
  797.         end
  798.     end
  799.  
  800.     if Current.ButtonTwo then
  801.         if colourMode then
  802.             Current.ButtonTwo:Draw()
  803.         else
  804.             Drawing.DrawCharacters(Drawing.Screen.Width - #Current.ButtonTwo.Text, Drawing.Screen.Height-1, Current.ButtonTwo.Text, colours.black, colours.white)
  805.             Drawing.DrawCharacters(Drawing.Screen.Width - 6, Drawing.Screen.Height, '[ENTER]', colours.black, colours.white)
  806.         end
  807.     end
  808.  
  809.     for i, v in ipairs(Current.PageControls) do
  810.         v:Draw()
  811.     end
  812.  
  813.     Drawing.DrawBuffer()
  814.         term.setTextColour(colours.black)
  815.  
  816.     if Current.TextInput and Current.CursorPos and not Current.Menu and not(Current.Window and Current.Document and Current.TextInput == Current.Document.TextInput) and Current.CursorPos[2] > 1 then
  817.         term.setCursorPos(Current.CursorPos[1], Current.CursorPos[2])
  818.         term.setCursorBlink(true)
  819.         term.setTextColour(Current.CursorColour)
  820.     else
  821.         term.setCursorBlink(false)
  822.     end
  823. end
  824. MainDraw = Draw
  825.  
  826. function GenerateFingerprint()
  827.     local str = ""
  828.     for _ = 1, 256 do
  829.         local char = math.random(32, 126)
  830.         --if char == 96 then char = math.random(32, 95) end
  831.         str = str .. string.char(char)
  832.     end
  833.     return str
  834. end
  835.  
  836. function MakeFingerprint()
  837.     local h = fs.open('.fingerprint', 'w')
  838.     if h then
  839.         h.write(GenerateFingerprint())
  840.     end
  841.     h.close()
  842.     Current.Fingerprint = str
  843. end
  844.  
  845. local drawTimer = nil
  846. function SetText(header, status, colour, isReset)
  847.     if header then
  848.         Current.HeaderText = header
  849.     end
  850.     if status then
  851.         Current.StatusText = status
  852.     end
  853.     if colour and colourMode then
  854.         Current.StatusColour = colour
  855.     elseif colour then
  856.         if colour == colours.white then
  857.             Current.StatusColour = colours.white
  858.         else
  859.             Current.StatusColour = colours.black
  860.         end
  861.     end
  862.     Draw()
  863.     if not isReset then
  864.         statusResetTimer = os.startTimer(2)
  865.     end
  866. end
  867.  
  868. function ResetStatus()
  869.     if pocket then
  870.         if Current.Locked then
  871.             SetText('Ultimate Door Lock', 'Add Wireless Modem to PDA', colours.red, true)
  872.         else
  873.             SetText('Ultimate Door Lock', 'Ready', colours.grey, true)
  874.         end
  875.     else
  876.         if Current.Locked then
  877.             SetText('Ultimate Door Lock', ' Attach a Wireless Modem then reboot', colours.red, true)
  878.         else
  879.             SetText('Ultimate Door Lock', 'Ready', colours.grey, true)
  880.         end
  881.     end
  882. end
  883.  
  884. function ResetPage()
  885.     Wireless.Responder = function()end
  886.     pingTimer = nil
  887.     Current.PageControls = nil
  888.     Current.StatusScreen = false
  889.     Current.ButtonOne = nil
  890.     Current.ButtonTwo = nil
  891.     Current.PageControls = {}
  892.     CloseDoor()
  893. end
  894.  
  895. function PocketInitialise()
  896.     Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black)
  897.     if not Wireless.Present() then
  898.         Current.Locked = true
  899.         ResetStatus()
  900.         return
  901.     end
  902.     Wireless.Initialise()
  903.     ResetStatus()
  904.     if fs.exists('.fingerprint') then
  905.         local h = fs.open('.fingerprint', 'r')
  906.         if h then
  907.             Current.Fingerprint = h.readAll()
  908.         else
  909.             MakeFingerprint()
  910.         end
  911.         h.close()
  912.     else
  913.         MakeFingerprint()
  914.     end
  915.  
  916.     Wireless.Responder = function(event, side, channel, replyChannel, message, distance)
  917.         if channel == Wireless.Channels.UltimateDoorlockPing then
  918.             Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequest, Current.Fingerprint, Wireless.Channels.UltimateDoorlockRequestReply, nil, message.senderID)
  919.         elseif channel == Wireless.Channels.UltimateDoorlockRequestReply then
  920.             if message.content == true then
  921.                 SetText(nil, 'Opening Door', colours.green)
  922.             else
  923.                 SetText(nil, ' Access Denied', colours.red)
  924.             end
  925.         end
  926.     end
  927. end
  928.  
  929. function FingerprintIsOnWhitelist(fingerprint)
  930.     if Current.Settings.Whitelist then
  931.         for i, f in ipairs(Current.Settings.Whitelist) do
  932.             if f == fingerprint then
  933.                 return true
  934.             end
  935.         end
  936.     end
  937.     return false
  938. end
  939.  
  940. function SaveSettings()
  941.     Current.Settings = Current.Settings or {}
  942.     local h = fs.open('.settings', 'w')
  943.     if h then
  944.         h.write(textutils.serialize(Current.Settings))
  945.     end
  946.     h.close()  
  947. end
  948.  
  949. local closeDoorTimer = nil
  950. function OpenDoor()
  951.     if Current.Settings and Current.Settings.RedstoneSide then
  952.         SetText(nil, 'Opening Door', colours.green)
  953.         redstone.setOutput(Current.Settings.RedstoneSide, true)
  954.         closeDoorTimer = os.startTimer(0.6)
  955.     end
  956. end
  957.  
  958. function CloseDoor()
  959.     if Current.Settings and Current.Settings.RedstoneSide then
  960.         if redstone.getOutput(Current.Settings.RedstoneSide) then
  961.             SetText(nil, 'Closing Door', colours.orange)
  962.             redstone.setOutput(Current.Settings.RedstoneSide, false)
  963.         end
  964.     end
  965. end
  966.  
  967. DefaultSettings = {
  968.     Whitelist = {},
  969.     RedstoneSide = 'back',
  970.     Distance = 10
  971. }
  972.  
  973. function RegisterPDA(event, drive)
  974.     if disk.hasData(drive) then
  975.         local _fs = fs
  976.         if OneOS then
  977.             _fs = OneOS.FS
  978.         end
  979.         local path = disk.getMountPath(drive)
  980.         local addStartup = true
  981.         if _fs.exists(path..'/System/') then
  982.             path = path..'/System/'
  983.             addStartup = false
  984.         end
  985.         local fingerprint = nil
  986.         if _fs.exists(path..'/.fingerprint') then
  987.             local h = _fs.open(path..'/.fingerprint', 'r')
  988.             if h then
  989.                 local str = h.readAll()
  990.                 if #str == 256 then
  991.                     fingerprint = str
  992.                 end
  993.             end
  994.             h.close()
  995.         end
  996.         if not fingerprint then
  997.             fingerprint = GenerateFingerprint()
  998.             local h = _fs.open(path..'/.fingerprint', 'w')
  999.             h.write(fingerprint)
  1000.             h.close()
  1001.             if addStartup then
  1002.                 local h = _fs.open(shell.getRunningProgram(), 'r')
  1003.                 local startup = h.readAll()
  1004.                 h.close()
  1005.                 local h = _fs.open(path..'/startup', 'w')
  1006.                 h.write(startup)
  1007.                 h.close()
  1008.             end
  1009.         end
  1010.         if not FingerprintIsOnWhitelist(fingerprint) then
  1011.             table.insert(Current.Settings.Whitelist, fingerprint)
  1012.             SaveSettings()
  1013.         end
  1014.         disk.eject(drive)
  1015.         SetText(nil, 'Registered Pocket Computer', colours.green)
  1016.     end
  1017. end
  1018.  
  1019. function HostSetup()
  1020.     ResetPage()
  1021.     Current.Page = 'HostSetup'
  1022.     Current.ButtonTwo = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, HostStatusPage, 'Save', colours.black)
  1023.     if not Current.Settings then
  1024.         Current.Settings = DefaultSettings
  1025.     end
  1026.  
  1027.     local sideButtons = {}
  1028.     local function resetSideToggle(self)
  1029.         for i, v in ipairs(sideButtons) do
  1030.             if v.Toggle ~= nil then
  1031.                 v.Toggle = false
  1032.             end
  1033.         end
  1034.         Current.Settings.RedstoneSide = self.Text:gsub('%[',''):gsub('%]',''):lower()
  1035.         SaveSettings()
  1036.     end
  1037.  
  1038.     table.insert(Current.PageControls, Label:Initialise(2, 2, 'Redstone Side'))
  1039.     if colourMode then
  1040.         sideButtons = {
  1041.             Button:Initialise(2, 4, nil, nil, nil, nil, resetSideToggle, 'Back', colours.black, false, colours.green),
  1042.             Button:Initialise(9, 4, nil, nil, nil, nil, resetSideToggle, 'Front', colours.black, false, colours.green),
  1043.             Button:Initialise(2, 6, nil, nil, nil, nil, resetSideToggle, 'Left', colours.black, false, colours.green),
  1044.             Button:Initialise(9, 6, nil, nil, nil, nil, resetSideToggle, 'Right', colours.black, false, colours.green),
  1045.             Button:Initialise(2, 8, nil, nil, nil, nil, resetSideToggle, 'Top', colours.black, false, colours.green),
  1046.             Button:Initialise(8, 8, nil, nil, nil, nil, resetSideToggle, 'Bottom', colours.black, false, colours.green)
  1047.         }
  1048.     else
  1049.         sideButtons = {
  1050.             Button:Initialise(2, 4, nil, nil, nil, nil, resetSideToggle, '[B]ack', colours.black, false, colours.green),
  1051.             Button:Initialise(9, 4, nil, nil, nil, nil, resetSideToggle, '[F]ront', colours.black, false, colours.green),
  1052.             Button:Initialise(2, 6, nil, nil, nil, nil, resetSideToggle, '[L]eft', colours.black, false, colours.green),
  1053.             Button:Initialise(9, 6, nil, nil, nil, nil, resetSideToggle, '[R]ight', colours.black, false, colours.green),
  1054.             Button:Initialise(2, 8, nil, nil, nil, nil, resetSideToggle, '[T]op', colours.black, false, colours.green),
  1055.             Button:Initialise(9, 8, nil, nil, nil, nil, resetSideToggle, 'b[O]ttom', colours.black, false, colours.green)
  1056.         }
  1057.     end
  1058.     for i, v in ipairs(sideButtons) do
  1059.         if v.Text:gsub('%[',''):gsub('%]',''):lower() == Current.Settings.RedstoneSide then
  1060.             v.Toggle = true
  1061.         end
  1062.         table.insert(Current.PageControls, v)
  1063.     end
  1064.  
  1065.     local distanceButtons = {}
  1066.     local function resetDistanceToggle(self)
  1067.         for i, v in ipairs(distanceButtons) do
  1068.             if v.Toggle ~= nil then
  1069.                 v.Toggle = false
  1070.             end
  1071.         end
  1072.         if self.Text:gsub('%[',''):gsub('%]',''):lower() == 'small' then
  1073.             Current.Settings.Distance = 5
  1074.         elseif self.Text:gsub('%[',''):gsub('%]',''):lower() == 'normal' then
  1075.             Current.Settings.Distance = 10
  1076.         elseif self.Text:gsub('%[',''):gsub('%]',''):lower() == 'far' then
  1077.             Current.Settings.Distance = 15
  1078.         end
  1079.         SaveSettings()
  1080.     end
  1081.  
  1082.     table.insert(Current.PageControls, Label:Initialise(23, 2, 'Opening Distance'))
  1083.     if colourMode then
  1084.         distanceButtons = {
  1085.             Button:Initialise(23, 4, nil, nil, nil, nil, resetDistanceToggle, 'Small', colours.black, false, colours.green),
  1086.             Button:Initialise(31, 4, nil, nil, nil, nil, resetDistanceToggle, 'Normal', colours.black, false, colours.green),
  1087.             Button:Initialise(40, 4, nil, nil, nil, nil, resetDistanceToggle, 'Far', colours.black, false, colours.green)
  1088.         }
  1089.     else
  1090.         distanceButtons = {
  1091.             Button:Initialise(22, 4, nil, nil, nil, nil, resetDistanceToggle, '[S]mall', colours.black, false, colours.green),
  1092.             Button:Initialise(30, 4, nil, nil, nil, nil, resetDistanceToggle, '[N]ormal', colours.black, false, colours.green),
  1093.             Button:Initialise(41, 4, nil, nil, nil, nil, resetDistanceToggle, 'f[A]r', colours.black, false, colours.green)
  1094.         }
  1095.     end
  1096.     for i, v in ipairs(distanceButtons) do
  1097.         if v.Text:gsub('%[',''):gsub('%]',''):lower() == 'small' and Current.Settings.Distance == 5 then
  1098.             v.Toggle = true
  1099.         elseif v.Text:gsub('%[',''):gsub('%]',''):lower() == 'formal' and Current.Settings.Distance == 10 then
  1100.             v.Toggle = true
  1101.         elseif v.Text:gsub('%[',''):gsub('%]',''):lower() == 'far' and Current.Settings.Distance == 15 then
  1102.             v.Toggle = true
  1103.         end
  1104.         table.insert(Current.PageControls, v)
  1105.     end
  1106.  
  1107.     table.insert(Current.PageControls, Label:Initialise(2, 10, 'Registered PDAs: '..#Current.Settings.Whitelist))
  1108.     if colourMode then
  1109.         table.insert(Current.PageControls, Button:Initialise(2, 12, nil, nil, nil, nil, function()Current.Settings.Whitelist = {}HostSetup()end, 'Unregister All', colours.black))
  1110.     else
  1111.         table.insert(Current.PageControls, Button:Initialise(2, 12, nil, nil, nil, nil, function()Current.Settings.Whitelist = {}HostSetup()end, '[U]nregister All', colours.black))
  1112.     end
  1113.  
  1114.    
  1115.     table.insert(Current.PageControls, Label:Initialise(23, 6, 'Help', colours.black))
  1116.     local helpLines = {
  1117.         Label:Initialise(23, 8, 'To register a new PDA simply', colours.black),
  1118.         Label:Initialise(23, 9, 'place a Disk Drive next to', colours.black),
  1119.         Label:Initialise(23, 10, 'the computer, then put the', colours.black),
  1120.         Label:Initialise(23, 11, 'PDA in the Drive, it will', colours.black),
  1121.         Label:Initialise(23, 12, 'register automatically. If', colours.black),
  1122.         Label:Initialise(23, 13, 'it worked it will eject.', colours.black),
  1123.         Label:Initialise(23, 15, 'Make sure you hide this', colours.red),
  1124.         Label:Initialise(23, 16, 'computer away from the', colours.red),
  1125.         Label:Initialise(23, 17, 'door! (other people)', colours.red)
  1126.     }
  1127.     for i, v in ipairs(helpLines) do
  1128.         table.insert(Current.PageControls, v)
  1129.     end
  1130.  
  1131.     if colourMode then
  1132.         table.insert(Current.PageControls, Button:Initialise(2, 14, nil, nil, nil, nil, function()
  1133.             for i = 1, 6 do
  1134.                 helpLines[i].TextColour = colours.green
  1135.             end
  1136.         end, 'Register New PDA', colours.black))
  1137.     end
  1138.  
  1139. end
  1140.  
  1141. function HostStatusPage()
  1142.     ResetPage()
  1143.     Current.Page = 'HostStatus'
  1144.     Current.StatusScreen = true
  1145.     Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black)
  1146.     Current.ButtonTwo = Button:Initialise(2, Drawing.Screen.Height - 1, nil, nil, nil, nil, HostSetup, 'Settings/Help', colours.black)
  1147.  
  1148.     Wireless.Responder = function(event, side, channel, replyChannel, message, distance)
  1149.         if channel == Wireless.Channels.UltimateDoorlockRequest and distance < Current.Settings.Distance then
  1150.             if FingerprintIsOnWhitelist(message.content) then
  1151.                 OpenDoor()
  1152.                 Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequestReply, true)
  1153.             else
  1154.                 Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequestReply, false)
  1155.             end
  1156.         end
  1157.     end
  1158.  
  1159.     PingPocketComputers()
  1160. end
  1161.  
  1162. function HostInitialise()
  1163.     if not Wireless.Present() then
  1164.         Current.Locked = true
  1165.         Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black)
  1166.         Current.ButtonTwo = Button:Initialise(2, Drawing.Screen.Height - 1, nil, nil, nil, nil, function()os.reboot()end, 'Reboot', colours.black)
  1167.         ResetStatus()
  1168.         return
  1169.     end
  1170.     Wireless.Initialise()
  1171.     ResetStatus()
  1172.     if fs.exists('.settings') then
  1173.         local h = fs.open('.settings', 'r')
  1174.         if h then
  1175.             Current.Settings = textutils.unserialize(h.readAll())
  1176.         end
  1177.         h.close()
  1178.         HostStatusPage()       
  1179.     else
  1180.         HostSetup()
  1181.     end
  1182.     if OneOS then
  1183.         OneOS.CanClose = function()
  1184.             CloseDoor()
  1185.             return true
  1186.         end
  1187.     end
  1188. end
  1189.  
  1190. local pingTimer = nil
  1191. function PingPocketComputers()
  1192.     Wireless.SendMessage(Wireless.Channels.UltimateDoorlockPing, 'Ping!', Wireless.Channels.UltimateDoorlockRequest)
  1193.     pingTimer = os.startTimer(0.5)
  1194. end
  1195.  
  1196. function Initialise(arg)
  1197.     EventRegister('mouse_click', TryClick)
  1198.     EventRegister('mouse_drag', function(event, side, x, y)TryClick(event, side, x, y, true)end)
  1199.     EventRegister('mouse_scroll', Scroll)
  1200.     EventRegister('key', HandleKey)
  1201.     EventRegister('char', HandleKey)
  1202.     EventRegister('timer', Timer)
  1203.     EventRegister('terminate', function(event) if Close() then error( "Terminated", 0 ) end end)
  1204.     EventRegister('modem_message', Wireless.HandleMessage)
  1205.     EventRegister('disk', RegisterPDA)
  1206.  
  1207.     if OneOS then
  1208.         OneOS.RequestRunAtStartup()
  1209.     end
  1210.  
  1211.     if pocket then
  1212.         PocketInitialise()
  1213.     else
  1214.         HostInitialise()
  1215.     end
  1216.  
  1217.  
  1218.     Draw()
  1219.  
  1220.     EventHandler()
  1221. end
  1222.  
  1223. function Timer(event, timer)
  1224.     if timer == pingTimer then
  1225.         PingPocketComputers()
  1226.     elseif timer == closeDoorTimer then
  1227.         CloseDoor()
  1228.     elseif timer == statusResetTimer then
  1229.         ResetStatus()
  1230.     end
  1231. end
  1232.  
  1233. local ignoreNextChar = false
  1234. function HandleKey(...)
  1235.     local args = {...}
  1236.     local event = args[1]
  1237.     local keychar = args[2]
  1238.  
  1239.     if keychar == keys.delete or keychar == keys.backspace then
  1240.         if Current.ButtonOne then
  1241.             Current.ButtonOne:Click()
  1242.         end
  1243.     elseif keychar == keys.enter then
  1244.         if Current.ButtonTwo then
  1245.             Current.ButtonTwo:Click()
  1246.         end
  1247.     elseif Current.Page == 'HostSetup' then
  1248.         local function findNamed(name)
  1249.             for i, v in ipairs(Current.PageControls) do
  1250.                 if v.Text == name then
  1251.                     return v
  1252.                 end
  1253.             end
  1254.         end
  1255.         if keychar == 'b' or keychar == 'B' then
  1256.             findNamed('[B]ack'):Click()
  1257.         elseif keychar == 'f' or keychar == 'F' then
  1258.             findNamed('[F]ront'):Click()
  1259.         elseif keychar == 'l' or keychar == 'L' then
  1260.             findNamed('[L]eft'):Click()
  1261.         elseif keychar == 'r' or keychar == 'R' then
  1262.             findNamed('[R]ight'):Click()
  1263.         elseif keychar == 't' or keychar == 'T' then
  1264.             findNamed('[T]op'):Click()
  1265.         elseif keychar == 'o' or keychar == 'O' then
  1266.             findNamed('b[O]ttom'):Click()
  1267.         elseif keychar == 's' or keychar == 'S' then
  1268.             findNamed('[S]mall'):Click()
  1269.         elseif keychar == 'n' or keychar == 'N' then
  1270.             findNamed('[N]ormal'):Click()
  1271.         elseif keychar == 'a' or keychar == 'A' then
  1272.             findNamed('F[A]r'):Click()
  1273.         elseif keychar == 'u' or keychar == 'U' then
  1274.             findNamed('[U]nregister All'):Click()
  1275.         end
  1276.     end
  1277.     Draw()
  1278. end
  1279.  
  1280. --[[
  1281.     Check if the given object falls under the click coordinates
  1282. ]]--
  1283. function CheckClick(object, x, y)
  1284.     if object.X <= x and object.Y <= y and object.X + object.Width > x and object.Y + object.Height > y then
  1285.         return true
  1286.     end
  1287. end
  1288.  
  1289. --[[
  1290.     Attempt to clicka given object
  1291. ]]--
  1292. function DoClick(object, side, x, y, drag)
  1293.     local obj = GetAbsolutePosition(object)
  1294.     obj.Width = object.Width
  1295.     obj.Height = object.Height
  1296.     if object and CheckClick(obj, x, y) then
  1297.         return object:Click(side, x - object.X + 1, y - object.Y + 1, drag)
  1298.     end
  1299. end
  1300.  
  1301. --[[
  1302.     Try to click at the given coordinates
  1303. ]]--
  1304. function TryClick(event, side, x, y, drag)
  1305.     if Current.ButtonOne then
  1306.         if DoClick(Current.ButtonOne, side, x, y, drag) then
  1307.             Draw()
  1308.             return
  1309.         end
  1310.     end
  1311.  
  1312.     if Current.ButtonTwo then
  1313.         if DoClick(Current.ButtonTwo, side, x, y, drag) then
  1314.             Draw()
  1315.             return
  1316.         end
  1317.     end
  1318.  
  1319.     for i, v in ipairs(Current.PageControls) do
  1320.         if DoClick(v, side, x, y, drag) then
  1321.             Draw()
  1322.             return
  1323.         end
  1324.     end
  1325.  
  1326.     Draw()
  1327. end
  1328.  
  1329. function Scroll(event, direction, x, y)
  1330.     if Current.Window and Current.Window.OpenButton then
  1331.         Current.Document.Scroll = Current.Document.Scroll + direction
  1332.         if Current.Window.Scroll < 0 then
  1333.             Current.Window.Scroll = 0
  1334.         elseif Current.Window.Scroll > Current.Window.MaxScroll then
  1335.             Current.Window.Scroll = Current.Window.MaxScroll
  1336.         end
  1337.         Draw()
  1338.     elseif Current.ScrollBar then
  1339.         if Current.ScrollBar:DoScroll(direction*2) then
  1340.             Draw()
  1341.         end
  1342.     end
  1343. end
  1344.  
  1345. --[[
  1346.     Registers functions to run on certain events
  1347. ]]--
  1348. function EventRegister(event, func)
  1349.     if not Events[event] then
  1350.         Events[event] = {}
  1351.     end
  1352.  
  1353.     table.insert(Events[event], func)
  1354. end
  1355.  
  1356. --[[
  1357.     The main loop event handler, runs registered event functinos
  1358. ]]--
  1359. function EventHandler()
  1360.     while isRunning do
  1361.         local event, arg1, arg2, arg3, arg4, arg5, arg6 = os.pullEventRaw()
  1362.         if Events[event] then
  1363.             for i, e in ipairs(Events[event]) do
  1364.                 e(event, arg1, arg2, arg3, arg4, arg5, arg6)
  1365.             end
  1366.         end
  1367.     end
  1368. end
  1369.  
  1370. function Quit()
  1371.     isRunning = false
  1372.     term.setCursorPos(1,1)
  1373.     term.setBackgroundColour(colours.black)
  1374.     term.setTextColour(colours.white)
  1375.     term.clear()
  1376.     if OneOS then
  1377.         OneOS.Close()
  1378.     end
  1379. end
  1380.  
  1381. if not term.current then -- if not 1.6
  1382.     print('Because it requires pocket computers, Ultimate Door Lock requires ComputerCraft 1.6. Please update to 1.6 to use Ultimate Door Lock.')
  1383. elseif not (OneOS and pocket) then
  1384.     -- If the program crashes close the door and reboot
  1385.     local _, err = pcall(Initialise)
  1386.     if err then
  1387.         CloseDoor()
  1388.         term.setCursorPos(1,1)
  1389.         term.setBackgroundColour(colours.black)
  1390.         term.setTextColour(colours.white)
  1391.         term.clear()
  1392.         print('Ultimate Door Lock has crashed')
  1393.         print('To maintain security, the computer will reboot.')
  1394.         print('If you are seeing this alot try turning off all Pocket Computers or reinstall.')
  1395.         print()
  1396.         print('Error:')
  1397.         printError(err)
  1398.         sleep(5)
  1399.         os.reboot()
  1400.     end
  1401. elseif OneOS and pocket then
  1402.     term.setCursorPos(1,3)
  1403.     term.setBackgroundColour(colours.white)
  1404.     term.setTextColour(colours.blue)
  1405.     term.clear()
  1406.     print('OneOS already acts as a door key. Simply place your PDA in the door\'s disk drive to register it.')
  1407.     print()
  1408.     print('Click anywhere to quit')
  1409.     os.pullEvent('mouse_click')
  1410.     Quit()
  1411. else
  1412.     print('Ultimate Door Lock requires an advanced (gold) computer or pocket computer.')
  1413. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement