cshwayze

Keypad Door Controller (ComputerCraft)

Oct 10th, 2025 (edited)
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.19 KB | Gaming | 0 0
  1. -- door_controller.lua
  2. -- Listens for OPEN messages for its tag and pulses redstone.
  3.  
  4. ------------- Config -------------
  5. local PROTOCOL = "doorAuth.v1"
  6. local OPEN_EVENT = "doorAuth.open.v1"
  7. local DOOR_TAG = "lobby" -- <--- set this to your door tag
  8. local REDSTONE_SIDE= "right" -- side to power (attach dust/door/pistons)
  9. local PULSE_DEFAULT= 3 -- fallback if server doesn't specify
  10. ---------------------------------
  11.  
  12. local function openModems()
  13. for _, side in ipairs(rs.getSides()) do
  14. if peripheral.getType(side) == "modem" then rednet.open(side) end
  15. end
  16. end
  17.  
  18. local function findServer()
  19. return rednet.lookup(PROTOCOL, "DoorAuthServer")
  20. end
  21.  
  22. local function pulseDoor(seconds)
  23. seconds = tonumber(seconds) or PULSE_DEFAULT
  24. redstone.setOutput(REDSTONE_SIDE, true)
  25. sleep(seconds)
  26. redstone.setOutput(REDSTONE_SIDE, false)
  27. end
  28.  
  29. local function registerLoop(expectedTag)
  30. while true do
  31. local server = findServer()
  32. if server then
  33. print("[DoorCtrl] Server #" .. server .. " found. Registering...")
  34. print("[DoorCtrl] Registering with tag '"..expectedTag.."'")
  35. rednet.send(server, {type="registerController", tag=expectedTag}, PROTOCOL)
  36.  
  37. local timer = os.startTimer(3)
  38. while true do
  39. local e = { os.pullEvent() }
  40. if e[1] == "rednet_message" then
  41. local id, msg, proto = e[2], e[3], e[4]
  42. if id == server and proto == PROTOCOL and type(msg)=="table" then
  43. if msg.type == "register_ack" and msg.tag == expectedTag then
  44. print("[DoorCtrl] Registered for tag '"..expectedTag.."'")
  45. return server
  46. elseif msg.type == "error" then
  47. print("[DoorCtrl] Registration error: "..tostring(msg.reason))
  48. sleep(2) ; break
  49. end
  50. end
  51. elseif e[1] == "timer" and e[2] == timer then
  52. print("[DoorCtrl] No ack, retrying...")
  53. break
  54. end
  55. end
  56. else
  57. print("[DoorCtrl] Waiting for server...")
  58. sleep(2)
  59. end
  60. end
  61. end
  62.  
  63. local function main()
  64. print(("[DoorCtrl] Tag='%s', side='%s'"):format(DOOR_TAG, REDSTONE_SIDE))
  65. openModems()
  66.  
  67. -- Register initially
  68. local server = registerLoop(DOOR_TAG)
  69. local lastHeartbeat = os.epoch("utc")
  70.  
  71. while true do
  72. local id, msg, proto = rednet.receive(OPEN_EVENT, 5)
  73.  
  74. if id then
  75. -- If server ID changed, re-register immediately
  76. if id ~= server then
  77. print("[DoorCtrl] Different server detected! Re-registering...")
  78. server = registerLoop(DOOR_TAG)
  79. end
  80.  
  81. if type(msg) == "table" and msg.type == "open" and msg.tag == DOOR_TAG then
  82. lastHeartbeat = os.epoch("utc")
  83. print(("[DoorCtrl] OPEN for '%s' (%ss)"):format(DOOR_TAG, msg.duration or PULSE_DEFAULT))
  84. pulseDoor(msg.duration)
  85. end
  86.  
  87. else
  88. -- No messages received for 5 seconds
  89. -- Check if server heartbeat expired
  90. if os.epoch("utc") - lastHeartbeat > 30000 then
  91. print("[DoorCtrl] Server silent for 30s, attempting re-register...")
  92. server = registerLoop(DOOR_TAG)
  93. lastHeartbeat = os.epoch("utc")
  94. end
  95. end
  96. end
  97. end
  98.  
  99.  
  100. main()
  101.  
Advertisement
Add Comment
Please, Sign In to add comment