mirror of
				https://github.com/LDDestroier/CC/
				synced 2025-10-31 07:22:59 +00:00 
			
		
		
		
	Added transmit/receive, fixed some bugs
This commit is contained in:
		
							
								
								
									
										417
									
								
								progdor2.lua
									
									
									
									
									
								
							
							
						
						
									
										417
									
								
								progdor2.lua
									
									
									
									
									
								
							| @@ -9,10 +9,15 @@ | ||||
|  | ||||
| local progdor = { | ||||
| 	version = "2.0", | ||||
| 	PBlogPath = ".progdor_PB_uploads" | ||||
| 	PBlogPath = ".progdor_PB_uploads", | ||||
| 	channel = 8366, | ||||
| 	skynetPath = "skynet.lua", | ||||
| 	skynetURL = "https://github.com/osmarks/skynet/raw/master/client.lua" | ||||
| } | ||||
|  | ||||
| local scr_x, scr_y = term.getSize() | ||||
| local modem = peripheral.find("modem") | ||||
| local skynet, skynetBigReceive, skynetBigSend | ||||
|  | ||||
| local function interpretArgs(tInput, tArgs) | ||||
|     local output = {} | ||||
| @@ -203,12 +208,16 @@ local argData = { | ||||
| 	["-dd"] = "string",		-- direct URL download | ||||
| 	["-m"] = "string",		-- specify main file | ||||
| 	["-PB"] = false,		-- pastebin upload | ||||
| 	["-t"] = false,			-- transmit file | ||||
| 	["-r"] = false,			-- receive file | ||||
| 	["-S"] = false,			-- use skynet | ||||
| 	["-e"] = false,			-- automatic self-extractor | ||||
| 	["-s"] = false,			-- silent | ||||
| 	["-a"] = false,			-- use as API with require, also makes silent | ||||
| 	["-c"] = false,			-- use CCA compression | ||||
| 	["-h"] = false,			-- show help | ||||
| 	["-i"] = false,			-- inspect mode | ||||
| 	["-o"] = false,			-- always overwrite | ||||
| } | ||||
|  | ||||
| local argList, argErrors = interpretArgs({...}, argData) | ||||
| @@ -231,6 +240,10 @@ local selfExtractor	 = argList["-e"]	-- boolean | ||||
| local silent		 = argList["-s"]	-- boolean | ||||
| local useCompression = argList["-c"]	-- boolean | ||||
| local justOverwrite	 = argList["-o"]	-- boolean | ||||
| local useSkynet		 = argList["-S"]	-- boolean | ||||
| local trMode		 = argList["-t"] and "transmit" or (argList["-r"] and "receive" or "normal") | ||||
|  | ||||
| local skynet | ||||
|  | ||||
| if useCompression and selfExtract then | ||||
| 	error("Cannot use compression with self-extractor.") | ||||
| @@ -248,13 +261,33 @@ local sPrint = function(text) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function showHelp() | ||||
| 	local helpInfo = { | ||||
| 		"progdor v" .. progdor.version, | ||||
| 		"Usage: progdor [options] inputFolder (outputFile)", | ||||
| 		"       progdor [options] inputFile (outputFolder)", | ||||
| 		"", | ||||
| 		"Progdor is a file/folder packaging program with support for CCA compression and self-extraction.", | ||||
| local cWrite = function(text, color, ignoreSilent) | ||||
| 	local col = term.getTextColor() | ||||
| 	term.setTextColor(color or col) | ||||
| 	if ignoreSilent then | ||||
| 		write(text) | ||||
| 	else | ||||
| 		sWrite(text) | ||||
| 	end | ||||
| 	term.setTextColor(col) | ||||
| end | ||||
|  | ||||
| local cPrint = function(text, color, ignoreSilent) | ||||
| 	local col = term.getTextColor() | ||||
| 	term.setTextColor(color or col) | ||||
| 	if ignoreSilent then | ||||
| 		print(text) | ||||
| 	else | ||||
| 		sPrint(text) | ||||
| 	end | ||||
| 	term.setTextColor(col) | ||||
| end | ||||
|  | ||||
| local function showHelp(verboseHelp) | ||||
| 	local helpInfo | ||||
| 	if verboseHelp then | ||||
| 		helpInfo = { | ||||
| 			"Progdor v" .. progdor.version, | ||||
| 			"", | ||||
| 			"Options:", | ||||
| 			" -pb [pastebin ID] : Download from Pastebin.",			-- added | ||||
| @@ -262,15 +295,30 @@ local function showHelp() | ||||
| 			" -dd [download URL] : Download from URL.",				-- added | ||||
| 			" -e : Adds on self-extractor code to archive.",		-- added | ||||
| 			" -s : Silences all terminal writing",					-- added | ||||
| 			" -S : Use skynet when transmitting/receiving.",		-- added | ||||
| 			" -t : Transmit a folder/file.",						-- added | ||||
| 			" -r : Receive a file/packed folder.",					-- added | ||||
| 			" -a : Allows programs to use require() on Progdor.",	-- added | ||||
| 			" -c : Enables CCA compression.",						-- added | ||||
| 			" -m : Specify main executable file in archive.",		-- added | ||||
| 			" -i : Inspect archive without extracting.",			-- added | ||||
| 			" -o : Overwrite files without asking.",				-- added | ||||
| 		" -h : Show this help.",								-- added | ||||
| 			"", | ||||
| 			"   This Progdor has Super Cow Powers."					-- not actually added | ||||
| 		} | ||||
| 	else | ||||
| 		helpInfo = { | ||||
| 			"Progdor v" .. progdor.version, | ||||
| 			"Usage: progdor [options] inputFolder (outputFile)", | ||||
| 			"       progdor [options] inputFile (outputFolder)", | ||||
| 			"", | ||||
| 			"Progdor is a file/folder packaging program with support for CCA compression and self-extraction.", | ||||
| 			"", | ||||
| 			"Use -h for all options.", | ||||
| 			"", | ||||
| 			"   This Progdor has Super Cow Powers."					-- not actually added | ||||
| 		} | ||||
| 	end | ||||
| 	for y = 1, #helpInfo do | ||||
| 		sPrint(helpInfo[y]) | ||||
| 	end | ||||
| @@ -304,7 +352,7 @@ ___________|_|_|_____________ | ||||
| end | ||||
|  | ||||
| if argList["-h"] then | ||||
| 	return showHelp() | ||||
| 	return showHelp(true) | ||||
| elseif argList["-a"] then | ||||
| 	mode = "api" | ||||
| elseif inputPath then | ||||
| @@ -316,8 +364,8 @@ elseif inputPath then | ||||
| 	else | ||||
| 		mode = "unpack" | ||||
| 	end | ||||
| else | ||||
| 	return showHelp() | ||||
| elseif trMode ~= "receive" then | ||||
| 	return showHelp(false) | ||||
| end | ||||
|  | ||||
| if mode == "api" then | ||||
| @@ -519,16 +567,338 @@ local writeArchiveData = function(archive, outputPath) | ||||
| 	specialPrint("Unpacked to '", outputPath .. "/", "'.", colors.yellow) | ||||
| end | ||||
|  | ||||
| local getSkynet = function() | ||||
| 	if http.websocket then | ||||
| 		-- Skynet only supports messages that are 65506 bytes or smaller | ||||
| 		-- I'm just going with 65200 bytes to play safe. | ||||
| 		local defineBigOnes = function(skynet) | ||||
| 			local div = 65200 | ||||
| 			return function(channel, _message)	-- big send | ||||
| 				local message = textutils.serialize(_message) | ||||
| 				for i = 1, math.ceil(#message / div) do | ||||
| 					skynet.send(progdor.channel, { | ||||
| 						msg = message:sub( (i - 1) * div + 1, i * div ), | ||||
| 						complete = i == math.ceil(#message / div), | ||||
| 						part = i | ||||
| 					}) | ||||
| 					sleep(0.1) | ||||
| 					cWrite(".", colors.lightGray) | ||||
| 				end | ||||
| 			end, function(channel)				-- big receive | ||||
| 				local ch, msg | ||||
| 				local output = {} | ||||
| 				local gotFile = false | ||||
| 				while true do | ||||
| 					ch, msg = skynet.receive(channel) | ||||
| 					if type(msg) == "table" then | ||||
| 						if type(msg.complete) == "boolean" and type(msg.msg) == "string" and type(msg.part) == "number" then | ||||
| 							output[msg.part] = msg.msg | ||||
| 							cWrite(".", colors.lightGray) | ||||
| 							if msg.complete then | ||||
| 								break | ||||
| 							end | ||||
| 						end | ||||
| 					end | ||||
| 				end | ||||
| 				return channel, textutils.unserialize(table.concat(output)) | ||||
| 			end | ||||
| 		end | ||||
| 		if skynet then | ||||
| 			local bS, bR = defineBigOnes(skynet) | ||||
| 			skynet.open(progdor.channel) | ||||
| 			return skynet, "", bS, bR | ||||
| 		else | ||||
| 			if fs.exists(progdor.skynetPath) then | ||||
| 				local sn = dofile(progdor.skynetPath) | ||||
| 				sn.open(progdor.channel) | ||||
| 				local bS, bR = defineBigOnes(sn) | ||||
| 				return sn, "", bS, bR | ||||
| 			else | ||||
| 				local net, contents = http.get(progdor.skynetURL) | ||||
| 				if net then | ||||
| 					contents = net.readAll() | ||||
| 					local file = fs.open(progdor.skynetPath, "w") | ||||
| 					file.write(contents) | ||||
| 					file.close() | ||||
| 					local sn = dofile(progdor.skynetPath) | ||||
| 					local bS, bR = defineBigOnes(sn) | ||||
| 					sn.open(progdor.channel) | ||||
| 					return sn, "", bS, bR | ||||
| 				else | ||||
| 					return false, "Couldn't download Skynet." | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 	else | ||||
| 		return false, "This version of CC does not support Skynet." | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local getModem = function() | ||||
| 	local mod = peripheral.find("modem") | ||||
| 	if mod then | ||||
| 		mod.open(progdor.channel) | ||||
| 		return mod | ||||
| 	else | ||||
| 		return false, "No modem was found." | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local archive | ||||
| local doOverwrite, doContinue = false, true | ||||
|  | ||||
| --[[ JUST SUMMIN' UP THE ELSEIF CHAIN | ||||
| 	if mode == "api" then | ||||
| 	elseif trMode == "transmit" then | ||||
| 		if mode == "pack" then | ||||
| 		end | ||||
| 	elseif trMode == "receive" then | ||||
| 		if mode == "pack" then | ||||
| 		end | ||||
| 	elseif mode == "pack" then | ||||
| 	elseif mode == "unpack" then | ||||
| 	elseif mode == "inspect" then | ||||
| 	end | ||||
| --]] | ||||
|  | ||||
| -- API mode takes top priority | ||||
| if mode == "api" then | ||||
|  | ||||
| 	return { | ||||
| 		parseArchive = parseArchive, | ||||
| 		parseArchiveData = parseArchiveData, | ||||
| 		buildArchive = buildArchive, | ||||
| 		uploadToPastebin = uploadToPastebin, | ||||
| 	} | ||||
|  | ||||
| -- after that, trans | ||||
| elseif trMode == "transmit" then | ||||
|  | ||||
| 	-- assemble something to send | ||||
| 	local output = {name = fs.getName(inputPath)} | ||||
| 	if mode == "pack" then | ||||
| 		output.contents = textutils.serialize(buildArchive(inputPath, mainFile, useCompression)) | ||||
| 	else | ||||
| 		local file = fs.open(inputPath, "r") | ||||
| 		output.contents = file.readAll() | ||||
| 		file.close() | ||||
| 	end | ||||
|  | ||||
| 	local grr | ||||
| 	if useSkynet then | ||||
| 		if not skynet then | ||||
| 			cWrite("Connecting to Skynet...", colors.lightGray) | ||||
| 			skynet, grr, skynetBigSend, skynetBigReceive = getSkynet() | ||||
| 			if not skynet then | ||||
| 				print(grr) | ||||
| 				print("Aborting.") | ||||
| 				return false | ||||
| 			else | ||||
| 				cPrint("good", colors.green) | ||||
| 			end | ||||
| 		end | ||||
| 		cWrite("Sending file...", colors.lightGray) | ||||
| 		skynetBigSend(progdor.channel, output) | ||||
| 		skynet.socket.close() | ||||
| 		cPrint("good", colors.green) | ||||
| 		sWrite("Sent '") | ||||
| 		cWrite(fs.getName(inputPath), colors.yellow) | ||||
| 		sWrite("' using Skynet.") | ||||
| 	else | ||||
| 		if not modem then | ||||
| 			modem, grr = getModem() | ||||
| 			if not modem then | ||||
| 				print(grr) | ||||
| 				print("Abort.") | ||||
| 				return false | ||||
| 			end | ||||
| 		end | ||||
| 		cWrite("Sending file...", colors.lightGray) | ||||
| 		modem.transmit(progdor.channel, progdor.channel, output) | ||||
| 		cPrint("good", colors.green) | ||||
| 		sWrite("Sent '") | ||||
| 		cWrite(fs.getName(inputPath), colors.yellow) | ||||
| 		sWrite("' using modem.") | ||||
| 	end | ||||
|  | ||||
| elseif trMode == "receive" then | ||||
| 	local grr | ||||
| 	local gotFile = false | ||||
| 	local input, channel | ||||
| 	local didAbort = false | ||||
| 	if useSkynet then | ||||
| 		if not skynet then | ||||
| 			cWrite("Connecting to Skynet...", colors.lightGray) | ||||
| 			skynet, grr, skynetBigSend, skynetBigReceive = getSkynet() | ||||
| 			if not skynet then | ||||
| 				print(grr) | ||||
| 				print("Aborting.") | ||||
| 				return false | ||||
| 			else | ||||
| 				cPrint("good", colors.green) | ||||
| 			end | ||||
| 		end | ||||
| 		cWrite("Waiting for file on Skynet...", colors.lightGray) | ||||
| 		local result, grr = pcall(function() | ||||
| 			sleep(0.05) | ||||
| 			while true do | ||||
| 				if parallel.waitForAny(function() | ||||
| 					channel, input = skynetBigReceive(progdor.channel) | ||||
| 				end, function() | ||||
| 					local evt | ||||
| 					while true do | ||||
| 						evt = {os.pullEvent()} | ||||
| 						if evt[1] == "key" then | ||||
| 							if evt[2] == keys.q then | ||||
| 								return | ||||
| 							end | ||||
| 						end | ||||
| 					end | ||||
| 				end) == 2 then | ||||
| 					print("\nAbort.") | ||||
| 					sleep(0.05) | ||||
| 					didAbort = true | ||||
| 					break | ||||
| 				end | ||||
| 				if channel == progdor.channel and type(input) == "table" then | ||||
| 					if type(input.contents) == "string" and type(input.name) == "string" then | ||||
| 						gotFile = true | ||||
| 						break | ||||
| 					end | ||||
| 				end | ||||
| 			end | ||||
| 		end) | ||||
| 		skynet.socket.close() | ||||
| 		if not result then | ||||
| 			error(grr, 0) | ||||
| 		end | ||||
| 	else | ||||
| 		modem, grr = getModem() | ||||
| 		if not modem then | ||||
| 			error("is it open? " .. modem.isOpen(progdor.channel)) | ||||
| 			print(grr) | ||||
| 			print("Abort.") | ||||
| 			sleep(0.05) | ||||
| 			return false | ||||
| 		end | ||||
| 		--modem.open(progdor.channel) | ||||
| 		local evt | ||||
| 		cWrite("Waiting for file...", colors.lightGray) | ||||
| 		sleep(0.05) | ||||
| 		while true do | ||||
| 			evt = {os.pullEvent()} | ||||
| 			if evt[1] == "modem_message" then | ||||
| 				if evt[3] == progdor.channel and type(evt[5]) == "table" then | ||||
| 					if type(evt[5].contents) == "string" and type(evt[5].name) == "string" then | ||||
| 						input = evt[5] | ||||
| 						gotFile = true | ||||
| 						break | ||||
| 					end | ||||
| 				end | ||||
| 			elseif evt[1] == "key" then | ||||
| 				if evt[2] == keys.q then | ||||
| 					print("\nAbort.") | ||||
| 					sleep(0.05) | ||||
| 					didAbort = true | ||||
| 					break | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	if gotFile then | ||||
| 		cPrint("good", colors.green) | ||||
| 		if input.contents then | ||||
| 			local writePath, c = fs.combine(shell.dir(), outputPath or input.name) | ||||
| 			write("Received '") | ||||
| 			cWrite(input.name or outputPath, colors.yellow, true) | ||||
| 			print("'.") | ||||
| 			if (not justOverwrite and fs.exists(writePath)) or fs.isReadOnly(writePath) then | ||||
| 				write("\nBut, '") | ||||
| 				cWrite(fs.getName(writePath), colors.yellow, true) | ||||
| 				print("' is already there.") | ||||
| 				local roCount = 0 | ||||
| 				local showROmessage = function(roCount) | ||||
| 					if roCount == 1 then | ||||
| 						write("\nThat file/folder is ") | ||||
| 						cWrite("read-only", colors.yellow, true) | ||||
| 						print("!") | ||||
| 					elseif roCount == 2 then | ||||
| 						write("\nI told you, that file/folder is ") | ||||
| 						cWrite("read-only", colors.yellow, true) | ||||
| 						print("!") | ||||
| 					elseif roCount == 3 then | ||||
| 						write("\nNope. The file/folder is ") | ||||
| 						cWrite("read-only", colors.yellow, true) | ||||
| 						print(".") | ||||
| 					elseif roCount == 4 then | ||||
| 						write("\nDoes the phrase ") | ||||
| 						cWrite("read-only", colors.yellow, true) | ||||
| 						print(" mean nothing to you?") | ||||
| 					elseif roCount == 5 then | ||||
| 						print("\nAlright wise-ass, that's enough.") | ||||
| 					elseif roCount > 5 then | ||||
| 						write("\nThat's ") | ||||
| 						cWrite("read-only", colors.yellow, true) | ||||
| 						print(", damn you!") | ||||
| 					end | ||||
| 				end | ||||
| 				while true do | ||||
| 					sleep(0.05) | ||||
| 					if roCount < 5 then | ||||
| 						write("Overwrite [Y/N]? Or [R]ename?\n") | ||||
| 						c = choice("nry", false) | ||||
| 					else | ||||
| 						write("Overwrite [ /N]? Or [R]ename?\n") | ||||
| 						c = choice("nr", false) | ||||
| 					end | ||||
| 					if c == 3 then | ||||
| 						if fs.isReadOnly(writePath) then | ||||
| 							roCount = roCount + 1 | ||||
| 							showROmessage(roCount) | ||||
| 						else | ||||
| 							break | ||||
| 						end | ||||
| 					elseif c == 1 then | ||||
| 						print("Abort.") | ||||
| 						return false | ||||
| 					elseif c == 2 then | ||||
| 						print("New name:") | ||||
| 						if shell.dir() == "" then | ||||
| 							write("/") | ||||
| 						else | ||||
| 							write("/" .. shell.dir() .. "/") | ||||
| 						end | ||||
| 						writePath = fs.combine(shell.dir(), read()) | ||||
| 						roCount = roCount + 1 | ||||
| 						if fs.isReadOnly(writePath) then | ||||
| 							showROmessage(roCount) | ||||
| 						else | ||||
| 							break | ||||
| 						end | ||||
| 					end | ||||
| 				end | ||||
| 			end | ||||
| 			local file = fs.open(writePath, "w") | ||||
| 			file.write(input.contents) | ||||
| 			file.close() | ||||
| 			sWrite("Wrote to '") | ||||
| 			cWrite(writePath, colors.yellow) | ||||
| 			sWrite("'") | ||||
| 		end | ||||
| 	elseif not didAbort then | ||||
| 		print("fail!") | ||||
| 	end | ||||
|  | ||||
| elseif mode == "pack" then | ||||
|  | ||||
| 	if not pastebinUpload then | ||||
| 		if fs.isReadOnly(outputPath) then | ||||
| 			error("Output path is read-only.") | ||||
| 		elseif fs.exists(outputPath) and (outputPath ~= inputPath) then | ||||
| 			doContinue, doOverwrite = overwriteOutputPath(inputPath, outputPath, false, justOverwrite) | ||||
| 		elseif fs.combine("", outputPath) == "" then | ||||
| 			error("Output path cannot be root.") | ||||
| 		end | ||||
| 		if not doContinue then | ||||
| 			return false | ||||
| @@ -662,7 +1032,9 @@ elseif mode == "unpack" then -- unpack OR upload | ||||
| 		if pastebinGet and directDownload then | ||||
| 			error("Cannot do both pastebin get and direct download.") | ||||
| 		elseif fs.isReadOnly(outputPath) then | ||||
| 			error("Output path is read only.") | ||||
| 			error("Output path is read-only.") | ||||
| 		elseif fs.combine(outputPath, "") == "" then | ||||
| 			error("Output path cannot be root.") | ||||
| 		else | ||||
| 			if pastebinGet then | ||||
| 				url = "http://www.pastebin.com/raw/" .. pastebinGet | ||||
| @@ -684,9 +1056,7 @@ elseif mode == "unpack" then -- unpack OR upload | ||||
| 			sWrite("\"...") | ||||
| 			local handle = http.get(url) | ||||
| 			if handle then | ||||
| 				setTextColor(colors.green) | ||||
| 				sPrint("success!") | ||||
| 				setTextColor(colors.white) | ||||
| 				cPrint("success!", colors.green) | ||||
| 				contents = handle.readAll() | ||||
| 				handle.close() | ||||
|  | ||||
| @@ -735,12 +1105,18 @@ elseif mode == "unpack" then -- unpack OR upload | ||||
| 			setTextColor(colors.lightGray) | ||||
| 			sWrite("Parsing archive...") | ||||
| 			archive = parseArchive(inputPath) | ||||
| 			if archive then | ||||
| 				setTextColor(colors.green) | ||||
| 				sPrint("good") | ||||
| 				if doOverwrite then | ||||
| 					fs.delete(outputPath) | ||||
| 				end | ||||
| 				writeArchiveData(archive, outputPath) | ||||
| 			else | ||||
| 				setTextColor(colors.red) | ||||
| 				sPrint("Invalid archive file.") | ||||
| 				return false | ||||
| 			end | ||||
| 		else | ||||
| 			error("No such input path exists.") | ||||
| 		end | ||||
| @@ -788,13 +1164,4 @@ elseif mode == "inspect" then | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| elseif mode == "api" then | ||||
| 	 | ||||
| 	return { | ||||
| 		parseArchive = parseArchive, | ||||
| 		parseArchiveData = parseArchiveData, | ||||
| 		buildArchive = buildArchive, | ||||
| 		uploadToPastebin = uploadToPastebin, | ||||
| 	} | ||||
| 	 | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 LDDestroier
					LDDestroier