-- Configuration
local MONITOR_SIDE = "top"
local REDSTONE_SIDE = "back"
local CHATBOX_SIDE = "bottom"
local WHITELIST = {"M_CI_HYPE"} -- Fixed nickname
local CHECK_RADIUS = 20
local SECRET_PASSWORD = "open"
local LOG_FILE = "security_log.txt"
-- Peripheral initialization
local playerDetector = peripheral.find("playerDetector")
local monitor = peripheral.find("monitor")
local chatBox = peripheral.find("chatBox")
if monitor then
monitor.setTextScale(0.5)
end
-- Colors
local colors = {
green = 32768,
yellow = 16,
white = 1,
red = 16384,
orange = 4
}
-- State variables
local currentPage = 1
local lastIntruders = {}
local lastTouchTime = 0
local touchCooldown = 0.5
local overrideActive = false
local overrideEndTime = 0
local overrideDuration = 10
local overrideBy = ""
-- Tracking for logging
local playersInZone = {}
function isInWhitelist(username)
for _, whitelistedName in ipairs(WHITELIST) do
if whitelistedName == username then
return true
end
end
return false
end
function logEvent(username, doorOpened, openedBy)
local timestamp = os.date("%H:%M:%S")
local status = doorOpened and "was" or "wasn't"
local logEntry = "Player detected: " .. username .. ", time: " .. timestamp ..
". Door " .. status .. " opened. Opened by: " .. openedBy
print("Attempting to log: " .. logEntry)
-- Save to file
local logFile = fs.open(LOG_FILE, "a")
if logFile then
logFile.writeLine(logEntry)
logFile.close()
print("Successfully logged to file")
else
print("ERROR: Failed to open log file for writing")
end
end
function handleMonitorTouch()
while true do
local event, side, x, y = os.pullEvent("monitor_touch")
local currentTime = os.clock()
if currentTime - lastTouchTime > touchCooldown then
lastTouchTime = currentTime
if #lastIntruders > 0 then
currentPage = currentPage + 1
if currentPage > #lastIntruders then
currentPage = 1
end
updateDisplay()
end
end
end
end
function handleChat()
while true do
local event, username, message, uuid = os.pullEvent("chat")
print("Chat received from " .. username .. ": " .. message)
if message:lower() == SECRET_PASSWORD then
local players = playerDetector.getPlayersInRange(CHECK_RADIUS)
local playerInRange = false
print("Checking players in range for " .. username)
for _, player in ipairs(players) do
if player and player.name then -- Added nil check
print("Found player: " .. player.name)
if player.name == username and isInWhitelist(username) then
playerInRange = true
break
end
end
end
if playerInRange then
overrideActive = true
overrideEndTime = os.time() + overrideDuration
overrideBy = username
logEvent(username, true, "secret word")
if chatBox then
chatBox.sendMessageToPlayer(username, "Override activated for " .. overrideDuration .. " seconds")
end
print("Override activated by " .. username)
updateDisplay()
else
print("Access denied for " .. username .. " - not in range or not in whitelist")
if chatBox then
chatBox.sendMessageToPlayer(username, "Access denied")
end
end
end
end
end
function updateDisplay()
if not monitor then
print("No monitor found")
return
end
monitor.clear()
local width, height = monitor.getSize()
monitor.setCursorPos(1, 1)
monitor.setTextColor(colors.white)
monitor.write("Access Control System")
if overrideActive then
local timeLeft = overrideEndTime - os.time()
if timeLeft > 0 then
monitor.setCursorPos(1, 2)
monitor.setTextColor(colors.orange)
monitor.write("OVERRIDE: " .. timeLeft .. "s")
monitor.setCursorPos(1, 3)
monitor.write("By: " .. overrideBy)
else
overrideActive = false
end
end
local doorStatusLine = overrideActive and 4 or 2
monitor.setCursorPos(1, doorStatusLine)
if #lastIntruders == 0 or overrideActive then
monitor.setTextColor(colors.green)
monitor.write("ACCESS GRANTED")
else
monitor.setTextColor(colors.red)
monitor.write("ACCESS DENIED")
end
local intrudersStartLine = doorStatusLine + 2
if #lastIntruders == 0 then
monitor.setCursorPos(1, intrudersStartLine)
monitor.setTextColor(colors.green)
monitor.write("Area secure")
monitor.setCursorPos(1, intrudersStartLine + 1)
monitor.write("No intruders detected")
else
monitor.setCursorPos(1, intrudersStartLine)
if overrideActive then
monitor.setTextColor(colors.orange)
monitor.write("Warning: " .. #lastIntruders .. " strangers")
else
monitor.setTextColor(colors.yellow)
monitor.write("Warning: " .. #lastIntruders .. " strangers")
end
monitor.setCursorPos(1, intrudersStartLine + 1)
monitor.setTextColor(colors.white)
monitor.write("Viewing: " .. currentPage .. "/" .. #lastIntruders)
local intruder = lastIntruders[currentPage]
if intruder then
monitor.setCursorPos(1, intrudersStartLine + 3)
monitor.setTextColor(colors.yellow)
monitor.write("Name: " .. intruder.name)
monitor.setCursorPos(1, intrudersStartLine + 4)
monitor.write("Max HP: " .. intruder.maxHealth)
end
if monitor.isColor() then
monitor.setCursorPos(1, height)
monitor.setTextColor(colors.white)
monitor.write("Touch screen to cycle")
end
end
end
function main()
print("Starting security system...")
-- Create log file with more verbose error handling
local logFile = fs.open(LOG_FILE, "a")
if logFile then
logFile.writeLine("Security System Log - Started: " .. os.date())
logFile.close()
print("Log file created/accessed successfully")
else
print("ERROR: Could not create or access log file")
end
-- Initial display update
updateDisplay()
-- Start listeners
local parallelFunctions = {}
if monitor and monitor.isColor() then
table.insert(parallelFunctions, function()
print("Starting touch listener")
handleMonitorTouch()
end)
end
if chatBox then
table.insert(parallelFunctions, function()
print("Starting chat listener")
handleChat()
end)
end
-- Main detection loop
table.insert(parallelFunctions, function()
print("Starting main detection loop")
local previousPlayers = {}
while true do
local players = playerDetector.getPlayersInRange(CHECK_RADIUS) or {}
local authorized = false
local intruders = {}
local currentPlayers = {}
print("Players in range: " .. #players)
-- Track current players for logging
for _, player in ipairs(players) do
if player and player.name then -- Added nil check
print("Processing player: " .. player.name)
currentPlayers[player.name] = true
if isInWhitelist(player.name) then
authorized = true
print("Authorized player detected: " .. player.name)
else
print("Intruder detected: " .. player.name)
table.insert(intruders, {
name = player.name,
maxHealth = math.floor(player.maxHealth or 20)
})
end
else
print("WARNING: Found player with nil name")
end
end
-- Log player entries (only when they first enter)
for playerName, _ in pairs(currentPlayers) do
if not previousPlayers[playerName] then
print("New player entered zone: " .. playerName)
local doorOpened = (authorized and #intruders == 0) or overrideActive
local openedBy = overrideActive and "secret word" or "auto"
logEvent(playerName, doorOpened, openedBy)
end
end
-- Reset page if intruder list changed
if #intruders ~= #lastIntruders then
currentPage = 1
end
lastIntruders = intruders
previousPlayers = currentPlayers
-- Check if override has expired
if overrideActive and os.time() > overrideEndTime then
overrideActive = false
print("Override expired")
end
-- Control door
local shouldOpen = (authorized and #intruders == 0) or overrideActive
redstone.setOutput(REDSTONE_SIDE, shouldOpen)
-- Update display
updateDisplay()
os.sleep(0.5)
end
end)
-- Run all functions in parallel
print("Starting parallel execution with " .. #parallelFunctions .. " functions")
parallel.waitForAny(table.unpack(parallelFunctions))
end
-- Error handling
print("Initializing security system...")
local ok, err = pcall(main)
if not ok then
print("System error: " .. err)
if monitor then
monitor.clear()
monitor.setCursorPos(1, 1)
monitor.setTextColor(colors.red)
monitor.write("SYSTEM ERROR")
monitor.setCursorPos(1, 2)
monitor.write(tostring(err))
end
end