Advertisement
Guest User

Untitled

a guest
May 28th, 2015
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.04 KB | None | 0 0
  1. -- ********************************************************************************** --
  2. -- **                                                                              ** --
  3. -- **   Internet server                  By: Krutoy                                ** --
  4. -- **                                                                              ** --
  5. -- ********************************************************************************** --
  6.  
  7.  
  8. --===========================================================
  9. -- Variables
  10. --===========================================================
  11. package.loaded.ui   = nil
  12.  
  13. local serialization = require"serialization"
  14. local component     = require"component"
  15. local internet      = require"internet"
  16. local unicode       = require"unicode"
  17. local thread        = require"thread"
  18. local shell         = require"shell"
  19. local term          = require"term"
  20. local on            = require"opennet"
  21. local fs            = require"filesystem"
  22. --local ui            = require"ui"
  23.  
  24. local unpack = table.unpack
  25. local insert = table.insert
  26. local concat = table.concat
  27. local gpu    = component.gpu
  28.  
  29. local _version      = 0 -- Current version
  30. local workDir       = "opennet/"
  31. local serverDir     = "opennet/internet_server/"
  32. local project       = "https://preview.c9.io/krutoy242/opennet/"
  33.  
  34. local W,H           = gpu.getResolution()
  35. local loaderSymbols = "▝▗▖▘"
  36. local loadStep      = unicode.len(loaderSymbols)
  37. local command       = {}
  38.  
  39. local args, options = shell.parse(...)
  40.  
  41. --===========================================================
  42. -- Inits
  43. --===========================================================
  44.  
  45. -- Init
  46. local ip, err = on.getIP()
  47. if not ip then io.stderr:write("\n"..err.."\n") ;return end
  48.  
  49. thread.init()
  50.  
  51.  
  52. --===========================================================
  53. -- Utilities
  54. --===========================================================
  55.  
  56. local function setColor(c)
  57.   if gpu.getForeground() ~= c then
  58.     io.stdout:flush()
  59.     gpu.setForeground(c)
  60.   end
  61. end
  62.  
  63. local function write_c(c, ...)
  64.   local oldCol = gpu.getForeground()
  65.   setColor(c)
  66.   io.write(...)
  67.   setColor(oldCol)
  68. end
  69.  
  70.  
  71. -- Shows small loading circle on screen
  72. local function workIndicator(isWorking)
  73.   local col = isWorking and 0xFF0000 or 0x00FF00
  74.   local oldCol = gpu.getForeground()
  75.   gpu.setForeground(col)
  76.   gpu.fill(W, 1, 1, 1, unicode.sub(loaderSymbols, loadStep, loadStep))
  77.   gpu.setForeground(oldCol)
  78.   loadStep = (loadStep % unicode.len(loaderSymbols)) + 1
  79. end
  80.  
  81. local function trimString(str, len)
  82.   len = len or 20
  83.   local s = tostring(str)
  84.   s = s:gsub("\r", ""):gsub("\n", " ")
  85.   return tostring(s):sub(1,len) .. ((#tostring(s)>len) and "..." or "")
  86. end
  87.  
  88. function parse_cloud9(pageContent)
  89.   local result={}
  90.   for _name, _type, _size in pageContent:gmatch(
  91.       '<tr>.-<td>.-<a href=".-">(.-)</a>.-</td>.-<td>(.-)</td>.-<td>(%d*)</td>.-</tr>') do
  92.       if unicode.len(_type)>0 then insert(result, {name=_name, type=_type, size=tonumber(_size)}) end
  93.   end
  94.   return result
  95. end
  96.  
  97.  
  98. local function readFile(fileName)
  99.   local f = io.open(fileName,"r")
  100.   if not f then return end
  101.  
  102.   local code=f:read("*a")
  103.   f:close()
  104.  
  105.   return code
  106. end
  107.  
  108. --===========================================================
  109. -- Update server
  110. --===========================================================
  111.  
  112. local function getVersion()
  113.   _version = tonumber(readFile(workDir.."_version") or 0)
  114.   return _version
  115. end
  116.  
  117. local function checkUpdate()
  118.  
  119.   -- Download url to file
  120.   local urlToFile = function(url, fileName)
  121.     local fPath = workDir..fileName
  122.     fs.makeDirectory(fs.path(fPath))
  123.     local ok, result = shell.execute("wget -f \""..url.."\" "..fPath)
  124.     if not ok or not result then
  125.       write_c(0xFF0000, "\nFailed to load "..fileName.."\n")
  126.       return
  127.     end
  128.     return true
  129.   end
  130.  
  131.   -- Load all text from url
  132.   local getUrlText = function(url)
  133.     local result, response = pcall(internet.request, url)
  134.     local chunks = {}
  135.     if result then
  136.       for chunk in response do
  137.         insert(chunks, chunk)
  138.       end
  139.     else
  140.       write_c(0xFF0000, "HTTP request failed: " .. response .. "\n")
  141.       return
  142.     end
  143.     return concat(chunks)
  144.   end  
  145.  
  146.  
  147.   -- Recursively add all files in table
  148.   local recursivePush
  149.   recursivePush = function(files, t, prefix)
  150.     prefix = prefix or ""
  151.     for _,v in ipairs(t) do
  152.       local localPath = prefix..v.name
  153.       local fullPath  = project..localPath
  154.       if v.type == "inode/directory" then
  155.         recursivePush(files, parse_cloud9(getUrlText(fullPath)), prefix..v.name.."/")
  156.       else
  157.         insert(files, {fullPath=fullPath, localPath=localPath})
  158.       end
  159.     end
  160.   end
  161.  
  162.   -- Our version
  163.   getVersion()
  164.  
  165.   -- Download version file
  166.   write_c(0x00AAFF, "Trying to update server...\n")
  167.   if not urlToFile(project.."_version", "_version") then
  168.     write_c(0xFF0000, "Updating failed.\n")
  169.     return
  170.   end
  171.  
  172.   -- Check our version
  173.   local ver = tonumber(readFile(workDir.."_version"))
  174.   if _version >= ver then
  175.     write_c(0xFFFF00, "Already latest version\n")
  176.     return
  177.   end
  178.  
  179.   -- Load all files in folder "client"
  180.   local allfiles = {}
  181.   write_c(0x00AAFF, "New vesion avaliable! Loading list...\n")
  182.   recursivePush(allfiles, parse_cloud9(getUrlText(project)))
  183.  
  184.   -- Rewrite all files to disk
  185.   for _,v in ipairs(allfiles) do
  186.     if not urlToFile(v.fullPath, v.localPath) then
  187.       write_c(0xFF0000, "Updating failed: "..v.fullPath.."\n")
  188.       return
  189.     end
  190.   end
  191.  
  192.  
  193.   -- Move autorun to root
  194.   local ok, err = shell.execute("mv -f "..serverDir.."autorun.lua autorun.lua")
  195.   if not ok then
  196.     write_c(0xFF0000, "Cant move autorun.lua: "..err.."\n")
  197.   end
  198.  
  199.  
  200.   -- Reload server program without updating
  201.   write_c(0xFFFFFF, "Reload program from autorun\n")
  202.   shell.execute("autorun -f", _G)
  203.   return true
  204. end
  205.  
  206. function command.getFileList(folderName)
  207.  
  208.   -- Recursively add all files
  209.   local recursivePush
  210.   recursivePush = function(t, folderName)
  211.     for f in fs.list(workDir..folderName) do
  212.       if fs.isDirectory(f) then
  213.         recursivePush(t, folderName..f)
  214.       else
  215.         insert(t, folderName..f)
  216.       end
  217.     end
  218.   end
  219.  
  220.   -- Get list of all files in this folder on working directory
  221.   local filesInFolder = {}
  222.   recursivePush(filesInFolder, folderName)
  223.  
  224.   return filesInFolder
  225. end
  226.  
  227. function command.getFile(fileName)
  228.   return readFile(workDir..fileName)
  229. end
  230.  
  231. function command.checkUpdate(currVers)
  232.   return currVers < _version
  233. end
  234.  
  235.  
  236.  
  237. --===========================================================
  238. -- Internet server
  239. --===========================================================
  240.  
  241. -- Additional function actions
  242. function command.request(...)
  243.   local resultFnc = internet.request(...)
  244.   local handleName
  245.   if resultFnc then
  246.     handleName = tostring(resultFnc)
  247.    
  248.     -- Add Function that will be executed by iterator handle
  249.     command[handleName] = function(...)
  250.       local chunk = resultFnc()
  251.       if not chunk then command[handleName] = nil end
  252.       io.write("\n┃●" .. trimString(chunk))
  253.       return chunk
  254.     end
  255.   end
  256.  
  257.   return handleName
  258. end
  259.  
  260.  
  261. --===========================================================
  262. -- Receive loop
  263. --===========================================================
  264.  
  265. local function processReceived(r)
  266.   if not r or #r==0 then return end
  267.   local r_senderIP = r[1]
  268.   local r_division = r[2]
  269.   local r_funcName = r[3]
  270.   local r_firstMsg = r[4]
  271.   -- Check if this message from internet
  272.   if type(r_firstMsg)=="string" then
  273.     local obj = serialization.unserialize(r_firstMsg)
  274.    
  275.     -- We have raw, not serialized data
  276.     if not obj then obj = {r_firstMsg} end
  277.    
  278.  
  279.     --io.write("\n▐ Calling function: " .. r_funcName .. "...")
  280.  
  281.     local returnedObj
  282.     if command[r_funcName] then
  283.       returnedObj = {command[r_funcName](unpack(obj))}
  284.     else
  285.       local fnc = internet[r_funcName]
  286.       if type(fnc)=="function" then
  287.         returnedObj = {fnc(unpack(obj))}
  288.       end
  289.     end
  290.    
  291.     -- Determine if we dont need to serialize object before send
  292.     local rawReturn = (r_funcName == "getFile")
  293.     local sendStr   = rawReturn and unpack(returnedObj) or serialization.serialize(returnedObj)
  294.  
  295.     io.write("\n┗◀", trimString(sendStr, 60))
  296.    
  297.     on.send(r_senderIP, sendStr)
  298.   end
  299.  
  300. end
  301.  
  302. -- Update if needed
  303. if not options.f then
  304.   -- Close upplication if we updated
  305.   if checkUpdate() then return end
  306. end
  307.  
  308. -- Welcome screen
  309. term.clear()
  310. write_c(0x0000FF, "\n========== Internet server (version:".. getVersion() ..") ==========\n")
  311.  
  312. -- Receiving loop
  313. while true do
  314.   local r = {on.receive(0.5)}
  315.  
  316.   -- Write log
  317.   if #r > 0 then
  318.     workIndicator(true)
  319.     write_c(0x00AAFF, "\n┏▶")
  320.     local s = ""
  321.     for _,v in pairs(r) do s = s..trimString(v).." " end
  322.     write_c(0xFFFFFF, trimString(s,60))
  323.   end
  324.  
  325.   -- Process it
  326.   local ok, err = pcall(processReceived,r)
  327.   if not ok then
  328.     io.stderr:write("\n⚠: "..tostring(err).."\n")
  329.   end
  330.  
  331.   -- Show that we are working
  332.   workIndicator()
  333. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement