This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
ags131's profile picture

[1.3] CraftFTP 0.2- Ingame File transfer (NEW! 0.4 Betas up!)

Started by ags131, 07 March 2012 - 05:00 PM
ags131 #1
Posted 07 March 2012 - 06:00 PM
Ok, this is my first project with ComputerCraft so I decided to make an ingame FTP system. This is my version of FTP inside MC using RedNet. Its simple to use and even works on turtles. To configure just set the side variables in the client/server and set the name on the server. Ive setup a system where servers can be accessed by name without knowing the ID.

Commands: (client, server has no commands)
get <filename> – downloads a file
send <filename> – sends a file
ls [dir] – lists files, dir is optional
exit – self explanatory

cftp 0.2: (Client)
Spoiler

local side='left' -- Rednet modem/wire

-- Dont change this!
local server=nil;
local servername='';
errorMsg={'Unable to connect','Unable to get directory listing',''}
leave=false
function err(num)
	return 'ERROR '..num..' '..errorMsg[num]
end

function ls(dir)
	if dir==nil then
		dir=cdir
	else
		dir=cdir..dir
	end
	rednet.send(server, 'ftp:'..servername..':ls:'..dir)
	id,value=rednet.receive(10)
	if value==nil then
		value=err(2)
	end
	print(value)
end
function get(file)
	if file==nil then
		print("No File Specified! Aborting!")
	else
		rednet.send(server, 'ftp:'..servername..':get:'..cdir..file)
		id,value=rednet.receive(10)
		if value==nil or value=='File Not Found' then
			print('File Not Found')
		else
			write('Downloading... ')
			file=fs.open('/'..fs.getName(file),'w')
			file.write(value)
			file.close()
			print('DONE')
			print('File saved')
		end
	end
end
function send(file)
	if file==nil then
		print("No File Specified! Aborting!")
	else
		rednet.send(server, 'ftp:'..servername..':set:'..cdir..file)
		id,value=rednet.receive(10)
		if value==nil then
			print('No reply from server')
		else
			if value=='OK' then
				write('File accepted.\n Sending... ')
				file=fs.open('/'..fs.getName(file),'r')
				rednet.send(server,file.readAll())
				file.close()
				print('DONE')
				print('File sent.')
			end
		end
	end
end
function close(unused)
	leave=true
end
function split(pString, pPattern)
   local Table = {}  -- NOTE: use {n = 0} in Lua-5.0
   local fpat = "(.-)" .. pPattern
   local last_end = 1
   local s, e, cap = pString:find(fpat, 1)
   while s do
	  if s ~= 1 or cap ~= "" then
	 table.insert(Table,cap)
	  end
	  last_end = e+1
	  s, e, cap = pString:find(fpat, last_end)
   end
   if last_end <= #pString then
	  cap = pString:sub(last_end)
	  table.insert(Table, cap)
   end
   return Table
end
cdir=''
com={exit=close,ls=ls,get=get,send=send}
rednet.open(side)
print('CraftFTP Client 0.2')
write('Please enter a server: ')
res=io.read()
servername=res
rednet.broadcast('ftp:'..res..':id')
res=rednet.receive(10)
if res==nil then
	print(err(1))
else
	server=res
	print('Connected!')
	while not leave do
		write('\nFTP:'..cdir..'>')
		res=io.read()
		res=split(res,' ')
		c=com[res[1]]
		c(res[2])
		--[[if res[1]=='exit' then
			break
		elseif res[1]=='ls' then
			ls(res[2])
		elseif res[1]=='get' then
			get(res[2])
		end]]
	end
end


cftd 0.2 (server)
Spoiler

local side='left' -- Rednet side
local name='test' -- Server name

wait=5

if fs.exists('/ftp')==false then
	fs.makeDir('/ftp')
end

function split(pString, pPattern)
   local Table = {}  -- NOTE: use {n = 0} in Lua-5.0
   local fpat = "(.-)" .. pPattern
   local last_end = 1
   local s, e, cap = pString:find(fpat, 1)
   while s do
	  if s ~= 1 or cap ~= "" then
	 table.insert(Table,cap)
	  end
	  last_end = e+1
	  s, e, cap = pString:find(fpat, last_end)
   end
   if last_end <= #pString then
	  cap = pString:sub(last_end)
	  table.insert(Table, cap)
   end
   return Table
end
term.clear()
term.setCursorPos((term.getSize()/2)-13,1)
print('CraftFTP Server 0.2 running')
rednet.open(side)
while true do
	id,res=rednet.receive(wait)
	if res == nil then
		if wait==5 then
			print('Server adjusting idle mode')
			wait=wait+60
		end
	else
		wait=5
		print(id..'->'..res)
		res=split(res,'\:')
		if res[1]=='ftp' and res[2]==name then
			if res[3]=='id' then
				rednet.send(id,'')
			elseif res[3]=='get' then
				fl=''
				fnf='File Not Found'
				if res[4]==nil then
					out=fnf
				else
					fl='/ftp/'..res[4]
				end
				if fs.exists(fl) and fs.isDir(fl)==false then
					file=fs.open(fl,'r')
					out=file.readAll()
					file.close()
				else
					out=fnf
				end
				rednet.send(id,out)
			elseif res[3]=='set' then
				fl=''
				if res[4]==nil then
					rednet.send(id,'INVALID')
				else
					fl='/ftp/'..res[4]
				end
				if fs.exists(fl)==false then
					rednet.send(id,'OK')
					id2,rec=rednet.receive(10)
					if id2==id then
						file=fs.open(fl,'w')
						out=file.write()
						file.close()
					end
				else
					rednet.send(id,'EXISTS')
				end
			elseif res[3]=='ls' then
				lst={}
				out=''
				if res[4]==nil then
					lst='/ftp'
				else
					lst='/ftp/'..res[4]
				end
				if fs.exists(lst) and fs.isDir(lst) then
					lst2=fs.list(lst)
					for k,v in ipairs(lst2) do
						if fs.isDir(lst..'/'..v) then
							out=out..'\nD '
						else
							out=out..'\nF '
						end
						out=out..v
					end
				else
					out='\nDirectory does not exist'
				end
				if out=='' then out='\nNo Files Found' end
				if not res[4]==nil then
					out=res[4]..out
				end
					
				rednet.send(id,'File listing: '..out)
			end
		end
	end
end


Beta 0.4 versions
SpoilerThis is the 0.4 beta versions of CraftFTP
This is the server (cftpd) and the client API (cftpAPI)
The server has limited user support, it will seperate user files but not check passwords yet. That will be added in 0.5
The server also now uses a config, run once then edit cftpd.conf for options. You can also run lua code therefore having a dynamic config. :mellow:/>/>
I will add the client when Wolvan finishes it. For now, feel free to add auto-update to your own programs by using the API ;)/>/>
Credits go to tomass1996 for his StrUtils API (No need to install, its been included in the top of each script, tomass1996: If you dont like me doing like this, please let me know and Ill change it)
cftpd 0.4 http://pastie.org/3578267
cftpAPI http://pastie.org/3578276
cftp 0.4 WIP, Will post soon!

cftpAPI functions: (All will return true if it succeeded or false if failed)
Spoilerfunction connect(side,serverName)
function needAuth()
function auth(user,pass)
function ls(dir)
function cd(dir)
function rm(item)
function exists(item)
function mv(src,dest)
function cp(src,dest)
function mkdir(dir)
function get(remoteFile,localFile)
function send(localFile,remoteFile)
function close()


Changelog:
Spoiler
  • 3-12-12
    • Removed old beta API and uploaded latest
    • Added cftpd 0.4
  • 3-9-12
    • Added Beta API
    • Updated API (Still untested)
  • 3-7-12
    • Initial upload of v0.2
Zitrone77 #2
Posted 07 March 2012 - 07:25 PM
Nice Job!

But:
Why do you use
'
Instead of:
"
??
Wolvan #3
Posted 07 March 2012 - 07:51 PM
I work on a Login System at the moment. As soon as it gets finished am I allowed to post it here?
ags131 #4
Posted 07 March 2012 - 09:58 PM
Sure, multi-user support was planned in future version but this was mainly a working prototype
Any difference in using ' instead of "?
Also, i'm wanting to add better directory support for the client, like a cd command that would set the cdir variable. Just haven't implemented it yet.

As a side thought, I may make the base ftp access an API then write the client around that, then stuff like backups and command-line access like wget and wput could be created. Also, im thinking of making a mail system using it :mellow:/>/>
Wolvan #5
Posted 07 March 2012 - 10:48 PM
Sure, multi-user support was planned in future version but this was mainly a working prototype
Any difference in using ' instead of "?
Also, i'm wanting to add better directory support for the client, like a cd command that would set the cdir variable. Just haven't implemented it yet.

As a side thought, I may make the base ftp access an API then write the client around that, then stuff like backups and command-line access like wget and wput could be created. Also, im thinking of making a mail system using it :mellow:/>/>
I really want to help you but no I mainly create a password set thingy. And no there is no difference between " and '
Just ask me if I can help programming with you
Mads #6
Posted 08 March 2012 - 12:27 PM
Nice Job!

But:
Why do you use
'
Instead of:
"
??
Some people(like me) likes it better, and it makes no difference at all :mellow:/>/>
solvillan #7
Posted 08 March 2012 - 01:43 PM
A tip, add an external configfile for both server and client, instead of asking people to mess with the code.
Zitrone77 #8
Posted 08 March 2012 - 03:08 PM
Nice Job!

But:
Why do you use
'
Instead of:
"
??
Some people(like me) likes it better, and it makes no difference at all :mellow:/>/>
Ok.. now i know that
'
works too!
Liraal #9
Posted 08 March 2012 - 03:12 PM
LUA's syntax is really loose one,

print"abc"
seems to work as well as

print("abc")

anyway, good job. How about making directory-management function as well?
Wolvan #10
Posted 08 March 2012 - 05:34 PM
How about making directory-management function as well?
He is working on that already
Liraal #11
Posted 08 March 2012 - 05:44 PM
ah sorry didn't notice
ags131 #12
Posted 08 March 2012 - 09:56 PM
Directory management will be made soon, also need to make delete commands. Im planing an API for clients then going to rebuild the client using the API. The API will also allow programs to autoupdate by checking for newer version via ftp :mellow:/>/>
Wolvan #13
Posted 09 March 2012 - 02:31 PM
Directory management will be made soon, also need to make delete commands. Im planing an API for clients then going to rebuild the client using the API. The API will also allow programs to autoupdate by checking for newer version via ftp ;)/>/>
Awesome :mellow:/>/> Can I help?
ags131 #14
Posted 09 March 2012 - 02:35 PM
Sure.
After starting on it, I noticed the server may need rewritten some. A few things such as deleting and moving files needs commands.
Ive wrote the basic API for it including authentication. I just set the server to always return no authentication required for now.
Updating OP with the (non-working!) WIP API version
ags131 #15
Posted 10 March 2012 - 03:20 PM
Updated OP lastnight with full API, untested though As im rewriting server
Wolvan #16
Posted 10 March 2012 - 05:44 PM
Updated OP lastnight with full API, untested though As im rewriting server
Can I help?
ags131 #17
Posted 10 March 2012 - 08:39 PM
Sure :mellow:/>/>
I'm open to help and suggestions ;)/>/>
Wolvan #18
Posted 10 March 2012 - 09:32 PM
Sure :mellow:/>/>
I'm open to help and suggestions ;)/>/>
Do you have a special server where your programming on/Steam/Skype or something like that?
ags131 #19
Posted 10 March 2012 - 10:36 PM
Been programming mostly in NP++ and testing on SSP and another whitelist server Im on
I am on skype as ags131,
ags131 #20
Posted 12 March 2012 - 03:44 PM
Update! Added 0.4 betas and full API
BigSHinyToys #21
Posted 19 March 2012 - 07:43 AM
would you mind if i made a modifed ver of this that was set up to use My gpsIP protocol ( currently not released.) as this looks like a perfect fit.
Mattzz #22
Posted 20 March 2012 - 07:04 AM
Hey ags,
could you PM me that pastey example of tables
im posting it here because it had to do with craftFTP
sorry if im posting in the wrong place
thanks
ags131 #23
Posted 22 March 2012 - 04:33 AM
would you mind if i made a modifed ver of this that was set up to use My gpsIP protocol ( currently not released.) as this looks like a perfect fit.
Sure, just please give credit :(/>/> Just a note, newer unreleased versions (0.5 and up) hae a simple way to change the system used for network. It will work with any system that implements their own broadcast, send, and receive. (Although events are used for receive atm)
Hey ags,
could you PM me that pastey example of tables
im posting it here because it had to do with craftFTP
sorry if im posting in the wrong place
thanks
What example? /me has forgotten…
You mean this?

testTable={1,2,3}
data=textutils.serialize(testTable)

result=textutils.unserialize(data)
print(testTable)
print(result)
--Should match
 
Technolust #24
Posted 28 March 2012 - 12:38 AM
TINY problem…
It does not copy the file insides too…
so its a blank file with the right name
djblocksaway #25
Posted 12 April 2012 - 05:55 AM
i cant seem to get this to work i set up the server and client and i run the server and the client (i connected modems also) but when i connect on the client it either doesnt connect or connects once and doesnt connect again and on the server it says

Server adjusting idle mode

how can i fix this cause i really like this program but i cant get it to work properly :P/>/>
strideynet #26
Posted 12 April 2012 - 07:13 AM
Welcome to project netblock!!!
You have a good knowledge of how to code including the name thing which is very clever.
Look at project netblock in general discussion
I own it and want you.
We have a server.
FTP is what we need and your good at all networking things now you ever thought on making a cloud OS
This is a computer that only has 1 file on it … How to connect to FTP
When a person types a command it checks with FTP for that file downloads it then runs command then deletes file
FuzzyPurp #27
Posted 16 August 2012 - 12:38 PM
Welcome to project netblock!!!
You have a good knowledge of how to code including the name thing which is very clever.
Look at project netblock in general discussion
I own it and want you.
We have a server.
FTP is what we need and your good at all networking things now you ever thought on making a cloud OS
This is a computer that only has 1 file on it … How to connect to FTP
When a person types a command it checks with FTP for that file downloads it then runs command then deletes file

Actually sounds pretty interesting, haha.
mad-murdock #28
Posted 18 August 2012 - 04:30 PM
wrong forum section?