Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Script for Bunker Control
- local component = require("component")
- local thread = require("thread")
- local event = require("event")
- local term = require("term")
- local serialization = require("serialization")
- local sides = require("sides")
- local colors = require("colors")
- local modem = component.modem
- local gpu = component.gpu
- local sg = component.stargate
- local zpm = component.zpmhub
- local tunnel = component.tunnel
- local reds = component.redstone
- local data = component.data
- local keyboard = require("keyboard")
- local lastMessageId = nil
- IDC = "1337"
- user = ""
- Local_Name = "Omega Site"
- Short_Name = "[Omega]"
- running = true
- tesla = false
- lights = false
- iris_status = false
- charging = false
- lockdown = true
- dialingyes = false
- -- Configuration
- beacon = true
- modem.open(123)
- local screenWidth, screenHeight = gpu.getResolution()
- local default_messages = {
- {
- from = "Omega Site",
- shrt = "[Omega]",
- user = "Unknown entity",
- to = Local_Name,
- header = "ComE",
- message = "Join us, we lvie in hramony, the msnoetrs are gone, we cannot aecscc your wold,\nyou will cmoe to ouesr, cmoe cmoe, Alvin missse you all",
- timestamp = 7
- },
- {
- from = "Alpha Site",
- shrt = "[ALERT]",
- user = "Rosewood, Head of Security",
- to = Local_Name,
- header = "LOCKDOWN INITIATED",
- message = "THIS IS NOT A DRILL, THIS IS NOT A DRILL, THIS IS NOT A DRILL\nALL SITES, COMMENCE Decontamination Procedure, COMMENCE LOCKDOWN.\nREAD REST OF MESSAGE WHEN COMPLETE!\n\nOmega site is unavailable, no one is answering. Lab 2 is the same.\nAlpha site received a wormhole from Omega site but no one got through!.\nWe cannot reach them since High Command is also unavailable.\nI have ordered an ALERT on all channels as proper procedure.\nPLEASE RESPOND IF YOU ARE READING THIS!.\nWe also have a power problem at Alpha site, today we were supposed to receive a new ZPM.\nAt limited usage we should be good for another month, but after that we need to evacuate.\nSince High Command is not available we cannot use our stargate, the Iris code is encrypted.\nRESPOND IMMEDIATELY if receiving this message!.",
- timestamp = 6
- },
- {
- from = "Laboratory 1",
- shrt = "[Lab 1]",
- user = "Jack, Shipment officer",
- to = Local_Name,
- header = "Missing Shipment",
- message = "Im reaching you since i cant get a hold of Lab 2 myself, my security clearence isnt that high.\nWe were supposed to receive a shipment today but it never came. It was supposed to be delivered through the gate.\nIt does not say what it even is, so you can imagine my frustration.\nLet me know if you find it, i will report this incident to my higher ups, you should report it to High Command.",
- timestamp = 5
- },
- {
- from = "Laboratory 2",
- shrt = "[Lab 2]",
- user = "Doctor Greywall",
- to = Local_Name,
- header = "Lab results",
- message = "We have dubbed it Alvin, from alvin and the chipmunks!\nAlvin has exceeded our expectations, he (or it rather) is a perfect creature. Able to adapt and reform his body at will.\nWe have feeded it live chipmunks and it immediately assumed its form as one! Before devouring them.\nIt has now grown, its the size of a human. Although i doubt it has the intelligence of one.\nIt also has this weird effect on life around it, it kinda dies, and reanimates into something different.\nWe had to increase the security zone around its holding area, my plants were dying because of it.\nWe will need to move it in the near future, to a more secure facility.\nI hear Lab 1 is getting a 20 billion dollar funding this year, lucky them.\nLet High Command know i will be terminating the rest of the eggs also, they have begun to smell.\nOh and that Lab 1 can take care of Alvin.",
- timestamp = 4
- },
- {
- from = "Omega Site",
- shrt = "[Omega]",
- user = "Bryan Haddoc",
- to = Local_Name,
- header = "Iris installed",
- message = "As per requested the Iris is now operational, although we are abit sceptical that the code is classified.\nWhat if the settlers have family to visit?\nAlso it will become harder to receive supply, High command needs to approve everytime so they can shutdown the Iris!\nPlease forward these issues to High Command, its important for us.\nWe have also been seeing things here, things in the dark. I'm not the only one.\nDavid saw a GIANT spider yesterday, looked like it could eat a cat!.",
- timestamp = 3
- },
- {
- from = "High Command",
- shrt = "[High cmd]",
- user = "Secretary General Coldwell",
- to = Local_Name,
- header = "Increased activity READ ME",
- message = "High Command has finished its assessment around the Omega site, new security measures are to be taken.\nThe local fauna has been increasing its hostility towards the site, where as before it was only curious of us, it is now our belief it has grown more hostile.\nNo doubt due to the experiments from Doctor Greywall in Lab 2.\nAn Iris to the gate at Omega site is to be installed at once! New intel suggests that there is currently a large scale operation\nunderway intended to sabotage the site, possibly even a takeover. Secure the gate, then take care of the wildlife surrounding the Omega site.\nWe dont want any surprises. Make sure that the Iris gate code is ONLY known by High Command.\n\nThe settlements beyond Omega is also now at greater risk.\nUntil we have a greater understanding of the local fauna, NO personnel is allowed to leave the Omega site.\nThe settlers can protect themselves, they are all armed after all.",
- timestamp = 2
- },
- {
- from = "Laboratory 2",
- shrt = "[Lab 2]",
- user = "Doctor Greywall",
- to = Local_Name,
- header = "Eggsacks",
- message = "The eggsacks found on the planet Nibiru have produced results.\nWe have managed to create a hybrid of a vein floater along with local fauna found on the Omega site.\nSo far it has adapted to everything we have thrown at it,\nLava, shotguns, electrocutions, it seems to handle it all.\nThe staff is beginning to wonder what we should do if it breaks out.\nNot to worry, the lab is set to blow with a 100 Megaton warhead if it does, but I won't tell them that.\nAlso it has begun laying eggs on its own, expect more results sooner now rather than later.",
- timestamp = 1
- },
- }
- function drawMessageBox(message_data)
- local screenWidth, _ = gpu.getResolution()
- -- Prepare message lines
- local lines = {
- "New message received from " .. message_data.from,
- "Subject: " .. message_data.shrt .. " " .. message_data.header,
- "Message: " .. message_data.message,
- "User: " .. message_data.user
- }
- -- Determine max line length
- local maxLength = 0
- for _, line in ipairs(lines) do
- if #line > maxLength then
- maxLength = #line
- end
- end
- -- Box styling
- local padding = 2
- local boxWidth = maxLength + padding * 2
- local boxHeight = #lines + 2 -- top + bottom border
- local startX = screenWidth - boxWidth + 1
- local startY = 1
- -- Draw top border
- gpu.set(startX, startY, "┌" .. string.rep("─", boxWidth - 2) .. "┐")
- -- Draw box sides and empty space
- for i = 1, boxHeight - 2 do
- gpu.set(startX, startY + i, "│" .. string.rep(" ", boxWidth - 2) .. "│")
- end
- -- Draw bottom border
- gpu.set(startX, startY + boxHeight - 1, "└" .. string.rep("─", boxWidth - 2) .. "┘")
- -- Write text inside the box
- for i, line in ipairs(lines) do
- gpu.set(startX + padding, startY + i, line)
- end
- end
- -- UI Drawing Function
- local function draw_ui()
- term.clear()
- print("Omega Site Control")
- print("[SPACE] Toggle Emergency Beacon [" .. (beacon and "ON" or "OFF") .. "]")
- print("[D] Toggle Perimeter Defense[" .. (tesla and "ON" or "OFF") .. "]")
- print("[L] Toggle Perimeter Lights[" .. (lights and "ON" or "OFF") .. "]")
- print("[U] Update orders from high command")
- print("[M] Messages")
- print("[C] Charge Gate")
- print("[Q] Dialing Menu")
- end
- -- UI Drawing Function messages
- local function draw_ui_messages()
- term.clear()
- print("Messages")
- print("[R] Read messages")
- print("[S] Send message")
- print("[E] Exit")
- end
- -- UI Drawing Function dialing
- local function draw_ui_dialing()
- term.clear()
- print("Dialing Menu")
- if not dialingyes then
- if lockdown then
- print("[WARNING] Lockdown in effect, iris will turn on when dialing out!")
- print("[L] Disable Lockdown")
- elseif not lockdown then
- print("[L] Enable Lockdown")
- end
- print("[1] Dial Epsilon Site")
- print("[2] Dial Laboratory 1")
- print("[3] Dial Laboratory 2")
- print("[4] Dial Alpha Site")
- print("[5] Dial High Command")
- print("[E] Exit")
- elseif dialingyes then
- print("Dialing: ") -- Fix later, in the middle of the screen and an abort function
- print("[E] Exit")
- end
- end
- local function is_floppy_valid()
- local privFile = io.open("/rPrivate.key", "r")
- if not privFile then
- print("[✘] Missing /rPrivate.key!")
- return false
- end
- local privSerialized = privFile:read("*a")
- privFile:close()
- local rPrivate = data.deserializeKey(serialization.unserialize(privSerialized), "ec-private")
- for address in component.list("disk_drive") do
- local drive = component.proxy(address)
- local ok, present = pcall(function() return not drive.isEmpty() end)
- if not ok then
- print("[DEBUG] Error calling isEmpty(): " .. tostring(present))
- elseif present then
- local fsAddress = drive.media()
- if fsAddress then
- local fs = component.proxy(fsAddress)
- if fs.exists("/key.dat") then
- local f = fs.open("/key.dat", "r")
- if f then
- local content = fs.read(f, math.huge)
- fs.close(f)
- if content then
- local packet = serialization.unserialize(content)
- local sPublic = data.deserializeKey(serialization.unserialize(packet.header.sPublic), "ec-public")
- local iv = packet.header.iv
- local encryptedData = packet.data
- local sharedKey = data.md5(data.ecdh(rPrivate, sPublic))
- local decrypted = data.decrypt(encryptedData, sharedKey, iv)
- if decrypted then
- local result = serialization.unserialize(decrypted)
- if result == "supersecretpassword" then
- return true
- else
- end
- else
- end
- else
- end
- else
- end
- else
- end
- else
- end
- else
- end
- end
- return false
- end
- local function decryptkey()
- term.clear()
- print("HIGH CMD SECURITY KEY NEEDED")
- print("Place the Floppy Disk Security key inside the Disk Drive")
- print("Press [E] to exit.")
- local animY = 6 -- Row to draw the blinking text
- while true do
- local visible = math.floor(os.clock() * 1.5) % 2 == 0
- local msg = "Waiting for Security Key..."
- local x = math.floor((screenWidth - #msg) / 2)
- if visible then
- gpu.set(x, animY, msg)
- else
- gpu.set(x, animY, string.rep(" ", #msg))
- end
- if is_floppy_valid() then
- print("\n[✔] Valid Security Key Detected.")
- lockdown = false
- os.sleep(1)
- return true
- end
- local ev, _, _, code = event.pull(0.1, "key_down")
- if ev == "key_down" then
- print("You pressed key ID:", code)
- if code == keyboard.keys.e then
- print("[✖] Authorization Aborted.")
- return false
- end
- end
- os.sleep(0.1)
- end
- end
- -- Function to send commands
- local function send_command(address, value, header)
- local data = {
- from = Local_Name,
- shrt = Short_Name,
- user = user,
- to = address,
- header = header,
- message = value,
- timestamp = os.time()
- }
- local serialized_data = serialization.serialize(data)
- tunnel.send(serialized_data)
- end
- local function handle_incomingwh()
- if not iris_status then
- iris_status = true
- if not charging then
- zpm.toggleSlots()
- end
- sg.toggleIris()
- print("INCOMING WORMHOLE!.")
- end
- end
- local function handle_closingwh()
- if iris_status then
- sg.toggleIris()
- zpm.toggleSlots()
- iris_status = false
- end
- end
- -- Function to read messages
- local function read_message()
- local path = "/messages.dat"
- local file = io.open(path, "r")
- if not file then
- print("No messages found.")
- os.sleep(2)
- return
- end
- local content = file:read("*a")
- file:close()
- local messages = serialization.unserialize(content)
- if not messages or #messages == 0 then
- print("Inbox empty.")
- os.sleep(2)
- return
- end
- -- Sort by timestamp descending (newest first)
- table.sort(messages, function(a, b)
- return tonumber(a.timestamp) > tonumber(b.timestamp)
- end)
- while true do
- term.clear()
- print("Inbox")
- print("︱NEWEST︱")
- for i, msg in ipairs(messages) do
- print(string.format("[%d] ︱ %s %s ︱", i, msg.shrt or "", msg.header or ""))
- end
- print("︱OLDEST︱")
- print("")
- print("[E] Exit")
- local answer = io.read()
- if answer == "e" or answer == "E" then
- break
- else
- local index = tonumber(answer)
- if index and messages[index] then
- local msg = messages[index]
- term.clear()
- print(string.format("︱ %s %s ︱", msg.shrt or "", msg.header or ""))
- print("")
- print(msg.message or "")
- print("")
- print(msg.user or "Unknown sender")
- print("")
- print("[E] Exit")
- local _ = io.read()
- end
- end
- end
- end
- -- Function to send messages
- local function send_message()
- ::continue1::
- term.clear()
- print("Pick receiver")
- print("[1] Epsilon Site")
- print("[2] Laboratory 1")
- print("[3] Laboratory 2")
- print("[4] High Command")
- print("[E] Exit")
- local answer = io.read()
- if answer == "1" then
- send_to = "Epsilon Site"
- print("Epsilon Site Confirmed, please type the subject of your message and press enter")
- print("")
- local header = io.read()
- term.clear()
- print("Subject: " .. header)
- print("")
- print("Please type your message")
- print("")
- local message = io.read()
- term.clear()
- print("From: " .. Local_Name)
- print("Subject: " .. header)
- print("Message: " .. message)
- print("")
- print("Do you want to send this message to ".. send_to .."?")
- io.write("Y/n: ")
- local answer = io.read()
- if answer == "Y" or answer == "y" then
- send_command(send_to, message, header)
- end
- term.clear()
- goto continue1
- elseif answer == "2" then
- send_to = "Laboratory 1"
- term.clear()
- print("Laboratory 1 Confirmed, please type the subject of your message and press enter")
- print("")
- local header = io.read()
- term.clear()
- print("Subject: " .. header)
- print("")
- print("Please type your message")
- print("")
- local message = io.read()
- term.clear()
- print("From: " .. Local_Name)
- print("Subject: " .. header)
- print("Message: " .. message)
- print("")
- print("Do you want to send this message to ".. send_to .."?")
- io.write("Y/n: ")
- local answer = io.read()
- if answer == "Y" or answer == "y" then
- send_command(send_to, message, header)
- end
- term.clear()
- goto continue1
- elseif answer == "3" then
- send_to = "Laboratory 2"
- term.clear()
- print("Laboratory 2 Confirmed, please type the subject of your message and press enter")
- print("")
- local header = io.read()
- term.clear()
- print("Subject: " .. header)
- print("")
- print("Please type your message")
- print("")
- local message = io.read()
- term.clear()
- print("From: " .. Local_Name)
- print("Subject: " .. header)
- print("Message: " .. message)
- print("")
- print("Do you want to send this message to ".. send_to .."?")
- io.write("Y/n: ")
- local answer = io.read()
- if answer == "Y" or answer == "y" then
- send_command(send_to, message, header)
- end
- term.clear()
- goto continue1
- elseif answer == "4" then
- send_to = "High Command"
- term.clear()
- print("High Command Confirmed, please type the subject of your message and press enter.")
- print("")
- local header = io.read()
- term.clear()
- print("Subject: " .. header)
- print("")
- print("Please type your message")
- print("")
- local message = io.read()
- term.clear()
- print("From: " .. Local_Name)
- print("Subject: " .. header)
- print("Message: " .. message)
- print("")
- print("Do you want to send this message to ".. send_to .."?")
- io.write("Y/n: ")
- local answer = io.read()
- if answer == "Y" or answer == "y" then
- send_command(send_to, message, header)
- end
- term.clear()
- goto continue1
- elseif answer == "e" or answer == "E" then
- else
- goto continue1
- end
- end
- local function init_message_file()
- local path = "/messages.dat"
- local f = io.open(path, "r")
- if not f then
- -- Save default messages to file
- local file = io.open(path, "w")
- if file then
- file:write(serialization.serialize(default_messages))
- file:close()
- end
- else
- f:close()
- end
- end
- local function save_message(message_data)
- local filepath = "/messages.dat"
- local messages = {}
- -- Load existing messages if file exists
- local file = io.open(filepath, "r")
- if file then
- local content = file:read("*a")
- file:close()
- if content and #content > 0 then
- messages = serialization.unserialize(content) or {}
- end
- end
- -- Add new message
- table.insert(messages, message_data)
- -- Sort by timestamp
- table.sort(messages, function(a, b)
- return a.timestamp < b.timestamp
- end)
- -- Save updated messages back to file
- file = io.open(filepath, "w")
- if file then
- file:write(serialization.serialize(messages))
- file:close()
- end
- end
- local function handle_modem_message(_, _, from, port, _, message, data)
- if port == 123 or port == 0 then
- if message == "error" then
- print("")
- print("[ERROR] " .. data)
- elseif message == "sent_message" then
- print("")
- print("Sent message to " .. data)
- elseif message == "new_message" then
- local message_data = serialization.unserialize(data)
- if message_data.timestamp ~= lastMessageId then
- lastMessageId = message_data.timestamp
- drawMessageBox(message_data)
- save_message(message_data)
- end
- elseif message == "code" then
- if data == IDC then
- if iris_status then
- iris_status = false
- sg.toggleIris()
- zpm.toggleSlots()
- end
- end
- elseif message == "lockdown" then
- lockdown = true
- end
- end
- end
- function drawChargingProgress()
- local screenWidth, screenHeight = gpu.getResolution()
- local label = "Charging Gate..."
- local labelX = math.floor((screenWidth - #label) / 2) + 1
- local labelY = math.floor(screenHeight / 2)
- -- Progress bar settings
- local barWidth = 30
- local barX = math.floor((screenWidth - barWidth) / 2) + 1
- local barY = labelY + 2
- local totalTime = 34 -- seconds
- local updateRate = 0.1 -- how often to update in seconds
- local steps = math.floor(totalTime / updateRate)
- -- Clear label and bar area
- for i = 0, 3 do
- gpu.set(1, labelY + i, string.rep(" ", screenWidth))
- end
- -- Draw label
- gpu.set(labelX, labelY, label)
- -- Progress bar loop
- for i = 0, steps do
- if iris_status then
- draw_ui()
- term.setCursor(1, barY + 2)
- print("[!] Charging aborted: Iris status triggered.")
- return end
- local filled = math.floor((i / steps) * barWidth)
- local empty = barWidth - filled
- gpu.set(barX, barY, "[" .. string.rep("█", filled) .. string.rep(" ", empty) .. "]")
- os.sleep(updateRate)
- end
- end
- local function chargegate()
- charging = true
- zpm.toggleSlots()
- drawChargingProgress()
- if not iris_status then
- zpm.toggleSlots()
- end
- charging = false
- end
- -- Keyboard Input Listener
- local function key_listener(_, _, char, code, playerName)
- local key = string.char(char)
- user = playerName
- event.ignore("key_down", key_listener)
- if key == "u" then
- term.clear()
- print("Connecting to central network...")
- os.sleep(3)
- print("[ERROR] No connection")
- os.sleep(0.5)
- print("[ERROR] Diagnosing...")
- os.sleep(3)
- print("[✔] Receiver [ONLINE]")
- print("[✔] Transmitter [ONLINE]")
- print("[ERROR] High Command blocked or not responding")
- print("[⚠] Can not receive orders!")
- print("")
- print("Please follow standard Emergency Procedures")
- os.sleep(8)
- draw_ui()
- elseif key == "d" then
- if tesla then
- tesla = not tesla
- reds.setBundledOutput(sides.bottom, colors.yellow, 0)
- draw_ui()
- print("Turned Off Perimeter Defense")
- elseif not tesla then
- tesla = not tesla
- reds.setBundledOutput(sides.bottom, colors.yellow, 255)
- draw_ui()
- print("Turned On Perimeter Defense")
- end
- elseif key == "l" then
- if lights then
- lights = not lights
- reds.setBundledOutput(sides.bottom, colors.green, 255)
- draw_ui()
- print("Turned Off Perimeter Lights")
- elseif not lights then
- lights = not lights
- reds.setBundledOutput(sides.bottom, colors.green, 0)
- draw_ui()
- print("Turned On Perimeter Lights")
- end
- elseif key == "q" then
- ::continue3::
- draw_ui_dialing()
- local answer = io.read()
- if answer == "l" or answer == "L" then
- if lockdown then
- decryptkey()
- elseif not lockdown then
- lockdown = true
- end
- goto continue3
- elseif answer == "1" then
- send_message()
- goto continue3
- elseif answer == "2" then
- send_message()
- goto continue3
- elseif answer == "3" then
- send_message()
- goto continue3
- elseif answer == "4" then
- send_message()
- goto continue3
- elseif answer == "5" then
- send_message()
- goto continue3
- elseif answer == "e" or answer == "E" then
- draw_ui()
- else
- goto continue3
- end
- elseif code == 57 then
- if beacon then
- print("Confirm Beacon Shutdown")
- io.write("Y/n: ")
- local answer = io.read()
- if answer == "y" or answer == "Y" then
- beacon = not beacon
- print("Confirmed")
- os.sleep(3)
- draw_ui()
- else
- print("Aborted!")
- os.sleep(3)
- draw_ui()
- end
- elseif not beacon then
- beacon = not beacon
- draw_ui()
- print("Emergency Beacon Online!")
- end
- elseif key == "m" then
- ::continue::
- draw_ui_messages()
- local answer = io.read()
- if answer == "r" or answer == "R" then
- read_message()
- goto continue
- elseif answer == "s" or answer == "S" then
- send_message()
- goto continue
- elseif answer == "e" or answer == "E" then
- draw_ui()
- else
- goto continue
- end
- elseif key == "c" then
- if iris_status then
- print("[!] Cannot Charge when Iris is up!.")
- elseif not iris_status then
- chargegate()
- draw_ui()
- end
- end
- event.listen("key_down", key_listener)
- end
- if reds.getBundledOutput(sides.bottom, colors.yellow) > 0 then
- tesla = true
- end
- if reds.getBundledOutput(sides.bottom, colors.green) < 1 then
- lights = true
- end
- draw_ui()
- init_message_file()
- messages = event.listen("modem_message", handle_modem_message)
- incomingwh = event.listen("stargate_incoming_wormhole", handle_incomingwh)
- closingwh = event.listen("stargate_wormhole_closed_fully", handle_closingwh)
- event.listen("key_down", key_listener)
- while running do
- os.sleep(0.5)
- end
- os.sleep(1)
- os.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement