cshwayze

Pocket Admin Auth Server for Doors (Computercraft)

Nov 29th, 2025 (edited)
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.99 KB | Gaming | 0 0
  1. -- admin_remote.lua (REMOTE OPEN + LOCKDOWN + LOG VIEW)
  2.  
  3. local PROTOCOL = "doorAuth.v1"
  4. local SERVER_NAME = "DoorAuthServer"
  5.  
  6. ---------------------------------------------------
  7. -- UTILS
  8. ---------------------------------------------------
  9. local function openModems()
  10. for _,side in ipairs(rs.getSides()) do
  11. if peripheral.getType(side)=="modem" then
  12. rednet.open(side)
  13. end
  14. end
  15. end
  16.  
  17. local function findServer()
  18. return rednet.lookup(PROTOCOL, SERVER_NAME)
  19. end
  20.  
  21. -- fallback hash (same as server)
  22. local function hash(str)
  23. local h=0
  24. for i=1,#str do h=(h*31 + str:byte(i)) % 2^31 end
  25. return tostring(h)
  26. end
  27.  
  28. local function setColor(col)
  29. if term.isColor and term.isColor() then
  30. term.setTextColor(col)
  31. end
  32. end
  33.  
  34. ---------------------------------------------------
  35. -- LOGIN
  36. ---------------------------------------------------
  37. local function login()
  38. term.clear()
  39. term.setCursorPos(1,1)
  40. print("=== DoorAuth Admin Remote ===")
  41. print("Enter Admin PIN:")
  42. local pin=read("*")
  43.  
  44. local server=findServer()
  45. if not server then
  46. print("Server not found!")
  47. sleep(1) return nil
  48. end
  49.  
  50. local stamp=tostring(os.epoch("utc"))
  51. local sig=hash(hash(pin) .. stamp)
  52.  
  53. rednet.send(server,{
  54. type="admin_login",
  55. timestamp=stamp,
  56. sig=sig
  57. },PROTOCOL)
  58.  
  59. local id,msg=rednet.receive(PROTOCOL,3)
  60. if id==server and msg and msg.type=="admin_login_ok" then
  61. sleep(0.4)
  62. term.clear()
  63. term.setCursorPos(1,1)
  64. return msg.token, pin
  65. end
  66.  
  67. print("Login failed.")
  68. sleep(1)
  69. return nil
  70. end
  71.  
  72. ---------------------------------------------------
  73. -- SEND ADMIN CMD
  74. ---------------------------------------------------
  75. local function adminCmd(token,cmdTable)
  76. local server=findServer()
  77. if not server then
  78. print("Server offline.")
  79. sleep(1)
  80. return nil
  81. end
  82.  
  83. cmdTable.type="admin_cmd"
  84. cmdTable.token=token
  85.  
  86. rednet.send(server,cmdTable,PROTOCOL)
  87. local _,msg=rednet.receive(PROTOCOL,3)
  88. return msg
  89. end
  90.  
  91. ---------------------------------------------------
  92. -- LOG VIEWER (Mode 3: interactive scroll)
  93. ---------------------------------------------------
  94. local function viewLogs(token)
  95. local msg = adminCmd(token, {cmd="logs"})
  96. if not msg or msg.type ~= "admin_logs" or type(msg.logs) ~= "table" then
  97. term.clear()
  98. term.setCursorPos(1,1)
  99. print("No logs or error fetching logs.")
  100. sleep(1.2)
  101. return
  102. end
  103.  
  104. local logs = msg.logs
  105. if #logs == 0 then
  106. term.clear()
  107. term.setCursorPos(1,1)
  108. print("No log entries yet.")
  109. sleep(1.2)
  110. return
  111. end
  112.  
  113. local maxVisible = 8
  114. local pos = math.max(#logs - maxVisible + 1, 1) -- start near newest
  115.  
  116. local function draw()
  117. term.clear()
  118. term.setCursorPos(1,1)
  119. print("=== Audit Logs ("..#logs.." entries) ===")
  120. print("W/S = scroll, Q = back")
  121.  
  122. local last = math.min(pos + maxVisible - 1, #logs)
  123. for i = pos, last do
  124. local e = logs[i]
  125. local lineY = 3 + (i - pos) + 1
  126. term.setCursorPos(1, lineY)
  127.  
  128. local label = string.format("%4d %s %-14s", i, e.time or "??:??", e.event or "?")
  129.  
  130. local tail = ""
  131. if e.tag then tail = tail .. " tag="..tostring(e.tag) end
  132. if e.ok ~= nil then
  133. tail = tail .. " "..(e.ok and "OK" or "FAIL")
  134. end
  135. if e.detail then
  136. tail = tail .. " "..tostring(e.detail)
  137. end
  138.  
  139. local color = colors.white
  140. if e.event == "pin_attempt" then
  141. color = e.ok and colors.lime or colors.red
  142. elseif e.event == "door_open" or e.event == "remote_open" then
  143. color = colors.cyan
  144. elseif e.event == "lockdown_on" or e.event == "lockdown_off" then
  145. color = colors.orange or colors.yellow
  146. elseif e.event == "admin_login" then
  147. color = e.ok and colors.lime or colors.red
  148. end
  149.  
  150. setColor(color)
  151. write(label.." "..tail)
  152. setColor(colors.white)
  153. end
  154.  
  155. local footerY = maxVisible + 5
  156. term.setCursorPos(1, footerY)
  157. print(string.format("Showing %d-%d of %d", pos, last, #logs))
  158. end
  159.  
  160. while true do
  161. draw()
  162. term.setCursorPos(1, maxVisible + 7)
  163. write("Command (W/S/Q): ")
  164. local inp = read()
  165. inp = string.lower(inp or "")
  166.  
  167. if inp == "w" then
  168. if pos > 1 then pos = pos - 1 end
  169. elseif inp == "s" then
  170. if pos < math.max(#logs - maxVisible + 1, 1) then
  171. pos = pos + 1
  172. end
  173. elseif inp == "q" or inp == "" then
  174. break
  175. end
  176. end
  177.  
  178. term.clear()
  179. term.setCursorPos(1,1)
  180. end
  181.  
  182. ---------------------------------------------------
  183. -- MAIN MENU
  184. ---------------------------------------------------
  185. local function mainMenu(token)
  186. while true do
  187. term.clear()
  188. term.setCursorPos(1,1)
  189. print([[=== DoorAuth Admin ===
  190.  
  191. 1) List Doors
  192. 2) Show Door
  193. 3) Add PIN
  194. 4) Delete PIN
  195. 5) Remove Door
  196. 6) Set OpenTime
  197. 7) Logout
  198. 8) Remote Open Door
  199. 9) LOCKDOWN ON
  200. 10) LOCKDOWN OFF
  201. 11) View Audit Logs
  202. ]])
  203.  
  204. write("Choose: ")
  205. local c=read()
  206.  
  207. if c=="1" then
  208. local msg=adminCmd(token,{cmd="list"})
  209. term.clear() term.setCursorPos(1,1)
  210. if msg and msg.doors then
  211. print("Doors:")
  212. for tag,data in pairs(msg.doors) do
  213. print(("%s (pins:%d, open:%s)"):format(tag,#data.pins,data.openTime))
  214. end
  215. else
  216. print("No response.")
  217. end
  218. print("\nPress Enter…") read()
  219.  
  220. elseif c=="2" then
  221. write("Door tag: ") local tag=read()
  222. local msg=adminCmd(token,{cmd="show",tag=tag})
  223. term.clear() term.setCursorPos(1,1)
  224. if msg and msg.door then
  225. print("Door:",tag)
  226. print("OpenTime:",msg.door.openTime)
  227. print("Pins:")
  228. for _,p in ipairs(msg.door.pins) do print(" "..p) end
  229. else
  230. print("No such door.")
  231. end
  232. print("\nPress Enter…") read()
  233.  
  234. elseif c=="3" then
  235. write("Door tag: ") local tag=read()
  236. write("New PIN: ") local pin=read()
  237. local msg=adminCmd(token,{cmd="add",tag=tag,pin=pin})
  238. term.clear() term.setCursorPos(1,1)
  239. print(msg and msg.ok and "Added." or "Already exists or error.")
  240. sleep(1)
  241.  
  242. elseif c=="4" then
  243. write("Door tag: ") local tag=read()
  244. write("PIN to remove: ") local pin=read()
  245. local msg=adminCmd(token,{cmd="del",tag=tag,pin=pin})
  246. term.clear() term.setCursorPos(1,1)
  247. print(msg and msg.ok and "Removed." or "Not found or error.")
  248. sleep(1)
  249.  
  250. elseif c=="5" then
  251. write("Door tag: ") local tag=read()
  252. local msg=adminCmd(token,{cmd="remove",tag=tag})
  253. term.clear() term.setCursorPos(1,1)
  254. print("Door removed.")
  255. sleep(1)
  256.  
  257. elseif c=="6" then
  258. write("Door tag: ") local tag=read()
  259. write("Seconds: ") local sec=read()
  260. local msg=adminCmd(token,{cmd="opentime",tag=tag,seconds=sec})
  261. term.clear() term.setCursorPos(1,1)
  262. print("Updated.")
  263. sleep(1)
  264.  
  265. elseif c=="8" then
  266. write("Door tag to open: ") local tag=read()
  267. local msg=adminCmd(token,{cmd="open",tag=tag})
  268. term.clear() term.setCursorPos(1,1)
  269. if msg and msg.ok then
  270. print("Door opened.")
  271. else
  272. print("Blocked (lockdown active or error).")
  273. end
  274. sleep(1)
  275.  
  276. elseif c=="9" then
  277. local msg=adminCmd(token,{cmd="lockdown_on"})
  278. term.clear() term.setCursorPos(1,1)
  279. print("LOCKDOWN ENABLED")
  280. sleep(1)
  281.  
  282. elseif c=="10" then
  283. local msg=adminCmd(token,{cmd="lockdown_off"})
  284. term.clear() term.setCursorPos(1,1)
  285. print("Lockdown disabled.")
  286. sleep(1)
  287.  
  288. elseif c=="11" then
  289. viewLogs(token)
  290.  
  291. elseif c=="7" then
  292. term.clear() term.setCursorPos(1,1)
  293. print("Logged out.")
  294. sleep(0.4)
  295. term.clear() term.setCursorPos(1,1)
  296. return
  297. end
  298. end
  299. end
  300.  
  301. ---------------------------------------------------
  302. -- ENTRY
  303. ---------------------------------------------------
  304. openModems()
  305.  
  306. while true do
  307. local token=login()
  308. if token then mainMenu(token) end
  309. end
  310.  
Advertisement
Add Comment
Please, Sign In to add comment