Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[ InnKeeper ]]--
- --[[ by Dog ]]--
- --[[ aka ]]--
- --[[ HydrantHunter ]]--
- --[[ pastebin ]]--
- --[[ Lj7Zw0nz ]]--
- local ikVer = "1.1.00"
- --[[
- Tested with/requires:
- - Minecraft 1.6.4 | 1.7.10
- - ComputerCraft 1.58+ | 1.73+
- - Gopher's Peripherals 2.13 | 2.2
- - An advanced computer
- - One or more biolocks
- ]]--
- --# "biolock", IDprint, attachName, learnedName, accessLevel
- local screen = "lock"
- local roomEntry, confirmTimer, printer, innKeeperKernel
- local kernelState, confirmState, scannerError, newInstall = true, false, false, false
- local bioScanners, scannerList, roomData, configData, scannerErrors = { }, { }, { }, { }, { }
- local pageNum, numPages, scanPage, scanPages, staffPage, staffPages, numDays = 1, 1, 1, 1, 1, 1, 0
- local roomColors = { available = colors.green, checkout = colors.brown, occupied = colors.lightBlue, unavailable = colors.orange, reserved = colors.purple, service = colors.red }
- local termX, termY = term.getSize()
- -- custom read function courtesy of theoriginalbit (modified by Dog)
- local function read(_mask, _history, _limit, _noTerminate, _noMouse)
- if _mask and type(_mask) ~= "string" then
- error("Invalid parameter #1: Expected string, got " .. type(_mask), 2)
- end
- if _history and type(_history) ~= "table" then
- error("Invalid parameter #2: Expected table, got " .. type(_history), 2)
- end
- if _limit and type(_limit) ~= "number" then
- error("Invalid parameter #3: Expected number, got " .. type(_limit), 2)
- end
- if _noTerminate and type(_noTerminate) ~= "boolean" then
- error("Invalid argument #4: Expected boolean, got " .. nativeType(_noTerminate), 2)
- end
- if _noMouse and type(_noMouse) ~= "boolean" then
- error("Invalid argument #5: Expected boolean, got " .. nativeType(_noMouse), 2)
- end
- term.setCursorBlink(true)
- local mouseLimit = _limit or 0
- local input = ""
- local pos = 0
- local historyPos = nil
- local pullEvent = _noTerminate and os.pullEventRaw or os.pullEvent
- local sw, sh = term.getSize()
- local sx, sy = term.getCursorPos()
- local function redraw(_special)
- local scroll = (sx + pos >= sw and (sx + pos) - sw or 0)
- local replace = _special or _mask
- local output = replace and (string.rep(replace, math.ceil(#input / #replace) - scroll)):sub(1, #input) or input:sub(scroll + 1)
- term.setCursorPos(sx, sy)
- term.write(output)
- term.setCursorPos(sx + pos - scroll, sy)
- end
- local nativeScroll = term.scroll
- 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
- while true do
- local event, code, mX, mY = pullEvent()
- if event == "char" and (not _limit or #input < _limit) then
- input = input:sub(1, pos) .. code .. input:sub(pos + 1)
- pos = pos + 1
- if not _limit then mouseLimit = math.min(mouseLimit + 1, sw - (sw - sx)) end
- elseif event == "paste" and (not _limit or #input < _limit) then
- if _limit and #input + #code > _limit then
- code = code:sub(1, _limit - #input)
- end
- input = input:sub(1, pos) .. code .. input:sub(pos + 1)
- pos = pos + #code
- if not _limit then mouseLimit = math.min(mouseLimit + #code, sw - (sw - sx)) end
- elseif event == "key" then
- if code == keys.enter or code == keys.numPadEnter then
- break
- elseif code == keys.backspace and pos > 0 then
- redraw(' ')
- input = input:sub(1, math.max(pos - 1, 0)) .. input:sub(pos + 1)
- pos = math.max(pos - 1, 0)
- if not _limit then mouseLimit = math.max(mouseLimit - 1, 0) end
- elseif code == keys.delete and pos < #input then
- redraw(' ')
- input = input:sub(1, pos) .. input:sub(pos + 2)
- if not _limit then mouseLimit = math.max(mouseLimit - 1, 0) end
- elseif code == keys.home then
- pos = 0
- elseif code == keys["end"] then
- pos = #input
- elseif code == keys.left and pos > 0 then
- pos = math.max(pos - 1, 0)
- elseif code == keys.right and pos < #input then
- pos = math.min(pos + 1, #input)
- elseif _history and code == keys.up or code == keys.down then
- redraw(' ')
- if code == keys.up then
- if not historyPos then
- historyPos = #_history
- elseif historyPos > 1 then
- historyPos = historyPos - 1
- end
- else
- if historyPos ~= nil and historyPos < #_history then
- historyPos = math.max(historyPos + 1, #_history)
- elseif historyPos == #_history then
- historyPos = nil
- end
- end
- if historyPos and #_history > 0 then
- input = string.sub(_history[historyPos], 1, _limit) or ""
- pos = #input
- if not _limit then mouseLimit = pos end
- else
- input = ""
- pos = 0
- if not _limit then mouseLimit = 0 end
- end
- end
- elseif event == "mouse_click" and not _noMouse and ((mX < sx or mX >= sx + mouseLimit) or (mY ~= sy)) then
- break
- end
- redraw(_mask)
- end
- term.scroll = nativeScroll
- term.setCursorBlink(false)
- if sy + 1 > sh then
- term.scroll(sy + 1 - sh)
- term.setCursorPos(1, sy)
- else
- term.setCursorPos(1, sy + 1)
- end
- return input
- end
- local function clearScreen()
- term.setBackgroundColor(colors.black)
- term.clear()
- end
- local function clearLowerScreen(bgColor)
- term.setBackgroundColor(bgColor or colors.black)
- local line = string.rep(" ", termX)
- for i = 4, termY do --# clear the display area
- term.setCursorPos(1, i)
- term.write(line)
- end
- end
- local function clearDataArea()
- term.setBackgroundColor(colors.black)
- local line = string.rep(" ", 34)
- for i = 4, termY do --# clear the data area
- term.setCursorPos(18, i)
- term.write(line)
- end
- end
- local function header(bgColor)
- bgColor = bgColor or colors.blue
- term.setTextColor(bgColor == colors.red and colors.red or colors.white)
- local line = string.rep(" ", termX - 3)
- for i = 1, 3 do --# header
- term.setBackgroundColor(bgColor)
- term.setCursorPos(1, i)
- term.write(line)
- term.setBackgroundColor(colors.red)
- term.write(i == 2 and " X " or " ") --# exit button
- end
- term.setBackgroundColor(bgColor)
- term.setTextColor(bgColor == colors.red and colors.orange or colors.lightBlue)
- local title = configData.facilityName or "InnKeeper"
- term.setCursorPos(math.ceil(termX / 2) - math.floor(#title / 2), 2)
- term.write(title) --# title
- end
- local function pageNumber()
- term.setBackgroundColor(colors.gray)
- term.setCursorPos(18, termY)
- term.write(string.rep(" ", 34))
- term.setTextColor(colors.lightGray)
- term.setCursorPos(24, termY)
- term.write("<< < > >>")
- local pageNumElement = tostring(pageNum) .. " of " .. tostring(numPages)
- term.setCursorPos(35 - math.floor(#pageNumElement / 2), termY)
- term.write(pageNumElement)
- end
- local function scannerCount()
- term.setBackgroundColor(colors.lightGray)
- local line = string.rep(" ", 16)
- for i = 17, 19 do --# box/body
- term.setCursorPos(1, i)
- term.write(line)
- end
- term.setTextColor(colors.gray)
- term.setCursorPos(2, 18)
- term.write("Scanners:")
- term.setTextColor(colors.black)
- term.setCursorPos(12, 18)
- term.write(tostring(#bioScanners))
- end
- local function numberOfGuestsInResidency()
- local gCount = 0
- for i = 1, #roomData do
- if (roomData[i].state == "occupied" or roomData[i].state == "service") and #roomData[i].guests > 0 then
- gCount = gCount + #roomData[i].guests
- end
- end
- return gCount
- end
- local function innStats()
- term.setBackgroundColor(colors.lightGray)
- local line = string.rep(" ", 16)
- for i = 4, 8 do --# box/body
- term.setCursorPos(1, i)
- term.write(line)
- end
- term.setCursorPos(2, 5)
- term.setTextColor(colors.gray)
- term.write("Rooms: ")
- term.setTextColor(colors.black)
- term.write(tostring(#roomData))
- term.setTextColor(colors.gray)
- term.setCursorPos(2, 7)
- term.write("Guests: ")
- term.setTextColor(colors.black)
- term.write(tostring(numberOfGuestsInResidency()))
- end
- local function roomInfoButtons()
- term.setBackgroundColor(colors.cyan)
- term.setTextColor(colors.white)
- local word = " Scanners "
- for i = 1, 10 do
- term.setCursorPos(termX - 2, i + 5)
- term.write(" " .. word:sub(i, i) .. " ")
- end
- if roomData[roomEntry].state == "checkout" then
- term.setCursorPos(34, termY - 2)
- term.setBackgroundColor(colors.green)
- term.write(" Invoice ")
- end
- if #roomData > 1 and (roomData[roomEntry].state == "available" or roomData[roomEntry].state == "unavailable") then
- term.setCursorPos(34, termY)
- term.setBackgroundColor(confirmState and colors.orange or colors.red)
- term.write(confirmState and " CONFIRM " or " Delete Room ")
- end
- end
- local function roomInfoLabels()
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.black)
- term.setCursorPos(2, 5)
- term.write("Room # Status")
- term.setCursorPos(2, 7)
- term.write("Guests")
- term.setCursorPos(22, 7)
- term.write("Notes/Messages")
- term.setCursorPos(2, termY - 2)
- term.write("Check-IN Day")
- term.setCursorPos(2, termY - 1)
- term.write("Check-OUT Day")
- if roomData[roomEntry].state ~= "checkout" then
- term.setCursorPos(34, termY - 2)
- term.write("Cr/Day: ")
- term.setBackgroundColor(colors.lightGray)
- term.write(" ") --# room rate
- end
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.white)
- term.setCursorPos(16, 5)
- term.write("#")
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.gray)
- term.setCursorPos(17, 5)
- term.write(string.rep(" ", 3 - #tostring(roomEntry)) .. tostring(roomEntry))
- term.setBackgroundColor(colors.green)
- term.setTextColor((#roomData[roomEntry].guests < 5 and roomData[roomEntry].state ~= "unavailable" and roomData[roomEntry].state ~= "service" and roomData[roomEntry].state ~= "checkout") and colors.white or colors.gray)
- term.setCursorPos(10, 7)
- term.write("+") --# add guest
- term.setTextColor(#roomData[roomEntry].notes < 5 and colors.white or colors.gray)
- term.setCursorPos(38, 7)
- term.write("+") --# add note
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(10, 5)
- term.write(" ") --# room number
- term.setCursorPos(29, 5)
- term.write(string.rep(" ", 13)) --# room state
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.lightGray)
- term.write("v")
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(10, 7)
- local lineA = string.rep(" ", 18)
- local lineB = string.rep(" ", 25)
- for i = 9, 15 do
- term.setCursorPos(2, i) --# guest list
- term.write(lineA)
- term.setCursorPos(22, i) --# note/message list
- term.write(lineB)
- end
- end
- local function roomInfoData()
- local colorWheel = { available = colors.lime, checkout = colors.brown, occupied = colors.lightBlue, unavailable = colors.orange, reserved = colors.purple, service = colors.red }
- term.setTextColor(colors.white)
- term.setCursorPos(14 - #tostring(roomData[roomEntry].roomNumber), 5)
- term.write(tostring(roomData[roomEntry].roomNumber)) --# room#
- term.setCursorPos(30, 5)
- term.setTextColor(colorWheel[roomData[roomEntry].state])
- term.setBackgroundColor(colors.lightGray)
- term.write(roomData[roomEntry].state) --# room state
- local uNames = { }
- if roomData[roomEntry].scanners[1] then
- local bio = peripheral.wrap(roomData[roomEntry].scanners[1])
- bio.unlock(configData.masterPass)
- uNames = { bio.getLearnedNames() }
- bio.lock(configData.masterPass)
- end
- local found
- for i = 1, #roomData[roomEntry].guests do --# guest list
- found = false
- for j = 1, #uNames do
- if uNames[j] == roomData[roomEntry].guests[i].name then found = true break end
- end
- term.setTextColor(found and colors.white or colors.red)
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(3, 9 + i)
- term.write(roomData[roomEntry].guests[i].name:sub(1, 15))
- term.setTextColor(roomData[roomEntry].state == "checkout" and colors.gray or colors.white)
- term.setCursorPos(19, 9 + i)
- term.setBackgroundColor(colors.red)
- term.write("x") --# 'remove guest' button
- end
- for i = 1, #roomData[roomEntry].notes do --# notes list
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(23, 9 + i)
- term.write(roomData[roomEntry].notes[i]:sub(1, 22))
- term.setTextColor(roomData[roomEntry].state == "checkout" and colors.gray or colors.white)
- term.setCursorPos(46, 9 + i)
- term.setBackgroundColor(colors.red)
- term.write("x") --# 'remove note' button
- end
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(12, termY - 2)
- term.write(tostring(roomData[roomEntry].checkIn.ciTime))
- term.setCursorPos(26, termY - 2)
- term.write(tostring(roomData[roomEntry].checkIn.ciDay))
- term.setCursorPos(12, termY - 1)
- term.write(tostring(roomData[roomEntry].checkOut.coTime))
- term.setCursorPos(26, termY - 1)
- term.write(tostring(roomData[roomEntry].checkOut.coDay))
- term.setBackgroundColor(colors.lightGray)
- if roomData[roomEntry].state ~= "checkout" then
- term.setTextColor((roomData[roomEntry].state ~= "occupied" and roomData[roomEntry].state ~="reserved" and roomData[roomEntry].state ~= "service") and colors.white or colors.gray)
- local rate = tostring(roomData[roomEntry].dailyRate)
- term.setCursorPos(46 - #rate, termY - 2)
- term.write(rate)
- end
- term.setTextColor(colors.gray)
- term.setCursorPos(12, 7)
- term.write(" " .. tostring(#roomData[roomEntry].guests) .. " ")
- term.setCursorPos(40, 7)
- term.write(" " .. tostring(#roomData[roomEntry].notes) .. " ")
- end
- local function roomInfo()
- screen = "room"
- clearLowerScreen(colors.white)
- roomInfoLabels()
- roomInfoData()
- roomInfoButtons()
- end
- local function roomList()
- screen = "main"
- local sX, sY = 20, 5
- term.setTextColor(colors.white)
- if #roomData > 0 then
- local roomNumStr, roomNumLen
- local magicNumber = (((pageNum - 1) * 27) + pageNum)
- for i = magicNumber, math.min(magicNumber + 27, #roomData) do
- term.setBackgroundColor(roomColors[roomData[i].state])
- roomNumStr = tostring(roomData[i].roomNumber)
- roomNumLen = #roomNumStr / 2
- term.setCursorPos(sX, sY)
- term.write(string.rep(" ", 3 - math.floor(roomNumLen)) .. roomNumStr .. string.rep(" ", 3 - math.ceil(roomNumLen)))
- sY = sY + 2
- if sY >= termY - 1 then sY = 5 sX = sX + 8 end
- end
- else
- term.setCursorPos(sX, sY)
- term.write("No rooms to manage")
- end
- pageNumber()
- end
- local function leftPane()
- term.setBackgroundColor(colors.gray)
- local line = string.rep(" ", 17)
- for i = 4, termY do --# sidebar body
- term.setCursorPos(1, i)
- term.write(line)
- end
- innStats() --# number of rooms and guests
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(2, 10)
- term.write("Search:")
- term.setBackgroundColor(colors.white)
- term.setCursorPos(1, 11)
- term.write(string.rep(" ", 16)) --# search entry area
- term.setCursorPos(1, 13)
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.cyan)
- term.write(" Add a room ") --# add room button
- term.setBackgroundColor(colors.blue)
- term.setCursorPos(1, 15)
- term.write(" Settings ") --# settings button
- scannerCount() --# number of scanners
- end
- local function lockScreen()
- screen = "lock"
- clearLowerScreen(colors.white)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(12, 8)
- term.write("Please log in . . .")
- term.setTextColor(colors.gray)
- term.setCursorPos(12, 11)
- term.write("Password: ")
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.write(string.rep(" ", 17)) --# password entry area
- end
- local function guestSearchHelp()
- term.setBackgroundColor(colors.white)
- term.setCursorPos(1, 11)
- term.write(string.rep(" ", 16))
- for i = 1, 7 do
- term.setCursorPos(19, 5 + i)
- term.write(string.rep(" ", 30))
- end
- term.setTextColor(colors.black)
- term.setCursorPos(22, 7)
- term.write("* = all guests")
- term.setCursorPos(22, 8)
- term.write("*o = all in occupancy")
- term.setCursorPos(22, 9)
- term.write("*r = all in reservation")
- term.setCursorPos(24, 11)
- term.setTextColor(colors.lightGray)
- term.write("Click mouse to close")
- term.setBackgroundColor(colors.blue)
- term.setCursorPos(19, 5)
- term.write(" Search Help ")
- os.pullEvent("mouse_click")
- end
- local function guestSearchNoResults()
- term.setBackgroundColor(colors.white)
- term.setCursorPos(1, 11)
- term.write(string.rep(" ", 16))
- for i = 1, 5 do
- term.setCursorPos(19, 4 + i)
- term.write(string.rep(" ", 30))
- end
- term.setCursorPos(26, 6)
- term.setTextColor(colors.black)
- term.write("No Search Results")
- term.setCursorPos(25, 8)
- term.setTextColor(colors.lightGray)
- term.write("Click mouse to close")
- os.pullEvent("mouse_click")
- end
- local function guestSearchResultsList(searchResults, searchPage, searchPages)
- term.setBackgroundColor(colors.blue)
- term.setTextColor(colors.lightBlue)
- term.setCursorPos(19, 5)
- term.write(" Name Room ")
- term.setBackgroundColor(colors.white)
- local line = string.rep(" ", 30)
- for i = 6, 14 do
- term.setCursorPos(19, i)
- term.write(line)
- end
- term.setBackgroundColor(colors.gray)
- for i = 15, 17 do
- term.setCursorPos(19, i)
- term.write(line)
- end
- local yPos = 7
- local magicNumber = (((searchPage - 1) * 6) + searchPage)
- for i = magicNumber, math.min(magicNumber + 6, #searchResults) do
- term.setBackgroundColor(colors.white)
- term.setTextColor(roomColors[roomData[searchResults[i].entry].state])
- term.setCursorPos(20, yPos)
- term.write(searchResults[i].name:sub(1, 15)) --# name
- term.setTextColor(colors.lightGray)
- term.write(" " .. string.rep(".", 21 - #searchResults[i].name:sub(1, 15))) --# separator
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.gray)
- term.setCursorPos(43, yPos)
- term.write(string.rep(" ", 4 - #tostring(searchResults[i].room)) .. tostring(searchResults[i].room) .. " ") --# room number
- yPos = yPos + 1
- end
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(23, 15)
- term.write("<< < > >>")
- local pages = tostring(searchPage) .. " of " .. tostring(searchPages)
- term.setCursorPos(34 - math.floor(#pages / 2), 15)
- term.write(pages)
- term.setBackgroundColor(colors.white)
- term.setCursorPos(2, 11)
- term.write(string.rep(" ", 15))
- term.setCursorPos(2, 11)
- term.setTextColor(colors.gray)
- term.write(tostring(#searchResults))
- term.write(#searchResults == 1 and " Result" or " Results")
- term.setCursorPos(29, 17)
- term.setBackgroundColor(colors.red)
- term.setTextColor(colors.white)
- term.write(" C L O S E ")
- end
- local function guestSearchResults(searchResults)
- screen = "search"
- local searchPage, searchPages = 1, math.ceil(#searchResults / 7)
- guestSearchResultsList(searchResults, searchPage, searchPages) --# send search results to list creator
- while true do
- local event, data, x, y = os.pullEvent()
- if event == "mouse_click" and data == 1 then
- if (x > 28 and x < 40 and y == termY - 2) or (x > termX - 3 and y < 4) then --# close
- clearDataArea()
- term.setBackgroundColor(colors.white)
- term.setCursorPos(2, 11)
- term.write(string.rep(" ", 15))
- roomList()
- break
- elseif y == 15 then
- if (x > 22 and x < 25) or (x > 42 and x < 45) then --# Home / End
- searchPage = (x > 22 and x < 25) and 1 or searchPages
- guestSearchResultsList(searchResults, searchPage, searchPages) --# redraw list on new page
- elseif (x > 25 and x < 27) or (x > 40 and x < 42) then --# Page back / Page forward
- searchPage = (x > 25 and x < 27) and math.max(1, searchPage - 1) or math.min(searchPage + 1, searchPages)
- guestSearchResultsList(searchResults, searchPage, searchPages) --# redraw list on new page
- end
- else
- local yPos, found = 7, false
- local magicNumber = (((searchPage - 1) * 6) + searchPage)
- for i = magicNumber, math.min(magicNumber + 6, #searchResults) do
- if x > 19 and x < termX - 3 and y == yPos then --# open the room sheet for the guest
- screen = "room"
- roomEntry = searchResults[i].entry
- found = true
- roomInfo()
- break
- else
- yPos = yPos + 1
- end
- end
- if found then break end
- end
- elseif event == "mouse_scroll" then
- searchPage = data == 1 and math.min(searchPage + 1, searchPages) or math.max(1, searchPage - 1)
- guestSearchResultsList(searchResults, searchPage, searchPages) --# redraw list on new page
- elseif event == "key" then
- if data == keys.home or data == keys["end"] then --# Home / End
- searchPage = data == keys.home and 1 or searchPages
- guestSearchResultsList(searchResults, searchPage, searchPages) --# redraw list on new page
- elseif data == keys.pageUp or data == keys.pageDown then --# Page forward / back
- searchPage = data == keys.pageUp and math.min(searchPage + 1, searchPages) or math.max(1, searchPage - 1)
- guestSearchResultsList(searchResults, searchPage, searchPages) --# redraw list on new page
- end
- end
- end
- end
- local function guestSearch(word)
- local searchResults, found = { }, false
- if word ~= "?" and word:lower() ~= "help" then
- for i = 1, #roomData do
- for j = 1, #roomData[i].guests do
- if string.lower(roomData[i].guests[j].name):find(string.lower(word)) or word == "*" then
- found = true
- elseif string.lower(word) == "*o" and roomData[i].state ~= "reserved" then
- found = true
- elseif string.lower(word) == "*r" and roomData[i].state == "reserved" then
- found = true
- end
- if found then
- searchResults[#searchResults + 1] = { }
- searchResults[#searchResults].name = roomData[i].guests[j].name
- searchResults[#searchResults].room = roomData[i].roomNumber
- searchResults[#searchResults].entry = i
- found = false
- end
- end
- end
- end
- if searchResults[1] then
- clearDataArea()
- guestSearchResults(searchResults) --# if there are results, send them to the results handler
- elseif word == "?" or string.lower(word) == "help" then
- guestSearchHelp()
- clearDataArea()
- roomList()
- else --# otherwise draw a pop-up with no results
- guestSearchNoResults()
- clearDataArea()
- roomList()
- end
- end
- local function saveData(which)
- local dataFile, dataContents
- if not fs.exists("/data") then fs.makeDir("/data") end
- if which == "room" then
- dataFile = "/data/innRooms"
- dataContents = roomData
- elseif which == "config" then
- dataFile = "/data/innSettings"
- dataContents = configData
- else
- error("saveData: no data target specified", 0)
- end
- local thisFile = fs.open(dataFile, "w")
- thisFile.write(textutils.serialize(dataContents))
- thisFile.close()
- end
- local function listScannerErrors(page, pages)
- local magicNumber = ((page - 1) * 2) + page
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.gray)
- local line = string.rep(" ", 30)
- for i = 6, 17 do --# body
- term.setCursorPos(12, i)
- term.write(line)
- end
- local yPos = 8
- for i = magicNumber, math.min(magicNumber + 2, #scannerErrors) do --# errors
- term.setTextColor(colors.lightGray)
- term.setCursorPos(14, yPos)
- term.write(tostring(i) .. ": ")
- term.setTextColor(colors.lightBlue)
- term.write(tostring(scannerErrors[i].room))
- term.setTextColor(colors.orange)
- term.setCursorPos(40 - #scannerErrors[i].name, yPos)
- term.write(scannerErrors[i].name)
- term.setTextColor(colors.red)
- term.setCursorPos(27 - math.ceil(#scannerErrors[i].message / 2), yPos + 1)
- term.write(scannerErrors[i].message)
- yPos = yPos + 3
- end
- term.setTextColor(colors.lightGray)
- term.setCursorPos(24, 17)
- term.write(tostring(page) .. " of " .. tostring(pages))
- end
- local function scannerErrorScreen()
- local sePage, sePages = 1, math.ceil(#scannerErrors / 3)
- clearLowerScreen()
- term.setBackgroundColor(colors.red)
- term.setCursorPos(12, 5)
- term.write(string.rep(" ", 30)) --# header
- term.setTextColor(colors.white)
- term.setCursorPos(18, 5)
- term.write("Scanner Error Log") --# title
- listScannerErrors(sePage, sePages)
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(12, 18)
- term.write(string.rep(" ", 30))
- term.setBackgroundColor(colors.orange)
- term.setCursorPos(22, 18)
- term.write(" Continue ")
- while true do
- local event, data, x, y = os.pullEvent()
- if event == "mouse_click" and data == 1 and x > 21 and x < 32 and y == 18 then
- for i = #scannerErrors, 1, -1 do
- table.remove(scannerErrors, i)
- end
- return
- elseif event == "mouse_scroll" then
- sePage = data == 1 and math.min(sePage + 1, sePages) or math.max(1, sePage - 1)
- listScannerErrors(sePage, sePages)
- end
- end
- end
- local function logScannerError(scannerID, data, errorMsg)
- scannerErrors[#scannerErrors + 1] = { }
- scannerErrors[#scannerErrors].name = scannerID or "n/a"
- scannerErrors[#scannerErrors].room = data or "0"
- scannerErrors[#scannerErrors].message = errorMsg or "Unspecified"
- end
- local function removeMissingScanners()
- local badScanners = { }
- badScanners[#badScanners + 1] = configData.masterScanner --# create a list of ALL recorded scanners
- for i = 1, #roomData do --#
- for j = 1, #roomData[i].scanners do --#
- badScanners[#badScanners + 1] = roomData[i].scanners[j] --#
- end
- end
- for i = 1, #bioScanners do --# ALL discovered scanners (bioScanners) ...
- for j = #badScanners, 1, -1 do --# ... vs. recorded scanners (badScanners)
- if bioScanners[i] == badScanners[j] then --# if a discovered scanner matches a recorded scanner...
- table.remove(badScanners, j) --# ...then remove it from the badScanners table
- break
- end
- end
- end --# we now have a table of scanners (badScanners) that are recorded, but aren't connected
- for i = #badScanners, 1, -1 do
- if badScanners[i] == configData.masterScanner then --# this is really bad
- configData.masterScanner = nil --# user will have to re-select the master scanner
- table.remove(badScanners, i)
- else
- local badFind = false
- for j = 1, #roomData do
- for k = #roomData[j].scanners, 1, -1 do
- if badScanners[i] == roomData[j].scanners[k] then
- logScannerError(roomData[j].scanners[k], "Room " .. tostring(roomData[j].roomNumber), "Scanner Missing")
- table.remove(roomData[j].scanners, k)
- table.remove(badScanners, i)
- saveData("room")
- badFind = true
- break
- end
- end
- if badFind then break end
- end
- end
- end
- if badScanners[1] then error("removeMissingScanners: " .. tostring(#badScanners) .. " badScanners remaining", 0) end --# this is seriously bad, this shouldn't happen
- end
- local function addEntityToScanner(scannerID, uName, uPrint)
- local scanner = peripheral.wrap(scannerID)
- if scanner then
- if scanner.unlock(configData.masterPass) then
- scanner.learn(uName, uPrint, 1)
- scanner.lock(configData.masterPass)
- end
- end
- end
- local function addGuestToScanners(uName, uPrint)
- for i = 1, #roomData[roomEntry].scanners do
- addEntityToScanner(roomData[roomEntry].scanners[i], uName, uPrint)
- end
- end
- local function addStaffMemberToScanners(uName, uPrint)
- for i = 1, #bioScanners do
- addEntityToScanner(bioScanners[i], uName, uPrint)
- end
- end
- local function removeEntityFromScanner(scannerID, uName)
- local scanner = peripheral.wrap(scannerID)
- if scanner then
- if scanner.unlock(configData.masterPass) then
- scanner.forget(uName)
- scanner.lock(configData.masterPass)
- end
- end
- end
- local function removeGuestFromScanners(uName)
- for i = 1, #roomData[roomEntry].scanners do --# staff are checked before removal is called
- removeEntityFromScanner(roomData[roomEntry].scanners[i], uName)
- end
- end
- local function removeStaffMemberFromScanners(uName, uPrint)
- for i = 1, #bioScanners do
- removeEntityFromScanner(bioScanners[i], uName)
- end
- for j = 1, #roomData do --# this adds the staff member back as a guest, if the staff member is registered also as a guest
- for k = 1, #roomData[j].guests do
- if roomData[j].guests[k].idPrint == uPrint then
- for l = 1, #roomData[j].scanners do
- addEntityToScanner(roomData[j].scanners[l], uName, uPrint)
- end
- break
- end
- end
- end
- end
- local function deleteNotes()
- for i = #roomData[roomEntry].notes, 1, -1 do
- table.remove(roomData[roomEntry].notes, i)
- end
- end
- local function removeGuest(guestNum, _tableRemove)
- local found = false
- for i = 1, #configData.staff do
- if roomData[roomEntry].guests[guestNum].idPrint == configData.staff[i].idPrint then
- found = true
- break
- end
- end
- if not found then
- removeGuestFromScanners(roomData[roomEntry].guests[guestNum].name)
- end
- if roomData[roomEntry].state == "checkout" then
- return
- end
- if #roomData[roomEntry].guests == 1 then
- if roomData[roomEntry].state == "reserved" then
- roomData[roomEntry].state = "available"
- deleteNotes()
- elseif roomData[roomEntry].state == "occupied" then
- roomData[roomEntry].state = "checkout"
- roomData[roomEntry].checkOut.coTime = textutils.formatTime(os.time(), false)
- roomData[roomEntry].checkOut.coDay = os.day()
- numDays = roomData[roomEntry].checkOut.coDay - roomData[roomEntry].checkIn.ciDay
- return
- end
- end
- if _tableRemove then table.remove(roomData[roomEntry].guests, guestNum) end
- saveData("room")
- end
- local function changeGuestField(name)
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(19, name and 7 or 9)
- term.write(string.rep(" ", 20))
- term.setCursorPos(19, name and 7 or 9)
- end
- local function changeGuestName(guestNum)
- changeGuestField(true)
- local newName = read(nil, nil, 20)
- if newName ~= "" then
- if roomData[roomEntry].state == "occupied" or roomData[roomEntry].state == "service" then
- local scanner
- for i = 1, #roomData[roomEntry].scanners do
- scanner = peripheral.wrap(roomData[roomEntry].scanners[i])
- if scanner then
- if scanner.unlock(configData.masterPass) then
- scanner.forget(roomData[roomEntry].guests[guestNum].name)
- scanner.learn(newName, roomData[roomEntry].guests[guestNum].idPrint, 1)
- scanner.lock(configData.masterPass)
- end
- end
- end
- end
- return newName
- else
- return roomData[roomEntry].guests[guestNum].name
- end
- end
- local function changeGuestPrint(guestNum)
- changeGuestField()
- local newPrint = read(nil, nil, 20)
- if newPrint ~= "" then
- if roomData[roomEntry].state == "occupied" or roomData[roomEntry].state == "service" then
- local scanner
- for i = 1, #roomData[roomEntry].scanners do
- scanner = peripheral.wrap(roomData[roomEntry].scanners[i])
- if scanner then
- if scanner.unlock(configData.masterPass) then
- scanner.forget(roomData[roomEntry].guests[guestNum].name)
- scanner.learn(roomData[roomEntry].guests[guestNum].name, newPrint, 1)
- scanner.lock(configData.masterPass)
- end
- end
- end
- end
- return newPrint
- else
- return roomData[roomEntry].guests[guestNum].idPrint
- end
- end
- local function accountInfoForm(uName, idPrint, scanned, staffMember)
- term.setTextColor(colors.lightBlue)
- term.setBackgroundColor(colors.blue)
- term.setCursorPos(9, 5)
- term.write(string.rep(" ", 33))
- local txPos = staffMember and 18 or 17
- term.setCursorPos(txPos, 5)
- term.write(staffMember and "Staff Information" or "Guest Information") --# Dialogue title
- term.setBackgroundColor(colors.gray)
- local line = string.rep(" ", 33)
- for i = 6, 14 do --# Dialogue body
- term.setCursorPos(9, i)
- term.write(line)
- end
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(18, 7)
- term.write(string.rep(" ", 22)) --# 'Name' input box
- term.setCursorPos(18, 9)
- term.write(string.rep(" ", 22)) --# 'Print' input box
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(11, 7)
- term.write("Name: ")
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.lightGray)
- term.write(" " .. uName:sub(1, 20)) --# Name
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(11, 9)
- term.write("Print: ")
- term.setTextColor(scanned and colors.gray or colors.white)
- term.setBackgroundColor(colors.lightGray)
- term.write(" " .. idPrint:sub(1, 20)) --# Print
- term.setBackgroundColor(colors.gray)
- term.setTextColor(scanned and colors.lime or colors.orange)
- local xPos = staffMember and 16 or 19
- term.setCursorPos(xPos, 11)
- term.write(idPrint:find("idPrint") and "Scan in " or "Scanned ")
- if staffMember then --# Staff title and buttons
- term.write("Staff Member")
- term.setBackgroundColor(colors.green)
- term.setTextColor(colors.white)
- term.setCursorPos(16, 13)
- term.write(" CONFIRM ")
- term.setBackgroundColor(colors.red)
- term.setCursorPos(28, 13)
- term.write(" DELETE ")
- else
- term.write("Guest") --# Guest title and button
- term.setCursorPos(20, 13)
- term.setBackgroundColor(colors.red)
- term.setTextColor(colors.white)
- term.write(" C L O S E ")
- end
- end
- local function viewGuestInfo(guestNum)
- if guestNum == 0 then
- roomData[roomEntry].guests[#roomData[roomEntry].guests + 1] = { }
- guestNum = #roomData[roomEntry].guests
- roomData[roomEntry].guests[guestNum].name = "Guest-" .. tostring(roomData[roomEntry].roomNumber) .. "-" .. tostring(math.random(1000, 9999))
- roomData[roomEntry].guests[guestNum].idPrint = "idPrint-" .. tostring(roomData[roomEntry].roomNumber) .. "-" .. tostring(math.random(1000, 9999))
- roomData[roomEntry].guests[guestNum].scanned = false
- saveData("room")
- end
- accountInfoForm(roomData[roomEntry].guests[guestNum].name, roomData[roomEntry].guests[guestNum].idPrint, roomData[roomEntry].guests[guestNum].scanned)
- while true do
- local event, data, x, y = os.pullEvent()
- if event == "biolock" and x == configData.masterScanner then
- roomData[roomEntry].guests[guestNum].name = y or roomData[roomEntry].guests[guestNum].name
- roomData[roomEntry].guests[guestNum].name = (roomData[roomEntry].guests[guestNum].name ~= "") and roomData[roomEntry].guests[guestNum].name or data
- roomData[roomEntry].guests[guestNum].idPrint = data
- roomData[roomEntry].guests[guestNum].scanned = true
- saveData("room")
- if roomData[roomEntry].state == "occupied" or roomData[roomEntry].state == "service" then
- addGuestToScanners(roomData[roomEntry].guests[guestNum].name, roomData[roomEntry].guests[guestNum].idPrint)
- end
- accountInfoForm(roomData[roomEntry].guests[guestNum].name, roomData[roomEntry].guests[guestNum].idPrint, roomData[roomEntry].guests[guestNum].scanned)
- elseif event == "mouse_click" and data == 1 then
- if x > 19 and x < 31 and y == 13 then
- if roomData[roomEntry].state == "occupied" or roomData[roomEntry].state == "service" then
- addGuestToScanners(roomData[roomEntry].guests[guestNum].name, roomData[roomEntry].guests[guestNum].idPrint)
- end
- roomInfo()
- break
- elseif x > 17 and x < 40 and y == 7 then
- roomData[roomEntry].guests[guestNum].name = changeGuestName(guestNum) --# change guest name
- saveData("room")
- if roomData[roomEntry].state == "occupied" or roomData[roomEntry].state == "service" then
- addGuestToScanners(roomData[roomEntry].guests[guestNum].name, roomData[roomEntry].guests[guestNum].idPrint)
- end
- accountInfoForm(roomData[roomEntry].guests[guestNum].name, roomData[roomEntry].guests[guestNum].idPrint, roomData[roomEntry].guests[guestNum].scanned)
- elseif x > 17 and x < 40 and y == 9 and not roomData[roomEntry].guests[guestNum].scanned then
- roomData[roomEntry].guests[guestNum].idPrint = changeGuestPrint(guestNum) --# change guest print
- saveData("room")
- if roomData[roomEntry].state == "occupied" or roomData[roomEntry].state == "service" then
- addGuestToScanners(roomData[roomEntry].guests[guestNum].name, roomData[roomEntry].guests[guestNum].idPrint)
- end
- accountInfoForm(roomData[roomEntry].guests[guestNum].name, roomData[roomEntry].guests[guestNum].idPrint, roomData[roomEntry].guests[guestNum].scanned)
- end
- end
- end
- end
- local function staffInfo()
- staffPages = math.max(1, math.ceil(#configData.staff / 4))
- staffPage = math.min(staffPage, staffPages)
- term.setBackgroundColor(colors.lightGray)
- local line = string.rep(" ", 34)
- for i = 13, 17 do
- term.setCursorPos(2, i)
- term.write(line)
- end
- local bio = peripheral.wrap(configData.masterScanner)
- bio.unlock(configData.masterPass)
- local uNames = { bio.getLearnedNames() }
- bio.lock(configData.masterPass)
- local sX, sY, found = 3, 14, false
- local magicNumber = (((staffPage - 1) * 3) + staffPage)
- for i = magicNumber, math.min(magicNumber + 3, #configData.staff) do
- term.setCursorPos(sX, sY)
- found = false
- for j = 1, #uNames do
- if uNames[j] == configData.staff[i].name then found = true break end
- end
- term.setTextColor(found and colors.white or colors.red)
- term.write(configData.staff[i].name:sub(1, 15))
- sY = sY + 2
- if sY > termY - 2 then sX = sX + 17 sY = 14 end
- end
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(9, termY - 1)
- term.write("<< < > >>")
- local pageInfo = tostring(staffPage) .. " of " .. tostring(staffPages)
- term.setCursorPos(19 - math.floor(#pageInfo / 2), termY - 1)
- term.write(pageInfo)
- end
- local function settingsData()
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(19, 5)
- term.write(string.rep(" ", 17))
- term.setCursorPos(20, 5)
- term.write(configData.masterScanner) --# masterScanner
- term.setCursorPos(19, 7)
- term.write(" ")
- term.write(string.rep("*", 15)) --# masterPass
- term.write(" ")
- term.setCursorPos(19, 9)
- term.write(" ")
- term.write(string.rep("*", 15)) --# screenPass
- term.write(" ")
- term.setCursorPos(19, 11)
- term.write(string.rep(" ", 5))
- term.setTextColor(colors.gray)
- local staffNumCount = tostring(#configData.staff)
- term.setCursorPos(23 - #staffNumCount, 11)
- term.write(staffNumCount) --# number of staff
- term.setBackgroundColor(colors.green)
- term.setTextColor(colors.white)
- term.setCursorPos(25, 11)
- term.write("+") --# add staff button
- end
- local function settingsScreen()
- clearLowerScreen(colors.white)
- screen = "settings"
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.black)
- term.setCursorPos(2, 5)
- term.write("Master Scanner")
- term.setCursorPos(2, 7)
- term.write("Master Password")
- term.setCursorPos(2, 9)
- term.write("Screen Password")
- term.setCursorPos(2, 11)
- term.write("Staff")
- term.setTextColor(colors.gray)
- term.setCursorPos(37, 5)
- term.write("Front Desk")
- term.setCursorPos(37, 7)
- term.write("All scanners")
- term.setCursorPos(37, 9)
- term.write("Main Screen")
- term.setCursorPos(37, 13)
- term.write("All staff are")
- term.setCursorPos(37, 14)
- term.write("automatically")
- term.setCursorPos(37, 15)
- term.write("added to all")
- term.setCursorPos(37, 16)
- term.write("biometric")
- term.setCursorPos(37, 17)
- term.write("scanners")
- settingsData()
- staffInfo()
- end
- local function oldPasswordChangePopup(master)
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.white)
- local line = string.rep(" ", 19)
- local startI = master and 4 or 6
- local endI = master and 11 or 13
- for i = startI, endI do
- term.setCursorPos(18, i)
- term.write(line)
- end
- term.setCursorPos(19, master and 5 or 7)
- term.write("Current Password")
- term.setCursorPos(21, master and 9 or 11)
- term.write("Enter nothing")
- term.setCursorPos(23, master and 10 or 12)
- term.write("to cancel")
- term.setBackgroundColor(colors.lightGray)
- end
- local function newPasswordChangePopup(master)
- term.setBackgroundColor(colors.gray)
- term.setCursorPos(19, master and 5 or 7)
- term.write(" New Password ")
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(19, master and 7 or 9)
- term.write(string.rep(" ", 17))
- term.setCursorPos(20, master and 7 or 9)
- end
- local function getOldPassword(master)
- term.setCursorPos(19, master and 7 or 9)
- term.write(string.rep(" ", 17))
- term.setCursorPos(20, master and 7 or 9)
- return read("*", nil, 15)
- end
- local function changeScreenPassword()
- oldPasswordChangePopup()
- local oldPass
- while true do
- oldPass = getOldPassword()
- if oldPass == configData.screenPass then
- break
- elseif oldPass == "" then
- settingsScreen()
- return
- end
- end
- newPasswordChangePopup()
- local newPass = read("*", nil, 15)
- if newPass and newPass ~= "" then
- configData.screenPass = newPass
- saveData("config")
- end
- settingsScreen()
- end
- local function changeMasterPassword()
- oldPasswordChangePopup(true)
- local oldPass
- while true do
- oldPass = getOldPassword(true)
- if oldPass == configData.masterPass then
- break
- elseif oldPass == "" then
- settingsScreen()
- return
- end
- end
- newPasswordChangePopup(true)
- local newPass = read("*", nil, 15)
- if newPass and newPass ~= "" then
- configData.masterPass = newPass
- local scanner
- for i = 1, #bioScanners do
- scanner = peripheral.wrap(bioScanners[i])
- if scanner then
- if scanner.unlock(oldPass) then
- scanner.lock(newPass)
- end
- end
- end
- saveData("config")
- end
- settingsScreen()
- end
- local function changeStaffField(name)
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(19, name and 7 or 9)
- term.write(string.rep(" ", 20))
- term.setCursorPos(19, name and 7 or 9)
- end
- local function changeStaffName(staffNum)
- changeStaffField(true)
- local newName = read(nil, nil, 20)
- if newName and newName ~= "" then
- removeStaffMemberFromScanners(configData.staff[staffNum].name, configData.staff[staffNum].idPrint)
- addStaffMemberToScanners(newName, configData.staff[staffNum].idPrint)
- return newName
- else
- return configData.staff[staffNum].name
- end
- end
- local function changeStaffPrint(staffNum)
- changeStaffField()
- local newPrint = read(nil, nil, 20)
- if newPrint ~= "" then
- removeStaffMemberFromScanners(configData.staff[staffNum].name, configData.staff[staffNum].idPrint)
- addStaffMemberToScanners(configData.staff[staffNum].name, newPrint)
- return newPrint
- else
- return configData.staff[staffNum].idPrint
- end
- end
- local function viewStaffInfo(staffNum)
- if staffNum == 0 then
- configData.staff[#configData.staff + 1] = { }
- staffNum = #configData.staff
- configData.staff[staffNum].name = "Staff-" .. tostring(#configData.staff) .. "-" .. tostring(math.random(1000, 9999))
- configData.staff[staffNum].idPrint = "idPrint-" .. tostring(#configData.staff) .. "-" .. tostring(math.random(1000, 9999))
- configData.staff[staffNum].scanned = false
- saveData("config")
- end
- accountInfoForm(configData.staff[staffNum].name, configData.staff[staffNum].idPrint, configData.staff[staffNum].scanned, true)
- while true do
- local event, data, x, y = os.pullEvent()
- if event == "biolock" and x == configData.masterScanner then
- configData.staff[staffNum].name = y or configData.staff[staffNum].name
- configData.staff[staffNum].name = (configData.staff[staffNum].name ~= "") and configData.staff[staffNum].name or data
- configData.staff[staffNum].idPrint = data
- configData.staff[staffNum].scanned = true
- saveData("config")
- addStaffMemberToScanners(configData.staff[staffNum].name, configData.staff[staffNum].idPrint)
- accountInfoForm(configData.staff[staffNum].name, configData.staff[staffNum].idPrint, configData.staff[staffNum].scanned, true)
- elseif event == "mouse_click" and data == 1 then
- if x > 15 and x < 25 and y == 13 then --# close dialogue
- addStaffMemberToScanners(configData.staff[staffNum].name, configData.staff[staffNum].idPrint)
- settingsScreen()
- break
- elseif x > 27 and x < 36 and y == 13 then --# delete staff member
- removeStaffMemberFromScanners(configData.staff[staffNum].name, configData.staff[staffNum].idPrint)
- table.remove(configData.staff, staffNum)
- saveData("config")
- settingsScreen()
- break
- elseif x > 17 and x < 40 and y == 7 then --# change name
- configData.staff[staffNum].name = changeStaffName(staffNum)
- saveData("config")
- accountInfoForm(configData.staff[staffNum].name, configData.staff[staffNum].idPrint, configData.staff[staffNum].scanned, true)
- elseif x > 17 and x < 40 and y == 9 and not configData.staff[staffNum].scanned then --# change idPrint
- configData.staff[staffNum].idPrint = changeStaffPrint(staffNum)
- saveData("config")
- accountInfoForm(configData.staff[staffNum].name, configData.staff[staffNum].idPrint, configData.staff[staffNum].scanned, true)
- end
- end
- end
- end
- local function deleteNote(noteNum)
- table.remove(roomData[roomEntry].notes, noteNum)
- saveData("room")
- roomInfoLabels()
- roomInfoData()
- roomInfoButtons()
- end
- local function editNote(noteNum)
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- while true do
- term.setCursorPos(5, 7)
- term.write(string.rep(" ", 41))
- term.setCursorPos(6, 7)
- local thisNote = read(nil, nil, 41)
- if thisNote == "" then
- term.setCursorPos(6, 7)
- term.write(roomData[roomEntry].notes[noteNum])
- return roomData[roomEntry].notes[noteNum]
- else
- return thisNote
- end
- end
- end
- local function viewNoteForm(noteNum)
- term.setBackgroundColor(colors.blue)
- term.setTextColor(colors.lightBlue)
- term.setCursorPos(4, 5)
- term.write(string.rep(" ", 45))
- term.setCursorPos(5, 5)
- term.write("Note")
- local noteNumStr = tostring(noteNum)
- term.setCursorPos(48 - #noteNumStr, 5)
- term.write(noteNumStr)
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.white)
- local line = string.rep(" ", 45)
- for i = 6, 11 do
- term.setCursorPos(4, i)
- term.write(line)
- end
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(5, 7)
- term.write(string.rep(" ", 43))
- term.setCursorPos(6, 7)
- term.write(roomData[roomEntry].notes[noteNum])
- end
- local function viewNote(noteNum)
- if noteNum == 0 then --# new note
- roomData[roomEntry].notes[#roomData[roomEntry].notes + 1] = "New Note"
- noteNum = #roomData[roomEntry].notes
- end
- viewNoteForm(noteNum)
- term.setCursorPos(21, 10)
- term.setBackgroundColor(colors.red)
- term.setTextColor(colors.white)
- term.write(" C L O S E ")
- while true do
- local _, button, x, y = os.pullEvent("mouse_click")
- if x > 4 and x < 49 and y == 7 and button == 1 then
- local newNote = editNote(noteNum)
- roomData[roomEntry].notes[noteNum] = newNote
- elseif x > 20 and x < 32 and y == 10 and button == 1 then
- break
- end
- end
- saveData("room")
- roomInfo()
- end
- local function helpScreen()
- clearLowerScreen(colors.white)
- term.setTextColor(colors.gray)
- term.setCursorPos(15, 7)
- term.write("Open/Close Help Screen")
- term.setCursorPos(15, 9)
- term.write("'X' at top right to lock the screen")
- term.setCursorPos(15, 14)
- term.write("Room number directly to change room #")
- term.setCursorPos(15, 16)
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.white)
- term.write("#")
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.gray)
- term.write(" to the right of Room# to re-order")
- term.setBackgroundColor(colors.gray)
- local line = string.rep(" ", 13)
- for i = 4, termY do
- term.setCursorPos(1, i)
- term.write(line)
- end
- term.setTextColor(colors.black)
- term.setCursorPos(2, 5)
- term.write("Main Screen")
- term.setCursorPos(2, 12)
- term.write("Room Screen")
- term.setTextColor(colors.lightGray)
- term.setCursorPos(2, 7)
- term.write("F1")
- term.setCursorPos(2, 9)
- term.write("Right click")
- term.setCursorPos(2, 14)
- term.write("Left click")
- term.setCursorPos(2, 16)
- term.write("Left click")
- while true do
- local event, data, x, y = os.pullEvent()
- if (event == "key" and data == keys.f1) or (event == "mouse_click" and data == 1 and x > termX - 3 and y < 4) then
- clearDataArea()
- leftPane()
- roomList()
- break
- end
- end
- end
- local function assignDeassignScanner(scannerID, learn)
- local sides = { "top", "bottom", "left", "right", "back" }
- local scanner = peripheral.wrap(scannerID)
- if not scanner then return end
- if scanner.unlock(configData.masterPass) then
- for _, side in pairs(sides) do
- scanner.forgetProgram(side)
- end
- local uNames = { scanner.getLearnedNames() }
- for i = 1, #uNames do
- scanner.forget(uNames[i])
- end
- if learn then
- for _, side in pairs(sides) do
- scanner.program(side, 1, 60, configData.redstone)
- end
- for i = 1, #configData.staff do
- scanner.learn(configData.staff[i].name, configData.staff[i].idPrint, 1)
- end
- if roomData[roomEntry].state == "occupied" or roomData[roomEntry].state == "service" then
- for i = 1, #roomData[roomEntry].guests do
- scanner.learn(roomData[roomEntry].guests[i].name, roomData[roomEntry].guests[i].idPrint, 1)
- end
- end
- end
- scanner.lock(configData.masterPass)
- end
- end
- local function assignDeassignMasterScanner(learn)
- local scanner = peripheral.wrap(configData.masterScanner)
- if not scanner then configData.masterScanner = nil return end --# this is bad and shouldn't happen
- if scanner.unlock(configData.masterPass) then
- for _, side in pairs(rs.getSides()) do
- scanner.forgetProgram(side)
- end
- local uNames = { scanner.getLearnedNames() }
- for i = 1, #uNames do
- scanner.forget(uNames[i])
- end
- if learn then
- for i = 1, #configData.staff do
- scanner.learn(configData.staff[i].name, configData.staff[i].idPrint, 1)
- end
- else
- configData.masterScanner = nil
- end
- scanner.lock(configData.masterPass)
- end
- end
- local function findUnusedScanners()
- local unusedScanners = { }
- for i = 1, #bioScanners do
- if bioScanners[i] ~= configData.masterScanner then
- unusedScanners[#unusedScanners + 1] = bioScanners[i]
- end
- end
- for i = 1, #roomData do
- for j = 1, #roomData[i].scanners do
- for k = #unusedScanners, 1, -1 do
- if roomData[i].scanners[j] == unusedScanners[k] then
- table.remove(unusedScanners, k)
- break
- end
- end
- end
- end
- return unusedScanners
- end
- local function unassignedScanners()
- for i = #scannerList, 1, -1 do
- table.remove(scannerList, i)
- end
- scannerList = findUnusedScanners()
- scanPages = math.max(1, math.ceil(#scannerList / 8))
- scanPage = math.min(scanPage, scanPages)
- local sX, sY = 2, 5
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(sX, sY)
- term.write("Scanners Available: (" .. tostring(#scannerList) .. ") ")
- term.setCursorPos(4, 17)
- term.write("<< < > >>")
- local sPages = tostring(scanPage) .. " of " .. tostring(scanPages)
- term.setCursorPos(15 - math.floor(#sPages / 2), 17)
- term.write(sPages)
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- local line = string.rep(" ", 27)
- for i = 1, 9 do --# draw the 'box'
- term.setCursorPos(sX, sY + 1 + i)
- term.write(line)
- end
- sX, sY = 3, 8
- local magicNumber = (((scanPage - 1) * 7) + scanPage)
- for i = magicNumber, math.min(magicNumber + 7, #scannerList) do
- term.setCursorPos(sX, sY)
- term.write(scannerList[i]:sub(1, 12))
- sY = sY + 2
- if sY > 14 then sX = sX + 13 sY = 8 end
- end
- end
- local function scannersAssignedBox(master)
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(33, 5)
- term.write(master and "Scanner Assigned:" or "Scanners Assigned:")
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- local line = string.rep(" ", 14)
- for i = 1, 9 do
- term.setCursorPos(35, 6 + i)
- term.write(line)
- end
- end
- local function masterAssignedScanners()
- scannersAssignedBox(true)
- term.setCursorPos(36, 8)
- term.write(configData.masterScanner and configData.masterScanner:sub(1, 12) or "")
- end
- local function assignedScanners()
- scannersAssignedBox()
- for i = 1, #roomData[roomEntry].scanners do
- term.setCursorPos(36, 6 + (2 * i))
- term.write(roomData[roomEntry].scanners[i]:sub(1, 12))
- end
- end
- local function scannerListing(which)
- unassignedScanners()
- if which then
- masterAssignedScanners()
- else
- assignedScanners()
- end
- end
- local function selectScanners()
- while true do
- local event, data, x, y = os.pullEvent()
- if event == "mouse_click" and data == 1 then
- if x > termX - 3 and y < 4 then return end
- if x > 35 and x < 48 and y > 7 and y < 15 then
- local scannerNumber = 0
- for i = 8, 14, 2 do
- scannerNumber = scannerNumber + 1
- if y == i and roomData[roomEntry].scanners[scannerNumber] then
- assignDeassignScanner(roomData[roomEntry].scanners[scannerNumber])
- table.remove(roomData[roomEntry].scanners, scannerNumber)
- saveData("room")
- scannerListing()
- break
- end
- end
- elseif y == 17 then
- if (x > 3 and x < 6) or (x > 23 and x < 26) then --# Home / End
- scanPage = (x > 3 and x < 6) and 1 or scanPages
- unassignedScanners()
- elseif (x > 6 and x < 8) or (x > 21 and x < 23) then --# Page back / Page forward
- scanPage = (x > 6 and x < 8) and math.max(1, scanPage - 1) or math.min(scanPage + 1, scanPages)
- unassignedScanners()
- end
- else
- local sX, sY = 2, 8
- local magicNumber = (((scanPage - 1) * 7) + scanPage)
- for i = magicNumber, math.min(magicNumber + 7, #scannerList) do
- if x > sX and x < sX + 13 and y == sY then
- if #roomData[roomEntry].scanners < 4 then
- roomData[roomEntry].scanners[#roomData[roomEntry].scanners + 1] = scannerList[i]
- assignDeassignScanner(scannerList[i], true)
- saveData("room")
- scannerListing()
- end
- break
- else
- sY = sY + 2
- if sY > 14 then sX = sX + 13 sY = 8 end
- end
- end
- end
- elseif event == "mouse_scroll" then
- scanPage = data == 1 and math.min(scanPage + 1, scanPages) or math.max(1, scanPage - 1)
- unassignedScanners()
- elseif event == "key" then
- if data == keys.home or data == keys["end"] then --# Home / End
- scanPage = data == keys.home and 1 or scanPages
- unassignedScanners()
- elseif data == keys.pageUp or data == keys.pageDown then --# Page forward / back
- scanPage = data == keys.pageUp and math.min(scanPage + 1, scanPages) or math.max(1, scanPage - 1)
- unassignedScanners()
- end
- end
- end
- end
- local function selectMasterScanner()
- while true do
- local event, data, x, y = os.pullEvent()
- if event == "mouse_click" and data == 1 then
- if x > termX - 3 and y < 4 then
- if newInstall then
- kernelState = false
- return
- else
- if configData.masterScanner ~= nil then return end
- end
- end
- if newInstall and configData.masterScanner ~= nil then
- if x > 20 and x < 34 and y == termY - 1 then return end
- end
- if x > 35 and x < 48 and y == 8 then
- if configData.masterScanner then
- assignDeassignMasterScanner()
- if not newInstall then saveData("config") end
- scannerListing(true)
- end
- elseif y == 17 then
- if (x > 3 and x < 6) or (x > 23 and x < 26) then --# Home / End
- scanPage = (x > 3 and x < 6) and 1 or scanPages
- unassignedScanners()
- elseif (x > 6 and x < 8) or (x > 21 and x < 23) then --# Page Back / Page forward
- scanPage = (x > 6 and x < 8) and math.max(1, scanPage - 1) or math.min(scanPage + 1, scanPages)
- unassignedScanners()
- end
- else
- local sX, sY = 2, 8
- local magicNumber = (((scanPage - 1) * 7) + scanPage)
- for i = magicNumber, math.min(magicNumber + 7, #scannerList) do
- if x > sX and x < sX + 11 and y == sY then
- if not configData.masterScanner then
- configData.masterScanner = scannerList[i]
- assignDeassignMasterScanner(true)
- if not newInstall then saveData("config") end
- scannerListing(true)
- end
- break
- else
- sY = sY + 2
- if sY > 14 then sX = sX + 13 sY = 8 end
- end
- end
- end
- elseif event == "mouse_scroll" then
- scanPage = data == 1 and math.min(scanPage + 1, scanPages) or math.max(scanPage - 1, 1)
- unassignedScanners()
- elseif event == "key" then
- if data == keys.home or data == keys["end"] then --# Home / End
- scanPage = data == keys.home and 1 or scanPages
- unassignedScanners()
- elseif data == keys.pageUp or data == keys.pageDown then --# Page forward / back
- scanPage = data == keys.pageUp and math.min(scanPage + 1, scanPages) or math.max(1, scanPage - 1)
- unassignedScanners()
- end
- end
- end
- end
- local function resetRoom(_delete)
- roomData[roomEntry].checkIn.ciTime = 0
- roomData[roomEntry].checkIn.ciDay = 0
- roomData[roomEntry].checkOut.coTime = 0
- roomData[roomEntry].checkOut.coDay = 0
- numDays = 0
- for i = #roomData[roomEntry].guests, 1, -1 do
- removeGuest(i, _delete)
- end
- end
- local function clearRoomStatusMenu()
- local yPos = 4
- term.setBackgroundColor(colors.black)
- local line = string.rep(" ", 15)
- for i = 1, 10 do
- yPos = yPos + 1
- term.setCursorPos(28, yPos)
- term.write(line)
- end
- end
- local function selectRoomStatus(_quick)
- local yPos, stateChanged = 4, false
- term.setBackgroundColor(colors.lightGray)
- if _quick then
- local line = string.rep(" ", 15)
- for i = 1, 10 do
- yPos = yPos + 1
- term.setCursorPos(28, yPos)
- term.write(line)
- end
- end
- yPos = 5
- term.setBackgroundColor(colors.gray)
- local line = string.rep(" ", 13)
- for i = 1, 8 do
- yPos = yPos + 1
- term.setCursorPos(29, yPos)
- term.write(line)
- end
- yPos = 6
- for k, v in pairs(roomColors) do
- yPos = yPos + 1
- term.setCursorPos(30, yPos)
- term.setTextColor(v)
- term.write(k)
- end
- yPos = 6
- local _, button, x, y = os.pullEvent("mouse_click")
- for k, v in pairs(roomColors) do
- yPos = yPos + 1
- if x > 29 and x < 41 and y == yPos and button == 1 then
- if roomData[roomEntry].state ~= k then
- stateChanged = true
- end
- roomData[roomEntry].state = k
- break
- end
- end
- if roomData[roomEntry].state == "occupied" and stateChanged then
- if roomData[roomEntry].checkIn.ciTime == 0 then
- roomData[roomEntry].checkIn.ciTime = textutils.formatTime(os.time(), false)
- roomData[roomEntry].checkIn.ciDay = os.day()
- end
- for i = 1, #roomData[roomEntry].guests do
- addGuestToScanners(roomData[roomEntry].guests[i].name, roomData[roomEntry].guests[i].idPrint)
- end
- roomData[roomEntry].checkOut.coTime = 0
- roomData[roomEntry].checkOut.coDay = 0
- numDays = 0
- elseif roomData[roomEntry].state == "checkout" and stateChanged then
- roomData[roomEntry].checkOut.coTime = textutils.formatTime(os.time(), false)
- roomData[roomEntry].checkOut.coDay = os.day()
- numDays = roomData[roomEntry].checkOut.coDay - roomData[roomEntry].checkIn.ciDay
- for i = 1, #roomData[roomEntry].guests do
- removeGuest(i) --# remove guests from scanners
- end
- elseif roomData[roomEntry].state == "reserved" and stateChanged then
- resetRoom()
- elseif roomData[roomEntry].state == "available" and stateChanged then
- resetRoom(true)
- deleteNotes()
- elseif roomData[roomEntry].state == "unavailable" and stateChanged then
- resetRoom(true)
- end
- saveData("room")
- if _quick then clearRoomStatusMenu() roomList() else roomInfo() end
- end
- local function changeRoomNumber()
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(11, 5)
- term.write(" ")
- term.setCursorPos(11, 5)
- local newRoomNum = tonumber(read(nil, nil, 3))
- if newRoomNum and newRoomNum > 0 then
- local found = false
- for i = 1, #roomData do
- if roomData[i].roomNumber == newRoomNum then
- found = true
- end
- end
- if not found then
- roomData[roomEntry].roomNumber = newRoomNum
- saveData("room")
- end
- end
- end
- local function moveRoom()
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(17, 5)
- term.write(" ")
- term.setCursorPos(17, 5)
- local newPos = tonumber(read(nil, nil, 3))
- if newPos and newPos > 0 and newPos <= #roomData and newPos ~= roomEntry then
- local tempRoomData = { }
- for k, v in pairs(roomData[roomEntry]) do
- tempRoomData[k] = v
- end
- table.remove(roomData, roomEntry)
- table.insert(roomData, newPos, tempRoomData)
- roomEntry = newPos
- saveData("room")
- end
- end
- local function deleteRoom()
- for i = #roomData[roomEntry].scanners, 1, -1 do
- assignDeassignScanner(roomData[roomEntry].scanners[i])
- end
- table.remove(roomData, roomEntry)
- saveData("room")
- end
- local function createRoom(roomNum)
- roomData[#roomData + 1] = { }
- roomData[#roomData]["roomNumber"] = roomNum
- roomData[#roomData]["scanners"] = { }
- roomData[#roomData]["notes"] = { "Assign scanners" }
- roomData[#roomData]["guests"] = { }
- roomData[#roomData]["checkIn"] = { ciTime = 0, ciDay = 0 }
- roomData[#roomData]["checkOut"] = { coTime = 0, coDay = 0 }
- roomData[#roomData]["dailyRate"] = 5
- roomData[#roomData]["state"] = "unavailable"
- end
- local function newRoom()
- local highest = 1
- for i = 1, #roomData do
- highest = math.max(highest, roomData[i].roomNumber)
- end
- createRoom(highest + 1)
- roomEntry = #roomData
- saveData("room")
- clearLowerScreen(colors.white)
- roomInfo()
- end
- local function cancelTimer(button)
- confirmState = false
- confirmTimer = nil
- if button and #roomData > 1 and (roomData[roomEntry].state == "available" or roomData[roomEntry].state == "unavailable") then
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.red)
- term.setCursorPos(34, termY)
- term.write(" Delete Room ")
- end
- end
- local function pageInput()
- term.setCursorPos(33, termY - 2)
- local newPage = tonumber(read(nil, nil, 4))
- if newPage then
- newPage = math.max(1, newPage)
- newPage = math.min(newPage, numPages)
- pageNum = newPage
- end
- clearDataArea()
- roomList()
- end
- local function selectPage()
- term.setBackgroundColor(colors.blue)
- term.setTextColor(colors.white)
- term.setCursorPos(31, termY - 4)
- term.write(" :Page: ")
- term.setBackgroundColor(colors.gray)
- local line = string.rep(" ", 8)
- for i = termY - 3, termY - 1 do
- term.setCursorPos(31, i)
- term.write(line)
- end
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(32, termY - 2)
- term.write(string.rep(" ", 6))
- pageInput()
- end
- local function printerMessage(message)
- term.setBackgroundColor(colors.blue)
- term.setTextColor(colors.white)
- term.setCursorPos(17, 7)
- term.write(string.rep(" ", 19))
- term.setCursorPos(23, 7)
- term.write("Printer")
- term.setBackgroundColor(colors.gray)
- local line = string.rep(" ", 19)
- for i = 8, 10 do
- term.setCursorPos(17, i)
- term.write(line)
- end
- term.setCursorPos(math.ceil(termX / 2) - math.floor((#message) / 2), 9)
- term.write(message)
- end
- local function screenInvoice(iDate)
- clearLowerScreen(colors.white)
- term.setTextColor(colors.gray)
- local iRoom = "Room " .. tostring(roomData[roomEntry].roomNumber)
- term.setCursorPos(2, 5)
- term.write(iRoom)
- term.setCursorPos(termX - (#iDate + 4), 5)
- term.write("Day " .. iDate)
- term.setTextColor(colors.black)
- term.setCursorPos(2, 6)
- term.write("Guests:")
- term.setBackgroundColor(colors.lightGray)
- local line = string.rep(" ", 41)
- for i = 6, termY - 4 do
- term.setCursorPos(10, i)
- term.write(line)
- end
- local yOffset = 5
- for i = 1, #roomData[roomEntry].guests do
- term.setTextColor(colors.black)
- term.setCursorPos(11, 1 + yOffset)
- term.write(roomData[roomEntry].guests[i].name)
- term.setTextColor(colors.gray)
- term.setCursorPos(12, 2 + yOffset)
- term.write(roomData[roomEntry].guests[i].idPrint)
- yOffset = yOffset + 2
- end
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.lightGray)
- term.setCursorPos(2, termY - 2)
- term.write(numDays .. " days @ " .. roomData[roomEntry].dailyRate .. " credits/day")
- term.setCursorPos(2, termY - 1)
- term.write("Total: ")
- term.setTextColor(colors.black)
- term.write(tostring(roomData[roomEntry].dailyRate * numDays):sub(1, termX - 8) .. " credits")
- if printer then
- term.setBackgroundColor(colors.yellow)
- term.setCursorPos(35, termY - 1)
- term.write(" P r i n t ")
- end
- end
- local function printInvoice(iDate)
- local numPaper = printer.getPaperLevel()
- local numInk = printer.getInkLevel()
- if numPaper > 0 and numInk > 0 then
- if printer.newPage() then
- printerMessage("Invoice: Printing")
- printer.setPageTitle(configData.facilityName .. " Invoice")
- local pX, pY = printer.getPageSize()
- printer.setCursorPos(1, 1)
- printer.write(configData.facilityName .. " Invoice")
- printer.setCursorPos(1, 3)
- printer.write("Room " .. tostring(roomData[roomEntry].roomNumber))
- printer.setCursorPos(1, 4)
- printer.write("Day " .. iDate)
- printer.setCursorPos(1, 6)
- printer.write("Guests...")
- local yOffset = 7
- for i = 1, #roomData[roomEntry].guests do
- printer.setCursorPos(1, 1 + yOffset)
- printer.write(roomData[roomEntry].guests[i].name)
- printer.setCursorPos(2, 2 + yOffset)
- printer.write(roomData[roomEntry].guests[i].idPrint)
- yOffset = yOffset + 2
- end
- printer.setCursorPos(2, pY - 2)
- printer.write(numDays .. " days @ " .. roomData[roomEntry].dailyRate .. " cr/day")
- printer.setCursorPos(2, pY -1 )
- printer.write("Total: " .. tostring(roomData[roomEntry].dailyRate * numDays):sub(1, pX - 8) .. " credits")
- if printer.endPage() then
- printerMessage("Invoice Printed")
- os.pullEvent("mouse_click")
- screenInvoice(iDate)
- return
- else
- printerMessage("Paper jam")
- os.pullEvent("mouse_click")
- screenInvoice(iDate)
- end
- else
- printerMessage("Paper jam")
- os.pullEvent("mouse_click")
- screenInvoice(iDate)
- end
- else
- local errorMessage = "Resources"
- if numPaper < 1 then errorMessage = "Out of paper!" end
- if numInk < 1 then errorMessage = "Out of ink!" end
- printerMessage(errorMessage)
- os.pullEvent("mouse_click")
- screenInvoice(iDate)
- end
- end
- local function viewInvoice(iDate)
- screenInvoice(iDate)
- while true do
- local _, button, x, y = os.pullEvent("mouse_click")
- if x > termX - 3 and y < 4 and button == 1 then
- clearLowerScreen(colors.white)
- roomInfo()
- return
- elseif x > 34 and x < 46 and y == termY - 1 and button == 1 and printer then
- printInvoice(iDate)
- end
- end
- end
- local function changeDailyRate()
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(43, termY - 2)
- term.write(" ")
- term.setCursorPos(43, termY - 2)
- local newRate = tonumber(read(nil, nil, 3))
- if newRate and newRate > 0 then
- roomData[roomEntry].dailyRate = newRate
- saveData("room")
- end
- term.setCursorPos(43, termY - 2)
- term.write(" ")
- local rateStr = tostring(roomData[roomEntry].dailyRate)
- term.setCursorPos(46 - #rateStr, termY - 2)
- term.write(rateStr)
- end
- local function roomInput()
- local event, data, x, y = os.pullEvent()
- if event == "mouse_click" and data == 1 then
- if x > termX - 3 and y < 4 then --# X / Quit
- cancelTimer()
- clearLowerScreen()
- roomList()
- leftPane()
- elseif x > 9 and x < 15 and y == 5 then --# change room number
- cancelTimer(true)
- changeRoomNumber()
- roomInfoLabels()
- roomInfoData()
- roomInfoButtons()
- elseif x == 16 and y == 5 then --# move room
- cancelTimer(true)
- moveRoom(roomEntry)
- roomInfoLabels()
- roomInfoData()
- roomInfoButtons()
- elseif x > 28 and x < 43 and y == 5 then --# change room status
- cancelTimer(true)
- selectRoomStatus()
- elseif x == 10 and y == 7 and #roomData[roomEntry].guests < 5 and roomData[roomEntry].state ~= "unavailable" and roomData[roomEntry].state ~= "service" and roomData[roomEntry].state ~= "checkout" then --# add guest
- cancelTimer(true)
- if roomData[roomEntry].state == "available" then roomData[roomEntry].state = "reserved" end
- viewGuestInfo(0)
- elseif x == 38 and y == 7 and #roomData[roomEntry].notes < 5 then --# add note
- cancelTimer(true)
- viewNote(0)
- elseif x > termX - 3 and y > 5 and y < 16 then --# select scanners
- clearLowerScreen(colors.white)
- cancelTimer()
- scannerListing()
- selectScanners()
- roomInfo()
- elseif x > 2 and x < 20 and y > 9 and y < 15 then --# select or delete guest
- if x == 19 and y - 9 <= #roomData[roomEntry].guests then --# delete
- cancelTimer(true)
- removeGuest(y - 9, true)
- roomInfoLabels()
- roomInfoData()
- roomInfoButtons()
- elseif y - 9 <= #roomData[roomEntry].guests then --# view guest info
- cancelTimer(true)
- viewGuestInfo(y - 9)
- end
- elseif x > 23 and x < 47 and y > 9 and y < 15 then --# select or delete note/message
- if x == 46 and y - 9 <= #roomData[roomEntry].notes then --# delete
- cancelTimer(true)
- deleteNote(y - 9)
- elseif y - 9 <= #roomData[roomEntry].notes then --# view notes/messages
- cancelTimer(true)
- viewNote(y - 9)
- end
- elseif y == termY - 2 and x > 41 and x < 47 and roomData[roomEntry].state ~= "checkout" and roomData[roomEntry].state ~= "occupied" and roomData[roomEntry].state ~="reserved" and roomData[roomEntry].state ~= "service" then --# change rate
- cancelTimer(true)
- changeDailyRate()
- elseif y == termY - 2 and x > 33 and x < 47 and roomData[roomEntry].state == "checkout" then --# invoice
- local iDate = roomData[roomEntry].checkOut.coDay .. " @ " .. roomData[roomEntry].checkOut.coTime
- cancelTimer()
- viewInvoice(iDate)
- elseif y == termY and x > 33 and x < 47 then --# delete room
- if confirmState then
- deleteRoom(roomEntry)
- confirmTimer = nil
- confirmState = false
- clearLowerScreen()
- roomList()
- leftPane()
- else
- if #roomData > 1 and (roomData[roomEntry].state == "available" or roomData[roomEntry].state == "unavailable") then
- confirmTimer = os.startTimer(1.5)
- confirmState = true
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.orange)
- term.setCursorPos(34, termY)
- term.write(" CONFIRM ")
- end
- end
- end
- elseif event == "timer" and data == confirmTimer then
- cancelTimer(true)
- end
- end
- local function guestSearchInput()
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.gray)
- term.setCursorPos(2, 11)
- local sWord = read(nil, nil, 15)
- if sWord ~= "" then
- guestSearch(sWord)
- end
- end
- local function settingsInput()
- local event, data, x, y = os.pullEvent()
- if event == "mouse_click" and data == 1 then
- if x > termX - 3 and y < 4 then --# X / Quit
- clearLowerScreen()
- roomList()
- leftPane()
- elseif x > 18 and x < 36 and y == 5 then --# select master scanner
- clearLowerScreen(colors.white)
- scannerListing(true)
- selectMasterScanner()
- settingsScreen()
- elseif x > 18 and x < 36 and y == 7 then --# change master scanner password
- changeMasterPassword()
- elseif x > 18 and x < 36 and y == 9 then --# change screen lock password
- changeScreenPassword()
- elseif x == 25 and y == 11 then --# add new staff member
- viewStaffInfo(0)
- elseif y == termY - 1 then
- if (x > 8 and x < 11) or (x > 26 and x < 29) then --# Home / End
- staffPage = (x > 8 and x < 11) and 1 or staffPages
- staffInfo()
- elseif (x > 11 and x < 13) or (x > 24 and x < 26) then --# Page back / Page forward
- staffPage = (x > 11 and x < 13) and math.max(1, staffPage - 1) or math.min(staffPage + 1, staffPages)
- staffInfo()
- end
- else --# staff member selection
- local sX, sY = 3, 14
- local magicNumber = (((staffPage - 1) * 3) + staffPage)
- for i = magicNumber, math.min(magicNumber + 3, #configData.staff) do
- if x >= sX and x <= sX + 15 and y == sY then
- viewStaffInfo(i)
- break
- else
- sY = sY + 2
- if sY > termY - 2 then sX = sX + 17 sY = 14 end
- end
- end
- end
- elseif event == "mouse_scroll" then
- staffPage = data == 1 and math.min(staffPage + 1, staffPages) or math.max(1, staffPage - 1)
- staffInfo()
- elseif event == "key" then
- if data == keys.home or data == keys["end"] then --# Home / End
- staffPage = data == keys.home and 1 or staffPages
- staffInfo()
- elseif data == keys.pageUp or data == keys.pageDown then --# Page forward / back
- staffPage = data == keys.pageUp and math.min(staffPage + 1, staffPages) or math.max(1, staffPage - 1)
- staffInfo()
- end
- end
- end
- local function lockInput()
- while true do
- term.setCursorPos(23, 11)
- local unlockPass = read("*", nil, 15, true, true)
- term.setCursorPos(23, 11)
- term.write(string.rep(" ", 15))
- if unlockPass == configData.screenPass then
- clearLowerScreen()
- roomList()
- leftPane()
- return
- end
- end
- end
- local function mainInput()
- local event, data, x, y = os.pullEvent()
- if event == "mouse_click" then
- if x > termX - 3 and y < 4 then --# big X
- if data == 1 then --# quit
- kernelState = false
- clearScreen()
- term.setCursorPos(1, 1)
- return
- elseif data == 2 then --# Lock
- lockScreen()
- end
- elseif x < 17 and data == 1 then
- if y == 11 then
- guestSearchInput() --# guest search
- elseif y == 13 and #roomData < 999 then
- newRoom() --# add a room
- elseif y == 15 then
- settingsScreen() --# settings
- end
- elseif y == termY then
- if x > 28 and x < 38 and y == termY and numPages > 1 and data == 1 then
- selectPage() --# page selection
- elseif (x > 23 and x < 25) or (x > 43 and x < 46) then --# home / end
- pageNum = (x > 23 and x < 25) and 1 or numPages
- if pageNum == numPages and numPages > 1 then clearDataArea() end
- roomList()
- elseif (x > 25 and x < 28) or (x > 41 and x < 43) then --# page - / page +
- pageNum = (x > 25 and x < 28) and math.max(1, pageNum - 1) or math.min(pageNum + 1, numPages)
- if pageNum == numPages and numPages > 1 then clearDataArea() end
- roomList()
- end
- else
- local sX, sY = 20, 5 --# select a room
- local magicNumber = (((pageNum - 1) * 27) + pageNum)
- for i = magicNumber, math.min(magicNumber + 27, #roomData) do
- if x >= sX and x <= sX + 5 and y == sY then
- roomEntry = i
- if data == 1 then
- roomInfo()
- break
- elseif data == 2 then
- selectRoomStatus(true)
- break
- end
- else
- sY = sY + 2
- if sY > termY - 1 then sX = sX + 8 sY = 5 end
- end
- end
- end
- elseif event == "mouse_scroll" then
- pageNum = data == 1 and math.min(pageNum + 1, numPages) or math.max(1, pageNum - 1)
- if pageNum == numPages and numPages > 1 then clearDataArea() end
- roomList()
- elseif event == "key" then
- if data == keys.f1 then
- helpScreen()
- elseif data == keys.home or data == keys["end"] then --# Home / End
- pageNum = data == keys.home and 1 or numPages
- if pageNum == numPages and numPages > 1 then clearDataArea() end
- roomList()
- elseif data == keys.pageUp or data == keys.pageDown then --# Page forward / Page back
- pageNum = data == keys.pageUp and math.max(1, pageNum - 1) or math.min(pageNum + 1, numPages)
- roomList()
- end
- end
- end
- do
- local input = {
- lock = function() lockInput() end,
- main = function() mainInput() end,
- room = function() roomInput() end,
- settings = function() settingsInput() end,
- }
- innKeeperKernel = function()
- while kernelState do
- if input[screen] then input[screen]() end
- end
- end
- end
- local function cancelFirstRun()
- clearScreen()
- term.setTextColor(colors.red)
- term.setCursorPos(1, 1)
- term.write("Innkeeper setup cancelled...")
- term.setTextColor(colors.white)
- term.setCursorPos(1, 4)
- return false
- end
- local function firstRun()
- if not os.getComputerLabel() then os.setComputerLabel("InnKeeper") end
- local gotSettings = fs.exists("/data/innSettings")
- header()
- clearLowerScreen(colors.white) --# Welcome
- term.setTextColor(colors.blue)
- term.setCursorPos(13, 6)
- term.write("Welcome to InnKeeper Setup!")
- term.setCursorPos(6, 8)
- term.write("The next few pages will walk you through")
- term.setCursorPos(7, 10)
- term.write("setting up InnKeeper for your facility.")
- term.setTextColor(colors.white)
- term.setCursorPos(22, 14)
- term.setBackgroundColor(colors.green)
- term.write(" Start ")
- while true do
- local _, button, x, y = os.pullEvent("mouse_click")
- if x > termX - 3 and y < 4 and button == 1 then
- return cancelFirstRun()
- elseif x > 21 and x < 31 and y == 14 and button == 1 then
- break
- end
- end
- if not gotSettings then
- clearLowerScreen(colors.white) --# Name
- term.setTextColor(colors.blue)
- term.setCursorPos(2, 5)
- term.write("Please choose a name for this facility...")
- term.setTextColor(colors.lightGray)
- term.setCursorPos(2, 9)
- term.write("Enter nothing to exit setup")
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.gray)
- term.setCursorPos(2, 7)
- term.write(string.rep(" ", 46))
- term.setCursorPos(3, 7)
- configData.facilityName = read(nil, nil, 44, nil, true)
- if configData.facilityName == "" then return cancelFirstRun() end
- clearLowerScreen(colors.white) --# Screen-lock password
- term.setTextColor(colors.blue)
- term.setCursorPos(5, 5)
- term.write("Please enter a screen lock password")
- term.setTextColor(colors.gray)
- term.setCursorPos(5, 7)
- term.write("Program access is limited by this password")
- term.setTextColor(colors.lightGray)
- term.setCursorPos(14, 12)
- term.write("Enter nothing to exit setup")
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.white)
- term.setCursorPos(14, 9)
- term.write(string.rep(" ", 27))
- term.setCursorPos(15, 9)
- configData.screenPass = read(nil, nil, 25, nil, true)
- if configData.screenPass == "" then return cancelFirstRun() end
- end
- if not fs.exists("/data/innRooms") then
- clearLowerScreen(colors.white) --# Number of rooms
- term.setTextColor(colors.blue)
- term.setCursorPos(2, 5)
- term.write("How many rooms will InnKeeper be managing? ")
- term.setBackgroundColor(colors.gray)
- term.write(" ")
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.gray)
- term.setCursorPos(2, 7)
- term.write("You may add/remove rooms at any time")
- term.setTextColor(colors.lightGray)
- term.setCursorPos(2, 9)
- term.write("Enter nothing to exit setup")
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.white)
- term.setCursorPos(46, 5)
- local numRooms = tonumber(read(nil, nil, 3, nil, true))
- if not numRooms then return cancelFirstRun() end
- for i = 1, numRooms do createRoom(i) end
- numPages = math.ceil(#roomData / 28)
- end
- if not gotSettings then
- clearLowerScreen(colors.white) --# Redsdtone
- term.setTextColor(colors.blue)
- term.setCursorPos(4, 5)
- term.write("Is redstone ")
- term.setTextColor(colors.green)
- term.write("ON")
- term.setTextColor(colors.blue)
- term.write(" or ")
- term.setTextColor(colors.red)
- term.write("OFF")
- term.setTextColor(colors.blue)
- term.write(" when doors are CLOSED?")
- term.setTextColor(colors.gray)
- term.setCursorPos(9, 7)
- term.write("Standard doors are ")
- term.setTextColor(colors.red)
- term.write("OFF")
- term.setTextColor(colors.gray)
- term.write(" when closed")
- term.setCursorPos(3, 8)
- term.write("Pistons/Forcefields are ")
- term.setTextColor(colors.green)
- term.write("ON")
- term.setTextColor(colors.gray)
- term.write(" when extended/closed")
- term.setCursorPos(4, 10)
- term.write("If this facility requires the ")
- term.setTextColor(colors.green)
- term.write("ON")
- term.setTextColor(colors.gray)
- term.write(" setting, use")
- term.setCursorPos(11, 11)
- term.write("only a single scanner per door")
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.green)
- term.setCursorPos(16, 13)
- term.write(" O N ")
- term.setCursorPos(28, 13)
- term.setBackgroundColor(colors.red)
- term.write(" O F F ")
- while true do
- local _, button, x, y = os.pullEvent("mouse_click")
- if x > termX - 3 and y < 4 and button == 1 then
- return cancelFirstRun()
- elseif y == 13 and button == 1 then
- if x > 15 and x < 24 then
- configData.redstone = true
- break
- elseif x > 27 and x < 37 then
- configData.redstone = false
- break
- end
- end
- end
- clearLowerScreen(colors.white) --# Master scanner password
- term.setTextColor(colors.blue)
- term.setCursorPos(5, 5)
- term.write("Please enter a system-wide scanner password")
- term.setTextColor(colors.gray)
- term.setCursorPos(5, 7)
- term.write("All scanners are locked with this password")
- term.setTextColor(colors.lightGray)
- term.setCursorPos(14, 12)
- term.write("Enter nothing to exit setup")
- term.setBackgroundColor(colors.gray)
- term.setTextColor(colors.white)
- term.setCursorPos(14, 9)
- term.write(string.rep(" ", 27))
- term.setCursorPos(15, 9)
- configData.masterPass = read(nil, nil, 25, nil, true)
- if configData.masterPass == "" then return cancelFirstRun() end
- local scanner
- for i = #bioScanners, 1, -1 do --# prepare scanners
- scanner = peripheral.wrap(bioScanners[i])
- if scanner then
- if scanner.unlock(configData.masterPass) or (scanner.lock(configData.masterPass) and scanner.unlock(configData.masterPass)) then
- for _, side in pairs(rs.getSides()) do
- scanner.forgetProgram(side)
- end
- local oldAccounts = { scanner.getLearnedNames() }
- for j = 1, #oldAccounts do
- scanner.forget(oldAccounts[j])
- end
- scanner.lock(configData.masterPass)
- else
- logScannerError(bioScanners[i], "0", "Different Password")
- table.remove(bioScanners, i)
- end
- else
- logScannerError(bioScanners[i], "0", "Scanner Missing")
- table.remove(bioScanners, i)
- end
- end
- clearLowerScreen(colors.white) --# Front desk scanner - you are about to...
- term.setTextColor(colors.blue)
- term.setCursorPos(3, 7)
- term.write("You are about to select the front desk scanner")
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.green)
- term.setCursorPos(18, 10)
- term.write(" C o n t i n u e ")
- while true do
- local _, button, x, y = os.pullEvent("mouse_click")
- if x > termX - 3 and y < 4 and button == 1 then
- return cancelFirstRun()
- elseif x > 16 and x < 34 and y == 10 and button == 1 then
- break
- end
- end
- clearLowerScreen(colors.white) --# Select front desk scanner
- scannerListing(true)
- term.setCursorPos(21, termY - 1)
- term.setBackgroundColor(colors.green)
- term.setTextColor(colors.white)
- term.write(" N E X T >> ")
- configData.staff = { }
- selectMasterScanner()
- if not kernelState then return cancelFirstRun() end
- end
- clearLowerScreen(colors.white) --# Outro
- term.setTextColor(colors.blue)
- term.setCursorPos(7, 6)
- term.write("Don't forget to add your staff members")
- term.setCursorPos(5, 7)
- term.write("(including yourself) in InnKeeper settings.")
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.green)
- term.setCursorPos(18, 10)
- term.write(" Start InnKeeper ")
- while true do
- local _, button, x, y = os.pullEvent("mouse_click")
- if x > termX - 3 and y < 4 and button == 1 then
- return cancelFirstRun()
- elseif x > 17 and x < 35 and y == 10 and button == 1 then
- break
- end
- end
- if not fs.exists("/data/innSettings") then saveData("config") end
- if not fs.exists("/data/innRooms") then saveData("room") end
- newInstall = false
- return true
- end
- local function quickSelectMasterScanner()
- header()
- clearLowerScreen(colors.white) --# Front desk scanner - you are about to...
- term.setTextColor(colors.blue)
- term.setCursorPos(3, 7)
- term.write("The front desk scanner is missing, or locked")
- term.setCursorPos(3, 8)
- term.write("with an unknown password.")
- term.setCursorPos(3, 10)
- term.write("Please select a replacement front desk scanner.")
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.green)
- term.setCursorPos(18, 13)
- term.write(" C o n t i n u e ")
- while true do
- local _, button, x, y = os.pullEvent("mouse_click")
- if x > termX - 3 and y < 4 and button == 1 then
- return cancelFirstRun()
- elseif x > 16 and x < 34 and y == 13 and button == 1 then
- break
- end
- end
- clearLowerScreen(colors.white)
- scannerListing(true)
- term.setCursorPos(21, termY - 1)
- term.setBackgroundColor(colors.green)
- term.setTextColor(colors.white)
- term.write(" N E X T >> ")
- selectMasterScanner() --# Select front desk scanner
- if kernelState then
- newInstall = false
- saveData("config")
- return true
- else
- return cancelFirstRun()
- end
- end
- local function initHardware()
- local notFind, found, perp = false, false, nil
- for _, side in pairs(rs.getSides()) do
- if peripheral.getType(side) == "biolock" then --# directly connected biometric scanners
- bioScanners[#bioScanners + 1] = side
- elseif peripheral.getType(side) == "modem" and not peripheral.call(side, "isWireless") then
- for _, name in pairs(peripheral.call(side, "getNamesRemote")) do
- if peripheral.getType(name) == "biolock" then --# remotely connected biometric scanners
- bioScanners[#bioScanners + 1] = name
- end
- end
- end
- end
- for _, side in pairs(rs.getSides()) do
- if peripheral.getType(side) == "printer" then --# directly connected printer
- printer = peripheral.wrap(side)
- break
- elseif peripheral.getType(side) == "modem" and not peripheral.call(side, "isWireless") then
- for _, name in pairs(peripheral.call(side, "getNamesRemote")) do
- if peripheral.getType(name) == "printer" then --# remotely connected printer
- printer = peripheral.wrap(name)
- found = true
- break
- end
- end
- if found then break end
- end
- end
- if not bioScanners[1] then
- notFind = true
- perp = "a Biometric Scanner"
- end
- if termX < 51 or termY < 19 then
- notFind = true
- perp = "full screen"
- end
- if not term.isColor() or pocket or turtle then
- notFind = true
- perp = "an Advanced Computer"
- end
- if notFind then
- clearScreen()
- term.setTextColor(colors.white)
- term.setCursorPos(2, 2)
- write("InnKeeper requires " .. perp)
- term.setCursorPos(1, 5)
- return false
- end
- return true
- end
- local function initScanners()
- local sides = { "top", "bottom", "left", "right", "back" }
- for i = #bioScanners, 1, -1 do
- local scanner = peripheral.wrap(bioScanners[i])
- if scanner then --# redundant check
- if scanner.unlock(configData.masterPass) or (scanner.lock(configData.masterPass) and scanner.unlock(configData.masterPass)) then --# unlock scanners (take posession of unlocked scanners)
- for _, side in pairs(sides) do
- scanner.forgetProgram(side) --# erase all programs
- end
- local bioNames = { scanner.getLearnedNames() }
- for j = 1, #bioNames do
- scanner.forget(bioNames[j]) --# remove all accounts
- end
- if configData.masterScanner == bioScanners[i] then --# if this is the front desk scanner...
- for j = 1, #configData.staff do
- scanner.learn(configData.staff[j].name, configData.staff[j].idPrint, 1) --# ...learn staff info
- end
- else
- for j = 1, #roomData do
- for k = 1, #roomData[j].scanners do
- if roomData[j].scanners[k] == bioScanners[i] then --# if this scanner is a room scanner then relearn everything
- for _, side in pairs(sides) do
- scanner.program(side, 1, 60, configData.redstone) --# learn door program
- end
- for l = 1, #configData.staff do
- scanner.learn(configData.staff[l].name, configData.staff[l].idPrint, 1) --# learn staff info
- end
- if #roomData[j].guests > 0 and roomData[j].state ~= "reserved" then
- for m = 1, #roomData[j].guests do
- scanner.learn(roomData[j].guests[m].name, roomData[j].guests[m].idPrint, 1) --# learn guest info
- end
- end
- end
- end
- end
- end
- scanner.lock(configData.masterPass) --# lock the scanner
- else
- local room, found = "0", false
- if configData.masterScanner == bioScanners[i] then
- room = "Front Desk"
- configData.masterScanner = nil
- else
- for j = 1, #roomData do
- for k = #roomData[j].scanners, 1, -1 do
- if roomData[j].scanners[k] == bioScanners[i] then
- room = "Room " .. tostring(roomData[j].roomNumber)
- table.remove(roomData[j].scanners, k)
- found = true
- saveData("room")
- break
- end
- end
- if found then break end
- end
- end
- if room ~= "Front Desk" then logScannerError(bioScanners[i], room, "Different Password") end
- table.remove(bioScanners, i)
- end
- else
- if room ~= "Front Desk" then logScannerError(bioScanners[i], room, "Scanner Missing") end
- table.remove(bioScanners, i)
- end
- end
- end
- if not initHardware() then return end
- if fs.exists("/data/innSettings") then
- local configFile = fs.open("/data/innSettings", "r")
- configData = textutils.unserialize(configFile.readAll())
- configFile.close()
- end
- if fs.exists("/data/innRooms") then
- local roomFile = fs.open("/data/innRooms", "r")
- roomData = textutils.unserialize(roomFile.readAll())
- roomFile.close()
- numPages = math.ceil(#roomData / 28)
- end
- if not fs.exists("/data/innRooms") or not fs.exists("/data/innSettings") then
- newInstall = true
- if not firstRun() then return end
- end
- local success = true
- removeMissingScanners()
- initScanners()
- if not configData.masterScanner then
- newInstall = true
- success = quickSelectMasterScanner()
- end
- if not success then return end
- if scannerErrors[1] then
- header(colors.red)
- scannerErrorScreen()
- end
- if configData.masterScanner and kernelState then --# redundant check
- header()
- lockScreen()
- innKeeperKernel() --# main loop
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement