Any suggestions are much appreciated :P/>
This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
[Question] Virtual Directory / Files
Started by darkrising, 14 May 2013 - 12:02 PMPosted 14 May 2013 - 02:02 PM
Hello, I'm working on a remote login type program which sends the users directory on the server computer to the client computer as one big table, the problem I'm facing is if the client computer is switched off before it can clear the files and another user comes along and logs in they will find the previous users files just sitting there. I could do a clean on startup type thing but I'm wondering if there is a way I can fool the computer into thinking that a table is a bunch of files (virtual directory in a sense) but still keep the editing and running of the programs intact.
Any suggestions are much appreciated :P/>
Any suggestions are much appreciated :P/>
Posted 14 May 2013 - 07:16 PM
I'm not the best with lua, but doing a clear at startup is quick and gets the job done. One thing I would recommend is adding this after you receive the table.
function clearscreen()
term.clear()
end
while true do
print ("Press Q to erase data")
local event, param = os.pullEvent("char")
if param == "Q" then
clearscreen()
else
sleep(1)
end
end
This should wait for your keystroke of "Q" and then clear your computer, and if you enter the wrong key, return you back to the start of this code so you can still view your tables. Hope this works for you!
function clearscreen()
term.clear()
end
while true do
print ("Press Q to erase data")
local event, param = os.pullEvent("char")
if param == "Q" then
clearscreen()
else
sleep(1)
end
end
This should wait for your keystroke of "Q" and then clear your computer, and if you enter the wrong key, return you back to the start of this code so you can still view your tables. Hope this works for you!
Posted 14 May 2013 - 09:01 PM
In my opinion, the best way to go about this is to just clean out the previous user's files, but if you really don't want to do this you could modify the 'fs' API to catch any kind of references to a file or directory in your table and cause the function to treat your table like a file or directory.
I would write you a code example, but I don't know how your virtual file system using a table would work with files in terms of contents, etc.
I would write you a code example, but I don't know how your virtual file system using a table would work with files in terms of contents, etc.
Posted 15 May 2013 - 03:03 AM
please send us an example table of files so we can see what it would look like, then we can give you examples
Posted 15 May 2013 - 06:28 AM
Example file: (afile)
That would be stored as
Hello,
How are you today?
some other lines...
That would be stored as
masterdb = {}
masterdb.afile = {}
masterdb.afile.filename = "afile"
masterdb.afile.dir = "/"
masterdb.afile = {"Hello,", "How are you today?", "", "some other lines..."}
Posted 15 May 2013 - 11:47 AM
good stuff. Quick question, if there is a fake file and a real file on the computer which gets preference?
Posted 15 May 2013 - 04:03 PM
good stuff. Quick question, if there is a fake file and a real file on the computer which gets preference?
The real file would probably take precedence over the fake one. :)/>
Posted 15 May 2013 - 05:07 PM
The best option for this use case would be to override the fs calls to communicate with the server. It's a bit complex, but it means that user files are almost never stored on the local machine and are always synced to the server.
Posted 15 May 2013 - 06:13 PM
here is a basic example. it only has code for reading files (not appending or writing) I'm sure you can figure that out
if not let me know, it's late now so I'm giving it a rest
CLIENT
FILESERVER
if not let me know, it's late now so I'm giving it a rest
CLIENT
rednet.open("left")
local nServerID=0
local function requestData(sRequest,...)
if type(sRequest)~="string" then error("Incorrect input. String expected, got "..type(sRequest),2) end
local ref,tEvt,tMsg=math.random(1,10000)
rednet.send(nServerID,textutils.serialize({ref,sRequest,...}))
repeat
tEvt={os.pullEvent()}
tMsg=type(tEvt[3])=="string" and textutils.unserialize(tEvt[3])
until tEvt[1]=="rednet_message" and tEvt[2]==nServerID and type(tMsg)=="table" and tMsg[1]==ref and tMsg[2]==sRequest
return unpack(tMsg,3)
end
local oldFS=fs
fs=setmetatable({},{__index=oldFS})
fs.list=function(sDir,...)
local ls=oldFS.list(sDir,...)
for k,v in pairs(requestData("dirList",sDir)) do
table.insert(ls,v)
end
table.sort(ls)
return ls
end
fs.open=function(sPath,sOperator,...)
if not oldFS.exists(sPath) and sOperator=="r" then
local tFile=requestData("getFile",sPath)
if type(tFile)=="table" then
return {readAll=function() if tFile.open then return table.concat(tFile.contents,"\n") end end,readLine=coroutine.wrap(function() for nLine=1,#tFile.contents do coroutine.yield(tFile.open and tFile.contents[nLine] or nil) end end),close=function() tFile.open=false end}
end
end
return oldFS.open(sPath,sOperator,...)
end
fs.exists=function(sDir,...)
return oldFS.exists(sDir,...) or requestData("doesExist",sDir)
end
fs.isDir=function(sDir,...)
return oldFS.isDir(sDir,...)~=nil and oldFS.isDir(sDir,...) or requestData("isDir",sDir)
end
fs.isReadOnly=function(sDir,...)
return oldFS.isReadOnly(sDir,...)~=nil and oldFS.isReadOnly(sDir,...) or requestData("isReadOnly",sDir)
end
FILESERVER
rednet.open("left")
while true do
local tEvts={os.pullEvent()}
if tEvts[1]=="rednet_message" and type(tEvts[3])=="string" then
local tMsg=textutils.unserialize(tEvts[3])
if type(tMsg)=="table" and type(tMsg[1])=="number" and tMsg[1]<=10000 and tMsg[1]>=1 and type(tMsg[2])=="string" then
if tMsg[2]=="dirList" and type(tMsg[3])=="string" then
rednet.send(textutils.serialize({tMsg[1],tMsg[2],fs.list(tMsg[3])}))
elseif tMsg[2]=="getFile" and type(tMsg[3])=="string" then
if fs.exists(tMsg[3]) and not fs.isDir(tMsg[3]) then
local oFile=fs.open(tMsg[3],"r")
local tFile={open=true,contents={}}
for sLine in oFile.read do
table.insert(tFile.contents,sLine)
end
end
rednet.send(textutils.serialize({tMsg[1],tMsg[2],tFile}))
elseif tMsg[2]=="doesExist" and type(tMsg[3])=="string" then
rednet.send(textutils.serialize({tMsg[1],tMsg[2],fs.exists(tMsg[3])}))
elseif tMsg[2]=="isDir" and type(tMsg[3])=="string" then
rednet.send(textutils.serialize({tMsg[1],tMsg[2],fs.isDir(tMsg[3])}))
elseif tMsg[2]=="isReadOnly" and type(tMsg[3])=="string" then
rednet.send(textutils.serialize({tMsg[1],tMsg[2],fs.isReadOnly(tMsg[3])}))
end
end
end
end
Posted 16 May 2013 - 03:40 PM
-snip-
Thanks for taking the time to write this, I'll give it a try! :)/>
Posted 16 May 2013 - 10:41 PM
derp… I sent you the untested version and deleted the tested version :(/> sorry, it was definitely late at night back then…
there will be a few bugs as this was the first writeup, just taking a look at the fileserver code in getFile it should be readLine not read
there will be a few bugs as this was the first writeup, just taking a look at the fileserver code in getFile it should be readLine not read
Posted 17 May 2013 - 03:49 PM
derp… I sent you the untested version and deleted the tested version :(/> sorry, it was definitely late at night back then…
there will be a few bugs as this was the first writeup, just taking a look at the fileserver code in getFile it should be readLine not read
Still helped a lot, now I've seen how you've done it :)/>
Posted 17 May 2013 - 05:37 PM
Still helped a lot, now I've seen how you've done it :)/>
Well it was my pleasure then :)/> I auto-follow every topic I participate in so if it doesn't work out let me know here, I've wanted to make something like this ever since making hidden files but it was just too much trouble to satisfy curiosity alone, I don't really have a use for it. Curiosity & assisting someone who can use it is enough motivation
Posted 18 May 2013 - 02:23 AM
for the server, the files could be stored in a specific folder that acts like the root directory of the virtual filesystem
Posted 18 May 2013 - 07:52 AM
Indeed, it should be easily implementable though, as I was not privy to the login system I cannot include a root folder changing system based on logins, I trust darkrising is capable of it though