diff --git a/api.lua b/api.lua index c4234fa..bb8a4a2 100755 --- a/api.lua +++ b/api.lua @@ -11,27 +11,6 @@ end dofile(modpath.."/fs.lua") -- do fs api file dofile(modpath.."/env.lua") -- do env file --- [function] run file under env -function digicompute.fs.run_file(pos, lpath, fields, replace) - local meta = minetest.get_meta(pos) - local lpath = path.."/"..meta:get_string("owner").."/"..meta:get_string("name").."/"..lpath - local env = digicompute.create_env(pos, fields) -- environment - local f = loadfile(lpath) -- load func - local e = digicompute.run(f, env) -- run function - -- if error, call error handle function and re-run start - if e and replace then - datalib.copy(lpath, lpath..".old") - datalib.copy(modpath.."/bios/"..replace, lpath) - meta:set_string("output", "Error: \n"..msg.."\n\nRestoring OS, modified files will remain.") -- set output - digicompute.refresh(pos) -- refresh - minetest.after(13, function() -- after 13 seconds, run start - local s = loadfile(path.."/"..meta:get_string("owner").."/"..meta:get_string("name").."/os/start.lua") -- load func - digicompute.run(s, env) -- run func - return false - end) - elseif e and not replace then return e end -- elseif no replace and error, return error msg -end - -- turn on function digicompute.on(pos, node) local temp = minetest.get_node(pos) -- get node @@ -83,4 +62,27 @@ function digicompute.run(f, env) if e == false then return msg end end +-- [function] run file under env +function digicompute.fs.run_file(pos, lpath, fields, replace) + local meta = minetest.get_meta(pos) + local lpath = path.."/"..meta:get_string("owner").."/"..meta:get_string("name").."/"..lpath + local env = digicompute.create_env(pos, fields) -- environment + local f, msg = loadfile(lpath) -- load func + + -- if error, call error handle function and re-run start + if msg and replace then + datalib.copy(lpath, lpath..".old") + datalib.copy(modpath.."/bios/"..replace, lpath) + meta:set_string("output", "Error: \n"..msg.."\n\nRestoring OS, modified files will remain.") -- set output + digicompute.refresh(pos) -- refresh + minetest.after(13, function() -- after 13 seconds, run start + local s = loadfile(path.."/"..meta:get_string("owner").."/"..meta:get_string("name").."/os/start.lua") -- load func + digicompute.run(s, env) -- run func + digicompute.refresh(pos) -- refresh + return false + end) + elseif msg and not replace then return msg -- elseif no replace and error, return error msg + else local res = digicompute.run(f, env) end -- else, run function +end + dofile(modpath.."/c_api.lua") -- do computer API file diff --git a/fs.lua b/fs.lua index 68a6679..f61bff1 100644 --- a/fs.lua +++ b/fs.lua @@ -7,18 +7,133 @@ local fs = digicompute.fs local path = digicompute.path local modpath = digicompute.modpath +----- BASE FUNCTIONS ----- + +-- [function] check if file exists +local function exists(path) + local f = io.open(path, "r") -- open file + if f ~= nil then f:close() return true end +end + +-- [function] make directory +local function mkdir(path) + local f = io.open(path) + if not f then + if minetest.mkdir then + minetest.mkdir(path) -- create directory if minetest.mkdir is available + return true + else + os.execute('mkdir "'..path..'"') -- create directory with os mkdir command + return true + end + end + + f:close() -- close file +end + +-- [function] remove directory +local function rmdir(path) + if not exists(path) then return end -- directory doesn't exist + + -- [local function] remove files + local function rm_files(ppath, files) + for _, f in ipairs(files) do + os.remove(ppath.."/"..f) + end + end + + -- [local function] check and rm dir + local function rm_dir(dpath) + local files = minetest.get_dir_list(dpath, false) + local subdirs = minetest.get_dir_list(dpath, true) + rm_files(dpath, files) + if subdirs then + for _, d in ipairs(subdirs) do + rm_dir(dpath.."/"..d) + end + end + os.remove(dpath) + end + + rm_dir(path) + return true +end + +-- [function] create file +local function create(path) + if exists(path) then return end -- if already exists, return + local f = io.open(path, "w") -- create file + f:close() -- close file + return true +end + +-- [function] write to file +local function write(path, data, overwrite) + -- check if append or overwrite + if overwrite == false then local w = "a" else + if not exists(path) then return end + local w = "w" + end + local f = io.open(path, w) -- open file for writing + f:write(minetest.serialize(data)) -- write serialized data (prevents errors when writing tables) + f:close() -- close file + return true +end + +-- [function] read file +local function read(path) + if not exists(path) then return end -- check if exists + local f = io.open(path, "r") -- open file for reading + local data = f:read("*all") -- read and store file data in variable "data" + return minetest.deserialize(data) -- return deserialized contents +end + +-- [function] copy file +local function cp(path, new) + if not exists(path) then return end -- check if path exists + local original = read(path) -- read + write(new, original, true) -- write + return true +end + +-- [function] copy directory +local function cpdir(path, new) + if not exists(path) then return end -- directory doesn't exist + + -- [local function] copy files + local function cp_files(ppath, files) + for _, f in ipairs(files) do + cp(ppath.."/"..f, new.."/"..f) -- copy + end + end + + -- [local function] check and copy dir + local function cp_dir(dpath) + mkdir(dpath) -- make new directory + local files = minetest.get_dir_list(dpath, false) + local subdirs = minetest.get_dir_list(dpath, true) + cp_files(dpath, files) + + for _, d in ipairs(subdirs) do + cp_dir(dpath.."/"..d) + end + end + + cp_dir(path) + return true +end + +----- FS ----- + -- [function] initalize fs function digicompute.fs.init(pos, cname) local meta = minetest.get_meta(pos) -- meta local player = meta:get_string("owner") -- owner username local cpath = path.."/"..player.."/"..cname -- comp path - if datalib.exists(path.."/"..player) == false then datalib.mkdir(path.."/"..player) end -- check for user dir - if datalib.exists(cpath) == true then return "A computer with this name already exists." end - datalib.mkdir(cpath) -- make computer dir - datalib.mkdir(cpath.."/os/") -- make os dir - datalib.copy(modpath.."/bios/conf.lua", cpath.."/os/conf.lua", false) - datalib.copy(modpath.."/bios/main.lua", cpath.."/os/main.lua", false) - datalib.copy(modpath.."/bios/start.lua", cpath.."/os/start.lua", false) + if not exists(path.."/"..player) then mkdir(path.."/"..player) end -- check for user dir + if exists(cpath) then return "A computer with this name already exists." end + mkdir(cpath) -- make computer dir + cpdir(modpath.."/bios", cpath.."/os") -- copy biosOS digicompute.log("Initialized computer "..cname.." placed by "..player..".") end @@ -70,7 +185,9 @@ function digicompute.fs.get_dir(pos, dpath) local cpath = path.."/"..player.."/"..cname -- comp path local files = minetest.get_dir_list(cpath.."/"..dpath, false) local subdirs = minetest.get_dir_list(cpath.."/"..dpath, true) - if not files and not subdirs then return { error = "Directory does not exist, or is empty.", contents = nil } end + if not files or files == {} or not subdirs or subdirs == {} then + return { error = "Directory does not exist, or is empty.", contents = nil } + end return { error = nil, contents = { files = files, subdirs = subdirs } } end