Created
July 13, 2022 14:00
-
-
Save AmariNoa/236d22fedc17c044743c4aa0f91b5b66 to your computer and use it in GitHub Desktop.
File server and client for ComputerCraft
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- FileClient | |
-- Ver. 0.1 | |
-- Include external lib | |
dofile("/lib/amari/string/StringUtil.lua") | |
local REDNET_SIDE = "left" | |
local REDNET_PROTOCOL_MASTER = "MasterServer" | |
local REDNET_PROTOCOL_FILE = "FileServer" | |
local function ParseCommand(str, pattern) | |
local start, tail = string.find(str, pattern) | |
local cmd = (start ~= nil) and string.sub(str, 1, start - 1) or str | |
local data = (start ~= nil) and string.sub(str, tail + 1, string.len(str)) or nil | |
return cmd, data | |
end | |
local computerId = os.getComputerID() | |
print("ComputerId = "..computerId) | |
rednet.open(REDNET_SIDE) | |
local isOpen = rednet.isOpen(REDNET_SIDE) | |
if not isOpen then | |
print("Rednet open failed.") | |
return | |
end | |
local masterServerId = 0 | |
rednet.broadcast("GetServerId", REDNET_PROTOCOL_MASTER) | |
while true do | |
local sender, receive, protocol = rednet.receive(REDNET_PROTOCOL_MASTER) | |
if sender == nil then | |
-- Time out | |
print("MasterServer not found.") | |
return | |
end | |
local starts = "response:"..string.lower("GetServerId") | |
print("Receive: "..receive) | |
print("Starts: "..starts) | |
if string.startsWith(receive, starts) then | |
-- Master response | |
masterServerId = tonumber(string.split(receive, ":")[4]) | |
break | |
end | |
end | |
local fileServerId = 0 | |
rednet.send(masterServerId, "GetServerId", REDNET_PROTOCOL_FILE) | |
while true do | |
local sender, receive, protocol = rednet.receive(REDNET_PROTOCOL_MASTER) | |
if sender == nil then | |
-- Time out | |
print("FileServer not found.") | |
return | |
end | |
if string.startsWith(receive, "response:"..string.lower("GetServerId")) then | |
-- Master response | |
fileServerId = tonumber(string.split(receive, ":")[4]) | |
break | |
end | |
end | |
local dir = "" | |
while true do | |
dir = read() | |
if string.lower(dir) == "download" then | |
break | |
elseif string.lower(dir) == "upload" then | |
break | |
end | |
print("Invalid argument. (Download or Upload)") | |
end | |
term.write("Enter file path >> ") | |
local filePath = read() | |
if string.lower(dir) == "download" then | |
local cmd = "Download:"..filePath | |
rednet.send(fileServerId, cmd, REDNET_PROTOCOL_FILE) | |
while true do | |
local sender, receive = rednet.receive(REDNET_PROTOCOL_FILE, 5) | |
if sender == nil then | |
print("Failed to connet to server.") | |
return | |
end | |
if receive.startsWith(receive, "response:"..string.lower("Download")) then | |
-- "response", "Download:result:data" | |
local rcvCmd, receive = ParseCommand(receive, ":") | |
-- "Download", "result:data" | |
rcvCmd, receive = ParseCommand(receive, ":") | |
-- "result", "data" | |
if rcvCmd == false then | |
print("Server error: "..receive) | |
return | |
end | |
print("** File received **") | |
print("FilePath: "..filePath) | |
local fileHandle = fs.open(filePath, "w") | |
if fileHandle then | |
fileHandle.write(receive) | |
fileHandle.close() | |
else | |
print("File cannot open.") | |
end | |
break | |
end | |
end | |
elseif string.lower(dir) == "upload" then | |
local fileHandle = fs.open(filePath, "r") | |
if fileHandle then | |
local cmd = "Upload:"..filePath..":"..fileHandle.readAll() | |
rednet.send(fileServerId, cmd, REDNET_PROTOCOL_FILE) | |
else | |
print("File cannot open.") | |
end | |
rednet.close(REDNET_SIDE) | |
else | |
print("Invalid command") | |
return | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- FileServer | |
-- Ver. 0.1 | |
-- Include external lib | |
dofile("/lib/amari/string/StringUtil.lua") | |
local REDNET_SIDE = "back" | |
local REDNET_PROTOCOL_MASTER = "MasterServer" | |
local REDNET_PROTOCOL = "FileServer" | |
local function ParseCommand(str, pattern) | |
local start, tail = string.find(str, pattern) | |
local cmd = (start ~= nil) and string.sub(str, 1, start - 1) or str | |
local data = (start ~= nil) and string.sub(str, tail + 1, string.len(str)) or nil | |
return cmd, data | |
end | |
local stopServer = false | |
local function readConsoleThread() | |
local input = "" | |
while (not stopServer) do | |
term.write(">> ") | |
input = read() | |
-- TODO Add console command here | |
if string.lower(input) == "stop" then | |
stopServer = true | |
print("Stopping server...") | |
else | |
print("Unknown command: "..input) | |
end | |
end | |
end | |
local function serverThread() | |
local isOpen = true | |
local sender, receive, protocol | |
while isOpen do | |
sender, receive, protocol = rednet.receive(3) | |
if (sender ~= nil) and (receive ~= nil) then | |
-- Message received | |
-- local cmdSplit = string.split(receive, ":") | |
local cmd, tempReceive = ParseCommand(receive, ":") | |
cmd = string.lower(cmd) | |
print("Cmd: "..cmd) | |
-- print("Data: "..tempReceive) | |
-- Execute command | |
local result = false | |
local data = "Unknown command" | |
-- Add command | |
if cmd == string.lower("Upload") then | |
-- TODO Upload :: Add version | |
-- Upload:filePath:fileData | |
local filePath, tempReceive = ParseCommand(tempReceive, ":") | |
print("** Upload command received **") | |
print("FilePath: "..filePath) | |
local fileHandle = fs.open(filePath, "w") | |
if fileHandle then | |
fileHandle.write(tempReceive) | |
fileHandle.close() | |
result = true | |
data = "Success" | |
else | |
result = false | |
data = "Failed to open file" | |
end | |
elseif cmd == string.lower("Download") then | |
-- TODO Download :: Add version | |
-- Download:filePath | |
local filePath = tempReceive | |
print("** Download command received **") | |
print("FilePath: "..filePath) | |
local fileHandle = fs.open(filePath, "r") | |
if fileHandle then | |
result = true | |
data = fileHandle.readAll() | |
fileHandle.close() | |
else | |
result = false | |
data = "Failed to open file" | |
end | |
end | |
-- Message format => response:cmdName:result:data | |
local sendMsg = "response:"..cmd..":"..tostring(result)..":"..data | |
rednet.send(sender, sendMsg, REDNET_PROTOCOL) | |
end | |
if stopServer == true then | |
break | |
end | |
isOpen = rednet.isOpen(REDNET_SIDE) | |
if not isOpen then | |
break | |
end | |
end | |
end | |
-- Script main | |
local computerId = os.getComputerID() | |
print("ComputerId = "..computerId) | |
rednet.open(REDNET_SIDE) | |
local isOpen = rednet.isOpen(REDNET_SIDE) | |
if not isOpen then | |
print("Rednet open failed.") | |
return | |
end | |
print("FileServer started.") | |
print("Sending server id...") | |
rednet.broadcast("SetServerId:"..computerId, REDNET_PROTOCOL) | |
-- TODO delete | |
while true do | |
local sender, receive, protocol = rednet.receive(REDNET_PROTOCOL_MASTER, 5) | |
if receive == nil then | |
print("Connection time out.") | |
break | |
end | |
print("** Receive **") | |
print("Sender: "..sender) | |
print("Message: "..receive) | |
print("Protocol: "..protocol) | |
if string.startsWith(receive, "response") then | |
break | |
end | |
end | |
parallel.waitForAll(readConsoleThread, serverThread) | |
rednet.close(REDNET_SIZE) | |
print("FileServer stopped.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment