Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- ********************************************************************************** --
- -- ** ** --
- -- ** Internet server By: Krutoy ** --
- -- ** ** --
- -- ********************************************************************************** --
- --===========================================================
- -- Variables
- --===========================================================
- package.loaded.ui = nil
- local serialization = require"serialization"
- local component = require"component"
- local internet = require"internet"
- local unicode = require"unicode"
- local thread = require"thread"
- local shell = require"shell"
- local term = require"term"
- local on = require"opennet"
- local fs = require"filesystem"
- --local ui = require"ui"
- local unpack = table.unpack
- local insert = table.insert
- local concat = table.concat
- local gpu = component.gpu
- local _version = 0 -- Current version
- local workDir = "opennet/"
- local serverDir = "opennet/internet_server/"
- local project = "https://preview.c9.io/krutoy242/opennet/"
- local W,H = gpu.getResolution()
- local loaderSymbols = "▝▗▖▘"
- local loadStep = unicode.len(loaderSymbols)
- local command = {}
- local args, options = shell.parse(...)
- --===========================================================
- -- Inits
- --===========================================================
- -- Init
- local ip, err = on.getIP()
- if not ip then io.stderr:write("\n"..err.."\n") ;return end
- thread.init()
- --===========================================================
- -- Utilities
- --===========================================================
- local function setColor(c)
- if gpu.getForeground() ~= c then
- io.stdout:flush()
- gpu.setForeground(c)
- end
- end
- local function write_c(c, ...)
- local oldCol = gpu.getForeground()
- setColor(c)
- io.write(...)
- setColor(oldCol)
- end
- -- Shows small loading circle on screen
- local function workIndicator(isWorking)
- local col = isWorking and 0xFF0000 or 0x00FF00
- local oldCol = gpu.getForeground()
- gpu.setForeground(col)
- gpu.fill(W, 1, 1, 1, unicode.sub(loaderSymbols, loadStep, loadStep))
- gpu.setForeground(oldCol)
- loadStep = (loadStep % unicode.len(loaderSymbols)) + 1
- end
- local function trimString(str, len)
- len = len or 20
- local s = tostring(str)
- s = s:gsub("\r", ""):gsub("\n", " ")
- return tostring(s):sub(1,len) .. ((#tostring(s)>len) and "..." or "")
- end
- function parse_cloud9(pageContent)
- local result={}
- for _name, _type, _size in pageContent:gmatch(
- '<tr>.-<td>.-<a href=".-">(.-)</a>.-</td>.-<td>(.-)</td>.-<td>(%d*)</td>.-</tr>') do
- if unicode.len(_type)>0 then insert(result, {name=_name, type=_type, size=tonumber(_size)}) end
- end
- return result
- end
- local function readFile(fileName)
- local f = io.open(fileName,"r")
- if not f then return end
- local code=f:read("*a")
- f:close()
- return code
- end
- --===========================================================
- -- Update server
- --===========================================================
- local function getVersion()
- _version = tonumber(readFile(workDir.."_version") or 0)
- return _version
- end
- local function checkUpdate()
- -- Download url to file
- local urlToFile = function(url, fileName)
- local fPath = workDir..fileName
- fs.makeDirectory(fs.path(fPath))
- local ok, result = shell.execute("wget -f \""..url.."\" "..fPath)
- if not ok or not result then
- write_c(0xFF0000, "\nFailed to load "..fileName.."\n")
- return
- end
- return true
- end
- -- Load all text from url
- local getUrlText = function(url)
- local result, response = pcall(internet.request, url)
- local chunks = {}
- if result then
- for chunk in response do
- insert(chunks, chunk)
- end
- else
- write_c(0xFF0000, "HTTP request failed: " .. response .. "\n")
- return
- end
- return concat(chunks)
- end
- -- Recursively add all files in table
- local recursivePush
- recursivePush = function(files, t, prefix)
- prefix = prefix or ""
- for _,v in ipairs(t) do
- local localPath = prefix..v.name
- local fullPath = project..localPath
- if v.type == "inode/directory" then
- recursivePush(files, parse_cloud9(getUrlText(fullPath)), prefix..v.name.."/")
- else
- insert(files, {fullPath=fullPath, localPath=localPath})
- end
- end
- end
- -- Our version
- getVersion()
- -- Download version file
- write_c(0x00AAFF, "Trying to update server...\n")
- if not urlToFile(project.."_version", "_version") then
- write_c(0xFF0000, "Updating failed.\n")
- return
- end
- -- Check our version
- local ver = tonumber(readFile(workDir.."_version"))
- if _version >= ver then
- write_c(0xFFFF00, "Already latest version\n")
- return
- end
- -- Load all files in folder "client"
- local allfiles = {}
- write_c(0x00AAFF, "New vesion avaliable! Loading list...\n")
- recursivePush(allfiles, parse_cloud9(getUrlText(project)))
- -- Rewrite all files to disk
- for _,v in ipairs(allfiles) do
- if not urlToFile(v.fullPath, v.localPath) then
- write_c(0xFF0000, "Updating failed: "..v.fullPath.."\n")
- return
- end
- end
- -- Move autorun to root
- local ok, err = shell.execute("mv -f "..serverDir.."autorun.lua autorun.lua")
- if not ok then
- write_c(0xFF0000, "Cant move autorun.lua: "..err.."\n")
- end
- -- Reload server program without updating
- write_c(0xFFFFFF, "Reload program from autorun\n")
- shell.execute("autorun -f", _G)
- return true
- end
- function command.getFileList(folderName)
- -- Recursively add all files
- local recursivePush
- recursivePush = function(t, folderName)
- for f in fs.list(workDir..folderName) do
- if fs.isDirectory(f) then
- recursivePush(t, folderName..f)
- else
- insert(t, folderName..f)
- end
- end
- end
- -- Get list of all files in this folder on working directory
- local filesInFolder = {}
- recursivePush(filesInFolder, folderName)
- return filesInFolder
- end
- function command.getFile(fileName)
- return readFile(workDir..fileName)
- end
- function command.checkUpdate(currVers)
- return currVers < _version
- end
- --===========================================================
- -- Internet server
- --===========================================================
- -- Additional function actions
- function command.request(...)
- local resultFnc = internet.request(...)
- local handleName
- if resultFnc then
- handleName = tostring(resultFnc)
- -- Add Function that will be executed by iterator handle
- command[handleName] = function(...)
- local chunk = resultFnc()
- if not chunk then command[handleName] = nil end
- io.write("\n┃●" .. trimString(chunk))
- return chunk
- end
- end
- return handleName
- end
- --===========================================================
- -- Receive loop
- --===========================================================
- local function processReceived(r)
- if not r or #r==0 then return end
- local r_senderIP = r[1]
- local r_division = r[2]
- local r_funcName = r[3]
- local r_firstMsg = r[4]
- -- Check if this message from internet
- if type(r_firstMsg)=="string" then
- local obj = serialization.unserialize(r_firstMsg)
- -- We have raw, not serialized data
- if not obj then obj = {r_firstMsg} end
- --io.write("\n▐ Calling function: " .. r_funcName .. "...")
- local returnedObj
- if command[r_funcName] then
- returnedObj = {command[r_funcName](unpack(obj))}
- else
- local fnc = internet[r_funcName]
- if type(fnc)=="function" then
- returnedObj = {fnc(unpack(obj))}
- end
- end
- -- Determine if we dont need to serialize object before send
- local rawReturn = (r_funcName == "getFile")
- local sendStr = rawReturn and unpack(returnedObj) or serialization.serialize(returnedObj)
- io.write("\n┗◀", trimString(sendStr, 60))
- on.send(r_senderIP, sendStr)
- end
- end
- -- Update if needed
- if not options.f then
- -- Close upplication if we updated
- if checkUpdate() then return end
- end
- -- Welcome screen
- term.clear()
- write_c(0x0000FF, "\n========== Internet server (version:".. getVersion() ..") ==========\n")
- -- Receiving loop
- while true do
- local r = {on.receive(0.5)}
- -- Write log
- if #r > 0 then
- workIndicator(true)
- write_c(0x00AAFF, "\n┏▶")
- local s = ""
- for _,v in pairs(r) do s = s..trimString(v).." " end
- write_c(0xFFFFFF, trimString(s,60))
- end
- -- Process it
- local ok, err = pcall(processReceived,r)
- if not ok then
- io.stderr:write("\n⚠: "..tostring(err).."\n")
- end
- -- Show that we are working
- workIndicator()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement