From 93d2aa331c3233f0e94c114303520b1fd1461057 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sun, 2 Dec 2018 18:42:49 -0500 Subject: [PATCH] better wireless --- milo/MiloRemote.lua | 114 +++++++++++++++++++++--------------- milo/apis/milo.lua | 2 + milo/plugins/exportTask.lua | 108 ++++++++++++++++++---------------- milo/plugins/importTask.lua | 80 +++++++++++++------------ milo/plugins/remote.lua | 54 ++++++++++++----- 5 files changed, 209 insertions(+), 149 deletions(-) diff --git a/milo/MiloRemote.lua b/milo/MiloRemote.lua index 4df1c51..42dfa04 100644 --- a/milo/MiloRemote.lua +++ b/milo/MiloRemote.lua @@ -177,9 +177,62 @@ function page:setStatus(status) self:sync() end -function page:sendRequest(data, statusMsg) - local response +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 + self.grid:draw() + self:sync() + end + elseif response.type == 'list' then + self.items = self:expandList(response.list) + self:applyFilter() + self.grid:draw() + self.grid:sync() + + 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 + self.grid:draw() + self:sync() + 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 config.server then self:setStatus('Invalid configuration') return @@ -202,30 +255,23 @@ function page:sendRequest(data, statusMsg) local r = socket:read(2) if r and not r.msg then self:setStatus('connected ...') + self:processMessages(socket) else msg = r and r.msg or 'Timed out' socket:close() socket = nil - break end end end if socket then if statusMsg then self:setStatus(statusMsg) + Event.onTimeout(2, function() + self:setStatus('') + end) end if socket:write(data) then - response = socket:read(2) - if response then - if response.msg then - self:setStatus(response.msg) - response = nil - end - Event.onTimeout(2, function() - self:setStatus('') - end) - return - end + return true end socket:close() socket = nil @@ -233,8 +279,6 @@ function page:sendRequest(data, statusMsg) end self:setStatus(msg or 'Failed to connect') end) - - return response end function page.grid:getRowTextColor(row, selected) @@ -282,17 +326,8 @@ function page.grid:eventHandler(event) end function page:transfer(item, count, msg) - Sound.play('ui.button.click', .3) - local response = self:sendRequest({ request = 'transfer', item = item, count = count }, msg) - if response then - item.count = response.current - response.count - self.grid:draw() - if response.craft > 0 then - self:setStatus(response.craft .. ' crafting ...') - elseif response.craft + response.count < response.requested then - self:setStatus((response.craft + response.count) .. ' available ...') - end - end + --Sound.play('ui.button.click', .3) + self:sendRequest({ request = 'transfer', item = item, count = count }, msg) end function page.setup:eventHandler(event) @@ -443,12 +478,7 @@ function page:expandList(list) end function page:refresh(requestType) - local items = self:sendRequest({ request = requestType }, 'refreshing...') - - if items then - self.items = self:expandList(items) - self:applyFilter() - end + self:sendRequest({ request = requestType }, 'refreshing...') end function page:applyFilter() @@ -486,23 +516,13 @@ Event.addRoutine(function() elseif config.server and (config.useShield or config.slot) then local s, m = pcall(function() local method = neural[inv] - local item = method and method().getItemMeta(config.useShield and SHIELD_SLOT or config.slot) + local item = method and method().list()[config.useShield and SHIELD_SLOT or config.slot] if item then - local slotNo = config.useShield and 'shield' or config.slot - local response = page:sendRequest({ + if page:sendRequest({ request = 'deposit', - slot = slotNo, + slot = config.useShield and 'shield' or config.slot, count = item.count, - key = table.concat({ item.name, item.damage, item.nbtHash }, ':') - }) - if response then - Sound.play('entity.item.pickup') - local ritem = page.items[response.key] - if ritem then - ritem.count = response.current + item.count - end - page.grid:draw() - page:sync() + }) then sleepTime = math.max(sleepTime - .25, .25) end else diff --git a/milo/apis/milo.lua b/milo/apis/milo.lua index 6e1ba94..ef2432d 100644 --- a/milo/apis/milo.lua +++ b/milo/apis/milo.lua @@ -188,6 +188,7 @@ function Milo:makeRequest(item, count, callback) count = 0, current = current.count, item = item, + key = item.key or Milo:uniqueKey(item), } end @@ -208,6 +209,7 @@ function Milo:makeRequest(item, count, callback) count = math.min(count, current.count), current = current.count, item = item, + key = item.key or Milo:uniqueKey(item), } if request.count > 0 then diff --git a/milo/plugins/exportTask.lua b/milo/plugins/exportTask.lua index 2e90c5b..c02ddf4 100644 --- a/milo/plugins/exportTask.lua +++ b/milo/plugins/exportTask.lua @@ -12,70 +12,76 @@ end function ExportTask:cycle(context) for node in context.storage:filterActive('machine', filter) do - for _, entry in pairs(node.exports) do + local s, m = pcall(function() + for _, entry in pairs(node.exports) do - if not entry.filter then - -- exports must have a filter - -- TODO: validate in exportView - break - end - - local function exportSingleSlot() - local slot = node.adapter.getItemMeta(entry.slot) - - if slot and slot.count == slot.maxCount then - return + if not entry.filter then + -- exports must have a filter + -- TODO: validate in exportView + break end - if slot then - -- something is in the slot, find what we can export - for key in pairs(entry.filter) do - local filterItem = Milo:splitKey(key) - if (slot.name == filterItem.name and - entry.ignoreDamage or slot.damage == filterItem.damage and - entry.ignoreNbtHash or slot.nbtHash == filterItem.nbtHash) then + local function exportSingleSlot() + local slot = node.adapter.getItemMeta(entry.slot) - local items = Milo:getMatches(filterItem, entry) - local _, item = next(items) - if item then - local count = math.min(item.count, slot.maxCount - slot.count) - context.storage:export(node, entry.slot, count, item) + if slot and slot.count == slot.maxCount then + return + end + + if slot then + -- something is in the slot, find what we can export + for key in pairs(entry.filter) do + local filterItem = Milo:splitKey(key) + if (slot.name == filterItem.name and + entry.ignoreDamage or slot.damage == filterItem.damage and + entry.ignoreNbtHash or slot.nbtHash == filterItem.nbtHash) then + + local items = Milo:getMatches(filterItem, entry) + local _, item = next(items) + if item then + local count = math.min(item.count, slot.maxCount - slot.count) + context.storage:export(node, entry.slot, count, item) + end + break end - break end + return end - return - end - -- slot is empty - export first matching item we have in storage - for key in pairs(entry.filter) do - local items = Milo:getMatches(Milo:splitKey(key), entry) - local _, item = next(items) - if item then - local count = math.min(item.count, itemDB:getMaxCount(item)) - context.storage:export(node, entry.slot, count, item) - break - end - end - end - - local function exportItems() - for key in pairs(entry.filter) do - local items = Milo:getMatches(itemDB:splitKey(key), entry) - for _,item in pairs(items) do - if context.storage:export(node, nil, item.count, item) == 0 then - -- TODO: really shouldn't break here as there may be room in other slots - -- leaving for now for performance reasons + -- slot is empty - export first matching item we have in storage + for key in pairs(entry.filter) do + local items = Milo:getMatches(Milo:splitKey(key), entry) + local _, item = next(items) + if item then + local count = math.min(item.count, itemDB:getMaxCount(item)) + context.storage:export(node, entry.slot, count, item) break end end end + + local function exportItems() + for key in pairs(entry.filter) do + local items = Milo:getMatches(itemDB:splitKey(key), entry) + for _,item in pairs(items) do + if context.storage:export(node, nil, item.count, item) == 0 then + -- TODO: really shouldn't break here as there may be room in other slots + -- leaving for now for performance reasons + break + end + end + end + end + if type(entry.slot) == 'number' then + exportSingleSlot() + else + exportItems() + end end - if type(entry.slot) == 'number' then - exportSingleSlot() - else - exportItems() - end + end) + if not s and m then + _G._debug('Importer error') + _G._debug(m) end end end diff --git a/milo/plugins/importTask.lua b/milo/plugins/importTask.lua index 5664c3c..4cf05ee 100644 --- a/milo/plugins/importTask.lua +++ b/milo/plugins/importTask.lua @@ -11,50 +11,56 @@ end function ImportTask:cycle(context) for node in context.storage:filterActive('machine', filter) do - for _, entry in pairs(node.imports) do + local s, m = pcall(function() + for _, entry in pairs(node.imports) do - local function itemMatchesFilter(item) - if not entry.ignoreDamage and not entry.ignoreNbtHash then - local key = Milo:uniqueKey(item) - return entry.filter[key] + local function itemMatchesFilter(item) + if not entry.ignoreDamage and not entry.ignoreNbtHash then + local key = Milo:uniqueKey(item) + return entry.filter[key] + end + + for key in pairs(entry.filter) do + local v = Milo:splitKey(key) + if item.name == v.name and + (entry.ignoreDamage or item.damage == v.damage) and + (entry.ignoreNbtHash or item.nbtHash == v.nbtHash) then + return true + end + end end - for key in pairs(entry.filter) do - local v = Milo:splitKey(key) - if item.name == v.name and - (entry.ignoreDamage or item.damage == v.damage) and - (entry.ignoreNbtHash or item.nbtHash == v.nbtHash) then + local function matchesFilter(item) + if not entry.filter then return true end + + if entry.blacklist then + return not itemMatchesFilter(item) + end + + return itemMatchesFilter(item) + end + + local function importSlot(slotNo) + local item = node.adapter.getItemMeta(slotNo) + if item and matchesFilter(item) then + context.storage:import(node, slotNo, item.count, item) + end + end + + if type(entry.slot) == 'number' then + importSlot(entry.slot) + else + for i in pairs(node.adapter.list()) do + importSlot(i) + end end end - - local function matchesFilter(item) - if not entry.filter then - return true - end - - if entry.blacklist then - return not itemMatchesFilter(item) - end - - return itemMatchesFilter(item) - end - - local function importSlot(slotNo) - local item = node.adapter.getItemMeta(slotNo) - if item and matchesFilter(item) then - context.storage:import(node, slotNo, item.count, item) - end - end - - if type(entry.slot) == 'number' then - importSlot(entry.slot) - else - for i in pairs(node.adapter.list()) do - importSlot(i) - end - end + end) + if not s and m then + _G._debug('Importer error') + _G._debug(m) end end end diff --git a/milo/plugins/remote.lua b/milo/plugins/remote.lua index ee74d13..a93437b 100644 --- a/milo/plugins/remote.lua +++ b/milo/plugins/remote.lua @@ -75,14 +75,22 @@ local function client(socket) if not data then break end +--_G._debug(data) + socket.co = coroutine.running() if data.request == 'scan' then -- full scan of all inventories local items = Milo:mergeResources(Milo:listItems(true)) - socket:write(compactList(items)) + socket:write({ + type = 'list', + list = compactList(items), + }) elseif data.request == 'list' then local items = Milo:mergeResources(Milo:listItems()) - socket:write(compactList(items)) + socket:write({ + type = 'list', + list = compactList(items), + }) elseif data.request == 'deposit' then local function deposit() @@ -97,19 +105,20 @@ local function client(socket) if node then local slot = node.adapter.getItemMeta(slotNo) if slot then - context.storage:import(node, slotNo, slot.count, slot) + if context.storage:import(node, slotNo, slot.count, slot) then + local item = Milo:getItem(Milo:listItems(), slot) + if item then + socket:write({ + type = 'received', + key = item.key, + count = item.count, + }) + end + end end end end - local list = Milo:listItems() - local current = list[data.key] and list[data.key].count or 0 - - socket:write({ - key = data.key, - current = current, - }) - Milo:queueRequest({ }, deposit) elseif data.request == 'transfer' then @@ -125,17 +134,34 @@ local function client(socket) local function transfer(request) local target = makeNode('inventory') if target then - context.storage:export( + local amount = context.storage:export( target, nil, request.requested, data.item) + local item = Milo:listItems()[request.key] + socket:write({ + type = 'transfer', + key = request.key, + requested = request.requested, + current = item and item.count or 0, + count = amount, + craft = request.craft, + }) end end local request = Milo:makeRequest(data.item, count, transfer) - - socket:write(request) + if (request.craft + request.count == 0) or + (request.craft > 0 and request.count == 0) then + socket:write({ + type = 'transfer', + key = request.key, + requested = request.requested, + count = request.current, + craft = request.craft, + }) + end end until not socket.connected