mirror of
				https://github.com/kepler155c/opus
				synced 2025-10-31 07:33:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			218 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local Event  = require('opus.event')
 | |
| local GPS    = require('opus.gps')
 | |
| local Socket = require('opus.socket')
 | |
| local Util   = require('opus.util')
 | |
| 
 | |
| local device  = _G.device
 | |
| local kernel  = _G.kernel
 | |
| local network = _G.network
 | |
| local os      = _G.os
 | |
| local turtle  = _G.turtle
 | |
| 
 | |
| -- move this into gps api
 | |
| local gpsRequested
 | |
| local gpsLastPoint
 | |
| local gpsLastRequestTime
 | |
| 
 | |
| local function snmpConnection(socket)
 | |
| 	while true do
 | |
| 		local msg = socket:read()
 | |
| 		if not msg then
 | |
| 			break
 | |
| 		end
 | |
| 
 | |
| 		if msg.type == 'reboot' then
 | |
| 			os.reboot()
 | |
| 
 | |
| 		elseif msg.type == 'shutdown' then
 | |
| 			os.shutdown()
 | |
| 
 | |
| 		elseif msg.type == 'ping' then
 | |
| 			socket:write('pong')
 | |
| 
 | |
| 		elseif msg.type == 'script' then
 | |
| 			local env = setmetatable(Util.shallowCopy(_ENV), { __index = _G })
 | |
| 			local fn, err = load(msg.args, 'script', nil, env)
 | |
| 			if fn then
 | |
| 				kernel.run({
 | |
| 					fn = fn,
 | |
| 					env = env,
 | |
| 					title = 'script',
 | |
| 				})
 | |
| 			else
 | |
| 				_G.printError(err)
 | |
| 			end
 | |
| 
 | |
| 		elseif msg.type == 'scriptEx' then
 | |
| 			local s, m = pcall(function()
 | |
| 				local env = setmetatable(Util.shallowCopy(_ENV), { __index = _G })
 | |
| 				local fn, m = load(msg.args, 'script', nil, env)
 | |
| 				if not fn then
 | |
| 					error(m)
 | |
| 				end
 | |
| 				return { fn() }
 | |
| 			end)
 | |
| 			if s then
 | |
| 				socket:write(m)
 | |
| 			else
 | |
| 				socket:write({ s, m })
 | |
| 			end
 | |
| 
 | |
| 		elseif msg.type == 'gps' then
 | |
| 			if gpsRequested then
 | |
| 				repeat
 | |
| 					os.sleep(0)
 | |
| 				until not gpsRequested
 | |
| 			end
 | |
| 
 | |
| 			if gpsLastPoint and os.clock() - gpsLastRequestTime < .5 then
 | |
| 				socket:write(gpsLastPoint)
 | |
| 			else
 | |
| 
 | |
| 				gpsRequested = true
 | |
| 				local pt = GPS.getPoint(2)
 | |
| 				if pt then
 | |
| 					socket:write(pt)
 | |
| 				else
 | |
| 					print('snmp: Unable to get GPS point')
 | |
| 				end
 | |
| 				gpsRequested = false
 | |
| 				gpsLastPoint = pt
 | |
| 				if pt then
 | |
| 					gpsLastRequestTime = os.clock()
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		elseif msg.type == 'info' then
 | |
| 			local info = {
 | |
| 				id = os.getComputerID(),
 | |
| 				label = os.getComputerLabel(),
 | |
| 				uptime = math.floor(os.clock()),
 | |
| 			}
 | |
| 			if turtle then
 | |
| 				info.fuel = turtle.getFuelLevel()
 | |
| 				info.status = turtle.getStatus()
 | |
| 			end
 | |
| 			socket:write(info)
 | |
| 		end
 | |
| 	end
 | |
| end
 | |
| 
 | |
| Event.addRoutine(function()
 | |
| 	print('snmp: listening on port 161')
 | |
| 
 | |
| 	while true do
 | |
| 		local socket = Socket.server(161)
 | |
| 
 | |
| 		Event.addRoutine(function()
 | |
| 			print('snmp: connection from ' .. socket.dhost)
 | |
| 			local s, m = pcall(snmpConnection, socket)
 | |
| 			print('snmp: closing connection to ' .. socket.dhost)
 | |
| 			if not s and m then
 | |
| 				print('snmp error')
 | |
| 				_G.printError(m)
 | |
| 			end
 | |
| 		end)
 | |
| 	end
 | |
| end)
 | |
| 
 | |
| device.wireless_modem.open(999)
 | |
| print('discovery: listening on port 999')
 | |
| 
 | |
| Event.on('modem_message', function(_, _, sport, id, info, distance)
 | |
| 	if sport == 999 and tonumber(id) and type(info) == 'table' then
 | |
| 		if info.label and info.id and
 | |
| 			type(info.label) == 'string' and type(info.id) == 'number' then
 | |
| 
 | |
| 			if not network[id] then
 | |
| 				network[id] = { }
 | |
| 			end
 | |
| 			Util.merge(network[id], info)
 | |
| 			network[id].distance = type(distance) == 'number' and distance
 | |
| 			network[id].timestamp = os.clock()
 | |
| 
 | |
| 			if not network[id].label then
 | |
| 				network[id].label = 'unknown'
 | |
| 			end
 | |
| 
 | |
| 			if not network[id].active then
 | |
| 				network[id].active = true
 | |
| 				os.queueEvent('network_attach', network[id])
 | |
| 			end
 | |
| 		else
 | |
| 			print('discovery: Invalid alive message ' .. id)
 | |
| 		end
 | |
| 	end
 | |
| end)
 | |
| 
 | |
| local info = {
 | |
| 	id = os.getComputerID()
 | |
| }
 | |
| local infoTimer = os.clock()
 | |
| 
 | |
| local function sendInfo()
 | |
| 	if os.clock() - infoTimer >= 1 then -- don't flood
 | |
| 		infoTimer = os.clock()
 | |
| 		info.label = os.getComputerLabel()
 | |
| 		info.uptime = math.floor(os.clock())
 | |
| 		info.group = network.getGroup()
 | |
| 		if turtle and turtle.getStatus then
 | |
| 			info.fuel = turtle.getFuelLevel()
 | |
| 			info.status = turtle.getStatus()
 | |
| 			info.point = turtle.point
 | |
| 			info.inventory = turtle.getInventory()
 | |
| 			info.slotIndex = turtle.getSelectedSlot()
 | |
| 		end
 | |
| 		if device.neuralInterface then
 | |
| 			info.status = device.neuralInterface.status
 | |
| 			if not info.status and device.neuralInterface.getMetaOwner then
 | |
| 				pcall(function()
 | |
| 					local meta = device.neuralInterface.getMetaOwner()
 | |
| 
 | |
| 					if meta.isWet then
 | |
| 						info.status = 'Swimming'
 | |
| 					elseif meta.isElytraFlying then
 | |
| 						info.status = 'Flying'
 | |
| 					elseif meta.isBurning then
 | |
| 						info.status = 'Burning'
 | |
| 					elseif meta.isDead then
 | |
| 						info.status = 'Deceased'
 | |
| 					elseif meta.isOnLadder then
 | |
| 						info.status = 'Climbing'
 | |
| 					elseif meta.isRiding then
 | |
| 						info.status = 'Riding'
 | |
| 					elseif meta.isSneaking then
 | |
| 						info.status = 'Sneaking'
 | |
| 					elseif meta.isSprinting then
 | |
| 						info.status = 'Running'
 | |
| 					else
 | |
| 						info.status = 'health: ' ..
 | |
| 							math.floor(meta.health /
 | |
| 								meta.maxHealth * 100)
 | |
| 					end
 | |
| 				end)
 | |
| 			end
 | |
| 		end
 | |
| 		device.wireless_modem.transmit(999, os.getComputerID(), info)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| -- every 10 seconds, send out this computer's info
 | |
| Event.onInterval(10, function()
 | |
| 	sendInfo()
 | |
| 	for _,c in pairs(_G.network) do
 | |
| 		local elapsed = os.clock()-c.timestamp
 | |
| 		if c.active and elapsed > 15 then
 | |
| 			c.active = false
 | |
| 			os.queueEvent('network_detach', c)
 | |
| 		end
 | |
| 	end
 | |
| end)
 | |
| 
 | |
| Event.on('turtle_response', function()
 | |
| 	if turtle.getStatus() ~= info.status or
 | |
| 		 turtle.fuel ~= info.fuel then
 | |
| 		sendInfo()
 | |
| 	end
 | |
| end)
 | 
