GLaDOS446

SCHLEUSEN KONTROLLE 3

Jun 7th, 2026
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.04 KB | Source Code | 0 0
  1. local component = require("component")
  2. local event = require("event")
  3. local sides = require("sides")
  4. local colors = require("colors")
  5. local term = require("term")
  6. local serialization = require("serialization")
  7. local computer = require("computer")
  8. local modem = component.modem
  9. local rs = component.redstone
  10.  
  11. if not modem then error("Dieses Programm benoetigt ein Wireless-Modem!") end
  12. modem.open(225)
  13. if modem.isWireless() then modem.setStrength(400) end
  14.  
  15. local CONFIG_FILE = "schleuse_config.cfg"
  16. local config = {}
  17.  
  18. local status = "BEREIT"
  19. local innen_entsperrt = false
  20.  
  21. local REDSTONE_SEITE = sides.back
  22. local CABLE_UNGESICHERT = colors.black  
  23. local CABLE_GESICHERT   = colors.gray  
  24. local CABLE_CYCLE       = colors.yellow
  25.  
  26. local letzte_eintritts_seite = CABLE_UNGESICHERT
  27.  
  28. local gpu_grau, gpu_schwarz, gpu_innen
  29. local alle_gpus = {}
  30. for addr in component.list("gpu") do table.insert(alle_gpus, component.proxy(addr)) end
  31.  
  32. if #alle_gpus < 3 then
  33.   error("Fehler: Es werden alle 3 Grafikkarten im Server/Rack benoetigt!")
  34. end
  35.  
  36. local function printZentriert(gpu, maxW, y, text, fore, back, offsetX)
  37.   offsetX = offsetX or 0
  38.   if fore then gpu.setForeground(fore) end
  39.   if back then gpu.setBackground(back) end
  40.   local gekuerzt = string.sub(text, 1, maxW)
  41.   local x = math.max(1, math.floor((maxW - #gekuerzt) / 2) + 1) + offsetX
  42.   gpu.set(x, y, gekuerzt)
  43. end
  44.  
  45. local function testeBildschirmMitIgendeinerGpu(screen_addr, text)
  46.   for _, g in ipairs(alle_gpus) do
  47.     if g.bind(screen_addr) then
  48.       g.setResolution(50, 16) -- Erzwingt großes Layout beim Setup
  49.       local sw, sh = g.getResolution()
  50.       g.setBackground(0x00FF00)
  51.       g.fill(1, 1, sw, sh, " ")
  52.       printZentriert(g, sw, math.floor(sh/2), text, 0x000000, 0x00FF00)
  53.       return g
  54.     end
  55.   end
  56.   return nil
  57. end
  58.  
  59. local function ladeOderErstelleConfig()
  60.   local f = io.open(CONFIG_FILE, "r")
  61.   if f then
  62.     config = serialization.unserialize(f:read("*a")) or {}
  63.     f:close()
  64.     if config.grau and config.schwarz and config.innen and config.lock_id and config.lock_name then
  65.       return
  66.     end
  67.   end
  68.  
  69.   term.clear()
  70.   print("=== SCHLEUSEN SETUP ===")
  71.   io.write("Anzeigename der Schleuse (z.B. Haupttor): ")
  72.   local lname = io.read()
  73.   if lname == "" then lname = "Unbenannt" end
  74.  
  75.   io.write("ID der Schleuse zur Verwaltung (z.B. gate_01): ")
  76.   local lid = io.read()
  77.   if lid == "" then lid = "lock_default" end
  78.  
  79.   print("\nMonitore leuchten nacheinander kurz GRÜN.")
  80.   print("Drücke ENTER zum Starten...")
  81.   io.read()
  82.  
  83.   config = { lock_name = lname, lock_id = lid }
  84.   local alle_monitore = {}
  85.   for addr in component.list("screen") do table.insert(alle_monitore, addr) end
  86.  
  87.   for i, addr in ipairs(alle_monitore) do
  88.     local verwendete_gpu = testeBildschirmMitIgendeinerGpu(addr, "MONITOR " .. i)
  89.    
  90.     term.clear()
  91.     print("Ein Monitor leuchtet jetzt GRÜN.")
  92.     print("Welcher Monitor ist das?")
  93.     print("1: Monitor AUSSEN (Ungesichert)")
  94.     print("2: Monitor BASIS (Gesichert)")
  95.     print("3: Monitor INNENRAUM (Karte)")
  96.     print("4: Ignorieren")
  97.    
  98.     local auswahl = ""
  99.     while auswahl ~= "1" and auswahl ~= "2" and auswahl ~= "3" and auswahl ~= "4" do
  100.       io.write("Auswahl (1-4): ")
  101.       auswahl = io.read()
  102.     end
  103.  
  104.     if auswahl == "1" then config.grau = addr
  105.     elseif auswahl == "2" then config.schwarz = addr
  106.     elseif auswahl == "3" then config.innen = addr
  107.     end
  108.  
  109.     if verwendete_gpu then
  110.       local sw, sh = verwendete_gpu.getResolution()
  111.       verwendete_gpu.setBackground(0x000000)
  112.       verwendete_gpu.fill(1, 1, sw, sh, " ")
  113.     end
  114.   end
  115.  
  116.   f = io.open(CONFIG_FILE, "w")
  117.   f:write(serialization.serialize(config))
  118.   f:close()
  119. end
  120.  
  121. local function frageServerAn(req_type, detail)
  122.   local alter_status = status
  123.   status = "PRUEFE..."
  124.  
  125.   if gpu_grau then drawAussenInterface(gpu_grau, "AUSSEN") end
  126.   if gpu_schwarz then drawAussenInterface(gpu_schwarz, "BASIS") end
  127.   if gpu_innen then
  128.     local iw, ih = gpu_innen.getResolution()
  129.     gpu_innen.setBackground(0x000000)
  130.     gpu_innen.fill(1, 1, iw, ih, " ")
  131.     printZentriert(gpu_innen, iw, math.floor(ih/2), "VERBINDE SERVER...", 0xFFFF00, 0x000000)
  132.   end
  133.  
  134.   modem.broadcast(225, req_type, config.lock_id, detail)
  135.  
  136.   local start = computer.uptime()
  137.   while computer.uptime() - start < 2 do
  138.     local e = { event.pull(0.2, "modem_message") }
  139.     if e[1] == "modem_message" then
  140.       local _, _, _, _, _, res_type, server_lock_id, allowed, info = table.unpack(e)
  141.       if server_lock_id == config.lock_id then
  142.         if (req_type == "card_auth_req" and res_type == "card_auth_res") or
  143.            (req_type == "button_auth_req" and res_type == "button_auth_res") then
  144.           status = alter_status
  145.           return allowed, info
  146.         end
  147.       end
  148.     end
  149.   end
  150.  
  151.   status = alter_status
  152.   return false, "SERVER TIMEOUT"
  153. end
  154.  
  155. function drawAussenInterface(gpu, titel)
  156.   local w, h = gpu.getResolution()
  157.   gpu.setBackground(0x000000)
  158.   gpu.fill(1, 1, w, h, " ")
  159.   printZentriert(gpu, w, math.floor(h*0.2), "== " .. config.lock_name .. " ==", 0xFFFFFF, 0x000000)
  160.  
  161.   if status == "BEREIT" then
  162.     printZentriert(gpu, w, math.floor(h*0.4), "STATUS: BEREIT", 0x00FF00, 0x000000)
  163.     gpu.setBackground(0x333333)
  164.     local btn_y = math.floor(h*0.6)
  165.     gpu.fill(1, btn_y, w, h - btn_y + 1, " ")
  166.     printZentriert(gpu, w, btn_y + math.floor((h-btn_y)/2), "[ OEFFNEN ]", 0xFFFFFF, 0x333333)
  167.   else
  168.     printZentriert(gpu, w, math.floor(h*0.4), "STATUS:", 0xFF0000, 0x000000)
  169.     printZentriert(gpu, w, math.floor(h*0.6), status, 0xFF0000, 0x000000)
  170.   end
  171. end
  172.  
  173. local function drawInnenInterface(gpu)
  174.   local w, h = gpu.getResolution()
  175.   gpu.setBackground(0x000000)
  176.   gpu.fill(1, 1, w, h, " ")
  177.   printZentriert(gpu, w, 1, "=== INNENRAUM ===", 0xFFFFFF, 0x000000)
  178.  
  179.   if status ~= "BEREIT" then
  180.     printZentriert(gpu, w, math.floor(h/2), status, 0xFF0000, 0x000000)
  181.     return
  182.   end
  183.  
  184.   local trenn_y = math.floor(h * 0.5)
  185.  
  186.   if innen_entsperrt then
  187.     local halbe_breite = math.floor(w / 2)
  188.     gpu.setBackground(0x555500)
  189.     gpu.fill(1, 2, halbe_breite, trenn_y - 1, " ")
  190.     printZentriert(gpu, halbe_breite, math.floor(trenn_y/2)+1, "[BASIS]", 0xFFFFFF, 0x555500, 0)
  191.    
  192.     gpu.setBackground(0x005500)
  193.     gpu.fill(halbe_breite + 1, 2, w - halbe_breite, trenn_y - 1, " ")
  194.     printZentriert(gpu, w - halbe_breite, math.floor(trenn_y/2)+1, "[AUSSEN]", 0xFFFFFF, 0x005500, halbe_breite)
  195.   else
  196.     printZentriert(gpu, w, math.floor(trenn_y/2), "BITTE KARTE", 0xFFFF00, 0x000000)
  197.     printZentriert(gpu, w, math.floor(trenn_y/2)+1, "SCANNEN", 0xFFFF00, 0x000000)
  198.   end
  199.  
  200.   gpu.setBackground(0x222222)
  201.   gpu.fill(1, trenn_y + 1, w, h - trenn_y, " ")
  202.   local weg_text = (letzte_eintritts_seite == CABLE_UNGESICHERT) and "<- ZURUECK (RAUS)" or "<- ZURUECK (REIN)"
  203.   printZentriert(gpu, w, trenn_y + math.floor((h-trenn_y)/2), weg_text, 0xFFFFFF, 0x222222)
  204. end
  205.  
  206. local function initialisiereFesteGpuZuweisung()
  207.   local pool = {}
  208.   for _, g in ipairs(alle_gpus) do table.insert(pool, g) end
  209.   local function weiseZu(screen_addr)
  210.     for i, g in ipairs(pool) do
  211.       if g.bind(screen_addr) then
  212.         -- HIER KORRIGIERT: Erzwingt ein sauberes, klobiges 50x16 Breitbild-Verhältnis
  213.         g.setResolution(50, 16)
  214.         table.remove(pool, i)
  215.         return g
  216.       end
  217.     end
  218.     return nil
  219.   end
  220.   gpu_grau = weiseZu(config.grau)
  221.   gpu_schwarz = weiseZu(config.schwarz)
  222.   gpu_innen = weiseZu(config.innen)
  223.   if not gpu_grau or not gpu_schwarz or not gpu_innen then
  224.     error("Konnte den Monitoren keine Grafikkarte zuweisen!")
  225.   end
  226. end
  227.  
  228. local function updateAlleMonitore()
  229.   if not gpu_grau or not gpu_schwarz or not gpu_innen then return end
  230.   drawAussenInterface(gpu_grau, "AUSSEN")
  231.   drawAussenInterface(gpu_schwarz, "BASIS")
  232.   drawInnenInterface(gpu_innen)
  233. end
  234.  
  235. local function oeffneTuer(farbe, mitCycle)
  236.   if mitCycle then
  237.     status = "CYCLE..."
  238.     updateAlleMonitore()
  239.     rs.setBundledOutput(REDSTONE_SEITE, CABLE_CYCLE, 255)
  240.     os.sleep(5)
  241.     rs.setBundledOutput(REDSTONE_SEITE, CABLE_CYCLE, 0)
  242.   end
  243.  
  244.   status = "OEFFNE..."
  245.   updateAlleMonitore()
  246.   rs.setBundledOutput(REDSTONE_SEITE, farbe, 255)
  247.   os.sleep(12)
  248.   status = "OFFEN"
  249.   updateAlleMonitore()
  250.   os.sleep(5)
  251.   status = "SCHLIESSEN"
  252.   updateAlleMonitore()
  253.   rs.setBundledOutput(REDSTONE_SEITE, farbe, 0)
  254.   os.sleep(2)
  255.   status = "ZULOCKEN..."
  256.   updateAlleMonitore()
  257.   os.sleep(8)
  258.   status = "BEREIT"
  259.   innen_entsperrt = false
  260.   updateAlleMonitore()
  261. end
  262.  
  263. local function zeigeFehler(text)
  264.   if not gpu_innen then return end
  265.   local iw, ih = gpu_innen.getResolution()
  266.   gpu_innen.setBackground(0x550000)
  267.   gpu_innen.fill(1, 1, iw, ih, " ")
  268.   printZentriert(gpu_innen, iw, math.floor(ih/2), text, 0xFFFFFF, 0x550000)
  269.   os.sleep(2)
  270.   updateAlleMonitore()
  271. end
  272.  
  273. -------------------------------------------------------------------------------
  274. -- MAIN RUNTIME START
  275. -------------------------------------------------------------------------------
  276. ladeOderErstelleConfig()
  277. initialisiereFesteGpuZuweisung()
  278.  
  279. term.clear()
  280. print("[ONLINE] '" .. config.lock_name .. "' (" .. config.lock_id .. ") aktiv.")
  281. updateAlleMonitore()
  282.  
  283. while true do
  284.   local eventDaten = { event.pull() }
  285.   local id = eventDaten[1]
  286.  
  287.   if id == "touch" and status == "BEREIT" then
  288.     local screen_addr, x, y = eventDaten[2], eventDaten[3], eventDaten[4]
  289.    
  290.     -- AUSSEN
  291.     if screen_addr == config.grau then
  292.       local _, h = gpu_grau.getResolution()
  293.       if y >= math.floor(h*0.6) then
  294.         local erlaubt, fehler = frageServerAn("button_auth_req", "aussen")
  295.         if erlaubt then
  296.           letzte_eintritts_seite = CABLE_UNGESICHERT
  297.           oeffneTuer(CABLE_UNGESICHERT, false)
  298.         else zeigeFehler(fehler) end
  299.       end
  300.      
  301.     -- BASIS
  302.     elseif screen_addr == config.schwarz then
  303.       local _, h = gpu_schwarz.getResolution()
  304.       if y >= math.floor(h*0.6) then
  305.         local erlaubt, fehler = frageServerAn("button_auth_req", "basis")
  306.         if erlaubt then
  307.           letzte_eintritts_seite = CABLE_GESICHERT
  308.           oeffneTuer(CABLE_GESICHERT, false)
  309.         else zeigeFehler(fehler) end
  310.       end
  311.      
  312.     -- INNENRAUM
  313.     elseif screen_addr == config.innen then
  314.       local w, h = gpu_innen.getResolution()
  315.       local trenn_y = math.floor(h * 0.5)
  316.      
  317.       if y >= 2 and y <= trenn_y and innen_entsperrt then
  318.         if x <= math.floor(w / 2) then
  319.           oeffneTuer(CABLE_GESICHERT, true)
  320.         else
  321.           oeffneTuer(CABLE_UNGESICHERT, true)
  322.         end
  323.       elseif y > trenn_y then
  324.         local erlaubt, fehler = frageServerAn("button_auth_req", "rueckweg")
  325.         if erlaubt then
  326.           oeffneTuer(letzte_eintritts_seite, true)
  327.         else zeigeFehler(fehler) end
  328.       end
  329.     end
  330.    
  331.   elseif id == "magData" and status == "BEREIT" then
  332.     local card_id = eventDaten[4]
  333.     local erlaubt, fehler = frageServerAn("card_auth_req", card_id)
  334.     if erlaubt then
  335.       innen_entsperrt = true
  336.       updateAlleMonitore()
  337.     else
  338.       zeigeFehler(fehler)
  339.     end
  340.   end
  341. end
Advertisement
Add Comment
Please, Sign In to add comment