Guest User

firewolf 27-2-13 hotfix

a guest
Feb 27th, 2013
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 86.58 KB | None | 0 0
  1.  
  2. --
  3. -- Firewolf Website Browser
  4. -- Made by GravityScore and 1lann
  5. -- License found here: https://raw.github.com/1lann/Firewolf/master/LICENSE
  6. --
  7. -- Original Concept From RednetExplorer 2.4.1
  8. -- RednetExplorer Made by ComputerCraftFan11
  9. --
  10.  
  11.  
  12. -- -------- Variables
  13.  
  14. -- Version
  15. local version = "2.4"
  16. local build = 6
  17. local browserAgentTemplate = "Firewolf " .. version
  18. browserAgent = browserAgentTemplate
  19. local tArgs = {...}
  20.  
  21. -- Server Identification
  22. local serverID = "other"
  23. local serverList = {experimental = "Experimental", other = "Other"}
  24.  
  25. -- Updating
  26. local autoupdate = "true"
  27. local noInternet = false
  28.  
  29. -- Resources
  30. local graphics = {}
  31. local files = {}
  32. local w, h = term.getSize()
  33.  
  34. -- Debugging
  35. local debugFile = nil
  36.  
  37. -- Environment
  38. local oldpullevent = os.pullEvent
  39. local oldEnv = {}
  40. local env = {}
  41. local backupEnv = {}
  42.  
  43. local api = {}
  44. local override = {}
  45. local antivirus = {}
  46.  
  47. -- Themes
  48. local theme = {}
  49.  
  50. -- Databases
  51. local blacklist = {}
  52. local whitelist = {}
  53. local dnsDatabase = {[1] = {}, [2] = {}}
  54.  
  55. -- Website Loading
  56. local pages = {}
  57. local errorPages = {}
  58.  
  59. local website = ""
  60. local homepage = ""
  61. local timeout = 0.2
  62. local loadingRate = 0
  63. local openAddressBar = true
  64. local menuBarOpen = false
  65.  
  66. -- Protocols
  67. local curProtocol = {}
  68. local protocols = {}
  69.  
  70. -- History
  71. local addressBarHistory = {}
  72.  
  73. -- Events
  74. local event_loadWebsite = "firewolf_loadWebsiteEvent"
  75. local event_exitWebsite = "firewolf_exitWebsiteEvent"
  76. local event_redirect = "firewolf_redirectEvent"
  77. local event_exitApp = "firewolf_exitAppEvent"
  78.  
  79. -- Download URLs
  80. local firewolfURL = "https://raw.github.com/1lann/Firewolf/master/entities/other.lua"
  81. local a = "release"
  82. if serverID == "experimental" then a = "experimental" end
  83. local serverURL = "https://raw.github.com/1lann/firewolf/master/server/server-" .. a .. ".lua"
  84. local buildURL = "https://raw.github.com/1lann/firewolf/master/build"
  85.  
  86. -- Data Locations
  87. local rootFolder = "/.Firewolf_Data"
  88. local cacheFolder = rootFolder .. "/cache"
  89. local serverFolder = rootFolder .. "/servers"
  90. local websiteDataFolder = rootFolder .. "/website_data"
  91. local themeLocation = rootFolder .. "/theme"
  92. local serverLocation = rootFolder .. "/server_software"
  93. local settingsLocation = rootFolder .. "/settings"
  94. local debugLogLocation = "/firewolf-log"
  95. local firewolfLocation = "/" .. shell.getRunningProgram()
  96.  
  97. local userBlacklist = rootFolder .. "/user_blacklist"
  98. local userWhitelist = rootFolder .. "/user_whitelist"
  99.  
  100.  
  101. -- -------- Utilities
  102.  
  103. local function debugLog(n, ...)
  104. local lArgs = {...}
  105. if debugFile then
  106. if n == nil then n = "" end
  107. debugFile:write("\n" .. tostring(n) .. " : ")
  108. for k, v in pairs(lArgs) do
  109. if type(v) == "string" or type(v) == "number" or type(v) == nil or
  110. type(v) == "boolean" then
  111. debugFile:write(tostring(v) .. ", ")
  112. else debugFile:write("type-" .. type(v) .. ", ") end
  113. end
  114. end
  115. end
  116.  
  117. local function modRead(properties)
  118. local w, h = term.getSize()
  119. local defaults = {replaceChar = nil, history = nil, visibleLength = nil, textLength = nil,
  120. liveUpdates = nil, exitOnKey = nil}
  121. if not properties then properties = {} end
  122. for k, v in pairs(defaults) do if not properties[k] then properties[k] = v end end
  123. if properties.replaceChar then properties.replaceChar = properties.replaceChar:sub(1, 1) end
  124. if not properties.visibleLength then properties.visibleLength = w end
  125.  
  126. local sx, sy = term.getCursorPos()
  127. local line = ""
  128. local pos = 0
  129. local historyPos = nil
  130.  
  131. local function redraw(repl)
  132. local scroll = 0
  133. if properties.visibleLength and sx + pos > properties.visibleLength + 1 then
  134. scroll = (sx + pos) - (properties.visibleLength + 1)
  135. end
  136.  
  137. term.setCursorPos(sx, sy)
  138. local a = repl or properties.replaceChar
  139. if a then term.write(string.rep(a, line:len() - scroll))
  140. else term.write(line:sub(scroll + 1, -1)) end
  141. term.setCursorPos(sx + pos - scroll, sy)
  142. end
  143.  
  144. local function sendLiveUpdates(event, ...)
  145. if type(properties.liveUpdates) == "function" then
  146. local ox, oy = term.getCursorPos()
  147. local a, data = properties.liveUpdates(line, event, ...)
  148. if a == true and data == nil then
  149. term.setCursorBlink(false)
  150. return line
  151. elseif a == true and data ~= nil then
  152. term.setCursorBlink(false)
  153. return data
  154. end
  155. term.setCursorPos(ox, oy)
  156. end
  157. end
  158.  
  159. local a = sendLiveUpdates("delete")
  160. if a then return a end
  161. term.setCursorBlink(true)
  162. while true do
  163. local e, but, x, y, p4, p5 = os.pullEvent()
  164.  
  165. if e == "char" then
  166. local s = false
  167. if properties.textLength and line:len() < properties.textLength then s = true
  168. elseif not properties.textLength then s = true end
  169.  
  170. local canType = true
  171. if not properties.grantPrint and properties.refusePrint then
  172. local canTypeKeys = {}
  173. if type(properties.refusePrint) == "table" then
  174. for _, v in pairs(properties.refusePrint) do
  175. table.insert(canTypeKeys, tostring(v):sub(1, 1))
  176. end
  177. elseif type(properties.refusePrint) == "string" then
  178. for char in properties.refusePrint:gmatch(".") do
  179. table.insert(canTypeKeys, char)
  180. end
  181. end
  182. for _, v in pairs(canTypeKeys) do if but == v then canType = false end end
  183. elseif properties.grantPrint then
  184. canType = false
  185. local canTypeKeys = {}
  186. if type(properties.grantPrint) == "table" then
  187. for _, v in pairs(properties.grantPrint) do
  188. table.insert(canTypeKeys, tostring(v):sub(1, 1))
  189. end
  190. elseif type(properties.grantPrint) == "string" then
  191. for char in properties.grantPrint:gmatch(".") do
  192. table.insert(canTypeKeys, char)
  193. end
  194. end
  195. for _, v in pairs(canTypeKeys) do if but == v then canType = true end end
  196. end
  197.  
  198. if s and canType then
  199. line = line:sub(1, pos) .. but .. line:sub(pos + 1, -1)
  200. pos = pos + 1
  201. redraw()
  202. end
  203. elseif e == "key" then
  204. if but == keys.enter then
  205. break
  206. elseif but == keys.left then
  207. if pos > 0 then pos = pos - 1 redraw() end
  208. elseif but == keys.right then
  209. if pos < line:len() then pos = pos + 1 redraw() end
  210. elseif (but == keys.up or but == keys.down) and properties.history and
  211. #properties.history > 0 then
  212. redraw(" ")
  213. if but == keys.up then
  214. if historyPos == nil and #properties.history > 0 then
  215. historyPos = #properties.history
  216. elseif historyPos > 1 then
  217. historyPos = historyPos - 1
  218. end
  219. elseif but == keys.down then
  220. if historyPos == #properties.history then historyPos = nil
  221. elseif historyPos ~= nil then historyPos = historyPos + 1 end
  222. end
  223.  
  224. if properties.history and historyPos then
  225. line = properties.history[historyPos]
  226. pos = line:len()
  227. else
  228. line = ""
  229. pos = 0
  230. end
  231.  
  232. redraw()
  233. local a = sendLiveUpdates("history")
  234. if a then return a end
  235. elseif but == keys.backspace and pos > 0 then
  236. redraw(" ")
  237. line = line:sub(1, pos - 1) .. line:sub(pos + 1, -1)
  238. pos = pos - 1
  239. redraw()
  240. local a = sendLiveUpdates("delete")
  241. if a then return a end
  242. elseif but == keys.home then
  243. pos = 0
  244. redraw()
  245. elseif but == keys.delete and pos < line:len() then
  246. redraw(" ")
  247. line = line:sub(1, pos) .. line:sub(pos + 2, -1)
  248. redraw()
  249. local a = sendLiveUpdates("delete")
  250. if a then return a end
  251. elseif but == keys["end"] then
  252. pos = line:len()
  253. redraw()
  254. elseif properties.exitOnKey then
  255. if but == properties.exitOnKey or (properties.exitOnKey == "control" and
  256. (but == 29 or but == 157)) then
  257. term.setCursorBlink(false)
  258. return nil
  259. end
  260. end
  261. end
  262.  
  263. local a = sendLiveUpdates(e, but, x, y, p4, p5)
  264. if a then return a end
  265. end
  266.  
  267. term.setCursorBlink(false)
  268. if line ~= nil then line = line:gsub("^%s*(.-)%s*$", "%1") end
  269. return line
  270. end
  271.  
  272.  
  273. -- -------- Environment and APIs
  274.  
  275. local function isAdvanced()
  276. return term.isColor and term.isColor()
  277. end
  278.  
  279. local function clearPage(site, color, redraw, tcolor)
  280. -- Site titles
  281. local titles = {firewolf = "Firewolf Homepage", ["server/rdnt"] = "RDNT Server Management",
  282. ["server/http"] = "HTTP Server Management", help = "Firewolf Help",
  283. settings = "Firewolf Settings", credits = "Firewolf Credits",
  284. crash = "Website Has Crashed!", overspeed = "Too Fast!"}
  285. local title = titles[site]
  286.  
  287. -- Clear
  288. term.setBackgroundColor(color or colors.black)
  289. term.setTextColor(colors[theme["address-bar-text"]])
  290. if redraw ~= true then term.clear() end
  291.  
  292. if not menuBarOpen then
  293. term.setBackgroundColor(colors[theme["address-bar-background"]])
  294. term.setCursorPos(2, 1)
  295. term.clearLine()
  296. local a = site
  297. if a:len() > w - 10 then a = a:sub(1, 38) .. "..." end
  298. if curProtocol == protocols.rdnt then write("rdnt://" .. a)
  299. elseif curProtocol == protocols.http then write("http://" .. a) end
  300.  
  301. if title ~= nil then
  302. term.setCursorPos(w - title:len() - 1, 1)
  303. write(title)
  304. end if isAdvanced() then
  305. term.setCursorPos(w, 1)
  306. term.setBackgroundColor(colors[theme["top-box"]])
  307. term.setTextColor(colors[theme["text-color"]])
  308. write("<")
  309. end
  310.  
  311. term.setBackgroundColor(color or colors.black)
  312. if tcolor then term.setTextColor(tcolor)
  313. else term.setTextColor(colors.white) end
  314. else
  315. term.setCursorPos(1, 1)
  316. term.setBackgroundColor(colors[theme["top-box"]])
  317. term.setTextColor(colors[theme["text-color"]])
  318. term.clearLine()
  319. write("> [- Exit Firewolf -] [- Incorrect Website -] ")
  320. end
  321.  
  322. print("")
  323. end
  324.  
  325. local function printWithType(t, func)
  326. if type(t) == "table" then
  327. for k, v in pairs(t) do
  328. env.pcall(function() printWithType(v, func) end)
  329. end
  330. else
  331. func(tostring(t))
  332. end
  333. end
  334.  
  335. -- Drawing Functions
  336. api.centerWrite = function(text)
  337. local x, y = term.getCursorPos()
  338. printWithType(text, function(t)
  339. term.setCursorPos(math.ceil((w + 1)/2 - t:len()/2), y)
  340. write(t)
  341. end)
  342. end
  343.  
  344. api.centerPrint = function(text)
  345. api.centerWrite(text)
  346. print()
  347. end
  348.  
  349. api.leftWrite = function(text)
  350. local x, y = term.getCursorPos()
  351. printWithType(text, function(t)
  352. term.setCursorPos(1, y)
  353. write(text)
  354. end)
  355. end
  356.  
  357. api.leftPrint = function(text)
  358. api.leftWrite(text)
  359. print()
  360. end
  361.  
  362. api.rightWrite = function(text)
  363. local x, y = term.getCursorPos()
  364. printWithType(text, function(t)
  365. term.setCursorPos(w - text:len() + 1, y)
  366. write(text)
  367. end)
  368. end
  369.  
  370. api.rightPrint = function(text)
  371. api.rightWrite(text)
  372. print()
  373. end
  374.  
  375. -- Server Interation Functions
  376.  
  377. api.loadFileFromServer = function(path)
  378. if type(path) ~= "string" then error("loadFile: expected string") end
  379. sleep(0.05)
  380. if path:sub(1, 1) == "/" then path = path:sub(2, -1) end
  381. local id, content = curProtocol.getWebsite(website .. "/" .. path)
  382. if id then
  383. return content
  384. end
  385. return nil
  386. end
  387.  
  388. api.ioReadFileFromServer = function(path)
  389. local content = api.loadFileFromServer(path)
  390. if content then
  391. local f = env.io.open(rootFolder .. "/temp_file", "w")
  392. f:write(content)
  393. f:close()
  394. local fi = env.io.open(rootFolder .. "/temp_file", "r")
  395. return fi
  396. end
  397. return nil
  398. end
  399.  
  400. api.loadImageFromServer = function(path)
  401. local content = api.loadFileFromServer(path)
  402. if content then
  403. local f = env.io.open(rootFolder .. "/temp_file", "w")
  404. f:write(content)
  405. f:close()
  406.  
  407. local image = paintutils.loadImage(rootFolder .. "/temp_file")
  408. env.fs.delete(f:close())
  409. return image
  410. end
  411. return nil
  412. end
  413.  
  414. api.writeDataFile = function(path, content)
  415. if type(path) ~= "string" or type(content) ~= "string" then
  416. error("writeDataFile: expected string, string") end
  417. if path:sub(1, 1) == "/" then path = path:sub(2, -1) end
  418. local dataPath = websiteDataFolder .. "/" .. path:gsub("/", "$slazh$")
  419.  
  420. if env.fs.isReadOnly(dataPath) then return false end
  421. if env.fs.exists(dataPath) then env.fs.delete(dataPath) end
  422. local f = env.io.open(dataPath, "w")
  423. if not f then return false end
  424. f:write(content)
  425. f:close()
  426. return true
  427. end
  428.  
  429. api.readDataFile = function(path)
  430. if type(path) ~= "string" then error("readDataFile: expected string") end
  431. if path:sub(1, 1) == "/" then path = path:sub(2, -1) end
  432. local dataPath = websiteDataFolder .. "/" .. path:gsub("/", "$slazh$")
  433.  
  434. if env.fs.isDir(dataPath) then env.fs.delete(dataPath) end
  435. if env.fs.exists(dataPath) then
  436. local f = env.io.open(dataPath, "r")
  437. local cont = f:read("*a")
  438. f:close()
  439. return cont
  440. end
  441. return nil
  442. end
  443.  
  444. api.saveFileToUserComputer = function(content)
  445. if type(content) ~= "string" then error("saveFileToUserComputer: expected string") end
  446. local oldback, oldtext = term.getBackgroundColor(), term.getTextColor()
  447. local ox, oy = term.getCursorPos()
  448.  
  449. term.setTextColor(colors[theme["text-color"]])
  450. term.setBackgroundColor(colors[theme["background"]])
  451. term.clear()
  452. term.setCursorPos(1, 1)
  453. term.setBackgroundColor(colors[theme["top-box"]])
  454. print("")
  455. leftPrint(string.rep(" ", 20))
  456. leftPrint(" Save File Request ")
  457. leftPrint(string.rep(" ", 20))
  458. print("")
  459.  
  460. term.setBackgroundColor(colors[theme["bottom-box"]])
  461. for i = 1, 11 do rightPrint(string.rep(" ", 36)) end
  462. term.setCursorPos(1, 7)
  463. rightPrint("The website: ")
  464. rightPrint(website .. " ")
  465. rightPrint("Is requesting to save a file ")
  466. rightPrint("to your comptuer. ")
  467.  
  468. local ret = nil
  469. local opt = prompt({{"Save File", w - 16, 12}, {"Cancel", w - 13, 13}}, "vertical")
  470. if opt == "Save File" then
  471. while true do
  472. term.setCursorPos(1, 15)
  473. rightWrite(string.rep(" ", 36))
  474. term.setCursorPos(w - 34, 15)
  475. write("Path: /")
  476. local p = read()
  477.  
  478. term.setCursorPos(1, 15)
  479. rightWrite(string.rep(" ", 36))
  480. if p == "" or p == nil then
  481. rightWrite("File Name Empty! Cancelling... ")
  482. break
  483. elseif fs.exists("/" .. p) then
  484. rightWrite("File Already Exists! ")
  485. else
  486. rightWrite("File Saved! ")
  487. ret = "/" .. p
  488. break
  489. end
  490.  
  491. openAddressBar = false
  492. sleep(1.3)
  493. openAddressBar = true
  494. end
  495. elseif opt == "Cancel" then
  496. term.setCursorPos(1, 15)
  497. rightWrite("Saving Cancelled! ")
  498. end
  499.  
  500. openAddressBar = false
  501. sleep(1.3)
  502. openAddressBar = true
  503.  
  504. term.setBackgroundColor(oldback or colors.black)
  505. term.setTextColor(oldtext or colors.white)
  506. term.clear()
  507. term.setCursorPos(ox, oy)
  508. return ret
  509. end
  510.  
  511. api.urlDownload = function(url)
  512. if type(url) ~= "string" then error("download: expected string") end
  513. local source = nil
  514. http.request(url)
  515. local a = os.startTimer(10)
  516. while true do
  517. local e, surl, handle = os.pullEvent()
  518. if e == "http_success" then
  519. source = handle.readAll()
  520. break
  521. elseif e == "http_failure" or (e == "timer" and surl == a) then
  522. break
  523. end
  524. end
  525.  
  526. if type(source) == "string" then
  527. local saveFunc = api.saveFileToUserComputer
  528. env.setfenv(saveFunc, override)
  529. return saveFunc(source)
  530. else return nil end
  531. end
  532.  
  533. api.pastebinDownload = function(code)
  534. return api.urlDownload("http://pastebin.com/raw.php?i=" .. tostring(code))
  535. end
  536.  
  537. -- Redirect
  538. api.redirect = function(url)
  539. if type(url) ~= "string" then url = "home" end
  540. os.queueEvent(event_redirect, url:gsub("rdnt://"):gsub("http://"))
  541. error()
  542. end
  543.  
  544. -- Theme Function
  545. api.themeColor = function(tag, default)
  546. if type(tag) ~= "string" then error("themeColor: expected string") end
  547. if theme[tag] then
  548. return colors[theme[tag]]
  549. elseif defaultTheme[tag] then
  550. return colors[defaultTheme[tag]]
  551. else
  552. return default or colors.white
  553. end
  554. end
  555.  
  556. api.themeColour = function(tag, default)
  557. return api.themeColor(tag, default)
  558. end
  559.  
  560. -- Prompt Software
  561. api.prompt = function(list, dir)
  562. if isAdvanced() then
  563. for _, v in pairs(list) do
  564. if v.bg then term.setBackgroundColor(v.bg) end
  565. if v.tc then term.setTextColor(v.tc) end
  566. if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 6)/2) end
  567.  
  568. term.setCursorPos(v[2], v[3])
  569. write("[- " .. v[1])
  570. term.setCursorPos(v[2] + v[1]:len() + 3, v[3])
  571. write(" -]")
  572. end
  573.  
  574. while true do
  575. local e, but, x, y = os.pullEvent()
  576. if e == "mouse_click" then
  577. for _, v in pairs(list) do
  578. if x >= v[2] and x <= v[2] + v[1]:len() + 5 and y == v[3] then
  579. return v[1]
  580. end
  581. end
  582. end
  583. end
  584. else
  585. for _, v in pairs(list) do
  586. term.setBackgroundColor(colors.black)
  587. term.setTextColor(colors.white)
  588. if v[2] == -1 then v[2] = math.ceil((w + 1)/2 - (v[1]:len() + 4)/2) end
  589.  
  590. term.setCursorPos(v[2], v[3])
  591. write(" " .. v[1])
  592. term.setCursorPos(v[2] + v[1]:len() + 2, v[3])
  593. write(" ")
  594. end
  595.  
  596. local key1, key2 = 200, 208
  597. if dir == "horizontal" then key1, key2 = 203, 205 end
  598.  
  599. local curSel = 1
  600. term.setCursorPos(list[curSel][2], list[curSel][3])
  601. write("[")
  602. term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])
  603. write("]")
  604.  
  605. while true do
  606. local e, key = os.pullEvent()
  607. term.setCursorPos(list[curSel][2], list[curSel][3])
  608. write(" ")
  609. term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])
  610. write(" ")
  611. if e == "key" and key == key1 and curSel > 1 then
  612. curSel = curSel - 1
  613. elseif e == "key" and key == key2 and curSel < #list then
  614. curSel = curSel + 1
  615. elseif e == "key" and key == 28 then
  616. return list[curSel][1]
  617. end
  618. term.setCursorPos(list[curSel][2], list[curSel][3])
  619. write("[")
  620. term.setCursorPos(list[curSel][2] + list[curSel][1]:len() + 3, list[curSel][3])
  621. write("]")
  622. end
  623. end
  624. end
  625.  
  626. api.scrollingPrompt = function(list, x, y, len, width)
  627. local wid = width
  628. if wid == nil then wid = w - 3 end
  629.  
  630. local function updateDisplayList(items, loc, len)
  631. local ret = {}
  632. for i = 1, len do
  633. local item = items[i + loc - 1]
  634. if item ~= nil then table.insert(ret, item) end
  635. end
  636. return ret
  637. end
  638.  
  639. if isAdvanced() then
  640. local function draw(a)
  641. for i, v in ipairs(a) do
  642. term.setCursorPos(x, y + i - 1)
  643. write(string.rep(" ", wid))
  644. term.setCursorPos(x, y + i - 1)
  645. write("[ " .. v:sub(1, wid - 5))
  646. term.setCursorPos(wid + x - 2, y + i - 1)
  647. write(" ]")
  648. end
  649. end
  650.  
  651. local loc = 1
  652. local disList = updateDisplayList(list, loc, len)
  653. draw(disList)
  654.  
  655. while true do
  656. local e, but, clx, cly = os.pullEvent()
  657. if e == "key" and but == 200 and loc > 1 then
  658. loc = loc - 1
  659. disList = updateDisplayList(list, loc, len)
  660. draw(disList)
  661. elseif e == "key" and but == 208 and loc + len - 1 < #list then
  662. loc = loc + 1
  663. disList = updateDisplayList(list, loc, len)
  664. draw(disList)
  665. elseif e == "mouse_scroll" and but > 0 and loc + len - 1 < #list then
  666. loc = loc + but
  667. disList = updateDisplayList(list, loc, len)
  668. draw(disList)
  669. elseif e == "mouse_scroll" and but < 0 and loc > 1 then
  670. loc = loc + but
  671. disList = updateDisplayList(list, loc, len)
  672. draw(disList)
  673. elseif e == "mouse_click" then
  674. for i, v in ipairs(disList) do
  675. if clx >= x and clx <= x + wid and cly == i + y - 1 then
  676. return v
  677. end
  678. end
  679. end
  680. end
  681. else
  682. local function draw(a)
  683. for i, v in ipairs(a) do
  684. term.setCursorPos(x, y + i - 1)
  685. write(string.rep(" ", wid))
  686. term.setCursorPos(x, y + i - 1)
  687. write("[ ] " .. v:sub(1, wid - 5))
  688. end
  689. end
  690.  
  691. local loc = 1
  692. local curSel = 1
  693. local disList = updateDisplayList(list, loc, len)
  694. draw(disList)
  695. term.setCursorPos(x + 1, y + curSel - 1)
  696. write("x")
  697.  
  698. while true do
  699. local e, key = os.pullEvent()
  700. term.setCursorPos(x + 1, y + curSel - 1)
  701. write(" ")
  702. if e == "key" and key == 200 then
  703. if curSel > 1 then
  704. curSel = curSel - 1
  705. elseif loc > 1 then
  706. loc = loc - 1
  707. disList = updateDisplayList(list, loc, len)
  708. draw(disList)
  709. end
  710. elseif e == "key" and key == 208 then
  711. if curSel < #disList then
  712. curSel = curSel + 1
  713. elseif loc + len - 1 < #list then
  714. loc = loc + 1
  715. disList = updateDisplayList(list, loc, len)
  716. draw(disList)
  717. end
  718. elseif e == "key" and key == 28 then
  719. return list[curSel + loc - 1]
  720. end
  721. term.setCursorPos(x + 1, y + curSel - 1)
  722. write("x")
  723. end
  724. end
  725. end
  726.  
  727. api.clearArea = function() api.clearPage(website) end
  728. api.cPrint = function(text) api.centerPrint(text) end
  729. api.cWrite = function(text) api.centerWrite(text) end
  730. api.lPrint = function(text) api.leftPrint(text) end
  731. api.lWrite = function(text) api.leftWrite(text) end
  732. api.rPrint = function(text) api.rightPrint(text) end
  733. api.rWrite = function(text) api.rightWrite(text) end
  734.  
  735. local pullevent = function(data)
  736. while true do
  737. local e, p1, p2, p3, p4, p5 = os.pullEventRaw()
  738. if e == event_exitWebsite or e == "terminate" then
  739. error()
  740. end
  741.  
  742. if data ~= "" and e == data then return e, p1, p2, p3, p4, p5
  743. else return e, p1, p2, p3, p4, p5 end
  744. end
  745. end
  746.  
  747. -- Set Environment
  748. for k, v in pairs(getfenv(0)) do env[k] = v end
  749. for k, v in pairs(getfenv(1)) do env[k] = v end
  750. for k, v in pairs(env) do oldEnv[k] = v end
  751. for k, v in pairs(api) do env[k] = v end
  752. for k, v in pairs(env) do backupEnv[k] = v end
  753.  
  754. oldEnv["os"]["pullEvent"] = oldpullevent
  755. env["os"]["pullEvent"] = pullevent
  756. os.pullEvent = pullevent
  757.  
  758.  
  759. -- -------- Website Overrides
  760.  
  761. for k, v in pairs(env) do override[k] = v end
  762. local curtext, curbackground = colors.white, colors.black
  763. override.term = {}
  764. for k, v in pairs(env.term) do override.term[k] = v end
  765.  
  766. override.term.getSize = function()
  767. local a, b = env.term.getSize()
  768. return a, b - 1
  769. end
  770.  
  771. override.term.setCursorPos = function(x, y)
  772. return env.term.setCursorPos(x, y + 1)
  773. end
  774.  
  775. override.term.getCursorPos = function()
  776. local x, y = env.term.getCursorPos()
  777. return x, y + 1
  778. end
  779.  
  780. override.term.getBackgroundColor = function()
  781. return curbackground
  782. end
  783.  
  784. override.term.getBackgroundColour = function()
  785. return override.term.getBackgroundColor()
  786. end
  787.  
  788. override.term.setBackgroundColor = function(col)
  789. curbackground = col
  790. return env.term.setBackgroundColor(col)
  791. end
  792.  
  793. override.term.setBackgroundColour = function(col)
  794. return override.term.setBackgroundColor(col)
  795. end
  796.  
  797. override.term.getTextColor = function()
  798. return curtext
  799. end
  800.  
  801. override.term.getTextColour = function()
  802. return override.term.getTextColor()
  803. end
  804.  
  805. override.term.setTextColor = function(col)
  806. curtext = col
  807. return env.term.setTextColor(col)
  808. end
  809.  
  810. override.term.setTextColour = function(col)
  811. return override.term.setTextColor(col)
  812. end
  813.  
  814. override.term.clear = function()
  815. local x, y = term.getCursorPos()
  816. local oldbackground = override.term.getBackgroundColor()
  817. local oldtext = override.term.getTextColor()
  818. clearPage(website, curbackground)
  819.  
  820. term.setBackgroundColor(oldbackground)
  821. term.setTextColor(oldtext)
  822. term.setCursorPos(x, y)
  823. end
  824.  
  825. override.term.scroll = function(n)
  826. local x, y = term.getCursorPos()
  827. local oldbackground = override.term.getBackgroundColor()
  828. local oldtext = override.term.getTextColor()
  829.  
  830. env.term.scroll(n)
  831. clearPage(website, curbackground, true)
  832. term.setBackgroundColor(oldbackground)
  833. term.setTextColor(oldtext)
  834. term.setCursorPos(x, y)
  835. end
  836.  
  837. override.term.isColor = function() return isAdvanced() end
  838. override.term.isColour = function() return override.term.isColor() end
  839.  
  840. override.prompt = function(list, dir)
  841. local a = {}
  842. for k, v in pairs(list) do
  843. table.insert(a, {v[1], v[2], v[3] + 1, tc = v.tc or curtext, bg = v.bg or curbackground})
  844. end
  845. return env.prompt(a, dir)
  846. end
  847.  
  848. override.scrollingPrompt = function(list, x, y, len, width)
  849. return env.scrollingPrompt(list, x, y + 1, len, width)
  850. end
  851.  
  852.  
  853. -- -------- Antivirus System
  854.  
  855. -- Overrides
  856. local antivirusOverrides = {
  857. ["Run Files"] = {"shell.run", "os.run"},
  858. ["Modify System"] = {"shell.setAlias", "shell.clearAlias", "os.setComputerLabel", "shell.setDir",
  859. "shell.setPath"},
  860. ["Modify Filesystem"] = {"fs.makeDir", "fs.move", "fs.copy", "fs.delete", "fs.open",
  861. "io.open", "io.write", "io.read", "io.close"},
  862. ["Shutdown Computer"] = {"os.shutdown", "os.reboot", "shell.exit"},
  863. ["Use pcall"] = {"pcall"},
  864. ["View Environment"] = {"getfenv"}
  865. }
  866.  
  867. local antivirusDestroy = {
  868. "rawset", "rawget", "setfenv", "loadfile", "loadstring", "dofile"
  869. }
  870.  
  871. -- Graphical Function
  872. local function triggerAntivirus(offence, onlyCancel)
  873. local oldback, oldtext = curbackground, curtext
  874.  
  875. local ox, oy = term.getCursorPos()
  876. openAddressBar = false
  877. term.setBackgroundColor(colors[theme["address-bar-background"]])
  878. term.setTextColor(colors[theme["address-bar-text"]])
  879. term.setCursorPos(2, 1)
  880. term.clearLine()
  881. write("Request: " .. offence)
  882. local a = {{"Allow", w - 24, 1}, {"Cancel", w - 12, 1}}
  883. if onlyCancel == true then a = {{"Cancel", w - 12, 1}} end
  884. local opt = prompt(a, "horizontal")
  885.  
  886. clearPage(website, nil, true)
  887. term.setTextColor(colors.white)
  888. term.setBackgroundColor(colors.black)
  889. term.setCursorPos(ox, oy)
  890. term.setBackgroundColor(oldback)
  891. term.setTextColor(oldtext)
  892. if opt == "Allow" then
  893. -- To prevent the menu bar from opening
  894. os.queueEvent("firewolf_requiredEvent")
  895. os.pullEvent()
  896.  
  897. openAddressBar = true
  898. return true
  899. elseif opt == "Cancel" then
  900. redirect("home")
  901. end
  902. end
  903.  
  904. -- Copy from override
  905. for k, v in pairs(override) do antivirus[k] = v end
  906.  
  907. antivirus.shell = {}
  908. for k, v in pairs(override.shell) do antivirus.shell[k] = v end
  909. antivirus.os = {}
  910. for k, v in pairs(override.os) do antivirus.os[k] = v end
  911. antivirus.fs = {}
  912. for k, v in pairs(override.fs) do antivirus.fs[k] = v end
  913. antivirus.io = {}
  914. for k, v in pairs(override.io) do antivirus.io[k] = v end
  915.  
  916. -- Override malicious functions
  917. for warning, v in pairs(antivirusOverrides) do
  918. for k, func in pairs(v) do
  919. if func:find(".", 1, true) then
  920. -- Functions in another table
  921. local table = func:sub(1, func:find(".", 1, true) - 1)
  922. local funcname = func:sub(func:find(".", 1, true) + 1, -1)
  923.  
  924. antivirus[table][funcname] = function(...)
  925. env.setfenv(triggerAntivirus, env)
  926. if triggerAntivirus(warning) then
  927. return override[table][funcname](...)
  928. end
  929. end
  930. else
  931. -- Plain functions
  932. antivirus[func] = function(...)
  933. env.setfenv(triggerAntivirus, env)
  934. if triggerAntivirus(warning) then
  935. return override[func](...)
  936. end
  937. end
  938. end
  939. end
  940. end
  941.  
  942. -- Override functions to destroy
  943. for k, v in pairs(antivirusDestroy) do
  944. antivirus[v] = function(...)
  945. env.setfenv(triggerAntivirus, env)
  946. triggerAntivirus("Destory your System! D:", true)
  947. return nil
  948. end
  949. end
  950.  
  951. antivirus.pcall = function(...)
  952. local suc, err = env.pcall(...)
  953. if err:lower():find("terminate") then
  954. error("terminate")
  955. elseif err:lower():find(event_exitWebsite) then
  956. error(event_exitWebsite)
  957. end
  958.  
  959. return suc, err
  960. end
  961.  
  962.  
  963. -- -------- Graphics and Files
  964.  
  965. graphics.githubImage = [[
  966. f f
  967. fffffffff
  968. fffffffff
  969. f4244424f
  970. f4444444f
  971. fffffefffe
  972. fffe e
  973. fffff e
  974. ff f fe e
  975. e e
  976. ]]
  977.  
  978. files.availableThemes = [[
  979. https://raw.github.com/1lann/firewolf/master/themes/default.txt| |Fire (default)
  980. https://raw.github.com/1lann/firewolf/master/themes/ice.txt| |Ice
  981. https://raw.github.com/1lann/firewolf/master/themes/carbon.txt| |Carbon
  982. https://raw.github.com/1lann/firewolf/master/themes/christmas.txt| |Christmas
  983. https://raw.github.com/1lann/firewolf/master/themes/original.txt| |Original
  984. https://raw.github.com/1lann/firewolf/master/themes/ocean.txt| |Ocean
  985. https://raw.github.com/1lann/firewolf/master/themes/forest.txt| |Forest
  986. https://raw.github.com/1lann/firewolf/master/themes/pinky.txt| |Pinky
  987. ]]
  988.  
  989. files.newTheme = [[
  990. -- Text color of the address bar
  991. address-bar-text=
  992.  
  993. -- Background color of the address bar
  994. address-bar-background=
  995.  
  996. -- Color of separator bar when live searching
  997. address-bar-base=
  998.  
  999. -- Top box color
  1000. top-box=
  1001.  
  1002. -- Bottom box color
  1003. bottom-box=
  1004.  
  1005. -- Background color
  1006. background=
  1007.  
  1008. -- Main text color
  1009. text-color=
  1010.  
  1011. ]]
  1012.  
  1013.  
  1014. -- -------- Themes
  1015.  
  1016. local defaultTheme = {["address-bar-text"] = "white", ["address-bar-background"] = "gray",
  1017. ["address-bar-base"] = "lightGray", ["top-box"] = "red", ["bottom-box"] = "orange",
  1018. ["text-color"] = "white", ["background"] = "gray"}
  1019. local originalTheme = {["address-bar-text"] = "white", ["address-bar-background"] = "black",
  1020. ["address-bar-base"] = "black", ["top-box"] = "black", ["bottom-box"] = "black",
  1021. ["text-color"] = "white", ["background"] = "black"}
  1022.  
  1023. local function loadTheme(path)
  1024. if fs.exists(path) and not fs.isDir(path) then
  1025. local a = {}
  1026. local f = io.open(path, "r")
  1027. local l = f:read("*l")
  1028. while l ~= nil do
  1029. l = l:gsub("^%s*(.-)%s*$", "%1")
  1030. if l ~= "" and l ~= nil and l ~= "\n" and l:sub(1, 2) ~= "--" then
  1031. local b = l:find("=")
  1032. if a and b then
  1033. local c = l:sub(1, b - 1)
  1034. local d = l:sub(b + 1, -1)
  1035. if c == "" or d == "" then return nil
  1036. else a[c] = d end
  1037. else return nil end
  1038. end
  1039. l = f:read("*l")
  1040. end
  1041. f:close()
  1042.  
  1043. return a
  1044. end
  1045. end
  1046.  
  1047.  
  1048. -- -------- Filesystem and HTTP
  1049.  
  1050. local function download(url, path)
  1051. for i = 1, 3 do
  1052. local response = http.get(url)
  1053. if response then
  1054. local data = response.readAll()
  1055. response.close()
  1056. if path then
  1057. local f = io.open(path, "w")
  1058. f:write(data)
  1059. f:close()
  1060. end
  1061. return true
  1062. end
  1063. end
  1064.  
  1065. return false
  1066. end
  1067.  
  1068. local function updateClient()
  1069. local skipNormal = false
  1070. if serverID ~= "experimental" then
  1071. http.request(buildURL)
  1072. local a = os.startTimer(10)
  1073. while true do
  1074. local e, url, handle = os.pullEvent()
  1075. if e == "http_success" then
  1076. if tonumber(handle.readAll()) > build then break
  1077. else return false end
  1078. elseif e == "http_failure" or (e == "timer" and url == a) then
  1079. skipNormal = true
  1080. break
  1081. end
  1082. end
  1083. end
  1084.  
  1085. local source = nil
  1086.  
  1087. if not skipNormal then
  1088. local _, y = term.getCursorPos()
  1089. term.setCursorPos(1, y - 2)
  1090. rightWrite(string.rep(" ", 32))
  1091. rightWrite("Updating Firewolf... ")
  1092.  
  1093. http.request(firewolfURL)
  1094. local a = os.startTimer(10)
  1095. while true do
  1096. local e, url, handle = os.pullEvent()
  1097. if e == "http_success" then
  1098. source = handle
  1099. break
  1100. elseif e == "http_failure" or (e == "timer" and url == a) then
  1101. break
  1102. end
  1103. end
  1104. end
  1105.  
  1106. if not source then
  1107. if isAdvanced() then
  1108. term.setTextColor(colors[theme["text-color"]])
  1109. term.setBackgroundColor(colors[theme["background"]])
  1110. term.clear()
  1111. if not fs.exists(rootFolder) then fs.makeDir(rootFolder) end
  1112. local f = io.open(rootFolder .. "/temp_file", "w")
  1113. f:write(graphics.githubImage)
  1114. f:close()
  1115. local a = paintutils.loadImage(rootFolder .. "/temp_file")
  1116. paintutils.drawImage(a, 5, 5)
  1117. fs.delete(rootFolder .. "/temp_file")
  1118.  
  1119. term.setCursorPos(19, 4)
  1120. term.setBackgroundColor(colors[theme["top-box"]])
  1121. write(string.rep(" ", 32))
  1122. term.setCursorPos(19, 5)
  1123. write(" Could Not Connect to GitHub! ")
  1124. term.setCursorPos(19, 6)
  1125. write(string.rep(" ", 32))
  1126. term.setBackgroundColor(colors[theme["bottom-box"]])
  1127. term.setCursorPos(19, 8)
  1128. write(string.rep(" ", 32))
  1129. term.setCursorPos(19, 9)
  1130. write(" Sorry, Firewolf could not ")
  1131. term.setCursorPos(19, 10)
  1132. write(" connect to GitHub to download ")
  1133. term.setCursorPos(19, 11)
  1134. write(" necessary files. Please check: ")
  1135. term.setCursorPos(19, 12)
  1136. write(" http://status.github.com ")
  1137. term.setCursorPos(19, 13)
  1138. write(string.rep(" ", 32))
  1139. term.setCursorPos(19, 14)
  1140. write(" Click to exit... ")
  1141. term.setCursorPos(19, 15)
  1142. write(string.rep(" ", 32))
  1143. else
  1144. term.clear()
  1145. term.setCursorPos(1, 1)
  1146. term.setBackgroundColor(colors.black)
  1147. term.setTextColor(colors.white)
  1148. print("\n")
  1149. centerPrint("Could not connect to GitHub!")
  1150. print("")
  1151. centerPrint("Sorry, Firewolf could not connect to")
  1152. centerPrint("GitHub to download necessary files.")
  1153. centerPrint("Please check:")
  1154. centerPrint("http://status.github.com")
  1155. print("")
  1156. centerPrint("Press any key to exit...")
  1157. end
  1158.  
  1159. while true do
  1160. local e = oldpullevent()
  1161. if e == "mouse_click" or e == "key" then break end
  1162. end
  1163.  
  1164. return true
  1165. elseif source and autoupdate == "true" then
  1166. local b = io.open(firewolfLocation, "r")
  1167. local new = source.readAll()
  1168. local cur = b:read("*a")
  1169. source.close()
  1170. b:close()
  1171.  
  1172. if cur ~= new then
  1173. fs.delete(firewolfLocation)
  1174. local f = io.open(firewolfLocation, "w")
  1175. f:write(new)
  1176. f:close()
  1177. return true
  1178. else
  1179. return false
  1180. end
  1181. end
  1182. end
  1183.  
  1184. local function resetFilesystem()
  1185. -- Migrate
  1186. fs.delete(rootFolder .. "/available_themes")
  1187. fs.delete(rootFolder .. "/default_theme")
  1188.  
  1189. -- Reset
  1190. if not fs.exists(rootFolder) then fs.makeDir(rootFolder)
  1191. elseif not fs.isDir(rootFolder) then fs.move(rootFolder, "/Firewolf_Data.old") end
  1192.  
  1193. if not fs.isDir(serverFolder) then fs.delete(serverFolder) end
  1194. if not fs.exists(serverFolder) then fs.makeDir(serverFolder) end
  1195. if not fs.isDir(cacheFolder) then fs.delete(cacheFolder) end
  1196. if not fs.exists(cacheFolder) then fs.makeDir(cacheFolder) end
  1197. if not fs.isDir(websiteDataFolder) then fs.delete(websiteDataFolder) end
  1198. if not fs.exists(websiteDataFolder) then fs.makeDir(websiteDataFolder) end
  1199.  
  1200. if fs.isDir(settingsLocation) then fs.delete(settingsLocation) end
  1201. if fs.isDir(serverLocation) then fs.delete(serverLocation) end
  1202.  
  1203. if not fs.exists(settingsLocation) then
  1204. local f = io.open(settingsLocation, "w")
  1205. f:write(textutils.serialize({auto = "true", incog = "false", home = "firewolf"}))
  1206. f:close()
  1207. end
  1208.  
  1209. if not fs.exists(serverLocation) then
  1210. download(serverURL, serverLocation)
  1211. end
  1212.  
  1213. fs.delete(rootFolder .. "/temp_file")
  1214.  
  1215. for _, v in pairs({userWhitelist, userBlacklist}) do
  1216. if fs.isDir(v) then fs.delete(v) end
  1217. if not fs.exists(v) then
  1218. local f = io.open(v, "w")
  1219. f:write("")
  1220. f:close()
  1221. end
  1222. end
  1223. end
  1224.  
  1225. local function checkForModem(display)
  1226. while true do
  1227. local present = false
  1228. for _, v in pairs(rs.getSides()) do
  1229. if peripheral.getType(v) == "modem" then
  1230. rednet.open(v)
  1231. present = true
  1232. break
  1233. end
  1234. end
  1235.  
  1236. if not present and type(display) == "function" then
  1237. display()
  1238. os.pullEvent("peripheral")
  1239. else
  1240. return true
  1241. end
  1242. end
  1243. end
  1244.  
  1245.  
  1246. -- -------- Databases
  1247.  
  1248. local function loadDatabases()
  1249. -- Blacklist
  1250. if fs.exists(userBlacklist) and not fs.isDir(userBlacklist) then
  1251. local bf = io.open(userBlacklist, "r")
  1252. local l = bf:read("*l")
  1253. while l ~= nil do
  1254. if l ~= nil and l ~= "" and l ~= "\n" then
  1255. l = l:gsub("^%s*(.-)%s*$", "%1")
  1256. table.insert(blacklist, l)
  1257. end
  1258. l = bf:read("*l")
  1259. end
  1260. bf:close()
  1261. end
  1262.  
  1263. -- Whitelist
  1264. if fs.exists(userWhitelist) and not fs.isDir(userWhitelist) then
  1265. local wf = io.open(userWhitelist, "r")
  1266. local l = wf:read("*l")
  1267. while l ~= nil do
  1268. if l ~= nil and l ~= "" and l ~= "\n" then
  1269. l = l:gsub("^%s*(.-)%s*$", "%1")
  1270. local a, b = l:find("| |")
  1271. table.insert(whitelist, {l:sub(1, a - 1), l:sub(b + 1, -1)})
  1272. end
  1273. l = wf:read("*l")
  1274. end
  1275. wf:close()
  1276. end
  1277. end
  1278.  
  1279. local function verifyBlacklist(id)
  1280. for _, v in pairs(blacklist) do
  1281. if tostring(id) == v then return true end
  1282. end
  1283. return false
  1284. end
  1285.  
  1286. local function verifyWhitelist(id, url)
  1287. for _, v in pairs(whitelist) do
  1288. if v[2] == tostring(args[1]) and v[1] == tostring(args[2]) then
  1289. return true
  1290. end
  1291. end
  1292. return false
  1293. end
  1294.  
  1295.  
  1296. -- -------- Protocols
  1297.  
  1298. protocols.rdnt = {}
  1299. protocols.http = {}
  1300.  
  1301. protocols.rdnt.getSearchResults = function()
  1302. dnsDatabase = {[1] = {}, [2] = {}}
  1303. local resultIDs = {}
  1304. local conflict = {}
  1305.  
  1306. rednet.broadcast("firewolf.broadcast.dns.list")
  1307. local startClock = os.clock()
  1308. while os.clock() - startClock < timeout do
  1309. local id, i = rednet.receive(timeout)
  1310. if id then
  1311. if i:sub(1, 14) == "firewolf-site:" then
  1312. i = i:sub(15, -1)
  1313. local bl, wl = verifyBlacklist(id), verifyWhitelist(id, i)
  1314. if not i:find(" ") and i:len() < 40 and (not bl or (bl and wl)) then
  1315. if not resultIDs[tostring(id)] then resultIDs[tostring(id)] = 1
  1316. else resultIDs[tostring(id)] = resultIDs[tostring(id)] + 1
  1317. end
  1318.  
  1319. if not i:find("rdnt://") then i = ("rdnt://" .. i) end
  1320. local x = false
  1321. if conflict[i] then
  1322. x = true
  1323. table.insert(conflict[i], id)
  1324. else
  1325. for m, n in pairs(dnsDatabase[1]) do
  1326. if n:lower() == i:lower() then
  1327. x = true
  1328. table.remove(dnsDatabase[1], m)
  1329. table.remove(dnsDatabase[2], m)
  1330. if conflict[i] then
  1331. table.insert(conflict[i], id)
  1332. else
  1333. conflict[i] = {}
  1334. table.insert(conflict[i], id)
  1335. end
  1336. break
  1337. end
  1338. end
  1339. end
  1340.  
  1341. if not x and resultIDs[tostring(id)] <= 3 then
  1342. table.insert(dnsDatabase[1], i)
  1343. table.insert(dnsDatabase[2], id)
  1344. end
  1345. end
  1346. end
  1347. else
  1348. break
  1349. end
  1350. end
  1351. for k,v in pairs(conflict) do
  1352. table.sort(v)
  1353. table.insert(dnsDatabase[1], k)
  1354. table.insert(dnsDatabase[2], v[1])
  1355. end
  1356.  
  1357. return dnsDatabase[1]
  1358. end
  1359.  
  1360. protocols.rdnt.getWebsite = function(site)
  1361. local id, content, status = nil, nil, nil
  1362. local clock = os.clock()
  1363. local websiteID = nil
  1364. for k, v in pairs(dnsDatabase[1]) do
  1365. local web = site:gsub("rdnt://", "")
  1366. if web:find("/") then web = web:sub(1, web:find("/") - 1) end
  1367. if web == v:gsub("rdnt://", "") then
  1368. websiteID = dnsDatabase[2][k]
  1369. break
  1370. end
  1371. end
  1372. if not websiteID then return nil, nil, nil end
  1373.  
  1374. sleep(timeout)
  1375. rednet.send(websiteID, site)
  1376. clock = os.clock()
  1377. while os.clock() - clock < timeout do
  1378. id, content = rednet.receive(timeout)
  1379. if id then
  1380. if id == websiteID then
  1381. local bl = verifyBlacklist(id)
  1382. local wl = verifyWhitelist(id, site)
  1383. status = nil
  1384. if (bl and not wl) or site == "" or site == "." or site == ".." then
  1385. -- Ignore
  1386. elseif wl then
  1387. status = "whitelist"
  1388. break
  1389. else
  1390. status = "safe"
  1391. break
  1392. end
  1393. end
  1394. end
  1395. end
  1396.  
  1397. return id, content, status
  1398. end
  1399.  
  1400. protocols.http.getSearchResults = function()
  1401. dnsDatabase = {[1] = {}, [2] = {}}
  1402. return dnsDatabase[1]
  1403. end
  1404.  
  1405. protocols.http.getWebsite = function()
  1406. return nil, nil, nil
  1407. end
  1408.  
  1409.  
  1410. -- -------- Homepage
  1411.  
  1412. pages["firewolf"] = function(site)
  1413. openAddressBar = true
  1414. term.setBackgroundColor(colors[theme["background"]])
  1415. term.clear()
  1416. term.setTextColor(colors[theme["text-color"]])
  1417. term.setBackgroundColor(colors[theme["top-box"]])
  1418. print("")
  1419. leftPrint(string.rep(" ", 42))
  1420. leftPrint([[ _,-='"-.__ /\_/\ ]])
  1421. leftPrint([[ -.} =._,.-==-._., @ @._, ]])
  1422. leftPrint([[ -.__ __,-. ) _,.-' ]])
  1423. leftPrint([[ Firewolf ]] .. version .. string.rep(" ", 8 - version:len()) ..
  1424. [[" G..m-"^m m' ]])
  1425. leftPrint(string.rep(" ", 42))
  1426. print("\n")
  1427.  
  1428. term.setBackgroundColor(colors[theme["bottom-box"]])
  1429. rightPrint(string.rep(" ", 42))
  1430. rightPrint(" News: [- Sites -] ")
  1431. rightPrint(" Firewolf 2.4 is out! It cuts out 1500 ")
  1432. rightPrint(" lines, and contains many improvements! ")
  1433. rightPrint(string.rep(" ", 42))
  1434. rightPrint(" Firewolf 3.0 will be out soon! It will ")
  1435. rightPrint(" bring the long awaited HTTP support! ")
  1436. rightPrint(string.rep(" ", 42))
  1437.  
  1438. while true do
  1439. local e, but, x, y = os.pullEvent()
  1440. if e == "mouse_click" and x >= 40 and x <= 50 and y == 12 then
  1441. redirect("firewolf/sites")
  1442. end
  1443. end
  1444. end
  1445.  
  1446. pages["firefox"] = function(site) redirect("firewolf") end
  1447.  
  1448. pages["firewolf/sites"] = function(site)
  1449. term.setBackgroundColor(colors[theme["background"]])
  1450. term.clear()
  1451. term.setTextColor(colors[theme["text-color"]])
  1452. term.setBackgroundColor(colors[theme["top-box"]])
  1453. print("\n")
  1454. leftPrint(string.rep(" ", 17))
  1455. leftPrint(" Built-In Sites ")
  1456. leftPrint(string.rep(" ", 17))
  1457.  
  1458. local sx = 8
  1459. term.setBackgroundColor(colors[theme["bottom-box"]])
  1460. term.setCursorPos(1, sx)
  1461. rightPrint(string.rep(" ", 40))
  1462. rightPrint(" rdnt://firewolf Homepage ")
  1463. rightPrint(" rdnt://firewolf/sites Sites ")
  1464. rightPrint(" rdnt://server Server Management ")
  1465. rightPrint(" rdnt://help Help Page ")
  1466. rightPrint(" rdnt://settings Settings ")
  1467. rightPrint(" rdnt://credits Credits ")
  1468. rightPrint(" rdnt://exit Exit ")
  1469. rightPrint(string.rep(" ", 40))
  1470.  
  1471. local a = {"firewolf", "firewolf/sites", "server", "help", "settings", "credits", "exit"}
  1472. while true do
  1473. local e, but, x, y = os.pullEvent()
  1474. if e == "mouse_click" and x >= 14 and x <= 50 then
  1475. for i, v in ipairs(a) do
  1476. if y == sx + i + 1 then
  1477. if v == "exit" then return true end
  1478. redirect(v)
  1479. end
  1480. end
  1481. end
  1482. end
  1483. end
  1484.  
  1485. pages["sites"] = function(site) redirect("firewolf/sites") end
  1486.  
  1487.  
  1488. -- -------- Server Management
  1489.  
  1490. local function manageServers(site, protocol, functionList, startServerName)
  1491. local servers = functionList["reload servers"]()
  1492. local sy = 7
  1493.  
  1494. if startServerName == nil then startServerName = "Start" end
  1495. if isAdvanced() then
  1496. local function draw(l, sel)
  1497. term.setBackgroundColor(colors[theme["bottom-box"]])
  1498. term.setCursorPos(4, sy)
  1499. write("[- New Server -]")
  1500. for i, v in ipairs(l) do
  1501. term.setCursorPos(3, i + sy)
  1502. write(string.rep(" ", 24))
  1503. term.setCursorPos(4, i + sy)
  1504. local nv = v
  1505. if nv:len() > 18 then nv = nv:sub(1, 15) .. "..." end
  1506. if i == sel then write("[ " .. nv .. " ]")
  1507. else write(" " .. nv) end
  1508. end
  1509. if #l < 1 then
  1510. term.setCursorPos(4, sy + 2)
  1511. write("A website is literally")
  1512. term.setCursorPos(4, sy + 3)
  1513. write("just a lua script!")
  1514. term.setCursorPos(4, sy + 4)
  1515. write("Go ahead and make one!")
  1516. term.setCursorPos(4, sy + 6)
  1517. write("Also, be sure to check")
  1518. term.setCursorPos(4, sy + 7)
  1519. write("out Firewolf's APIs to")
  1520. term.setCursorPos(4, sy + 8)
  1521. write("help you make your")
  1522. term.setCursorPos(4, sy + 9)
  1523. write("site, at rdnt://help")
  1524. end
  1525.  
  1526. term.setCursorPos(30, sy)
  1527. write(string.rep(" ", 19))
  1528. term.setCursorPos(30, sy)
  1529. if l[sel] then
  1530. local nl = l[sel]
  1531. if nl:len() > 19 then nl = nl:sub(1, 16) .. "..." end
  1532. write(nl)
  1533. else write("No Server Selected!") end
  1534. term.setCursorPos(30, sy + 2)
  1535. write("[- " .. startServerName .. " -]")
  1536. term.setCursorPos(30, sy + 4)
  1537. write("[- Edit -]")
  1538. term.setCursorPos(30, sy + 6)
  1539. if functionList["run on boot"] then write("[- Run on Boot -]") end
  1540. term.setCursorPos(30, sy + 8)
  1541. write("[- Delete -]")
  1542. end
  1543.  
  1544. local function updateDisplayList(items, loc, len)
  1545. local ret = {}
  1546. for i = 1, len do
  1547. if items[i + loc - 1] then table.insert(ret, items[i + loc - 1]) end
  1548. end
  1549. return ret
  1550. end
  1551.  
  1552. while true do
  1553. term.setBackgroundColor(colors[theme["background"]])
  1554. term.clear()
  1555. term.setCursorPos(1, 1)
  1556. term.setTextColor(colors[theme["text-color"]])
  1557. term.setBackgroundColor(colors[theme["top-box"]])
  1558. print("")
  1559. leftPrint(string.rep(" ", 27))
  1560. leftPrint(" Server Management - " .. protocol:upper() .. " ")
  1561. leftPrint(string.rep(" ", 27))
  1562. print("")
  1563.  
  1564. term.setBackgroundColor(colors[theme["bottom-box"]])
  1565. for i = 1, 12 do
  1566. term.setCursorPos(3, i + sy - 2)
  1567. write(string.rep(" ", 24))
  1568. term.setCursorPos(29, i + sy - 2)
  1569. write(string.rep(" ", 21))
  1570. end
  1571.  
  1572. local sel = 1
  1573. local loc = 1
  1574. local len = 10
  1575. local disList = updateDisplayList(servers, loc, len)
  1576. draw(disList, sel)
  1577.  
  1578. while true do
  1579. local e, but, x, y = os.pullEvent()
  1580. if e == "key" and but == 200 and #servers > 0 and loc > 1 then
  1581. loc = loc - 1
  1582. disList = updateDisplayList(servers, loc, len)
  1583. draw(disList, sel)
  1584. elseif e == "key" and but == 208 and #servers > 0 and loc + len - 1 < #servers then
  1585. loc = loc + 1
  1586. disList = updateDisplayList(servers, loc, len)
  1587. draw(disList, sel)
  1588. elseif e == "mouse_click" then
  1589. if x >= 4 and x <= 25 then
  1590. if y == 8 then
  1591. functionList["new server"]()
  1592. servers = functionList["reload servers"]()
  1593. break
  1594. elseif #servers > 0 then
  1595. for i, v in ipairs(disList) do
  1596. if y == i + 8 then
  1597. sel = i
  1598. draw(disList, sel)
  1599. end
  1600. end
  1601. end
  1602. elseif x >= 30 and x <= 40 and y == 10 and #servers > 0 then
  1603. functionList["start"](disList[sel])
  1604. servers = functionList["reload servers"]()
  1605. break
  1606. elseif x >= 30 and x <= 39 and y == 12 and #servers > 0 then
  1607. functionList["edit"](disList[sel])
  1608. servers = functionList["reload servers"]()
  1609. break
  1610. elseif x >= 30 and x <= 46 and y == 14 and #servers > 0 and
  1611. functionList["run on boot"] then
  1612. functionList["run on boot"](disList[sel])
  1613. term.setBackgroundColor(colors[theme["bottom-box"]])
  1614. term.setCursorPos(32, 15)
  1615. write("Will Run on Boot!")
  1616. openAddressBar = false
  1617. sleep(1.3)
  1618. openAddressBar = true
  1619. term.setCursorPos(32, 15)
  1620. write(string.rep(" ", 18))
  1621. break
  1622. elseif x >= 30 and x <= 41 and y == 16 and #servers > 0 then
  1623. functionList["delete"](disList[sel])
  1624. servers = functionList["reload servers"]()
  1625. break
  1626. end
  1627. end
  1628. end
  1629. end
  1630. else
  1631. while true do
  1632. term.setBackgroundColor(colors[theme["background"]])
  1633. term.clear()
  1634. term.setTextColor(colors[theme["text-color"]])
  1635. term.setBackgroundColor(colors[theme["top-box"]])
  1636. print("")
  1637. centerPrint(string.rep(" ", 27))
  1638. centerPrint(" Server Management - " .. protocol:upper() .. " ")
  1639. centerPrint(string.rep(" ", 27))
  1640. print("")
  1641.  
  1642. local a = {"New Server"}
  1643. for _, v in pairs(servers) do table.insert(a, v) end
  1644. local server = scrollingPrompt(a, 4, 7, 10)
  1645. if server == "New Server" then
  1646. functionList["new server"]()
  1647. servers = functionList["reload servers"]()
  1648. else
  1649. term.setCursorPos(30, 8)
  1650. write(server)
  1651. local a = {{"Start", 30, 9}, {"Edit", 30, 11}, {"Run on Boot", 30, 12},
  1652. {"Delete", 30, 13}, {"Back", 30, 15}}
  1653. if not functionList["run on boot"] then
  1654. a = {{"Start", 30, 9}, {"Edit", 30, 11}, {"Delete", 30, 13}, {"Back", 30, 15}}
  1655. end
  1656. local opt = prompt(a, "vertical")
  1657. if opt == "Start" then
  1658. functionList["start"]()
  1659. servers = functionList["reload servers"]()
  1660. elseif opt == "Edit" then
  1661. functionList["edit"]()
  1662. servers = functionList["reload servers"]()
  1663. elseif opt == "Run on Boot" and functionList["run on boot"] then
  1664. functionList["run on boot"]()
  1665. term.setCursorPos(32, 16)
  1666. write("Will Run on Boot!")
  1667. openAddressBar = false
  1668. sleep(1.3)
  1669. openAddressBar = true
  1670. elseif opt == "Delete" then
  1671. functionList["delete"]()
  1672. servers = functionList["reload servers"]()
  1673. end
  1674. end
  1675. end
  1676. end
  1677. end
  1678.  
  1679. local function editPages(dir)
  1680. local oldLoc = shell.dir()
  1681. local commandHis = {}
  1682. term.setBackgroundColor(colors.black)
  1683. term.setTextColor(colors.white)
  1684. term.clear()
  1685. term.setCursorPos(1, 1)
  1686. print("")
  1687. print(" Server Shell Editing")
  1688. print(" Type 'exit' to return to Firewolf.")
  1689. print(" The 'home' file is the index of your site.")
  1690. print("")
  1691.  
  1692. local allowed = {"move", "mv", "cp", "copy", "drive", "delete", "rm", "edit",
  1693. "eject", "exit", "help", "id", "monitor", "rename", "alias", "clear",
  1694. "paint", "firewolf", "lua", "redstone", "rs", "redprobe", "redpulse", "programs",
  1695. "redset", "reboot", "hello", "label", "list", "ls", "easter", "pastebin", "dir"}
  1696.  
  1697. while true do
  1698. shell.setDir(dir)
  1699. term.setBackgroundColor(colors.black)
  1700. if isAdvanced() then term.setTextColor(colors.yellow)
  1701. else term.setTextColor(colors.white) end
  1702. write("> ")
  1703. term.setTextColor(colors.white)
  1704. local line = read(nil, commandHis)
  1705. table.insert(commandHis, line)
  1706.  
  1707. local words = {}
  1708. for m in string.gmatch(line, "[^ \t]+") do
  1709. local a = m:gsub("^%s*(.-)%s*$", "%1")
  1710. table.insert(words, a)
  1711. end
  1712.  
  1713. local com = words[1]
  1714. if com == "exit" then
  1715. break
  1716. elseif com then
  1717. local a = false
  1718. for _, v in pairs(allowed) do
  1719. if com == v then a = true break end
  1720. end
  1721.  
  1722. if a then
  1723. term.setBackgroundColor(colors.black)
  1724. term.setTextColor(colors.white)
  1725. shell.run(com, unpack(words, 2))
  1726. else
  1727. term.setTextColor(colors.red)
  1728. print("Program Not Allowed!")
  1729. end
  1730. end
  1731. end
  1732. shell.setDir(oldLoc)
  1733. end
  1734.  
  1735. local function newServer(onCreate)
  1736. term.setBackgroundColor(colors[theme["background"]])
  1737. for i = 1, 12 do
  1738. term.setCursorPos(3, i + 5)
  1739. term.clearLine()
  1740. end
  1741.  
  1742. term.setBackgroundColor(colors[theme["bottom-box"]])
  1743. term.setCursorPos(1, 7)
  1744. for i = 1, 8 do centerPrint(string.rep(" ", 47)) end
  1745. term.setCursorPos(5, 8)
  1746. write("Name: ")
  1747. local name = modRead({refusePrint = "`", visibleLength = w - 4, textLength = 200})
  1748. term.setCursorPos(5, 10)
  1749. write("URL:")
  1750. term.setCursorPos(8, 11)
  1751. write("rdnt://")
  1752. local url = modRead({grantPrint = "abcdefghijklmnopqrstuvwxyz1234567890-_.+",
  1753. visibleLength = w - 4, textLength = 200})
  1754. url = url:gsub(" ", "")
  1755. if name == "" or url == "" then
  1756. term.setCursorPos(5, 13)
  1757. write("URL or Name is Empty!")
  1758. openAddressBar = false
  1759. sleep(1.3)
  1760. openAddressBar = true
  1761. else
  1762. local c = onCreate(name, url)
  1763.  
  1764. term.setCursorPos(5, 13)
  1765. if c and c == "true" then
  1766. write("Successfully Created Server!")
  1767. elseif c == "false" or c == nil then
  1768. write("Server Creation Failed!")
  1769. else
  1770. write(c)
  1771. end
  1772. openAddressBar = false
  1773. sleep(1.3)
  1774. openAddressBar = true
  1775. end
  1776. end
  1777.  
  1778. pages["server/rdnt"] = function(site)
  1779. manageServers(site, "rdnt", {["reload servers"] = function()
  1780. local servers = {}
  1781. for _, v in pairs(fs.list(serverFolder)) do
  1782. if fs.isDir(serverFolder .. "/" .. v) then table.insert(servers, v) end
  1783. end
  1784.  
  1785. return servers
  1786. end, ["new server"] = function()
  1787. newServer(function(name, url)
  1788. if fs.exists(serverFolder .. "/" .. url) then
  1789. return "Server Already Exists!"
  1790. end
  1791.  
  1792. fs.makeDir(serverFolder .. "/" .. url)
  1793. local f = io.open(serverFolder .. "/" .. url .. "/home", "w")
  1794. f:write("print(\"\")\ncenterPrint(\"Welcome To " .. name .. "!\")\n\n")
  1795. f:close()
  1796. return "true"
  1797. end)
  1798. end, ["start"] = function(server)
  1799. term.clear()
  1800. term.setCursorPos(1, 1)
  1801. term.setBackgroundColor(colors.black)
  1802. term.setTextColor(colors.white)
  1803. openAddressBar = false
  1804. setfenv(1, oldEnv)
  1805. shell.run(serverLocation, server, serverFolder .. "/" .. server)
  1806. setfenv(1, override)
  1807. openAddressBar = true
  1808. checkForModem()
  1809. end, ["edit"] = function(server)
  1810. openAddressBar = false
  1811. editPages(serverFolder .. "/" .. server)
  1812. openAddressBar = true
  1813. if not fs.exists(serverFolder .. "/" .. server .. "/home") then
  1814. local f = io.open(serverFolder .. "/" .. server .. "/home", "w")
  1815. f:write("print(\"\")\ncenterPrint(\"Welcome To " .. server .. "!\")\n\n")
  1816. f:close()
  1817. end
  1818. end, ["run on boot"] = function(server)
  1819. fs.delete("/old-startup")
  1820. if fs.exists("/startup") then fs.move("/startup", "/old-startup") end
  1821. local f = io.open("/startup", "w")
  1822. f:write("shell.run(\"" .. serverLocation .. "\", \"" .. server .. "\", \"" ..
  1823. serverFolder .. "/" .. server .. "\")")
  1824. f:close()
  1825. end, ["delete"] = function(server)
  1826. fs.delete(serverFolder .. "/" .. server)
  1827. end})
  1828. end
  1829.  
  1830. pages["server/http"] = function(site)
  1831. term.setBackgroundColor(colors[theme["background"]])
  1832. term.clear()
  1833. print("\n\n")
  1834. term.setBackgroundColor(colors[theme["top-box"]])
  1835. centerPrint(string.rep(" ", 17))
  1836. centerPrint(" Comming Soon! ")
  1837. centerPrint(string.rep(" ", 17))
  1838. end
  1839.  
  1840. pages["server"] = function(site)
  1841. setfenv(manageServers, override)
  1842. setfenv(newServer, override)
  1843. setfenv(editPages, env)
  1844. if curProtocol == protocols.rdnt then redirect("server/rdnt")
  1845. elseif curProtocol == protocols.http then redirect("server/http") end
  1846. end
  1847.  
  1848.  
  1849. -- -------- Help
  1850.  
  1851. pages["help"] = function(site)
  1852. term.setBackgroundColor(colors[theme["background"]])
  1853. term.clear()
  1854. term.setTextColor(colors[theme["text-color"]])
  1855. term.setBackgroundColor(colors[theme["top-box"]])
  1856. print("")
  1857. leftPrint(string.rep(" ", 16))
  1858. leftPrint(" Firewolf Help ")
  1859. leftPrint(string.rep(" ", 16))
  1860. print("")
  1861.  
  1862. term.setBackgroundColor(colors[theme["bottom-box"]])
  1863. for i = 1, 12 do rightPrint(string.rep(" ", 41)) end
  1864. term.setCursorPos(1, 15)
  1865. rightPrint(" View the full documentation here: ")
  1866. rightPrint(" https://github.com/1lann/Firewolf/wiki ")
  1867.  
  1868. local opt = prompt({{"Getting Started", w - 21, 8}, {"Making a Theme", w - 20, 10},
  1869. {"API Documentation", w - 23, 12}}, "vertical")
  1870. local pages = {}
  1871. if opt == "Getting Started" then
  1872. pages[1] = {title = "Getting Started - Intoduction", content = {
  1873. "Hey there!",
  1874. "",
  1875. "Firewolf is an app that allows you to create",
  1876. "and visit websites! Each site has an address",
  1877. "(the URL) which you can type into the address",
  1878. "bar above, and then visit the site.",
  1879. "",
  1880. "You can open the address bar by clicking on",
  1881. "it, or by pressing control."
  1882. }} pages[2] = {title = "Getting Started - Searching", content = {
  1883. "The address bar can be also be used to",
  1884. "search for sites, by simply typing in the",
  1885. "search term.",
  1886. "",
  1887. "To view all sites, just open it and hit",
  1888. "enter (leave the field blank)."
  1889. }} pages[3] = {title = "Getting Started - Built-In Websites", content = {
  1890. "Firewolf has a set of built-in websites",
  1891. "available for use:",
  1892. "",
  1893. "rdnt://firewolf Normal hompage",
  1894. "rdnt://sites Built-In Site",
  1895. "rdnt://server Create websites",
  1896. "rdnt://help Help and documentation"
  1897. }} pages[4] = {title = "Getting Started - Built-In Websites", content = {
  1898. "More built-in websites:",
  1899. "",
  1900. "rdnt://settings Firewolf settings",
  1901. "rdnt://credits View the credits",
  1902. "rdnt://exit Exit the app"
  1903. }}
  1904. elseif opt == "Making a Theme" then
  1905. pages[1] = {title = "Making a Theme - Introduction", content = {
  1906. "Firewolf themes are files that tell Firewolf",
  1907. "to color which things what.",
  1908. "Several themes can already be downloaded for",
  1909. "Firewolf from rdnt://settings/themes.",
  1910. "",
  1911. "You can also make your own theme, use it in",
  1912. "your copy of Firewolf.Your theme can also be",
  1913. "submitted it to the themes list!"
  1914. }} pages[2] = {title = "Making a Theme - Example", content = {
  1915. "A theme file consists of several lines of",
  1916. "text. Here is the default theme file:",
  1917. "address-bar-text=white",
  1918. "address-bar-background=gray",
  1919. "address-bar-base=lightGray",
  1920. "top-box=red",
  1921. "bottom-box=orange",
  1922. "background=gray",
  1923. "text-color=white"
  1924. }} pages[3] = {title = "Making a Theme - Explanation", content = {
  1925. "On each line of the example, something is",
  1926. "given a color, like on the last line, the",
  1927. "text of the page is told to be white.",
  1928. "",
  1929. "The color specified after the = is the same",
  1930. "as when you call colors.[color name].",
  1931. "For example, specifying 'red' after the =",
  1932. "colors that object red."
  1933. }} pages[4] = {title = "Making a Theme - Have a Go", content = {
  1934. "Themes can be made at rdnt://settings/themes,",
  1935. "click on 'Change Theme' button, and click on",
  1936. "'New Theme'.",
  1937. "",
  1938. "Enter a theme name, then exit Firewolf and",
  1939. "edit the newly created file",
  1940. "Specify the colors for each of the keys,",
  1941. "and return to the themes section of the",
  1942. "downloads center. Click 'Load Theme'."
  1943. }} pages[5] = {title = "Making a Theme - Submitting", content = {
  1944. "To submit a theme to the theme list,",
  1945. "send GravityScore a message on the CCForums",
  1946. "that contains your theme file and name.",
  1947. "",
  1948. "He will message you back saying whether your",
  1949. "theme has been added, or if anything needs to",
  1950. "be changed before it is added."
  1951. }}
  1952. elseif opt == "API Documentation" then
  1953. pages[1] = {title = "API Documentation - 1", content = {
  1954. "The Firewolf API is a bunch of global",
  1955. "functions that aim to simplify your life when",
  1956. "designing and coding websites.",
  1957. "",
  1958. "For a full documentation on these functions,",
  1959. "visit the Firewolf Wiki Page here:",
  1960. "https://github.com/1lann/Firewolf/wiki"
  1961. }} pages[2] = {title = "API Documentation - 2", content = {
  1962. "centerPrint(string text)",
  1963. "cPrint(string text)",
  1964. "centerWrite(string text)",
  1965. "cWrite(string text)",
  1966. "",
  1967. "leftPrint(string text)",
  1968. "lPrint(string text)",
  1969. }} pages[3] = {title = "API Documentation - 3", content = {
  1970. "leftWrite(string text)",
  1971. "lWrite(string text)",
  1972. "",
  1973. "rightPrint(string text)",
  1974. "rPrint(string text)",
  1975. "rightWrite(string text)",
  1976. "rWrite(string text)"
  1977. }} pages[4] = {title = "API Documentation - 4", content = {
  1978. "prompt(table list, string direction)",
  1979. "scrollingPrompt(table list, integer x,",
  1980. " integer y, integer length[,",
  1981. " integer width])",
  1982. "",
  1983. "urlDownload(string url)",
  1984. "pastebinDownload(string code)",
  1985. "redirect(string site)",
  1986. }} pages[5] = {title = "API Documentation - 5", content = {
  1987. "loadImageFromServer(string imagePath)",
  1988. "ioReadFileFromServer(string filePath)",
  1989. "fileFileFromServer(string filePath)",
  1990. "saveFileToUserComputer(string content)",
  1991. "",
  1992. "writeDataFile(string path, string contents)",
  1993. "readDataFile(string path)"
  1994. }}
  1995. end
  1996.  
  1997. local function drawPage(page)
  1998. term.setBackgroundColor(colors[theme["background"]])
  1999. term.clear()
  2000. term.setCursorPos(1, 1)
  2001. term.setTextColor(colors[theme["text-color"]])
  2002. term.setBackgroundColor(colors[theme["top-box"]])
  2003. print("")
  2004. leftPrint(string.rep(" ", page.title:len() + 3))
  2005. leftPrint(" " .. page.title .. " ")
  2006. leftPrint(string.rep(" ", page.title:len() + 3))
  2007. print("")
  2008.  
  2009. term.setBackgroundColor(colors[theme["bottom-box"]])
  2010. for i = 1, 12 do print(string.rep(" ", w)) end
  2011. for i, v in ipairs(page.content) do
  2012. term.setCursorPos(4, i + 7)
  2013. write(v)
  2014. end
  2015. end
  2016.  
  2017. local curPage = 1
  2018. local a = {{"Prev", 26, 17}, {"Next", 38, 17}, {"Back", 14, 17}}
  2019. drawPage(pages[curPage])
  2020.  
  2021. while true do
  2022. local b = {a[3]}
  2023. if curPage == 1 then table.insert(b, a[2])
  2024. elseif curPage == #pages then table.insert(b, a[1])
  2025. else table.insert(b, a[1]) table.insert(b, a[2]) end
  2026.  
  2027. local opt = prompt(b, "horizontal")
  2028. if opt == "Prev" then
  2029. curPage = curPage - 1
  2030. elseif opt == "Next" then
  2031. curPage = curPage + 1
  2032. elseif opt == "Back" then
  2033. break
  2034. end
  2035.  
  2036. drawPage(pages[curPage])
  2037. end
  2038.  
  2039. redirect("help")
  2040. end
  2041.  
  2042.  
  2043. -- -------- Settings
  2044.  
  2045. pages["settings/themes"] = function(site)
  2046. term.setBackgroundColor(colors[theme["background"]])
  2047. term.clear()
  2048. term.setTextColor(colors[theme["text-color"]])
  2049. term.setBackgroundColor(colors[theme["top-box"]])
  2050. print("")
  2051. leftPrint(string.rep(" ", 17))
  2052. leftPrint(" Theme Settings ")
  2053. leftPrint(string.rep(" ", 17))
  2054. print("")
  2055.  
  2056. if isAdvanced() then
  2057. term.setBackgroundColor(colors[theme["bottom-box"]])
  2058. for i = 1, 12 do rightPrint(string.rep(" ", 36)) end
  2059.  
  2060. local themes = {}
  2061. local themenames = {"Back", "New Theme", "Load Theme"}
  2062. local f = io.open(rootFolder .. "/temp_file", "w")
  2063. f:write(files.availableThemes)
  2064. f:close()
  2065. local f = io.open(rootFolder .. "/temp_file", "r")
  2066. local l = f:read("*l")
  2067. while l do
  2068. l = l:gsub("^%s*(.-)%s*$", "%1")
  2069. local a, b = l:find("| |")
  2070. table.insert(themenames, l:sub(b + 1, -1))
  2071. table.insert(themes, {name = l:sub(b + 1, -1), url = l:sub(1, a - 1)})
  2072. l = f:read("*l")
  2073. end
  2074. f:close()
  2075. fs.delete(rootFolder .. "/temp_file")
  2076.  
  2077. local t = scrollingPrompt(themenames, w - 33, 7, 10, 32)
  2078. if t == "Back" then
  2079. redirect("settings")
  2080. elseif t == "New Theme" then
  2081. term.setCursorPos(w - 33, 17)
  2082. write("Path: /")
  2083. local n = modRead({visibleLength = w - 2, textLength = 100})
  2084. if n ~= "" and n ~= nil then
  2085. n = "/" .. n
  2086. local f = io.open(n, "w")
  2087. f:write(files.newTheme)
  2088. f:close()
  2089.  
  2090. term.setCursorPos(1, 17)
  2091. rightWrite(string.rep(" ", 36))
  2092. term.setCursorPos(1, 17)
  2093. rightWrite("File Created! ")
  2094. openAddressBar = false
  2095. sleep(1.1)
  2096. openAddressBar = true
  2097. end
  2098. elseif t == "Load Theme" then
  2099. term.setCursorPos(w - 33, 17)
  2100. write("Path: /")
  2101. local n = modRead({visibleLength = w - 2, textLength = 100})
  2102. if n ~= "" and n ~= nil then
  2103. n = "/" .. n
  2104. term.setCursorPos(1, 17)
  2105. rightWrite(string.rep(" ", 36))
  2106.  
  2107. term.setCursorPos(1, 17)
  2108. if fs.exists(n) and not fs.isDir(n) then
  2109. local a = loadTheme(n)
  2110. if a ~= nil then
  2111. fs.delete(themeLocation)
  2112. fs.copy(n, themeLocation)
  2113. theme = a
  2114. rightWrite("Theme File Loaded! :D ")
  2115. else
  2116. rightWrite("Theme File is Corrupt! D: ")
  2117. end
  2118. elseif not(fs.exists(n)) then
  2119. rightWrite("File does not exist! ")
  2120. elseif fs.isDir(n) then
  2121. rightWrite("File is a directory! ")
  2122. end
  2123.  
  2124. openAddressBar = false
  2125. sleep(1.1)
  2126. openAddressBar = true
  2127. end
  2128. else
  2129. local url = ""
  2130. for _, v in pairs(themes) do if v.name == t then url = v.url break end end
  2131. term.setBackgroundColor(colors[theme["top-box"]])
  2132. term.setCursorPos(1, 3)
  2133. leftWrite(string.rep(" ", 17))
  2134. leftWrite(" Downloading... ")
  2135.  
  2136. fs.delete(rootFolder .. "/temp_file")
  2137. download(url, rootFolder .. "/temp_file")
  2138. local th = loadTheme(rootFolder .. "/temp_file")
  2139. if th == nil then
  2140. term.setCursorPos(1, 3)
  2141. leftWrite(string.rep(" ", 17))
  2142. leftWrite(" Theme Corrupt! ")
  2143. openAddressBar = false
  2144. sleep(1.3)
  2145. openAddressBar = true
  2146.  
  2147. fs.delete(rootFolder .. "/temp_file")
  2148. else
  2149. term.setCursorPos(1, 3)
  2150. leftWrite(string.rep(" ", 17))
  2151. leftWrite(" Theme Loaded! ")
  2152. openAddressBar = false
  2153. sleep(1.3)
  2154. openAddressBar = true
  2155.  
  2156. fs.delete(themeLocation)
  2157. fs.move(rootFolder .. "/temp_file", themeLocation)
  2158. theme = th
  2159. redirect("home")
  2160. end
  2161. end
  2162. else
  2163. print("")
  2164. rightPrint(string.rep(" ", 30))
  2165. rightPrint(" Themes are not available on ")
  2166. rightPrint(" normal computers! :( ")
  2167. rightPrint(string.rep(" ", 30))
  2168. end
  2169. end
  2170.  
  2171. pages["downloads"] = function(site) redirect("settings/themes") end
  2172.  
  2173. pages["settings"] = function(site)
  2174. term.setBackgroundColor(colors[theme["background"]])
  2175. term.clear()
  2176. term.setTextColor(colors[theme["text-color"]])
  2177. term.setBackgroundColor(colors[theme["top-box"]])
  2178. print("")
  2179. leftPrint(string.rep(" ", 17 + serverList[serverID]:len()))
  2180. leftPrint(" Firewolf Settings " .. string.rep(" ", serverList[serverID]:len() - 3))
  2181. leftPrint(" Designed For: " .. serverList[serverID] .. " ")
  2182. leftPrint(string.rep(" ", 17 + serverList[serverID]:len()))
  2183. print("\n")
  2184.  
  2185. local a = "Automatic Updating - On"
  2186. if autoupdate == "false" then a = "Automatic Updating - Off" end
  2187. local b = "Home - rdnt://" .. homepage
  2188. if b:len() >= 28 then b = b:sub(1, 24) .. "..." end
  2189.  
  2190. term.setBackgroundColor(colors[theme["bottom-box"]])
  2191. for i = 1, 9 do rightPrint(string.rep(" ", 36)) end
  2192. local c = {{a, w - a:len() - 6, 9}, {"Change Theme", w - 18, 11}, {b, w - b:len() - 6, 13},
  2193. {"Reset Firewolf", w - 20, 15}}
  2194. if not isAdvanced() then
  2195. c = {{a, w - a:len(), 9}, {b, w - b:len(), 11}, {"Reset Firewolf", w - 14, 13}}
  2196. end
  2197.  
  2198. local opt = prompt(c, "vertical")
  2199. if opt == a then
  2200. if autoupdate == "true" then autoupdate = "false"
  2201. elseif autoupdate == "false" then autoupdate = "true" end
  2202. elseif opt == "Change Theme" and isAdvanced() then
  2203. redirect("settings/themes")
  2204. elseif opt == b then
  2205. if isAdvanced() then term.setCursorPos(w - 30, 14)
  2206. else term.setCursorPos(w - 30, 12) end
  2207. write("rdnt://")
  2208. local a = read()
  2209. if a ~= "" then homepage = a end
  2210. elseif opt == "Reset Firewolf" then
  2211. term.setBackgroundColor(colors[theme["background"]])
  2212. term.clear()
  2213. term.setCursorPos(1, 1)
  2214. term.setTextColor(colors[theme["text-color"]])
  2215. term.setBackgroundColor(colors[theme["top-box"]])
  2216. print("")
  2217. leftPrint(string.rep(" ", 17))
  2218. leftPrint(" Reset Firewolf ")
  2219. leftPrint(string.rep(" ", 17))
  2220. print("\n")
  2221. term.setBackgroundColor(colors[theme["bottom-box"]])
  2222. for i = 1, 11 do rightPrint(string.rep(" ", 26)) end
  2223. local opt = prompt({{"Reset History", w - 19, 8}, {"Reset Servers", w - 19, 9},
  2224. {"Reset Theme", w - 17, 10}, {"Reset Cache", w - 17, 11}, {"Reset Databases", w - 21, 12},
  2225. {"Reset Settings", w - 20, 13}, {"Back", w - 10, 14}, {"Reset All", w - 15, 16}},
  2226. "vertical")
  2227.  
  2228. openAddressBar = false
  2229. if opt == "Reset All" then
  2230. fs.delete(rootFolder)
  2231. elseif opt == "Reset History" then
  2232. fs.delete(historyLocation)
  2233. elseif opt == "Reset Servers" then
  2234. fs.delete(serverFolder)
  2235. fs.delete(serverLocation)
  2236. elseif opt == "Reset Cache" then
  2237. fs.delete(cacheFolder)
  2238. elseif opt == "Reset Databases" then
  2239. fs.delete(userWhitelist)
  2240. fs.delete(userBlacklist)
  2241. elseif opt == "Reset Settings" then
  2242. fs.delete(settingsLocation)
  2243. elseif opt == "Reset Theme" then
  2244. fs.delete(themeLocation)
  2245. elseif opt == "Back" then
  2246. openAddressBar = true
  2247. redirect("settings")
  2248. end
  2249.  
  2250. term.setBackgroundColor(colors[theme["background"]])
  2251. term.clear()
  2252. term.setCursorPos(1, 1)
  2253. term.setBackgroundColor(colors[theme["top-box"]])
  2254. print("\n\n")
  2255. leftPrint(string.rep(" ", 17))
  2256. leftPrint(" Reset Firewolf ")
  2257. leftPrint(string.rep(" ", 17))
  2258. print("")
  2259.  
  2260. term.setCursorPos(1, 10)
  2261. term.setBackgroundColor(colors[theme["bottom-box"]])
  2262. rightPrint(string.rep(" ", 27))
  2263. rightPrint(" Firewolf has been reset! ")
  2264. rightWrite(string.rep(" ", 27))
  2265. if isAdvanced() then rightPrint(" Click to exit... ")
  2266. else rightPrint(" Press any key to exit... ") end
  2267. rightPrint(string.rep(" ", 27))
  2268.  
  2269. while true do
  2270. local e = os.pullEvent()
  2271. if e == "mouse_click" or e == "key" then return true end
  2272. end
  2273. end
  2274.  
  2275. -- Save
  2276. local f = io.open(settingsLocation, "w")
  2277. f:write(textutils.serialize({auto = autoupdate, incog = incognito, home = homepage}))
  2278. f:close()
  2279.  
  2280. redirect("settings")
  2281. end
  2282.  
  2283.  
  2284. -- -------- Credits
  2285.  
  2286. pages["credits"] = function(site)
  2287. term.setBackgroundColor(colors[theme["background"]])
  2288. term.clear()
  2289. print("\n")
  2290. term.setTextColor(colors[theme["text-color"]])
  2291. term.setBackgroundColor(colors[theme["top-box"]])
  2292. leftPrint(string.rep(" ", 19))
  2293. leftPrint(" Firewolf Credits ")
  2294. leftPrint(string.rep(" ", 19))
  2295. print("\n")
  2296.  
  2297. term.setBackgroundColor(colors[theme["bottom-box"]])
  2298. rightPrint(string.rep(" ", 38))
  2299. rightPrint(" Coded by: GravityScore ")
  2300. rightPrint(" and 1lann ")
  2301. rightPrint(string.rep(" ", 38))
  2302. rightPrint(" Based off: RednetExplorer 2.4.1 ")
  2303. rightPrint(" Made by ComputerCraftFan11 ")
  2304. rightPrint(string.rep(" ", 38))
  2305. end
  2306.  
  2307.  
  2308. -- -------- Error Pages
  2309.  
  2310. errorPages["overspeed"] = function(site)
  2311. clearPage("overspeed", colors[theme["background"]])
  2312. print("")
  2313. term.setTextColor(colors[theme["text-color"]])
  2314. term.setBackgroundColor(colors[theme["top-box"]])
  2315. leftPrint(string.rep(" ", 14))
  2316. leftPrint(" Warning! D: ")
  2317. leftPrint(string.rep(" ", 14))
  2318. print("")
  2319.  
  2320. term.setBackgroundColor(colors[theme["bottom-box"]])
  2321. rightPrint(string.rep(" ", 40))
  2322. rightPrint(" Website browsing sleep limit reached! ")
  2323. rightPrint(string.rep(" ", 40))
  2324. rightPrint(" To prevent Firewolf from spamming ")
  2325. rightPrint(" rednet, Firewolf has stopped loading ")
  2326. rightPrint(" the page. ")
  2327. for i = 1, 3 do rightPrint(string.rep(" ", 40)) end
  2328.  
  2329. openAddressBar = false
  2330. for i = 1, 5 do
  2331. term.setCursorPos(1, 14)
  2332. rightWrite(string.rep(" ", 43))
  2333. if 6 - i == 1 then rightWrite(" Please wait 1 second... ")
  2334. else rightWrite(" Please wait " .. tostring(6 - i) .. " seconds... ") end
  2335. sleep(1)
  2336. end
  2337. openAddressBar = true
  2338.  
  2339. term.setCursorPos(1, 14)
  2340. rightWrite(string.rep(" ", 43))
  2341. rightWrite(" You may now browse normally ")
  2342. end
  2343.  
  2344. errorPages["crash"] = function(error)
  2345. clearPage("crash", colors[theme["background"]])
  2346. print("")
  2347. term.setTextColor(colors[theme["text-color"]])
  2348. term.setBackgroundColor(colors[theme["top-box"]])
  2349. leftPrint(string.rep(" ", 30))
  2350. leftPrint(" The Website Has Crashed! D: ")
  2351. leftPrint(string.rep(" ", 30))
  2352. print("")
  2353.  
  2354. term.setBackgroundColor(colors[theme["bottom-box"]])
  2355. rightPrint(string.rep(" ", 31))
  2356. rightPrint(" The website has crashed! ")
  2357. rightPrint(" Report this to the operator: ")
  2358. rightPrint(string.rep(" ", 31))
  2359. term.setBackgroundColor(colors[theme["background"]])
  2360. print("")
  2361. print(" " .. tostring(error))
  2362. print("")
  2363.  
  2364. term.setBackgroundColor(colors[theme["bottom-box"]])
  2365. rightPrint(string.rep(" ", 31))
  2366. rightPrint(" You may now browse normally ")
  2367. rightPrint(string.rep(" ", 31))
  2368. end
  2369.  
  2370.  
  2371. -- -------- External Page
  2372.  
  2373. local function external(site)
  2374. -- Clear
  2375. term.setTextColor(colors[theme["text-color"]])
  2376. term.setBackgroundColor(colors[theme["background"]])
  2377. term.clear()
  2378. term.setCursorPos(1, 1)
  2379. print("\n\n\n")
  2380. centerWrite("Connecting to Website...")
  2381. loadingRate = loadingRate + 1
  2382.  
  2383. -- Modem
  2384. if curProtocol == protocols.rdnt then
  2385. setfenv(checkForModem, override)
  2386. checkForModem(function()
  2387. term.setBackgroundColor(colors[theme["background"]])
  2388. term.clear()
  2389. term.setCursorPos(1, 1)
  2390. print("\n")
  2391. term.setTextColor(colors[theme["text-color"]])
  2392. term.setBackgroundColor(colors[theme["top-box"]])
  2393. leftPrint(string.rep(" ", 24))
  2394. leftPrint(" No Modem Attached! D: ")
  2395. leftPrint(string.rep(" ", 24))
  2396. print("\n")
  2397.  
  2398. term.setBackgroundColor(colors[theme["bottom-box"]])
  2399. rightPrint(string.rep(" ", 40))
  2400. rightPrint(" No wireless modem was found on this ")
  2401. rightPrint(" computer, and Firewolf cannot use the ")
  2402. rightPrint(" RDNT protocol without one! ")
  2403. rightPrint(string.rep(" ", 40))
  2404. rightPrint(" Waiting for a modem to be attached... ")
  2405. rightPrint(string.rep(" ", 40))
  2406. end)
  2407. end
  2408.  
  2409. -- Get website
  2410. local webFunc = curProtocol.getWebsite
  2411. setfenv(webFunc, override)
  2412. local id, content, status = nil, nil, nil
  2413. pcall(function() id, content, status = webFunc(site) end)
  2414.  
  2415. local cacheLoc = cacheFolder .. "/" .. site:gsub("/", "$slazh$")
  2416. if id and status then
  2417. -- Clear
  2418. term.setBackgroundColor(colors.black)
  2419. term.setTextColor(colors.white)
  2420. term.clear()
  2421. term.setCursorPos(1, 1)
  2422.  
  2423. -- Save
  2424. local f = io.open(cacheLoc, "w")
  2425. f:write(content)
  2426. f:close()
  2427.  
  2428. local fn, err = loadfile(cacheLoc)
  2429. if not err then
  2430. setfenv(fn, antivirus)
  2431. if status == "whitelist" then setfenv(fn, override) end
  2432. _, err = pcall(function() fn() end)
  2433. setfenv(1, override)
  2434. end
  2435.  
  2436. if err then
  2437. local errFunc = errorPages["crash"]
  2438. setfenv(errFunc, override)
  2439. pcall(function() errFunc(err) end)
  2440. end
  2441. else
  2442. if fs.exists(cacheLoc) and not fs.isDir(cacheLoc) then
  2443. term.clearLine()
  2444. centerPrint("Could Not Connect to Website!")
  2445. print("")
  2446. centerPrint("A Cached Version was Found.")
  2447. local opt = prompt({{"Load Cache", -1, 10}, {"Continue to Search Results", -1, 12}},
  2448. "vertical")
  2449. if opt == "Load Cache" then
  2450. -- Clear
  2451. term.setBackgroundColor(colors.black)
  2452. term.setTextColor(colors.white)
  2453. term.clear()
  2454. term.setCursorPos(1, 1)
  2455.  
  2456. -- Run
  2457. local fn, err = loadfile(cacheLoc)
  2458. if not err then
  2459. setfenv(fn, antivirus)
  2460. _, err = pcall(function() fn() end)
  2461. setfenv(1, override)
  2462. end
  2463.  
  2464. return
  2465. end
  2466. end
  2467.  
  2468. openAddressBar = true
  2469. local res = {}
  2470. if site ~= "" then
  2471. for _, v in pairs(dnsDatabase[1]) do
  2472. if v:find(site:lower(), 1, true) then
  2473. table.insert(res, v)
  2474. end
  2475. end
  2476. else
  2477. for _, v in pairs(dnsDatabase[1]) do
  2478. table.insert(res, v)
  2479. end
  2480. end
  2481.  
  2482. table.sort(res)
  2483. table.sort(res, function(a, b)
  2484. local _, ac = a:gsub("rdnt://", ""):gsub("http://", ""):gsub(site:lower(), "")
  2485. local _, bc = b:gsub("rdnt://", ""):gsub("http://", ""):gsub(site:lower(), "")
  2486. return ac > bc
  2487. end)
  2488.  
  2489. term.setBackgroundColor(colors[theme["background"]])
  2490. term.clear()
  2491. term.setCursorPos(1, 1)
  2492. if #res > 0 then
  2493. print("")
  2494. term.setTextColor(colors[theme["text-color"]])
  2495. term.setBackgroundColor(colors[theme["top-box"]])
  2496. local t = "1 Search Result"
  2497. if #res > 1 then t = #res .. " Search Results" end
  2498. leftPrint(string.rep(" ", t:len() + 3))
  2499. leftPrint(" " .. t .. " ")
  2500. leftPrint(string.rep(" ", t:len() + 3))
  2501. print("")
  2502.  
  2503. term.setBackgroundColor(colors[theme["bottom-box"]])
  2504. for i = 1, 12 do rightPrint(string.rep(" ", 42)) end
  2505. local opt = scrollingPrompt(res, w - 39, 7, 10, 38)
  2506. if opt then redirect(opt:gsub("rdnt://", ""):gsub("http://", "")) end
  2507. elseif site == "" and #res < 1 then
  2508. print("\n\n")
  2509. term.setTextColor(colors[theme["text-color"]])
  2510. term.setBackgroundColor(colors[theme["top-box"]])
  2511. centerPrint(string.rep(" ", 47))
  2512. centerWrite(string.rep(" ", 47))
  2513. centerPrint("No Websites are Currently Online! D:")
  2514. centerWrite(string.rep(" ", 47))
  2515. centerPrint(string.rep(" ", 47))
  2516. centerWrite(string.rep(" ", 47))
  2517. centerPrint("Why not make one yourself?")
  2518. centerWrite(string.rep(" ", 47))
  2519. centerPrint("Visit rdnt://server!")
  2520. centerPrint(string.rep(" ", 47))
  2521. else
  2522. print("")
  2523. term.setTextColor(colors[theme["text-color"]])
  2524. term.setBackgroundColor(colors[theme["top-box"]])
  2525. leftPrint(string.rep(" ", 11))
  2526. leftPrint(" Oh Noes! ")
  2527. leftPrint(string.rep(" ", 11))
  2528. print("\n")
  2529.  
  2530. term.setBackgroundColor(colors[theme["bottom-box"]])
  2531. rightPrint(string.rep(" ", 43))
  2532. rightPrint([[ ______ __ ]])
  2533. rightPrint([[ / ____/_____ _____ ____ _____ / / ]])
  2534. rightPrint([[ / __/ / ___// ___// __ \ / ___// / ]])
  2535. rightPrint([[ / /___ / / / / / /_/ // / /_/ ]])
  2536. rightPrint([[ /_____//_/ /_/ \____//_/ (_) ]])
  2537. rightPrint(string.rep(" ", 43))
  2538. if verifyBlacklist(id) then
  2539. rightPrint(" Could not connect to the website! It has ")
  2540. rightPrint(" been blocked by a database admin! ")
  2541. else
  2542. rightPrint(" Could not connect to the website! It may ")
  2543. rightPrint(" be down, or not exist! ")
  2544. end
  2545. rightPrint(string.rep(" ", 43))
  2546. end
  2547. end
  2548. end
  2549.  
  2550.  
  2551. -- -------- Website Coroutine
  2552.  
  2553. local function websitecoroutine()
  2554. local loadingClock = os.clock()
  2555. while true do
  2556. -- Reset and clear
  2557. setfenv(1, backupEnv)
  2558. os.pullEvent = pullevent
  2559. browserAgent = browserAgentTemplate
  2560. w, h = term.getSize()
  2561. curbackground = colors.black
  2562. curtext = colors.white
  2563.  
  2564. clearPage(website)
  2565. term.setBackgroundColor(colors.black)
  2566. term.setTextColor(colors.white)
  2567.  
  2568. -- Add to history
  2569. if website ~= "exit" and website ~= addressBarHistory[#addressBarHistory] then
  2570. table.insert(addressBarHistory, website)
  2571. end
  2572.  
  2573. -- Overspeed
  2574. checkForModem()
  2575. if os.clock() - loadingClock > 5 then
  2576. -- Reset loading rate
  2577. loadingRate = 0
  2578. loadingClock = os.clock()
  2579. end
  2580.  
  2581. -- Run site
  2582. if loadingRate >= 8 then
  2583. -- Overspeed error
  2584. local overspeedFunc = errorPages["overspeed"]
  2585. setfenv(overspeedFunc, override)
  2586. overspeedFunc()
  2587.  
  2588. loadingRate = 0
  2589. loadingClock = os.clock()
  2590. elseif type(pages[website]) == "function" then
  2591. -- Run site function
  2592. local siteFunc = pages[website]
  2593. setfenv(siteFunc, override)
  2594. local exit = false
  2595. local _, err = pcall(function() exit = siteFunc() end)
  2596.  
  2597. if err then
  2598. local errFunc = errorPages["crash"]
  2599. setfenv(errFunc, override)
  2600. errFunc(err)
  2601. end
  2602.  
  2603. if exit then
  2604. os.queueEvent("terminate")
  2605. return
  2606. end
  2607. else
  2608. setfenv(external, override)
  2609. local _, err = pcall(function() external(website) end)
  2610.  
  2611. if err then
  2612. local errFunc = errorPages["crash"]
  2613. setfenv(errFunc, override)
  2614. errFunc(err)
  2615. end
  2616. end
  2617.  
  2618. -- Clear data folder
  2619. fs.delete(websiteDataFolder)
  2620. fs.makeDir(websiteDataFolder)
  2621.  
  2622. -- Wait for load
  2623. oldpullevent(event_loadWebsite)
  2624. end
  2625. end
  2626.  
  2627.  
  2628. -- -------- Address Bar Coroutine
  2629.  
  2630. local function searchresults()
  2631. local mod = true
  2632. if curProtocol == protocols.rdnt then
  2633. mod = false
  2634. for _, v in pairs(rs.getSides()) do if rednet.isOpen(v) then mod = true end end
  2635. end
  2636. if mod then curProtocol.getSearchResults() end
  2637.  
  2638. local lastCheck = os.clock()
  2639. while true do
  2640. local e = oldpullevent()
  2641. if website ~= "exit" and e == event_loadWebsite then
  2642. mod = true
  2643. if curProtocol == protocols.rdnt then
  2644. mod = false
  2645. for _, v in pairs(rs.getSides()) do if rednet.isOpen(v) then mod = true end end
  2646. end
  2647. if mod and os.clock() - lastCheck > 5 then
  2648. curProtocol.getSearchResults()
  2649. lastCheck = os.clock()
  2650. end
  2651. end
  2652. end
  2653. end
  2654.  
  2655. local function addressbarread()
  2656. local len = 4
  2657. local list = {}
  2658.  
  2659. local function draw(l)
  2660. local ox, oy = term.getCursorPos()
  2661. for i = 1, len do
  2662. term.setTextColor(colors[theme["address-bar-text"]])
  2663. term.setBackgroundColor(colors[theme["address-bar-background"]])
  2664. term.setCursorPos(1, i + 1)
  2665. write(string.rep(" ", w))
  2666. end
  2667. if theme["address-bar-base"] then term.setBackgroundColor(colors[theme["address-bar-base"]])
  2668. else term.setBackgroundColor(colors[theme["bottom-box"]]) end
  2669. term.setCursorPos(1, len + 2)
  2670. write(string.rep(" ", w))
  2671. term.setBackgroundColor(colors[theme["address-bar-background"]])
  2672.  
  2673. for i, v in ipairs(l) do
  2674. term.setCursorPos(2, i + 1)
  2675. write(v)
  2676. end
  2677. term.setCursorPos(ox, oy)
  2678. end
  2679.  
  2680. local function update(line, event, ...)
  2681. local params = {...}
  2682. local y = params[3]
  2683. if event == "char" or event == "history" or event == "delete" then
  2684. list = {}
  2685. for _, v in pairs(dnsDatabase[1]) do
  2686. if #list < len and
  2687. v:gsub("rdnt://", ""):gsub("http://", ""):find(line:lower(), 1, true) then
  2688. table.insert(list, v)
  2689. end
  2690. end
  2691.  
  2692. table.sort(list)
  2693. table.sort(list, function(a, b)
  2694. local _, ac = a:gsub("rdnt://", ""):gsub("http://", ""):gsub(line:lower(), "")
  2695. local _, bc = b:gsub("rdnt://", ""):gsub("http://", ""):gsub(line:lower(), "")
  2696. return ac > bc
  2697. end)
  2698. draw(list)
  2699. return false
  2700. elseif event == "mouse_click" then
  2701. for i = 1, #list do
  2702. if y == i + 1 then
  2703. return true, list[i]:gsub("rdnt://", ""):gsub("http://", "")
  2704. end
  2705. end
  2706. end
  2707. end
  2708.  
  2709. local mod = true
  2710. if curProtocol == protocols.rdnt then
  2711. mod = false
  2712. for _, v in pairs(rs.getSides()) do if rednet.isOpen(v) then mod = true end end
  2713. end
  2714. if isAdvanced() and mod then
  2715. return modRead({history = addressBarHistory, visibleLength = w - 2, textLength = 300,
  2716. liveUpdates = update, exitOnKey = "control"})
  2717. else
  2718. return modRead({history = addressBarHistory, visibleLength = w - 2, textLength = 300,
  2719. exitOnKey = "control"})
  2720. end
  2721. end
  2722.  
  2723. local function addressbarcoroutine()
  2724. while true do
  2725. local e, but, x, y = oldpullevent()
  2726. if (e == "key" and (but == 29 or but == 157)) or
  2727. (e == "mouse_click" and y == 1) then
  2728. if openAddressBar then
  2729. if e == "key" then x = -1 end
  2730. if x == w then
  2731. -- Open menu bar
  2732. menuBarOpen = true
  2733. term.setBackgroundColor(colors[theme["top-box"]])
  2734. term.setTextColor(colors[theme["text-color"]])
  2735. term.setCursorPos(1, 1)
  2736. write("> [- Exit Firewolf -] ")
  2737. elseif menuBarOpen and (x == 1 or (but == 29 or but == 157)) then
  2738. -- Close menu bar
  2739. menuBarOpen = false
  2740. clearPage(website, nil, true)
  2741. elseif x > 2 and x < 22 and menuBarOpen then
  2742. -- Exit
  2743. menuBarOpen = false
  2744. os.queueEvent(event_exitWebsite)
  2745. os.queueEvent("terminate")
  2746. return
  2747. elseif not menuBarOpen then
  2748. -- Exit website
  2749. os.queueEvent(event_exitWebsite)
  2750.  
  2751. -- Clear
  2752. term.setBackgroundColor(colors[theme["address-bar-background"]])
  2753. term.setTextColor(colors[theme["address-bar-text"]])
  2754. term.setCursorPos(2, 1)
  2755. term.clearLine()
  2756. if curProtocol == protocols.rdnt then write("rdnt://")
  2757. elseif curProtocol == protocols.http then write("http://") end
  2758.  
  2759. -- Read
  2760. local oldWebsite = website
  2761. os.pullEvent = oldpullevent
  2762. website = addressbarread()
  2763. os.pullEvent = pullevent
  2764. if website == nil then
  2765. website = oldWebsite
  2766. elseif website == "home" or website == "homepage" then
  2767. website = homepage
  2768. elseif website == "exit" then
  2769. os.queueEvent("terminate")
  2770. return
  2771. end
  2772.  
  2773. -- Load
  2774. os.queueEvent(event_loadWebsite)
  2775. end
  2776. end
  2777. elseif e == event_redirect then
  2778. -- Exit website
  2779. os.queueEvent(event_exitWebsite)
  2780.  
  2781. -- Set website
  2782. local oldWebsite = website
  2783. website = but
  2784. if website == nil or website == "exit" then
  2785. website = oldWebsite
  2786. elseif website == "home" or website == "homepage" then
  2787. website = homepage
  2788. end
  2789.  
  2790. -- Load
  2791. os.queueEvent(event_loadWebsite)
  2792. end
  2793. end
  2794. end
  2795.  
  2796.  
  2797. -- -------- Main
  2798.  
  2799. local function main()
  2800. -- Logo
  2801. term.setBackgroundColor(colors[theme["background"]])
  2802. term.setTextColor(colors[theme["text-color"]])
  2803. term.clear()
  2804. term.setCursorPos(1, 2)
  2805. term.setBackgroundColor(colors[theme["top-box"]])
  2806. leftPrint(string.rep(" ", 47))
  2807. leftPrint([[ ______ ____ ____ ______ ]])
  2808. leftPrint([[ ------- / ____// _// __ \ / ____/ ]])
  2809. leftPrint([[ ------ / /_ / / / /_/ // __/ ]])
  2810. leftPrint([[ ----- / __/ _/ / / _ _// /___ ]])
  2811. leftPrint([[ ---- / / /___//_/ |_|/_____/ ]])
  2812. leftPrint([[ --- / / _ __ ____ __ ______ ]])
  2813. leftPrint([[ -- /_/ | | / // __ \ / / / ____/ ]])
  2814. leftPrint([[ | | /| / // / / // / / /_ ]])
  2815. leftPrint([[ | |/ |/ // /_/ // /___ / __/ ]])
  2816. leftPrint([[ |__/|__/ \____//_____//_/ ]])
  2817. leftPrint(string.rep(" ", 47))
  2818. print("\n")
  2819. term.setBackgroundColor(colors[theme["bottom-box"]])
  2820.  
  2821. -- Load Settings
  2822. if fs.exists(settingsLocation) and not fs.isDir(settingsLocation) then
  2823. local f = io.open(settingsLocation, "r")
  2824. local a = textutils.unserialize(f:read("*l"))
  2825. if type(a) == "table" then
  2826. autoupdate = a.auto
  2827. incognito = a.incog
  2828. homepage = a.home
  2829. end
  2830. f:close()
  2831. else
  2832. autoupdate = "true"
  2833. incognito = "false"
  2834. homepage = "firewolf"
  2835. end
  2836. curProtocol = protocols.rdnt
  2837.  
  2838. -- Update
  2839. rightPrint(string.rep(" ", 32))
  2840. rightPrint(" Checking for Updates... ")
  2841. rightPrint(string.rep(" ", 32))
  2842. setfenv(updateClient, env)
  2843. if not noInternet then if updateClient(rightWrite) then
  2844. if debugFile then debugFile:close() end
  2845.  
  2846. -- Reset Environment
  2847. setfenv(1, oldEnv)
  2848. os.pullEvent = oldpullevent
  2849. shell.run(firewolfLocation)
  2850. error()
  2851. end end
  2852.  
  2853. -- Download Files
  2854. local x, y = term.getCursorPos()
  2855. term.setCursorPos(1, y - 2)
  2856. rightWrite(string.rep(" ", 32))
  2857. rightWrite(" Downloading Required Files... ")
  2858.  
  2859. if not noInternet then resetFilesystem() end
  2860. loadDatabases()
  2861.  
  2862. -- Modem
  2863. checkForModem()
  2864. website = homepage
  2865.  
  2866. -- Run
  2867. parallel.waitForAll(websitecoroutine, addressbarcoroutine, searchresults)
  2868. end
  2869.  
  2870. local function startup()
  2871. -- HTTP
  2872. if not http and not noInternet then
  2873. term.setTextColor(colors[theme["text-color"]])
  2874. term.setBackgroundColor(colors[theme["background"]])
  2875. term.clear()
  2876. term.setCursorPos(1, 2)
  2877. term.setBackgroundColor(colors[theme["top-box"]])
  2878. api.leftPrint(string.rep(" ", 24))
  2879. api.leftPrint(" HTTP API Not Enabled! ")
  2880. api.leftPrint(string.rep(" ", 24))
  2881. print("")
  2882.  
  2883. term.setBackgroundColor(colors[theme["bottom-box"]])
  2884. api.rightPrint(string.rep(" ", 36))
  2885. api.rightPrint(" Firewolf is unable to run without ")
  2886. api.rightPrint(" the HTTP API Enabled! Please ")
  2887. api.rightPrint(" enable it in your ComputerCraft ")
  2888. api.rightPrint(" Config! ")
  2889. api.rightPrint(string.rep(" ", 36))
  2890.  
  2891. if isAdvanced() then api.rightPrint(" Click to exit... ")
  2892. else api.rightPrint(" Press any key to exit... ") end
  2893. api.rightPrint(string.rep(" ", 36))
  2894.  
  2895. while true do
  2896. local e, but, x, y = oldpullevent()
  2897. if e == "mouse_click" or e == "key" then break end
  2898. end
  2899.  
  2900. return false
  2901. end
  2902.  
  2903. -- Turtle
  2904. if turtle then
  2905. term.clear()
  2906. term.setCursorPos(1, 2)
  2907. api.centerPrint("Advanced Comptuer Required!")
  2908. print("\n")
  2909. api.centerPrint(" This version of Firewolf requires ")
  2910. api.centerPrint(" an Advanced Comptuer to run! ")
  2911. print("")
  2912. api.centerPrint(" Turtles may not be used to run ")
  2913. api.centerPrint(" Firewolf! :( ")
  2914. print("")
  2915. api.centerPrint("Press any key to exit...")
  2916.  
  2917. oldpullevent("key")
  2918. return false
  2919. end
  2920.  
  2921. -- Run
  2922. setfenv(main, env)
  2923. local _, err = pcall(main)
  2924. if err and err ~= "parallel:22: Terminated" then
  2925. term.setTextColor(colors[theme["text-color"]])
  2926. term.setBackgroundColor(colors[theme["background"]])
  2927. term.clear()
  2928. term.setCursorPos(1, 2)
  2929. term.setCursorBlink(false)
  2930. term.setBackgroundColor(colors[theme["top-box"]])
  2931. api.leftPrint(string.rep(" ", 27))
  2932. api.leftPrint(" Firewolf has Crashed! D: ")
  2933. api.leftPrint(string.rep(" ", 27))
  2934. print("")
  2935. term.setBackgroundColor(colors[theme["background"]])
  2936. print("")
  2937. print(" " .. err)
  2938. print("")
  2939.  
  2940. term.setBackgroundColor(colors[theme["bottom-box"]])
  2941. api.rightPrint(string.rep(" ", 41))
  2942. if autoupdate == "true" then
  2943. api.rightPrint(" Please report this error to 1lann or ")
  2944. api.rightPrint(" GravityScore so we are able to fix it! ")
  2945. api.rightPrint(" If this problem persists, try deleting ")
  2946. api.rightPrint(" " .. rootFolder .. " ")
  2947. else
  2948. api.rightPrint(" Automatic updating is off! A new ")
  2949. api.rightPrint(" version may have have been released ")
  2950. api.rightPrint(" that may fix this error! ")
  2951. api.rightPrint(" If you didn't turn auto updating ")
  2952. api.rightPrint(" off, delete " .. rootFolder .. " ")
  2953. end
  2954.  
  2955. api.rightPrint(string.rep(" ", 41))
  2956. if isAdvanced() then api.rightPrint(" Click to exit... ")
  2957. else api.rightPrint(" Press any key to exit... ") end
  2958. api.rightPrint(string.rep(" ", 41))
  2959.  
  2960. while true do
  2961. local e, but, x, y = oldpullevent()
  2962. if e == "mouse_click" or e == "key" then break end
  2963. end
  2964.  
  2965. return false
  2966. end
  2967. end
  2968.  
  2969. -- Check If Read Only
  2970. if fs.isReadOnly(firewolfLocation) or fs.isReadOnly(rootFolder) then
  2971. print("Firewolf cannot modify itself or its root folder!")
  2972. print("")
  2973. print("This cold be caused by Firewolf being placed in")
  2974. print("the rom folder, or another program may be")
  2975. print("preventing the modification of Firewolf.")
  2976.  
  2977. -- Reset Environment and Exit
  2978. setfenv(1, oldEnv)
  2979. error()
  2980. end
  2981.  
  2982. -- Theme
  2983. if not isAdvanced() then
  2984. theme = originalTheme
  2985. else
  2986. theme = loadTheme(themeLocation)
  2987. if theme == nil then theme = defaultTheme end
  2988. end
  2989.  
  2990. -- Debug File
  2991. if #tArgs > 0 and tArgs[1] == "debug" then
  2992. print("Debug Mode Enabled!")
  2993.  
  2994. if fs.exists(debugLogLocation) then debugFile = io.open(debugLogLocation, "a")
  2995. else debugFile = io.open(debugLogLocation, "w") end
  2996. debugFile:write("\n-- [" .. textutils.formatTime(os.time()) .. "] New Log --")
  2997. sleep(1.3)
  2998. end
  2999.  
  3000. -- Start
  3001. startup()
  3002.  
  3003. -- Exit Message
  3004. term.setBackgroundColor(colors.black)
  3005. term.setTextColor(colors.white)
  3006. term.setCursorBlink(false)
  3007. term.clear()
  3008. term.setCursorPos(1, 1)
  3009. api.centerPrint("Thank You for Using Firewolf " .. version)
  3010. api.centerPrint("Made by 1lann and GravityScore")
  3011. term.setCursorPos(1, 3)
  3012.  
  3013. -- Close
  3014. for _, v in pairs(rs.getSides()) do
  3015. if peripheral.getType(v) == "modem" then rednet.close(v) end
  3016. end
  3017. if debugFile then debugFile:close() end
  3018.  
  3019. -- Reset Environment
  3020. setfenv(1, oldEnv)
  3021. os.pullEvent = oldpullevent
Advertisement
Add Comment
Please, Sign In to add comment