FTP API
ftp transfers files directly between computers in memory, bypassing the network message queue.
This makes it far more efficient than line-by-line script-driven transfers via net.
Typical usage
-- ── Server computer ──────────────────────────────────────────────────────────
ftp.listen("secret") -- accept one client at a time
-- optional: ftp.listen("secret", true) -- read-only (no uploads/deletes)
-- ── Client computer ──────────────────────────────────────────────────────────
if ftp.connect("server-host", "secret") then
-- single-file transfers
ftp.download("/remote/prog.lua", "/local/prog.lua")
ftp.upload("/local/config.txt", "/remote/config.txt")
-- recursive directory transfers
local n = ftp.downloadDir("/remote/libs", "/local/libs")
print("downloaded " .. n .. " files")
ftp.disconnect()
end
-- ── Server computer (cleanup) ────────────────────────────────────────────────
ftp.stop()
Server API
listen(password)Start accepting FTP connections with the given password. Returnsfalseif already listening or password is blank. Only one client may connect at a time.listen(password, readOnly)Same as above, but whenreadOnlyistrueclients are limited todownload,downloadDir,list,exists, andisDir. Upload,mkdir, anddeleteoperations are rejected.stop()Stop listening and disconnect any connected client.isListening()Returnstrueif this computer is currently listening for FTP connections.getConnectedClient()Returns the hostname of the connected client, ornil.
Client API
connect(serverHostname, password)Connect to a listening FTP server. Returnstrueon success. Fails if already connected, the server is busy, or the password is wrong.disconnect()Disconnect from the current FTP server.isConnected()Returnstrueif this computer has an active FTP connection.getServer()Returns the hostname of the connected server, ornil.
Remote file inspection
exists(remotePath)Returnstrueif the path exists on the server.isDir(remotePath)Returnstrueif the path is a directory on the server.list(remotePath)Returns an array of file/directory names in the remote directory, ornilif not connected or path is invalid.
Remote mutations
mkdir(remotePath)Creates a directory on the server. Returnsfalseif the server is read-only or the call fails.delete(remotePath)Deletes a file or directory on the server. Returnsfalseif the server is read-only or the call fails.
File transfer
download(remotePath, localPath)Downloads a single file from the server to this computer’s filesystem. Returnstrueon success.upload(localPath, remotePath)Uploads a single file from this computer’s filesystem to the server. Returnsfalseif the server is read-only.downloadDir(remotePath, localPath)Recursively downloads an entire remote directory. CreateslocalPathif it does not exist. Returns the number of files transferred, or-1if not connected or the source is not a directory.uploadDir(localPath, remotePath)Recursively uploads an entire local directory to the server. CreatesremotePathif it does not exist. Returns the number of files transferred, or-1if not connected, read-only, or the source is not a directory.
Notes
listencreates a single-client lock. A second client trying toconnectwhile one is already connected will receivefalse.The server’s existing
fs.protect/fs.authrules are enforced on every transfer. Protect a path and callfs.authon the server beforeftp.listenif you want FTP clients to be able to write to protected directories.Transfers are in-memory operations. No data crosses the network message queue and there is no per-file protocol overhead.
Both the server and client must be in the same running game instance (same JVM). FTP does not work across separate servers.
When a computer is removed or shut down, any active FTP server or client state is cleaned up automatically.
downloadDiranduploadDirskip files that fail to read or write (e.g. due to permission rules) and continue transferring the rest; the returned count reflects only files that succeeded.