local net = require('libs/net') local utils = require('libs/utils') local CountersSelector = require('libs/ui/CountersSelector') local INFERIUM_SERVER = 'inferium.com' local function centerString(str, width) width = width or term.getSize() local padding = (width / 2) - (#str / 2) return string.rep(' ', padding) .. str end local function formatSeedName(essenceName) if not essenceName then return false end return 'mysticalagriculture:' .. essenceName .. '_seeds' end local function parseSeedName(seedName) local result, nbReplaced = string.gsub(seedName, 'mysticalagriculture:', '') if nbReplaced == 0 then return nil end local finalResult, nbFinalReplaced = string.gsub(result, '_seeds', '') if nbFinalReplaced == 0 then return nil end return finalResult end local function getCountersSelectorConfig(counterMax) local titleFn = function(countersMap, _, win) local total = 0; for _, counterPayload in pairs(countersMap) do if counterPayload and counterPayload.count then total = total + counterPayload.count end end local width = win.getSize() return centerString("" .. total .. '/' .. counterMax .. ' used farmlands' .. "", width) end local config = { counterMax = counterMax, titleFn = titleFn } return config end local function fetchAllHarvesters(serverName) local harvesters, listErrMessage = net.sendQuery(serverName, { type = 'list-harvesters' }) if listErrMessage then error('getAllHarvesters cannot list: ' .. listErrMessage, 0) end if utils.sizeof(harvesters) == 0 then error('getAllHarvesters get no harvesters from the remote server', 0) end for k, harvester in pairs(harvesters) do local response, errMessage = net.sendQuery(serverName, { type = 'get-config', payload = { id = harvester.id } }) if errMessage then error('getAllHarvesters cannot get-config: ' .. errMessage, 0) end local payload = response and response.payload if not payload then error('getAllHarvesters no payload returned for harvester ' .. harvester.id, 0) end if not payload.plan then error('getAllHarvesters no plan returned for the harvester ' .. harvester.id, 0) end harvesters[k].config = payload end return harvesters end local function getMaxCounter(harvesters) local maxCounter = 0 for _, harvester in pairs(harvesters) do maxCounter = maxCounter + utils.sizeof(harvester.config.plan) end return maxCounter end local function getCountersMapFromIndexed(countersMapIndexed) local countersMap = {} local i = 1 for name, count in pairs(countersMapIndexed) do countersMap[i] = { name = name, count = count } i = i + 1 end return countersMap end local function createCountersMap(harvesters) local countersMapIndexed = {} for _, harvester in pairs(harvesters) do for _, seedName in pairs(harvester.config.plan) do local name = parseSeedName(seedName) if name then local currentCounter = countersMapIndexed[name] or 0 countersMapIndexed[name] = currentCounter + 1 end end end return getCountersMapFromIndexed(countersMapIndexed) end local function pickSeedNameFromCountersMap(countersMap) local newCountersMap = {} local pickedCounterName = nil for k, counterPayload in pairs(countersMap) do local count = counterPayload.count local name = counterPayload.name if not pickedCounterName and count > 0 then pickedCounterName = name count = count - 1 end local newCounterPayload = { count = count, name = name } newCountersMap[k] = newCounterPayload end return formatSeedName(pickedCounterName), newCountersMap end local function preparePayloads(countersMap, maxCounter, harvesters) local payloads = {} local globalCounter = 0 local configIndex = 1 for _, harvester in pairs(harvesters) do local newConfig = utils.merge(harvester.config, { plan = {}, }) payloads[configIndex] = { id = harvester.id, config = newConfig } for k, _ in pairs(harvester.config.plan) do local seedName, newCountersMaps = pickSeedNameFromCountersMap(countersMap) countersMap = newCountersMaps newConfig.plan[k] = seedName globalCounter = globalCounter + 1 if globalCounter > maxCounter then error('preparePayload fatal error: globalCounter is greater than maxCounter') end end configIndex = configIndex + 1 end return payloads end local function saveAllConfigs(payloads) for _, payload in pairs(payloads) do local _, errMessage = net.sendQuery(INFERIUM_SERVER, { type = 'set-config', payload = payload }) if errMessage then return false, errMessage end end return true end local function main(serverName) net.openRednet() print('> fetching all configs from ' .. serverName) local harvesters = fetchAllHarvesters(serverName) print('> ' .. utils.sizeof(harvesters) .. ' harvesters fetched') local maxCounter = getMaxCounter(harvesters) local countersMap = createCountersMap(harvesters) local countersMapResult = CountersSelector(countersMap, getCountersSelectorConfig(maxCounter)) local payloads = preparePayloads(countersMapResult, maxCounter, harvesters) if utils.sizeof(payloads) == 0 then error('fatal error: there is no payloads to save', 0) end print('> saving...') local saveOk, saveErrMessage = saveAllConfigs(payloads) if saveOk then print('> done.') else error('Cannot save configs because: ' .. tostring(saveErrMessage), 0) end net.closeRednet() end main(INFERIUM_SERVER)