minecraft-cc-tools/inferium-gui.lua

280 lines
7.0 KiB
Lua

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)
if not seedName then
return nil
end
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 fetchAvailableSeeds(serverName)
local availableSeeds, errMessage = net.sendQuery(serverName, { type = 'list-seeds' })
if errMessage then
error('fetchAvailableSeeds error: ' .. errMessage, 0)
end
if not availableSeeds then
error('no available seeds', 0)
end
return availableSeeds
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 mergeCountersMap(countersMapLeft, countersMapRight)
local indexed = {}
for _, counterPayload in pairs(countersMapLeft) do
indexed[counterPayload.name] = counterPayload.count
end
for _, counterPayload in pairs(countersMapRight) do
indexed[counterPayload.name] = counterPayload.count
end
return getCountersMapFromIndexed(indexed)
end
local function getInitialCountersMap(availableSeeds)
local result = {}
for k, seedName in pairs(availableSeeds) do
result[k] = {
name = parseSeedName(seedName),
count = 0
}
end
return result
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 setConfigResponse, errMessage = net.sendQuery(INFERIUM_SERVER, { type = 'set-config', payload = payload })
if errMessage then
return false, errMessage
end
if not setConfigResponse then
return false, 'unable to save config (check server logs)'
end
end
return true
end
local function main(serverName)
net.openRednet() -- TODO: handle closeRednet properly
print('> fetching available seeds from ' .. serverName)
local availableSeeds = fetchAvailableSeeds(serverName)
print('> ' .. utils.sizeof(availableSeeds) .. ' available seeds fetched')
print('> fetching all configs from ' .. serverName)
local harvesters = fetchAllHarvesters(serverName)
print('> ' .. utils.sizeof(harvesters) .. ' harvesters fetched')
local maxCounter = getMaxCounter(harvesters)
local countersMap = mergeCountersMap(getInitialCountersMap(availableSeeds), createCountersMap(harvesters))
local countersMapResult = CountersSelector(countersMap, getCountersSelectorConfig(maxCounter))
if not countersMapResult then
print('> canceled')
net.closeRednet()
return
end
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)