local net = require('libs/net') local utils = require('libs/utils') local inferium = require('libs/inferium') local inferiumConfig = require('config/inferium') local DEFAULT_HARVESTER_NAME = 'harvester' local VERSION = "2.1.0" local PERSISTED_CONFIGS = '/data/inferium-configs' local UPGRADE_SCRIPT = '/upgrade.lua' local defaultConfig = inferiumConfig.defaultConfig or error('no default config provided in config', 0) local defaultAvailableSeeds = { inferium.formatSeedName('inferium'), inferium.formatSeedName('coal') } -- Persistance utils local savePersistedConfigs = function(configs) local file = fs.open(PERSISTED_CONFIGS, 'w') if not file then error('savePersistedConfigs: cannot open ' .. PERSISTED_CONFIGS .. ' file!') end file.write(textutils.serialize(configs)) file.close() end local readPersistedConfigs = function() local file = fs.open(PERSISTED_CONFIGS, 'r') if not file then local initialConfig = {} savePersistedConfigs(initialConfig) return initialConfig end local serializedConfigs = file.readAll() file.close() return textutils.unserialize(serializedConfigs) end -- State local LOCAL_CONFIGS = readPersistedConfigs() local function getConfigForComputer(computerId) return LOCAL_CONFIGS[tostring(computerId)] end local function saveConfigForComputer(computerId, config) LOCAL_CONFIGS[tostring(computerId)] = config savePersistedConfigs(LOCAL_CONFIGS) end -- Utils local function getConfigWithLength(config) if not config then return config end local configWithLength = utils.shallowClone(config) configWithLength.length = utils.sizeof(config.plan) return configWithLength end local function isValidConfig(config) if not config or type(config.plan) ~= 'table' then return false end if config.firstCropZ == nil or config.firstCropZ < 1 then return false end if config.fertilizedBoost == nil then return false end return true end -- Routes local function getConfig(message) local id = message and message.payload and message.payload.id if not id then return { type = "get-config/error", payload = nil, errorMessage = "no id provided in message payload" } end local config = getConfigForComputer(id) if not config then return { type = "get-config/error", payload = nil, errorMessage = "cannot retrieve configuration for given id" } end return { type = "get-config/response", payload = getConfigWithLength(config) } end local function registerAndGetConfig(_, computerId) if not computerId == nil then print('get-config error: no computerId found') return nil end local config = getConfigForComputer(computerId) if not config then print('new harvester detected: ' .. tostring(computerId)) saveConfigForComputer(computerId, defaultConfig) config = defaultConfig end return { type = "register-and-get-config/response", payload = getConfigWithLength(config) } end local function setConfig(message) local payload = message and message.payload local harvesterId = payload and payload.id local config = payload and payload.config if not isValidConfig(config) or not harvesterId then return false end saveConfigForComputer(harvesterId, config) return true end local function deleteConfig(message) local payload = message and message.payload local harvesterId = payload and payload.id if not harvesterId then return false end if LOCAL_CONFIGS[tostring(harvesterId)] then saveConfigForComputer(harvesterId, nil) return true end return false end -- return a table of harvesters { id: string, name: string }[] local function listHarvesters() local result = {} for k, v in pairs(LOCAL_CONFIGS) do local harvester = { id = k, name = v.name or DEFAULT_HARVESTER_NAME } table.insert(result, harvester) end return result end local function listAvailableSeeds() local inv = peripheral.find('inventory') if not inv then print('warning: no inventory found for the inferium server') return defaultAvailableSeeds end local seeds = {} for _, item in pairs(inv.list()) do if inferium.isMysticalSeed(item.name) then table.insert(seeds, item.name) end end return seeds end local function exitServer(_, _, stopServer) stopServer(); return true end local function upgradeServer() shell.execute(UPGRADE_SCRIPT) return true end local ROUTES = { ['register-and-get-config'] = registerAndGetConfig, ['get-config'] = getConfig, ['set-config'] = setConfig, ['delete-config'] = deleteConfig, ['list-harvesters'] = listHarvesters, ['list-seeds'] = listAvailableSeeds, ['exit-server'] = exitServer, ['upgrade-server'] = upgradeServer, } net.openRednet() print('> inferium server v' .. VERSION .. ' started') net.listenQuery(inferium.SERVER, function(message, computerId, stopServer) if type(message) ~= 'table' then print('error: malformed message received', textutils.serialize(message)) return {} end local router = ROUTES[message.type] if not router then print('warning: unknown type of message received', message.type) return {} end return router(message, computerId, stopServer) end) print('> server stopped') net.closeRednet() print('> rednet closed')