Milo: remote learn + remove logger
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
local Event = require('event')
|
local Event = require('event')
|
||||||
local Logger = require('logger')
|
|
||||||
local MEProvider = require('meProvider')
|
local MEProvider = require('meProvider')
|
||||||
local Message = require('message')
|
local Message = require('message')
|
||||||
local Point = require('point')
|
local Point = require('point')
|
||||||
@@ -31,9 +30,6 @@ if not device.wireless_modem then
|
|||||||
error('No wireless modem detected')
|
error('No wireless modem detected')
|
||||||
end
|
end
|
||||||
|
|
||||||
Logger.filter('modem_send', 'event', 'ui')
|
|
||||||
Logger.setWirelessLogging()
|
|
||||||
|
|
||||||
local __BUILDER_ID = 6
|
local __BUILDER_ID = 6
|
||||||
local itemInfoDB
|
local itemInfoDB
|
||||||
|
|
||||||
@@ -130,7 +126,6 @@ function Builder:refuel()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Builder:log(...)
|
function Builder:log(...)
|
||||||
Logger.log('supplier', ...)
|
|
||||||
Util.print(...)
|
Util.print(...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ local function isValid(drive)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function needsLabel(drive)
|
local function needsLabel(drive)
|
||||||
return drive.isDiskPresent() and not drive.getMountPath()
|
return drive.isDiskPresent() and not drive.getMountPath() and not drive.getAudioTitle()
|
||||||
end
|
end
|
||||||
|
|
||||||
function page:drawInfo(drive, textArea)
|
function page:drawInfo(drive, textArea)
|
||||||
@@ -117,8 +117,7 @@ function page:copy(sdrive, tdrive)
|
|||||||
|
|
||||||
local function countFiles(source, target)
|
local function countFiles(source, target)
|
||||||
if fs.isDir(source) then
|
if fs.isDir(source) then
|
||||||
local list = fs.list(source)
|
for _,f in pairs(fs.list(source)) do
|
||||||
for _,f in pairs(list) do
|
|
||||||
countFiles(fs.combine(source, f), fs.combine(target, f))
|
countFiles(fs.combine(source, f), fs.combine(target, f))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -133,8 +132,7 @@ function page:copy(sdrive, tdrive)
|
|||||||
if not fs.exists(target) then
|
if not fs.exists(target) then
|
||||||
fs.makeDir(target)
|
fs.makeDir(target)
|
||||||
end
|
end
|
||||||
local list = fs.list(source)
|
for _,f in pairs(fs.list(source)) do
|
||||||
for _,f in pairs(list) do
|
|
||||||
rawCopy(fs.combine(source, f), fs.combine(target, f))
|
rawCopy(fs.combine(source, f), fs.combine(target, f))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
local Event = require('event')
|
local Event = require('event')
|
||||||
local Logger = require('logger')
|
|
||||||
|
|
||||||
local Message = { }
|
local Message = { }
|
||||||
|
|
||||||
@@ -45,8 +44,6 @@ Event.on('modem_message',
|
|||||||
function(event, side, sendChannel, replyChannel, msg, distance)
|
function(event, side, sendChannel, replyChannel, msg, distance)
|
||||||
if msg and msg.type then -- filter out messages from other systems
|
if msg and msg.type then -- filter out messages from other systems
|
||||||
local id = replyChannel
|
local id = replyChannel
|
||||||
Logger.log('modem_receive', { id, msg.type })
|
|
||||||
--Logger.log('modem_receive', msg.contents)
|
|
||||||
for k,h in pairs(messageHandlers) do
|
for k,h in pairs(messageHandlers) do
|
||||||
if h.type == msg.type then
|
if h.type == msg.type then
|
||||||
-- should provide msg.contents instead of message - type is already known
|
-- should provide msg.contents instead of message - type is already known
|
||||||
@@ -63,12 +60,10 @@ function Message.send(id, msgType, contents)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if id then
|
if id then
|
||||||
Logger.log('modem_send', { tostring(id), msgType })
|
|
||||||
device.wireless_modem.transmit(id, os.getComputerID(), {
|
device.wireless_modem.transmit(id, os.getComputerID(), {
|
||||||
type = msgType, contents = contents
|
type = msgType, contents = contents
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
Logger.log('modem_send', { 'broadcast', msgType })
|
|
||||||
device.wireless_modem.transmit(60000, os.getComputerID(), {
|
device.wireless_modem.transmit(60000, os.getComputerID(), {
|
||||||
type = msgType, contents = contents
|
type = msgType, contents = contents
|
||||||
})
|
})
|
||||||
@@ -81,8 +76,6 @@ function Message.broadcast(t, contents)
|
|||||||
end
|
end
|
||||||
|
|
||||||
Message.send(nil, t, contents)
|
Message.send(nil, t, contents)
|
||||||
-- Logger.log('rednet_send', { 'broadcast', t })
|
|
||||||
-- rednet.broadcast({ type = t, contents = contents })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Message.waitForMessage(msgType, timeout, fromId)
|
function Message.waitForMessage(msgType, timeout, fromId)
|
||||||
@@ -99,8 +92,4 @@ function Message.waitForMessage(msgType, timeout, fromId)
|
|||||||
until e == 'timer' and side == timerId
|
until e == 'timer' and side == timerId
|
||||||
end
|
end
|
||||||
|
|
||||||
function Message.enableWirelessLogging()
|
|
||||||
Logger.setWirelessLogging()
|
|
||||||
end
|
|
||||||
|
|
||||||
return Message
|
return Message
|
||||||
@@ -9,15 +9,14 @@ local Util = require('util')
|
|||||||
local colors = _G.colors
|
local colors = _G.colors
|
||||||
local device = _G.device
|
local device = _G.device
|
||||||
local fs = _G.fs
|
local fs = _G.fs
|
||||||
local os = _G.os
|
|
||||||
local shell = _ENV.shell
|
local shell = _ENV.shell
|
||||||
local string = _G.string
|
local string = _G.string
|
||||||
|
|
||||||
local SHIELD_SLOT = 2
|
|
||||||
local STARTUP_FILE = 'usr/autorun/miloRemote.lua'
|
local STARTUP_FILE = 'usr/autorun/miloRemote.lua'
|
||||||
|
|
||||||
local context = {
|
local context = {
|
||||||
state = Config.load('miloRemote', { displayMode = 0, deposit = true }),
|
state = Config.load('miloRemote', { displayMode = 0, deposit = true }),
|
||||||
|
responseHandlers = { },
|
||||||
}
|
}
|
||||||
|
|
||||||
local depositMode = {
|
local depositMode = {
|
||||||
@@ -164,125 +163,6 @@ local function getPlayerName()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function page:setStatus(status)
|
|
||||||
self.menuBar.infoBar:setStatus(status)
|
|
||||||
self:sync()
|
|
||||||
end
|
|
||||||
|
|
||||||
function page:processMessages(s)
|
|
||||||
Event.addRoutine(function()
|
|
||||||
repeat
|
|
||||||
local response = s:read()
|
|
||||||
if not response then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
if response.type == 'received' then
|
|
||||||
Sound.play('entity.item.pickup')
|
|
||||||
local ritem = self.items[response.key]
|
|
||||||
if ritem then
|
|
||||||
ritem.count = response.count
|
|
||||||
if self.enabled then
|
|
||||||
self.grid:draw()
|
|
||||||
self:sync()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif response.type == 'list' then
|
|
||||||
self.items = self:expandList(response.list)
|
|
||||||
self:applyFilter()
|
|
||||||
if self.enabled then
|
|
||||||
self.grid:draw()
|
|
||||||
self.grid:sync()
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif response.type == 'transfer' then
|
|
||||||
if response.count > 0 then
|
|
||||||
Sound.play('entity.item.pickup')
|
|
||||||
local item = self.items[response.key]
|
|
||||||
if item then
|
|
||||||
item.count = response.current
|
|
||||||
if self.enabled then
|
|
||||||
self.grid:draw()
|
|
||||||
self:sync()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if response.craft then
|
|
||||||
if response.craft > 0 then
|
|
||||||
self:setStatus(response.craft .. ' crafting ...')
|
|
||||||
elseif response.craft + response.count < response.requested then
|
|
||||||
if response.craft + response.count == 0 then
|
|
||||||
Sound.play('entity.villager.no')
|
|
||||||
end
|
|
||||||
self:setStatus((response.craft + response.count) .. ' available ...')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if response.msg then
|
|
||||||
self:setStatus(response.msg)
|
|
||||||
end
|
|
||||||
until not s.connected
|
|
||||||
|
|
||||||
s:close()
|
|
||||||
s = nil
|
|
||||||
self:setStatus('disconnected ...')
|
|
||||||
Sound.play('entity.villager.no')
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
function page:sendRequest(data, statusMsg)
|
|
||||||
if not context.state.server then
|
|
||||||
self:setStatus('Invalid configuration')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local player = getPlayerName()
|
|
||||||
if not player then
|
|
||||||
self:setStatus('Missing neural or introspection')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local success
|
|
||||||
sync(self, function()
|
|
||||||
local msg
|
|
||||||
for _ = 1, 2 do
|
|
||||||
if not context.socket or not context.socket.connected then
|
|
||||||
self:setStatus('connecting ...')
|
|
||||||
context.socket, msg = Socket.connect(context.state.server, 4242)
|
|
||||||
if context.socket then
|
|
||||||
context.socket:write(player)
|
|
||||||
local r = context.socket:read(2)
|
|
||||||
if r and not r.msg then
|
|
||||||
self:setStatus('connected ...')
|
|
||||||
self:processMessages(context.socket)
|
|
||||||
else
|
|
||||||
msg = r and r.msg or 'Timed out'
|
|
||||||
context.socket:close()
|
|
||||||
context.socket = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if context.socket then
|
|
||||||
if statusMsg then
|
|
||||||
self:setStatus(statusMsg)
|
|
||||||
Event.onTimeout(2, function()
|
|
||||||
self:setStatus('')
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
if context.socket:write(data) then
|
|
||||||
success = true
|
|
||||||
return
|
|
||||||
end
|
|
||||||
context.socket:close()
|
|
||||||
context.socket = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self:setStatus(msg or 'Failed to connect')
|
|
||||||
end)
|
|
||||||
|
|
||||||
return success
|
|
||||||
end
|
|
||||||
|
|
||||||
function page.grid:getRowTextColor(row, selected)
|
function page.grid:getRowTextColor(row, selected)
|
||||||
if row.is_craftable then
|
if row.is_craftable then
|
||||||
return colors.yellow
|
return colors.yellow
|
||||||
@@ -328,7 +208,7 @@ function page.grid:eventHandler(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function page:transfer(item, count, msg)
|
function page:transfer(item, count, msg)
|
||||||
self:sendRequest({ request = 'transfer', item = item, count = count }, msg)
|
context:sendRequest({ request = 'transfer', item = item, count = count }, msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
function page.setup:eventHandler(event)
|
function page.setup:eventHandler(event)
|
||||||
@@ -350,7 +230,7 @@ function page:eventHandler(event)
|
|||||||
context.state.deposit = not context.state.deposit
|
context.state.deposit = not context.state.deposit
|
||||||
Util.merge(self.statusBar.depositToggle, depositMode[context.state.deposit])
|
Util.merge(self.statusBar.depositToggle, depositMode[context.state.deposit])
|
||||||
self.statusBar:draw()
|
self.statusBar:draw()
|
||||||
self:setStatus(depositMode[context.state.deposit].help)
|
context:setStatus(depositMode[context.state.deposit].help)
|
||||||
Config.update('miloRemote', context.state)
|
Config.update('miloRemote', context.state)
|
||||||
|
|
||||||
elseif event.type == 'form_complete' then
|
elseif event.type == 'form_complete' then
|
||||||
@@ -375,7 +255,7 @@ shell.openForegroundTab('packages/milo/MiloRemote')]])
|
|||||||
self:setFocus(self.statusBar.filter)
|
self:setFocus(self.statusBar.filter)
|
||||||
|
|
||||||
elseif event.type == 'focus_change' then
|
elseif event.type == 'focus_change' then
|
||||||
self.menuBar.infoBar:setStatus(event.focused.help)
|
context:setStatus(event.focused.help)
|
||||||
|
|
||||||
elseif event.type == 'eject' or event.type == 'grid_select' then
|
elseif event.type == 'eject' or event.type == 'grid_select' then
|
||||||
local item = self.grid:getSelected()
|
local item = self.grid:getSelected()
|
||||||
@@ -404,7 +284,7 @@ shell.openForegroundTab('packages/milo/MiloRemote')]])
|
|||||||
self:transfer(item, count, 'requesting ' .. count .. ' ...')
|
self:transfer(item, count, 'requesting ' .. count .. ' ...')
|
||||||
else
|
else
|
||||||
Sound.play('entity.villager.no')
|
Sound.play('entity.villager.no')
|
||||||
self:setStatus('nope ...')
|
context:setStatus('nope ...')
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif event.type == 'plugin' then
|
elseif event.type == 'plugin' then
|
||||||
@@ -431,7 +311,7 @@ shell.openForegroundTab('packages/milo/MiloRemote')]])
|
|||||||
Util.merge(event.button, displayModes[context.state.displayMode])
|
Util.merge(event.button, displayModes[context.state.displayMode])
|
||||||
event.button:draw()
|
event.button:draw()
|
||||||
self:applyFilter()
|
self:applyFilter()
|
||||||
self:setStatus(event.button.help)
|
context:setStatus(event.button.help)
|
||||||
self.grid:draw()
|
self.grid:draw()
|
||||||
Config.update('miloRemote', context.state)
|
Config.update('miloRemote', context.state)
|
||||||
|
|
||||||
@@ -490,7 +370,7 @@ function page:expandList(list)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function page:refresh(requestType)
|
function page:refresh(requestType)
|
||||||
self:sendRequest({ request = requestType }, 'refreshing...')
|
context:sendRequest({ request = requestType }, 'refreshing...')
|
||||||
end
|
end
|
||||||
|
|
||||||
function page:applyFilter()
|
function page:applyFilter()
|
||||||
@@ -516,43 +396,89 @@ function page:applyFilter()
|
|||||||
self.grid:setValues(t)
|
self.grid:setValues(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
Event.addRoutine(function()
|
context.page = page
|
||||||
local lastTransfer
|
|
||||||
while true do
|
|
||||||
local sleepTime = 1.5
|
|
||||||
if lastTransfer and os.clock() - lastTransfer < 3 then
|
|
||||||
sleepTime = .25
|
|
||||||
end
|
|
||||||
|
|
||||||
os.sleep(context.socket and sleepTime or 5)
|
function context:setStatus(status)
|
||||||
if context.state.deposit then
|
page.menuBar.infoBar:setStatus(status)
|
||||||
local neural = device.neuralInterface
|
page:sync()
|
||||||
local inv = context.state.useShield and 'getEquipment' or 'getInventory'
|
end
|
||||||
if not neural or not neural[inv] then
|
|
||||||
_G._debug('missing Introspection module')
|
local function processMessages(s)
|
||||||
elseif context.state.server and (context.state.useShield or context.state.slot) then
|
Event.addRoutine(function()
|
||||||
local s, m = pcall(function()
|
s.co = coroutine.running()
|
||||||
local method = neural[inv]
|
repeat
|
||||||
local item = method and method().list()[context.state.useShield and SHIELD_SLOT or context.state.slot]
|
local response = s:read()
|
||||||
if item then
|
if not response then
|
||||||
if page:sendRequest({
|
break
|
||||||
request = 'deposit',
|
end
|
||||||
slot = context.state.useShield and 'shield' or context.state.slot,
|
local h = context.responseHandlers[response.type]
|
||||||
count = item.count,
|
if h then
|
||||||
}) then
|
h(response)
|
||||||
lastTransfer = os.clock()
|
end
|
||||||
end
|
if response.msg then
|
||||||
|
context:setStatus(response.msg)
|
||||||
|
end
|
||||||
|
until not s.connected
|
||||||
|
|
||||||
|
s:close()
|
||||||
|
s = nil
|
||||||
|
context:setStatus('disconnected ...')
|
||||||
|
Sound.play('entity.villager.no')
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function context:sendRequest(data, statusMsg)
|
||||||
|
if not context.state.server then
|
||||||
|
self:setStatus('Invalid configuration')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local player = getPlayerName()
|
||||||
|
if not player then
|
||||||
|
self:setStatus('Missing neural or introspection')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local success
|
||||||
|
sync(page, function()
|
||||||
|
local msg
|
||||||
|
for _ = 1, 2 do
|
||||||
|
if not context.socket or not context.socket.connected then
|
||||||
|
self:setStatus('connecting ...')
|
||||||
|
context.socket, msg = Socket.connect(context.state.server, 4242)
|
||||||
|
if context.socket then
|
||||||
|
context.socket:write(player)
|
||||||
|
local r = context.socket:read(2)
|
||||||
|
if r and not r.msg then
|
||||||
|
self:setStatus('connected ...')
|
||||||
|
processMessages(context.socket)
|
||||||
|
else
|
||||||
|
msg = r and r.msg or 'Timed out'
|
||||||
|
context.socket:close()
|
||||||
|
context.socket = nil
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
if not s and m then
|
|
||||||
_debug(m)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if context.socket then
|
||||||
|
if statusMsg then
|
||||||
|
self:setStatus(statusMsg)
|
||||||
|
Event.onTimeout(2, function()
|
||||||
|
self:setStatus('')
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
if context.socket:write(data) then
|
||||||
|
success = true
|
||||||
|
return
|
||||||
|
end
|
||||||
|
context.socket:close()
|
||||||
|
context.socket = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
self:setStatus(msg or 'Failed to connect')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
context.page = page
|
return success
|
||||||
|
end
|
||||||
|
|
||||||
function context:getState(key)
|
function context:getState(key)
|
||||||
return self.state[key]
|
return self.state[key]
|
||||||
@@ -563,6 +489,51 @@ function context:setState(key, value)
|
|||||||
Config.update('miloRemote', self.state)
|
Config.update('miloRemote', self.state)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context.responseHandlers['received'] = function(response)
|
||||||
|
Sound.play('entity.item.pickup')
|
||||||
|
local ritem = page.items[response.key]
|
||||||
|
if ritem then
|
||||||
|
ritem.count = response.count
|
||||||
|
if page.enabled then
|
||||||
|
page.grid:draw()
|
||||||
|
page:sync()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context.responseHandlers['list'] = function(response)
|
||||||
|
page.items = page:expandList(response.list)
|
||||||
|
page:applyFilter()
|
||||||
|
if page.enabled then
|
||||||
|
page.grid:draw()
|
||||||
|
page.grid:sync()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context.responseHandlers['transfer'] = function(response)
|
||||||
|
if response.count > 0 then
|
||||||
|
Sound.play('entity.item.pickup')
|
||||||
|
local item = page.items[response.key]
|
||||||
|
if item then
|
||||||
|
item.count = response.current
|
||||||
|
if page.enabled then
|
||||||
|
page.grid:draw()
|
||||||
|
page:sync()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if response.craft then
|
||||||
|
if response.craft > 0 then
|
||||||
|
context:setStatus(response.craft .. ' crafting ...')
|
||||||
|
elseif response.craft + response.count < response.requested then
|
||||||
|
if response.craft + response.count == 0 then
|
||||||
|
Sound.play('entity.villager.no')
|
||||||
|
end
|
||||||
|
context:setStatus((response.craft + response.count) .. ' available ...')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function loadDirectory(dir)
|
local function loadDirectory(dir)
|
||||||
local dropdown = {
|
local dropdown = {
|
||||||
{ text = 'Setup', event = 'setup' },
|
{ text = 'Setup', event = 'setup' },
|
||||||
|
|||||||
@@ -222,6 +222,93 @@ function Milo:eject(item, count)
|
|||||||
return count
|
return count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Milo:learnRecipe()
|
||||||
|
local ingredients = self:getTurtleInventory()
|
||||||
|
|
||||||
|
if not ingredients then
|
||||||
|
return false, 'No recipe defined'
|
||||||
|
end
|
||||||
|
|
||||||
|
turtle.select(1)
|
||||||
|
if not turtle.craft() then
|
||||||
|
return false, 'Failed to craft'
|
||||||
|
end
|
||||||
|
|
||||||
|
local results = self:getTurtleInventory()
|
||||||
|
if not results or not results[1] then
|
||||||
|
return false, 'Failed to craft'
|
||||||
|
end
|
||||||
|
|
||||||
|
local maxCount
|
||||||
|
local newRecipe = {
|
||||||
|
ingredients = ingredients,
|
||||||
|
}
|
||||||
|
|
||||||
|
local numResults = 0
|
||||||
|
for _,v in pairs(results) do
|
||||||
|
if v.count > 0 then
|
||||||
|
numResults = numResults + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if numResults > 1 then
|
||||||
|
for _,v1 in pairs(results) do
|
||||||
|
for _,v2 in pairs(ingredients) do
|
||||||
|
if v1.name == v2.name and
|
||||||
|
v1.nbtHash == v2.nbtHash and
|
||||||
|
(v1.damage == v2.damage or
|
||||||
|
(v1.maxDamage > 0 and v2.maxDamage > 0 and
|
||||||
|
v1.damage ~= v2.damage)) then
|
||||||
|
if not newRecipe.crafingTools then
|
||||||
|
newRecipe.craftingTools = { }
|
||||||
|
end
|
||||||
|
local tool = Util.shallowCopy(v2)
|
||||||
|
if tool.maxDamage > 0 then
|
||||||
|
tool.damage = '*'
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Turtles can only craft one item at a time using a tool :(
|
||||||
|
]]--
|
||||||
|
maxCount = 1
|
||||||
|
|
||||||
|
newRecipe.craftingTools[itemDB:makeKey(tool)] = true
|
||||||
|
v1.craftingTool = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local recipe
|
||||||
|
for _,v in pairs(results) do
|
||||||
|
if not v.craftingTool then
|
||||||
|
recipe = v
|
||||||
|
if maxCount then
|
||||||
|
recipe.maxCount = maxCount
|
||||||
|
end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not recipe then
|
||||||
|
return false, 'Unknown error'
|
||||||
|
end
|
||||||
|
|
||||||
|
newRecipe.count = recipe.count
|
||||||
|
|
||||||
|
local key = itemDB:makeKey(recipe)
|
||||||
|
if recipe.maxCount ~= 64 then
|
||||||
|
newRecipe.maxCount = recipe.maxCount
|
||||||
|
end
|
||||||
|
for k,ingredient in pairs(Util.shallowCopy(ingredients)) do
|
||||||
|
ingredients[k] = itemDB:makeKey(ingredient)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:updateRecipe(key, newRecipe)
|
||||||
|
|
||||||
|
return recipe
|
||||||
|
end
|
||||||
|
|
||||||
function Milo:updateRecipe(result, recipe)
|
function Milo:updateRecipe(result, recipe)
|
||||||
-- save the recipe
|
-- save the recipe
|
||||||
if recipe then
|
if recipe then
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ local function client(socket)
|
|||||||
if not data then
|
if not data then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
--_G._debug(data)
|
_G._debug(data)
|
||||||
socket.co = coroutine.running()
|
socket.co = coroutine.running()
|
||||||
|
|
||||||
if data.request == 'scan' then -- full scan of all inventories
|
if data.request == 'scan' then -- full scan of all inventories
|
||||||
@@ -163,6 +163,12 @@ local function client(socket)
|
|||||||
craft = request.craft,
|
craft = request.craft,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
for _,v in pairs(context.plugins.remoteHandler or { }) do
|
||||||
|
if v.messages and v.messages[data.request] then
|
||||||
|
v.callback(user, data, socket)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
until not socket.connected
|
until not socket.connected
|
||||||
|
|
||||||
@@ -191,7 +197,7 @@ Event.on({ 'device_attach', 'device_detach' }, function(_, name)
|
|||||||
if handler then
|
if handler then
|
||||||
handler:terminate()
|
handler:terminate()
|
||||||
handler = nil
|
handler = nil
|
||||||
_debug('REMOTE: wireless modem disconnected')
|
_G._debug('REMOTE: wireless modem disconnected')
|
||||||
else
|
else
|
||||||
listen()
|
listen()
|
||||||
end
|
end
|
||||||
|
|||||||
26
milo/plugins/remote/craft.lua
Normal file
26
milo/plugins/remote/craft.lua
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
local Sound = require('sound')
|
||||||
|
|
||||||
|
local args = { ... }
|
||||||
|
local context = args[1]
|
||||||
|
|
||||||
|
local function learn()
|
||||||
|
context:sendRequest({
|
||||||
|
request = 'craft',
|
||||||
|
slot = 15,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
context.responseHandlers['craft'] = function(response)
|
||||||
|
if response.success then
|
||||||
|
Sound.play('entity.item.pickup')
|
||||||
|
else
|
||||||
|
Sound.play('entity.villager.no')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
menuItem = 'Learn Recipe',
|
||||||
|
callback = function()
|
||||||
|
learn()
|
||||||
|
end,
|
||||||
|
}
|
||||||
45
milo/plugins/remote/deposit.lua
Normal file
45
milo/plugins/remote/deposit.lua
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
local Event = require('event')
|
||||||
|
|
||||||
|
local device = _G.device
|
||||||
|
local os = _G.os
|
||||||
|
|
||||||
|
local args = { ... }
|
||||||
|
local context = args[1]
|
||||||
|
|
||||||
|
local SHIELD_SLOT = 2
|
||||||
|
|
||||||
|
Event.addRoutine(function()
|
||||||
|
local lastTransfer
|
||||||
|
while true do
|
||||||
|
local sleepTime = 1.5
|
||||||
|
if lastTransfer and os.clock() - lastTransfer < 3 then
|
||||||
|
sleepTime = .25
|
||||||
|
end
|
||||||
|
|
||||||
|
os.sleep(context.socket and sleepTime or 5)
|
||||||
|
if context.state.deposit then
|
||||||
|
local neural = device.neuralInterface
|
||||||
|
local inv = context.state.useShield and 'getEquipment' or 'getInventory'
|
||||||
|
if not neural or not neural[inv] then
|
||||||
|
_G._debug('missing Introspection module')
|
||||||
|
elseif context.state.server and (context.state.useShield or context.state.slot) then
|
||||||
|
local s, m = pcall(function()
|
||||||
|
local method = neural[inv]
|
||||||
|
local item = method and method().list()[context.state.useShield and SHIELD_SLOT or context.state.slot]
|
||||||
|
if item then
|
||||||
|
if context:sendRequest({
|
||||||
|
request = 'deposit',
|
||||||
|
slot = context.state.useShield and 'shield' or context.state.slot,
|
||||||
|
count = item.count,
|
||||||
|
}) then
|
||||||
|
lastTransfer = os.clock()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
if not s and m then
|
||||||
|
_G._debug(m)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
@@ -81,7 +81,7 @@ function page:depositAll()
|
|||||||
|
|
||||||
for slot, item in pairs(inv) do
|
for slot, item in pairs(inv) do
|
||||||
if (context.state.depositAll.includeHotbar or slot > 9) and item.name ~= 'plethora:neuralconnector' then
|
if (context.state.depositAll.includeHotbar or slot > 9) and item.name ~= 'plethora:neuralconnector' then
|
||||||
context.page:sendRequest({
|
context:sendRequest({
|
||||||
request = 'deposit',
|
request = 'deposit',
|
||||||
slot = slot,
|
slot = slot,
|
||||||
count = item.count,
|
count = item.count,
|
||||||
@@ -94,12 +94,15 @@ function page:eventHandler(event)
|
|||||||
if event.type == 'checkbox_change' and event.element.formKey == 'includeHotbar' then
|
if event.type == 'checkbox_change' and event.element.formKey == 'includeHotbar' then
|
||||||
context.state.depositAll.includeHotbar = event.checked
|
context.state.depositAll.includeHotbar = event.checked
|
||||||
page:updateInventoryList()
|
page:updateInventoryList()
|
||||||
|
|
||||||
elseif event.type == 'form_complete' then
|
elseif event.type == 'form_complete' then
|
||||||
Config.update('miloRemote', context.state)
|
Config.update('miloRemote', context.state)
|
||||||
page:depositAll()
|
page:depositAll()
|
||||||
UI:setPreviousPage()
|
UI:setPreviousPage()
|
||||||
|
|
||||||
elseif event.type == 'form_cancel' then
|
elseif event.type == 'form_cancel' then
|
||||||
UI:setPreviousPage()
|
UI:setPreviousPage()
|
||||||
|
|
||||||
else
|
else
|
||||||
return UI.Page.eventHandler(self, event)
|
return UI.Page.eventHandler(self, event)
|
||||||
end
|
end
|
||||||
|
|||||||
57
milo/plugins/remoteCraft.lua
Normal file
57
milo/plugins/remoteCraft.lua
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
local itemDB = require('itemDB')
|
||||||
|
local Milo = require('milo')
|
||||||
|
|
||||||
|
local context = Milo:getContext()
|
||||||
|
local device = _G.device
|
||||||
|
|
||||||
|
local function craftHandler(user, message, socket)
|
||||||
|
local function makeNode()
|
||||||
|
local devName = user .. ':inventory'
|
||||||
|
local adapter = device[devName]
|
||||||
|
if adapter then
|
||||||
|
return {
|
||||||
|
adapter = adapter,
|
||||||
|
name = devName,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function craft()
|
||||||
|
local slots = {
|
||||||
|
[1] = 1, [2] = 2, [3] = 3,
|
||||||
|
[5] = 10, [6] = 11, [7] = 12,
|
||||||
|
[9] = 19, [10] = 20, [11] = 21,
|
||||||
|
}
|
||||||
|
local node = makeNode()
|
||||||
|
if node then
|
||||||
|
for k, v in pairs(slots) do
|
||||||
|
node.adapter.pushItems(context.turtleInventory.name, v + message.slot - 1, 1, k)
|
||||||
|
end
|
||||||
|
local recipe, msg = Milo:learnRecipe()
|
||||||
|
if recipe then
|
||||||
|
socket:write({
|
||||||
|
type = 'craft',
|
||||||
|
msg = 'Learned: ' .. itemDB:getName(recipe),
|
||||||
|
success = true,
|
||||||
|
})
|
||||||
|
for k,v in pairs(context.turtleInventory.adapter.list()) do
|
||||||
|
node.adapter.pullItems(context.turtleInventory.name, k, v.count)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
socket:write({
|
||||||
|
type = 'craft',
|
||||||
|
msg = msg,
|
||||||
|
})
|
||||||
|
for k, v in pairs(slots) do
|
||||||
|
node.adapter.pullItems(context.turtleInventory.name, k, 1, v + message.slot - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Milo:queueRequest({ }, craft)
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
remoteHandler = { callback = craftHandler, messages = { craft = true } }
|
||||||
|
}
|
||||||
@@ -1,102 +1,10 @@
|
|||||||
local itemDB = require('itemDB')
|
local itemDB = require('itemDB')
|
||||||
local Milo = require('milo')
|
local Milo = require('milo')
|
||||||
local UI = require('ui')
|
local UI = require('ui')
|
||||||
local Util = require('util')
|
|
||||||
|
|
||||||
local colors = _G.colors
|
local colors = _G.colors
|
||||||
local turtle = _G.turtle
|
local turtle = _G.turtle
|
||||||
|
|
||||||
local function learnRecipe()
|
|
||||||
local ingredients = Milo:getTurtleInventory()
|
|
||||||
|
|
||||||
if not ingredients then
|
|
||||||
return false, 'No recipe defined'
|
|
||||||
end
|
|
||||||
|
|
||||||
turtle.select(1)
|
|
||||||
if not turtle.craft() then
|
|
||||||
return false, 'Failed to craft'
|
|
||||||
end
|
|
||||||
|
|
||||||
local results = Milo:getTurtleInventory()
|
|
||||||
if not results or not results[1] then
|
|
||||||
return false, 'Failed to craft'
|
|
||||||
end
|
|
||||||
|
|
||||||
local maxCount
|
|
||||||
local newRecipe = {
|
|
||||||
ingredients = ingredients,
|
|
||||||
}
|
|
||||||
|
|
||||||
local numResults = 0
|
|
||||||
for _,v in pairs(results) do
|
|
||||||
if v.count > 0 then
|
|
||||||
numResults = numResults + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if numResults > 1 then
|
|
||||||
for _,v1 in pairs(results) do
|
|
||||||
for _,v2 in pairs(ingredients) do
|
|
||||||
if v1.name == v2.name and
|
|
||||||
v1.nbtHash == v2.nbtHash and
|
|
||||||
(v1.damage == v2.damage or
|
|
||||||
(v1.maxDamage > 0 and v2.maxDamage > 0 and
|
|
||||||
v1.damage ~= v2.damage)) then
|
|
||||||
if not newRecipe.crafingTools then
|
|
||||||
newRecipe.craftingTools = { }
|
|
||||||
end
|
|
||||||
local tool = Util.shallowCopy(v2)
|
|
||||||
if tool.maxDamage > 0 then
|
|
||||||
tool.damage = '*'
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Turtles can only craft one item at a time using a tool :(
|
|
||||||
]]--
|
|
||||||
maxCount = 1
|
|
||||||
|
|
||||||
newRecipe.craftingTools[itemDB:makeKey(tool)] = true
|
|
||||||
v1.craftingTool = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local recipe
|
|
||||||
for _,v in pairs(results) do
|
|
||||||
if not v.craftingTool then
|
|
||||||
recipe = v
|
|
||||||
if maxCount then
|
|
||||||
recipe.maxCount = maxCount
|
|
||||||
end
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not recipe then
|
|
||||||
return false, 'Unknown error'
|
|
||||||
end
|
|
||||||
|
|
||||||
newRecipe.count = recipe.count
|
|
||||||
|
|
||||||
local key = itemDB:makeKey(recipe)
|
|
||||||
if recipe.maxCount ~= 64 then
|
|
||||||
newRecipe.maxCount = recipe.maxCount
|
|
||||||
end
|
|
||||||
for k,ingredient in pairs(Util.shallowCopy(ingredients)) do
|
|
||||||
if ingredient.maxDamage > 0 then
|
|
||||||
-- ingredient.damage = '*' -- I don't think this is right
|
|
||||||
end
|
|
||||||
ingredients[k] = itemDB:makeKey(ingredient)
|
|
||||||
end
|
|
||||||
|
|
||||||
Milo:updateRecipe(key, newRecipe)
|
|
||||||
turtle.emptyInventory()
|
|
||||||
|
|
||||||
return recipe
|
|
||||||
end
|
|
||||||
|
|
||||||
local pages = {
|
local pages = {
|
||||||
turtleCraft = UI.Window {
|
turtleCraft = UI.Window {
|
||||||
index = 2,
|
index = 2,
|
||||||
@@ -110,11 +18,13 @@ local pages = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function pages.turtleCraft:validate()
|
function pages.turtleCraft:validate()
|
||||||
local recipe, msg = learnRecipe()
|
local recipe, msg = Milo:learnRecipe()
|
||||||
|
|
||||||
if recipe then
|
if recipe then
|
||||||
local displayName = itemDB:getName(recipe)
|
local displayName = itemDB:getName(recipe)
|
||||||
|
|
||||||
|
turtle.emptyInventory()
|
||||||
|
|
||||||
UI:setPage('listing', {
|
UI:setPage('listing', {
|
||||||
filter = displayName,
|
filter = displayName,
|
||||||
message = 'Learned: ' .. displayName,
|
message = 'Learned: ' .. displayName,
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
local Event = require('event')
|
local Event = require('event')
|
||||||
local Logger = require('logger')
|
|
||||||
local Socket = require('socket')
|
local Socket = require('socket')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local multishell = _ENV.multishell
|
local multishell = _ENV.multishell
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
|
|
||||||
Logger.setScreenLogging()
|
|
||||||
|
|
||||||
local remoteId
|
local remoteId
|
||||||
local args = { ... }
|
local args = { ... }
|
||||||
if #args == 1 then
|
if #args == 1 then
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
local Event = require('event')
|
local Event = require('event')
|
||||||
local Logger = require('logger')
|
|
||||||
local Socket = require('socket')
|
local Socket = require('socket')
|
||||||
|
|
||||||
local colors = _G.colors
|
local colors = _G.colors
|
||||||
local term = _G.term
|
local term = _G.term
|
||||||
|
|
||||||
Logger.setScreenLogging()
|
|
||||||
|
|
||||||
local mon = term.current()
|
local mon = term.current()
|
||||||
local args = { ... }
|
local args = { ... }
|
||||||
if args[1] then
|
if args[1] then
|
||||||
|
|||||||
Reference in New Issue
Block a user