DorianH935

firm.lpsw

Feb 15th, 2026
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- LemonOS: Pocket Shell for Lemonphone
  2. -- by ChatGPT (GPT-5)
  3. -- Features: Persistent settings, live clock, distance-based signal bars, auto-netchat install
  4.  
  5. -- ===== CONFIG PATHS =====
  6. local CONFIG_PATH = "/lemonos.cfg"
  7. local NETCHAT_PATH = "/netchat"
  8. local STARTUP_PATH = "/startup.lua"
  9.  
  10. -- ===== FIRMWARE INFO =====
  11. local firmware = {
  12. device = "Lemonphone",
  13. version = "LemonOS 2.0"
  14. }
  15.  
  16. -- ===== SETTINGS =====
  17. local config = {
  18. username = "User",
  19. accentColor = colors.yellow,
  20. bgColor = colors.black,
  21. rednetSide = "back"
  22. }
  23.  
  24. -- ===== CONFIG LOAD/SAVE =====
  25. local function saveConfig()
  26. local file = fs.open(CONFIG_PATH, "w")
  27. if file then
  28. file.write(textutils.serialize(config))
  29. file.close()
  30. end
  31. end
  32.  
  33. local function loadConfig()
  34. if fs.exists(CONFIG_PATH) then
  35. local file = fs.open(CONFIG_PATH, "r")
  36. if file then
  37. local data = file.readAll()
  38. file.close()
  39. local ok, tbl = pcall(textutils.unserialize, data)
  40. if ok and type(tbl) == "table" then
  41. for k, v in pairs(tbl) do config[k] = v end
  42. end
  43. end
  44. end
  45. end
  46. loadConfig()
  47.  
  48. -- ===== AUTO-DOWNLOAD NETCHAT =====
  49. if not fs.exists(NETCHAT_PATH) then
  50. print("Downloading netchat...")
  51. if http then
  52. local ok, resp = pcall(http.get, "https://pastebin.com/raw/KeRK2UWE")
  53. if ok and resp then
  54. local content = resp.readAll()
  55. resp.close()
  56. local file = fs.open(NETCHAT_PATH, "w")
  57. file.write(content)
  58. file.close()
  59. print("netchat installed!")
  60. else
  61. print("Failed to download netchat.")
  62. end
  63. else
  64. print("HTTP API not enabled.")
  65. end
  66. -- set startup to run firm.lpsw
  67. local file = fs.open(STARTUP_PATH, "w")
  68. file.write('shell.run("firm.lpsw")')
  69. file.close()
  70. end
  71.  
  72. -- ===== INITIALIZE REDNET =====
  73. if peripheral.find("modem") then
  74. rednet.open(config.rednetSide)
  75. else
  76. rednet.close(config.rednetSide)
  77. end
  78.  
  79. -- ===== GLOBAL SIGNAL VARIABLE =====
  80. local signalStrength = 0 -- 1–3 bars
  81.  
  82. -- ===== UTILITIES =====
  83. local function centerText(y, text, color)
  84. local w = term.getSize()
  85. local x = math.floor((w - #text) / 2)
  86. term.setCursorPos(x, y)
  87. if color then term.setTextColor(color) end
  88. term.write(text)
  89. term.setTextColor(colors.white)
  90. end
  91.  
  92. -- Map distance to signal bars
  93. local function distanceToBars(distance)
  94. if distance <= 5 then
  95. return 3
  96. elseif distance <= 20 then
  97. return 2
  98. else
  99. return 1
  100. end
  101. end
  102.  
  103. -- ===== ASYNC SIGNAL UPDATER =====
  104. local function updateSignal()
  105. while true do
  106. local strength = 0
  107. if rednet.isOpen(config.rednetSide) then
  108. local peers = {}
  109. local ids = rednet.lookup("lemonphone_ping") or {}
  110. for _, id in ipairs(ids) do
  111. local ok = pcall(rednet.send, id, "ping", 0.1)
  112. if ok then
  113. local d = math.abs(os.getComputerID() - id) -- simple heuristic for distance
  114. table.insert(peers, d)
  115. end
  116. end
  117. if #peers > 0 then
  118. table.sort(peers)
  119. strength = distanceToBars(peers[1])
  120. end
  121. end
  122. signalStrength = strength
  123. sleep(5)
  124. end
  125. end
  126.  
  127. -- Draw signal bars based on latest value
  128. local function drawSignalBars()
  129. local barChar = "|"
  130. local maxBars = 3
  131. for i = 1, maxBars do
  132. if i <= signalStrength then
  133. term.setTextColor(colors.lime)
  134. else
  135. term.setTextColor(colors.gray)
  136. end
  137. term.write(barChar)
  138. end
  139. term.setTextColor(colors.white)
  140. end
  141.  
  142. -- ===== TOP BAR =====
  143. local function drawTopBar()
  144. local w = term.getSize()
  145. term.setCursorPos(1,1)
  146. term.setBackgroundColor(config.accentColor)
  147. term.clearLine()
  148.  
  149. -- Left: signal
  150. term.setCursorPos(2,1)
  151. if rednet.isOpen(config.rednetSide) then
  152. drawSignalBars()
  153. term.write(" Net")
  154. else
  155. term.setTextColor(colors.red)
  156. term.write("X NoNet")
  157. term.setTextColor(colors.black)
  158. end
  159.  
  160. -- Right: time/date
  161. local timeStr = textutils.formatTime(os.time(), true)
  162. local dateStr = os.date("%b %d")
  163. local clock = timeStr .. " | " .. dateStr
  164. term.setCursorPos(w - #clock - 1, 1)
  165. term.setTextColor(colors.black)
  166. term.write(clock)
  167. end
  168.  
  169. -- ===== MENU =====
  170. local function drawMenu(selected)
  171. local apps = {
  172. {name="Messages", cmd="netchat"},
  173. {name="Worm", cmd="worm"},
  174. {name="Falling Blocks", cmd="falling"},
  175. {name="Redirection", cmd="redirection"},
  176. {name="Settings", cmd="settings"},
  177. {name="About Lemonphone", cmd="about"},
  178. {name="Shutdown", cmd="shutdown"}
  179. }
  180.  
  181. local startY = 4
  182. term.setTextColor(colors.white)
  183. for i, app in ipairs(apps) do
  184. term.setCursorPos(4, startY + i - 1)
  185. if i == selected then
  186. term.setBackgroundColor(colors.gray)
  187. term.setTextColor(colors.black)
  188. else
  189. term.setBackgroundColor(config.bgColor)
  190. term.setTextColor(colors.white)
  191. end
  192. term.clearLine()
  193. term.setCursorPos(4, startY + i - 1)
  194. term.write(app.name)
  195. end
  196.  
  197. term.setBackgroundColor(config.bgColor)
  198. return apps
  199. end
  200.  
  201. -- ===== SETTINGS MENU =====
  202. local function openSettings()
  203. while true do
  204. term.setBackgroundColor(config.bgColor)
  205. term.clear()
  206. centerText(3, "Settings", config.accentColor)
  207. term.setCursorPos(2,5)
  208. term.write("1. Change Username")
  209. term.setCursorPos(2,6)
  210. term.write("2. Change Accent Color")
  211. term.setCursorPos(2,7)
  212. term.write("3. Back")
  213.  
  214. local _, key = os.pullEvent("key")
  215. if key == keys.one then
  216. term.setCursorPos(2,9)
  217. term.clearLine()
  218. term.write("Enter new username: ")
  219. config.username = read()
  220. saveConfig()
  221. elseif key == keys.two then
  222. term.setCursorPos(2,9)
  223. term.clearLine()
  224. term.write("Color name (e.g. yellow): ")
  225. local colorName = read()
  226. if colors[colorName] then
  227. config.accentColor = colors[colorName]
  228. saveConfig()
  229. else
  230. term.setCursorPos(2,10)
  231. term.write("Invalid color.")
  232. sleep(1)
  233. end
  234. elseif key == keys.three then
  235. return
  236. end
  237. end
  238. end
  239.  
  240. -- ===== ABOUT PAGE =====
  241. local function aboutLemonphone()
  242. term.setBackgroundColor(config.bgColor)
  243. term.clear()
  244. centerText(3,"About Lemonphone", config.accentColor)
  245. term.setCursorPos(2,5)
  246. term.write("Device: " .. firmware.device)
  247. term.setCursorPos(2,6)
  248. term.write("Firmware: " .. firmware.version)
  249. term.setCursorPos(2,8)
  250. term.write("Press any key to return...")
  251. os.pullEvent("key")
  252. end
  253.  
  254. -- ===== MAIN LOOP =====
  255. local function mainLoop()
  256. local selected = 1
  257. local refreshRate = 1.0
  258. local timer = os.startTimer(refreshRate)
  259.  
  260. while true do
  261. term.setBackgroundColor(config.bgColor)
  262. term.clear()
  263. drawTopBar()
  264. centerText(3, config.username .. "'s Lemonphone", config.accentColor)
  265. local apps = drawMenu(selected)
  266.  
  267. local event, key = os.pullEvent()
  268. if event == "key" then
  269. if key == keys.up then selected = math.max(1, selected-1)
  270. elseif key == keys.down then selected = math.min(#apps, selected+1)
  271. elseif key == keys.enter then
  272. local chosen = apps[selected]
  273. if chosen.name == "Settings" then openSettings()
  274. elseif chosen.name == "About Lemonphone" then aboutLemonphone()
  275. else
  276. term.setBackgroundColor(config.bgColor)
  277. term.clear()
  278. term.setCursorPos(1,1)
  279. shell.run(chosen.cmd)
  280. end
  281. end
  282. elseif event == "timer" then
  283. timer = os.startTimer(refreshRate)
  284. drawTopBar()
  285. end
  286. end
  287. end
  288.  
  289. -- ===== START SIGNAL UPDATER IN PARALLEL WITH MAIN LOOP =====
  290. parallel.waitForAny(updateSignal, mainLoop)
  291.  
Add Comment
Please, Sign In to add comment