Configuration update

Centralize all of the configuration settings and defaults into one file
Move the available components into the configuration
Move the verbose debugging into the configuration

Also start work on a modem component

Also fix configuration not saving on computer shutdown
This commit is contained in:
gamax92 2015-06-25 20:45:08 -06:00
parent 95405445d9
commit dd2daa2554
8 changed files with 219 additions and 64 deletions

View File

@ -17,9 +17,11 @@ local doclist = {}
component = {}
function component.connect(...)
function component.connect(info, ...)
local address
local info = table.pack(...)
if type(info) ~= "table" then
info = table.pack(info, ...)
end
checkArg(2,info[2],"string","number")
if type(info[2]) == "string" then
address = info[2]
@ -109,10 +111,10 @@ function component.cecinvoke(address, method, ...)
end
-- Load components
local components = conf.components
local components = settings.components
for k,v in pairs(components) do
v[2] = v[2] or k
component.connect(table.unpack(v))
component.connect(v)
end
env.component = {list = component.list}

View File

@ -35,12 +35,12 @@ end
function env.computer.freeMemory()
--STUB
cprint("computer.freeMemory")
return 10000
return machine.totalMemory
end
function env.computer.totalMemory()
--STUB
cprint("computer.totalMemory")
return 10000
return machine.totalMemory
end
function env.computer.pushSignal(name, ...)
cprint("computer.pushSignal", name, ...)
@ -73,6 +73,7 @@ function env.computer.energy()
return math.huge
end
function env.computer.maxEnergy()
-- TODO: What is this ...
cprint("computer.maxEnergy")
return config.get("power.buffer.computer",500)
return 1500
end

View File

@ -4,9 +4,9 @@ env.system = {}
function env.system.allowBytecode()
cprint("system.allowBytecode")
return config.get("computer.lua.allowBytecode",false)
return settings.allowBytecode
end
function env.system.timeout()
cprint("system.timeout")
return config.get("computer.timeout",5)
return settings.timeout
end

View File

@ -38,18 +38,18 @@ end
function obj.isTcpEnabled() -- Returns whether TCP connections can be made (config setting).
cprint("internet.isTcpEnabled")
return config.get("internet.enableTcp",true)
return settings.tcpEnabled
end
function obj.isHttpEnabled() -- Returns whether HTTP requests can be made (config setting).
cprint("internet.isHttpEnabled")
return config.get("internet.enableHttp",true)
return settings.httpEnabled
end
function obj.connect(address, port) -- Opens a new TCP connection. Returns the handle of the connection.
cprint("internet.connect",address, port)
if port == nil then port = -1 end
compCheckArg(1,address,"string")
compCheckArg(2,port,"number")
if not config.get("internet.enableTcp",true) then
if not settings.tcpEnabled then
return nil, "tcp connections are unavailable"
end
-- TODO Check for too many connections
@ -120,7 +120,7 @@ end
function obj.request(url, postData) -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.
cprint("internet.request",url, postData)
compCheckArg(1,url,"string")
if not config.get("internet.enableHttp",true) then
if not settings.httpEnabled then
return nil, "http requests are unavailable"
end
-- TODO: Check for too many connections

107
src/component/modem.lua Normal file
View File

@ -0,0 +1,107 @@
local address, _, wireless = ...
compCheckArg(1,wireless,"boolean")
local wakeMessage
local strength
if wireless then
strength = settings.maxWirelessRange
end
local function checkPort(port)
if port < 1 and port >= 65536 then
error("invalid port number",4)
end
return math.floor(port)
end
-- modem component
local obj = {}
function obj.send(address, port, ...) -- Sends the specified data to the specified target.
--STUB
cprint("modem.send",address, port, ...)
compCheckArg(1,address,"string")
compCheckArg(2,port,"number")
port=checkPort(port)
return true
end
function obj.getWakeMessage() -- Get the current wake-up message.
--STUB
cprint("modem.getWakeMessage")
return wakeMessage
end
function obj.setWakeMessage(message) -- Set the wake-up message.
--STUB
cprint("modem.setWakeMessage",message)
compCheckArg(1,message,"string","nil")
wakeMessage = message
end
function obj.close(port) -- Closes the specified port (default: all ports). Returns true if ports were closed.
--STUB
cprint("modem.close",port)
compCheckArg(1,port,"number","nil")
if port ~= nil then
port=checkPort(port)
end
return false
end
function obj.maxPacketSize() -- Gets the maximum packet size (config setting).
cprint("modem.maxPacketSize")
return settings.maxNetworkPacketSize
end
if wireless then
function obj.getStrength() -- Get the signal strength (range) used when sending messages.
--STUB
cprint("modem.getStrength")
return strength
end
function obj.setStrength(newstrength) -- Set the signal strength (range) used when sending messages.
--STUB
cprint("modem.setStrength",newstrength)
compCheckArg(1,newstrength,"number")
strength = newstrength
end
end
function obj.isOpen(port) -- Whether the specified port is open.
--STUB
cprint("modem.isOpen",port)
compCheckArg(1,port,"number")
return false
end
function obj.open(port) -- Opens the specified port. Returns true if the port was opened.
--STUB
cprint("modem.open",port)
compCheckArg(1,port,"number")
port=checkPort(port)
return false
end
function obj.isWireless() -- Whether this is a wireless network card.
--STUB
cprint("modem.isWireless")
return wireless
end
function obj.broadcast(port, ...) -- Broadcasts the specified data on the specified port.
--STUB
cprint("modem.broadcast",port, ...)
compCheckArg(1,port,"number")
port=checkPort(port)
return true
end
local cec = {}
local doc = {
["send"]="function(address:string, port:number, data...) -- Sends the specified data to the specified target.",
["getWakeMessage"]="function():string -- Get the current wake-up message.",
["setWakeMessage"]="function(message:string):string -- Set the wake-up message.",
["close"]="function([port:number]):boolean -- Closes the specified port (default: all ports). Returns true if ports were closed.",
["maxPacketSize"]="function():number -- Gets the maximum packet size (config setting).",
["getStrength"]="function():number -- Get the signal strength (range) used when sending messages.",
["setStrength"]="function(strength:number):number -- Set the signal strength (range) used when sending messages.",
["isOpen"]="function(port:number):boolean -- Whether the specified port is open.",
["open"]="function(port:number):boolean -- Opens the specified port. Returns true if the port was opened.",
["isWireless"]="function():boolean -- Whether this is a wireless network card.",
["broadcast"]="function(port:number, data...) -- Broadcasts the specified data on the specified port.",
}
return obj,cec,doc

View File

@ -6,15 +6,21 @@ local comments = {
["computer.lua"]="Settings specific to the Lua architecture.",
["computer.lua.allowBytecode"]="Whether to allow loading precompiled bytecode via Lua's `load` function, or related functions (`loadfile`, `dofile`). Enable this only if you absolutely trust all users on your server and all Lua code you run. This can be a MASSIVE SECURITY RISK, since precompiled code can easily be used for exploits, running arbitrary code on the real server! I cannot stress this enough: only enable this is you know what you're doing.",
["computer.timeout"]="The time in seconds a program may run without yielding before it is forcibly aborted. This is used to avoid stupidly written or malicious programs blocking other computers by locking down the executor threads. Note that changing this won't have any effect on computers that are already running - they'll have to be rebooted for this to take effect.",
["emulator"]="Emulator related settings. Components, accuracy, and debugging.",
["emulator.components"]="Default components available to the computer.",
["emulator.debug"]="Whether to enable the emulator's extremely verbose logging.",
["internet.enableHttp"]="Whether to allow HTTP requests via internet cards. When enabled, the `request` method on internet card components becomes available.",
["internet.enableTcp"]="Whether to allow TCP connections via internet cards. When enabled, the `connect` method on internet card components becomes available.",
["misc"]="Other settings that you might find useful to tweak.",
["misc.maxNetworkPacketSize"]="The maximum size of network packets to allow sending via network cards. This has *nothing to do* with real network traffic, it's just a limit for the network cards, mostly to reduce the chance of computer with a lot of RAM killing those with less by sending huge packets. This does not apply to HTTP traffic.",
["misc.maxWirelessRange"]="The maximum distance a wireless message can be sent. In other words, this is the maximum signal strength a wireless network card supports. This is used to limit the search range in which to check for modems, which may or may not lead to performance issues for ridiculous ranges - like, you know, more than the loaded area. See also: `wirelessCostPerRange`.",
}
local function writeComment(text,file,size)
file:write(string.rep(" ",size) .. "--")
local line = ""
for word in text:gmatch("[%S]+") do
if #line + #word + 1 > 78 then
if #line + #word + 1 > 78-size then
line = ""
file:write("\n" .. string.rep(" ",size) .. "--")
end
@ -40,10 +46,32 @@ function serialize(tbl,key,path,file,size)
if comments[spath] then
writeComment(comments[spath],file,size)
end
if type(v) == "table" then
if spath == "emulator.components" then
file:write(string.rep(" ",size) .. k .. " {\n\n")
for i = 1,#v do
local comp = v[i]
file:write(string.rep(" ",size+2) .. "{")
for i = 1,#comp do
if type(comp[i]) == "string" then
file:write(string.format("%q",comp[i]))
else
file:write(tostring(comp[i]))
end
if i < #comp then
file:write(", ")
end
end
file:write("}")
if i < #v then
file:write(",")
end
file:write("\n")
end
file:write(string.rep(" ",size) .. "}\n")
elseif type(v) == "table" then
local list = true
for k,l in pairs(v) do
if type(l) ~= "number" then
if type(k) ~= "number" or type(l) ~= "number" then
list = false
break
end
@ -81,19 +109,19 @@ function config.load()
rawdata = (rawdata .. "\n"):reverse():match("\n+(.*)"):reverse()
local data = ""
for line in (rawdata .. "\n"):gmatch("(.-)\n") do
if line:sub(-2) == " {" then
line = line:sub(1,-3) .. "={"
if line:match("{%s-$") then
line = line:gsub("{%s-$","={")
end
if line:sub(-1) == "[" then
line = line:sub(1,-2) .. "{"
if line:match("%[%s-$") then
line = line:gsub("%[%s-$","{")
end
if line:sub(-1) == "]" then
line = line:sub(1,-2) .. "}"
if line:match("%]%s-$") then
line = line:gsub("%]%s-$","}")
end
if line ~= "" and line:sub(-1) ~= "{" and line:sub(-1) ~= "[" and line:sub(-1) ~= "," then
if line:gsub("%s","") ~= "" and not line:match("{%s-$") and not line:match(",%s-$") then
line = line .. ","
end
if line == "ocemu={" then
if line:match("ocemu%s-=%s-{") then
line = "return {"
end
data = data .. line .. "\n"

View File

@ -7,45 +7,6 @@ function math.trunc(n)
return n < 0 and math.ceil(n) or math.floor(n)
end
-- load configuration
elsa.filesystem.load("config.lua")()
config.load()
elsa.cleanup = {}
function elsa.quit()
config.save()
for k,v in pairs(elsa.cleanup) do
v()
end
end
conf = {
-- Format: string:type, (string or number or nil):address, (number or nil):slot, component parameters
-- Read component files for parameter documentation
components = {
{"gpu",nil,0,160,50,3},
{"eeprom",nil,9,"lua/bios.lua"},
{"filesystem",nil,7,"loot/OpenOS",true},
{"filesystem",nil,nil,"tmpfs",false},
{"filesystem",nil,5,nil,false},
{"internet"},
{"computer"},
{"ocemu"},
}
}
if elsa.SDL then
table.insert(conf.components, {"screen_sdl2",nil,nil,80,25,3})
table.insert(conf.components, {"keyboard_sdl2"})
else
-- TODO: Alternatives
end
machine = {
starttime = elsa.timer.getTime(),
deadline = elsa.timer.getTime(),
signals = {},
}
local function check(have, want, ...)
if not want then
return false
@ -70,7 +31,49 @@ function compCheckArg(n, have, ...)
end
end
if true then
-- load configuration
elsa.filesystem.load("config.lua")()
config.load()
elsa.filesystem.load("settings.lua")()
elsa.cleanup = {}
function elsa.quit()
config.save()
for k,v in pairs(elsa.cleanup) do
v()
end
end
if settings.components == nil then
-- Format: string:type, (string or number or nil):address, (number or nil):slot, component parameters
-- Read component files for parameter documentation
settings.components = {
{"gpu",nil,0,160,50,3},
{"eeprom",nil,9,"lua/bios.lua"},
{"filesystem",nil,7,"loot/OpenOS",true},
{"filesystem",nil,nil,"tmpfs",false},
{"filesystem",nil,5,nil,false},
{"internet"},
{"computer"},
{"ocemu"},
}
if elsa.SDL then
table.insert(settings.components, {"screen_sdl2",nil,nil,80,25,3})
table.insert(settings.components, {"keyboard_sdl2"})
else
-- TODO: Alternatives
end
config.set("emulator.components",settings.components)
end
machine = {
starttime = elsa.timer.getTime(),
deadline = elsa.timer.getTime(),
signals = {},
totalMemory = 2*1024*1024,
}
if settings.emulatorDebug then
cprint = print
else
cprint = function() end
@ -292,6 +295,7 @@ function resume_thread(...)
if results[2] then
boot_machine()
else
elsa.quit()
error("Machine power off",0)
end
end

13
src/settings.lua Normal file
View File

@ -0,0 +1,13 @@
settings = {
allowBytecode = config.get("computer.lua.allowBytecode",false),
timeout = config.get("computer.timeout",5),
components = config.get("emulator.components"),
emulatorDebug = config.get("emulator.debug",true),
httpEnabled = config.get("internet.enableHttp",true),
tcpEnabled = config.get("internet.enableTcp",true),
maxNetworkPacketSize = config.get("misc.maxNetworkPacketSize",8192),
maxWirelessRange = config.get("misc.maxWirelessRange",400),
}