mirror of
				https://github.com/LDDestroier/CC/
				synced 2025-10-31 07:22:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			221 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| --[[
 | |
| 	Virtipheral -- virtual peripheral tool
 | |
| 
 | |
| 	Docs:
 | |
| 
 | |
| 		virtipheral.activate() - Turns on Virtipheral, and overwrites _G.peripheral.
 | |
| 		virtipheral.deactivate() - Turns off Virtipheral, and reverts _G.peripheral back.
 | |
| 
 | |
| 	Upon activation, some new functions are added into _G.peripheral.
 | |
| 
 | |
| 		peripheral.attach(string Side, string PeripheralType) - Adds a new virtual peripheral on the specified Side. If that side is occupied by a real peripheral, the virtual one will take precedent.
 | |
| 		peripheral.detach(string Side) - Detaches a virtual peripheral from the specified Side.
 | |
| 		peripheral.saveAttach(optional string Path) - Saves the current setup of attached virtual peripherals to a file (by default, "/.virtipheral/p.lson").
 | |
| 		peripheral.loadAttach(optional string Path, optional boolean Additive) - Loads a saved setup of virtual peripherals from a file. If additive is true, it will add any new peripherals into the current setup instead of overwriting the setup.
 | |
| 
 | |
| 	Create new virtual peripherals by making a Lua script that returns a table of methods.
 | |
| 	Place these files at "/.virtipheral/peripherals/ and load them with peripheral.attach()."
 | |
| --]]
 | |
| 
 | |
| local virtipheral = {
 | |
| 	-- path where virtual peripherals are stored
 | |
| 	peripheralPath = ".virtipheral/peripherals",
 | |
| 
 | |
| 	-- default path to store the list of currently loaded peripherals
 | |
| 	configPath = ".virtipheral/p.lson",
 | |
| }
 | |
| 
 | |
| -- list of currently loaded virtual peripherals
 | |
| -- K = side, V = methods
 | |
| local virtualPeripherals = {}
 | |
| 
 | |
| local function tableCopy(tbl)
 | |
| 	local output = {}
 | |
| 	for k,v in pairs(tbl) do
 | |
| 		if type(v) == "table" then
 | |
| 			output[k] = tableCopy(v)
 | |
| 		else
 | |
| 			output[k] = v
 | |
| 		end
 | |
| 	end
 | |
| 	return output
 | |
| end
 | |
| 
 | |
| local loadPeripheral = function(name)
 | |
| 	local path = fs.combine(virtipheral.peripheralPath, name)
 | |
| 	local output
 | |
| 	if not fs.exists(path) then	-- counteract edit.lua's fixation with ending every goddamn file with ".lua"
 | |
| 		path = path .. ".lua"
 | |
| 	end
 | |
| 	if fs.exists(path) then
 | |
| 		output = dofile(path)
 | |
| 		return output
 | |
| 	else
 | |
| 		return false
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local makeNewPeripheralAPI = function(old)
 | |
| 	local p = {}
 | |
| 
 | |
| 	p.attach = function(side, name)
 | |
| 		assert(type(side) == "string", "bad argument #1 to 'attach' (expected string, got " .. type(side) .. ")")
 | |
| 		assert(type(name) == "string", "bad argument #2 to 'attach' (expected string, got " .. type(name) .. ")")
 | |
| 		local methods = loadPeripheral(name)
 | |
| 		if methods then
 | |
| 			virtualPeripherals[side] = {
 | |
| 				name = name,
 | |
| 				side = side,
 | |
| 				methods = methods,
 | |
| 			}
 | |
| 			return true
 | |
| 		else
 | |
| 			return false
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	p.detach = function(side)
 | |
| 		assert(type(side) == "string", "bad argument #1 to 'detach' (expected string, got " .. type(side) .. ")")
 | |
| 		virtualPeripherals[side] = nil
 | |
| 	end
 | |
| 
 | |
| 	p.saveAttach = function(configPath)
 | |
| 		configPath = configPath or virtipheral.configPath
 | |
| 
 | |
| 		local save = {}
 | |
| 		for k,v in pairs(virtualPeripherals) do
 | |
| 			save[k] = {
 | |
| 				name = v.name,
 | |
| 				side = v.side,
 | |
| 			}
 | |
| 		end
 | |
| 		local file = fs.open(configPath, "w")
 | |
| 		file.write(textutils.serialize(save))
 | |
| 		file.close()
 | |
| 	end
 | |
| 
 | |
| 	p.loadAttach = function(configPath, additive)
 | |
| 		configPath = configPath or virtipheral.configPath
 | |
| 		local file = fs.open(configPath, "r")
 | |
| 		local contents = textutils.unserialize(file.readAll() or "")
 | |
| 		file.close()
 | |
| 		if not additive then
 | |
| 			virtualPeripherals = {}
 | |
| 		end
 | |
| 		if contents then
 | |
| 			for k,v in pairs(contents) do
 | |
| 				p.attach(v.side or k, v.name)
 | |
| 			end
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	p.wrap = function(side)
 | |
| 		assert(type(side) == "string", "bad argument #1 to 'wrap' (expected string, got " .. type(side) .. ")")
 | |
| 		if virtualPeripherals[side] then
 | |
| 			return virtualPeripherals[side].methods
 | |
| 		else
 | |
| 			return old.wrap(side)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	p.call = function(side, method, ...)
 | |
| 		assert(type(side)   == "string", "bad argument #1 to 'call' (expected string, got " .. type(side) .. ")")
 | |
| 		assert(type(method) == "string", "bad argument #2 to 'call' (expected string, got " .. type(method) .. ")")
 | |
| 		if virtualPeripherals[side] then
 | |
| 			if virtualPeripherals[side].methods[method] then
 | |
| 				virtualPeripherals[side].methods[method](...)
 | |
| 			else
 | |
| 				error("no such method", 0)
 | |
| 			end
 | |
| 		else
 | |
| 			return old.call(side, method, ...)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	p.find = function(pType)
 | |
| 		assert(type(pType) == "string", "bad argument #1 to 'find' (expected string, got " .. type(pType) .. ")")
 | |
| 		for k,v in pairs(virtualPeripherals) do
 | |
| 			if v.name == pType then
 | |
| 				return v.methods
 | |
| 			end
 | |
| 		end
 | |
| 		return old.find(pType)
 | |
| 	end
 | |
| 
 | |
| 	p.getNames = function()
 | |
| 		local output = {}
 | |
| 		for k, v in pairs(virtualPeripherals) do
 | |
| 			output[#output + 1] = k
 | |
| 		end
 | |
| 		for k, v in pairs(old.getNames()) do
 | |
| 			output[#output + 1] = v
 | |
| 		end
 | |
| 		return output
 | |
| 	end
 | |
| 
 | |
| 	p.getMethods = function(side)
 | |
| 		local output = {}
 | |
| 		local list = (virtualPeripherals[side] or {}).methods or old.wrap(side)
 | |
| 		if list then
 | |
| 			for k,v in pairs(list) do
 | |
| 				output[#output + 1] = k
 | |
| 			end
 | |
| 		else
 | |
| 			return nil
 | |
| 		end
 | |
| 		return output
 | |
| 	end
 | |
| 
 | |
| 	p.getType = function(side)
 | |
| 		if virtualPeripherals[side] then
 | |
| 			return virtualPeripherals[side].name
 | |
| 		else
 | |
| 			return old.getType(side)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	p.isPresent = function(side)
 | |
| 		if virtualPeripherals[side] then
 | |
| 			return true
 | |
| 		else
 | |
| 			return old.isPresent(side)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	return p
 | |
| end
 | |
| 
 | |
| virtipheral.activate = function()
 | |
| 	if _G.virtipheralActive then
 | |
| 		error("Virtipheral is already running", 0)
 | |
| 	else
 | |
| 		fs.makeDir(virtipheral.peripheralPath)
 | |
| 		local old = tableCopy(_G.peripheral)
 | |
| 		for k,v in pairs(old) do
 | |
| 			local env = getfenv(old[k])
 | |
| 			env.peripheral = old
 | |
| 		end
 | |
| 		_G.__old_peripheral = old
 | |
| 		_G.peripheral = makeNewPeripheralAPI(old)
 | |
| 		_G.virtipheralActive = true
 | |
| 		return true
 | |
| 	end
 | |
| end
 | |
| 
 | |
| virtipheral.deactivate = function()
 | |
| 	if not _G.virtipheralActive then
 | |
| 		error("Virtipheral is not running", 0)
 | |
| 	else
 | |
| 		_G.peripheral = tableCopy(_G.__old_peripheral)
 | |
| 		for k,v in pairs(_G.peripheral) do
 | |
| 			local env = getfenv(_G.peripheral[k])
 | |
| 			env.peripheral = _G.peripheral
 | |
| 		end
 | |
| 		_G.__old_peripheral = nil
 | |
| 		_G.virtipheralActive = false
 | |
| 		return true
 | |
| 	end
 | |
| end
 | |
| 
 | |
| return virtipheral
 | 
