I see that you are trying to write to the "apis" folder. That's part of ROM, so it can't be modified with script. If you want to have an updateable API, you need to have it either go into root, or a designated directory that you create. And yes, you can do that, just lead the full path when loading the API. (such as: os.loadAPI("testDir/config"), and it will still retain the proper function call.)
I did fix your program, and it will run. The problem was that you were trying to write to the ROM….
Spoiler
local function printUsage()
print( "Usage:" )
print( shell.getRunningProgram().." <interval> (config)" )
print("Parameters:")
print("<> = required")
print("() = optional")
end
local x,y = term.getSize()
local function cPrint( txt )
local function printC( text )
x2,y2 = term.getCursorPos()
term.setCursorPos(math.ceil((x / 2) - (text:len() / 2)), y2)
write(text.. "\n")
end
if type(txt) == "string" then
printC( txt )
elseif type(txt) == "table" then
for i=1,#txt do
printC( txt[i] )
end
end
end
local function autoUpdate()
local programName = shell.getRunningProgram()
term.clear()
term.setCursorPos(1,6)
cPrint("+--------------------+")
cPrint("| Loading... |")
cPrint("| |||||| |")
cPrint("+--------------------+")
while true do
local downloadedFile = http.request("http://pastebin.com/raw.php?i=XR9C8z75")
local event, url, body = os.pullEvent()
if event == "http_success" then
_tBody = body.readAll()
break
elseif event == "http_failed" then
break
end
end
term.clear()
term.setCursorPos(1,6)
cPrint("+--------------------+")
cPrint("| Loading... |")
cPrint("| |||||||||||| |")
cPrint("+--------------------+")
file = fs.open(programName, "r")
_fBody = file.readAll()
file.close()
sleep(0.5)
term.clear()
term.setCursorPos(1,6)
cPrint("+--------------------+")
cPrint("| Loading... |")
cPrint("| |||||||||||||||||| |")
cPrint("+--------------------+")
sleep(0.5)
local selection = 1
--[[if _fBody ~= _tBody then
cPrint("+--------------------+")
cPrint("| Updating... |")
cPrint("+--------------------+")
sleep(2)
fs.delete(programName)
file = fs.open(programName, "w")
file.write(_tBody)
file.close()
shell.run(programName, sInterval)
error()
end]]
end
autoUpdate()
if not fs.exists("config") then --NON WORKING CODDE NEEDS A FIXXXXXXXX
local sCode = "fkcMT9CE"
local sFile = "config"
local sPath = shell.resolve(sFile)
local response = http.get(
"http://pastebin.com/raw.php?i="..textutils.urlEncode( sCode )
)
if response then
local sResponse = response.readAll()
response.close()
local file = fs.open( sPath, "w" )
file.write( sResponse )
file.close()
end
end
if not fs.exists("config") then
shell.run("pastebin","get","fkcMT9CE","config")
os.reboot()
end
os.loadAPI("config")
local function editConfig()
term.clear()
term.setCursorPos(1,1)
fs.delete("configs")
cPrint("Interactive Configuration Editor (I.C.E.)")
config.load("configs","Timer.cfg")
term.setCursorPos(1,3)
print("Please set a computer id to receive all the rednet messages")
local sMid = read("*")
config.writeVal("mId",sMid)
print("Please type out the sides you'd like to output redstone on (one at a time and leave blank for nil)")
for i=1,rs.getSides() do
redstoneSide[i] = read()
if redstoneSide[i] ~= nil then
if checkValidSide(input) then
table.insert(redstoneSides,i,redstoneSide[i])
config.writeVal("redstoneSide"..tostring(i),redstoneSide[i])
elseif not checkValidSide(input) then
print("Not a valid side!")
i=i-1
end
elseif redstoneSide[i] == nil then
config.writeVal("numOfActiveSides",tostring((i-1)))
break
end
end
config.save()
print("Success, please restart your timer")
sleep(2)
end
local function checkValidSide(input)
local availableRedstoneSides = rs.getSides()
for i2=1,#availableRedstoneSides do
if input == availableRedstoneSides[i] then
return true
end
end
return false
end
local function readConfig()
redstoneSides = {}
config.load("configs","Timer.cfg")
mId = tonumber(config.readVal(mId))
sInterval = tonumber(config.readVal(sInterval))
if tonumber(config.readVal(numOfActiveSides)) == nil then
local activeSides = 6
else
local activeSides = tonumber(config.readVal(numOfActiveSides))
end
for i=1,activeSides do
redstoneSide[i] = tostring(config.readVal(redstoneSide[i]))
end
config.save()
end
local function redstoneOut(boolean)
for i=1,#redstoneSides do
redstone.setOutput(redstoneSides[i],boolean)
end
end
local function pWrapper()
local bOpen, sFreeSide = false, nil
for n,sSide in pairs(rs.getSides()) do
if peripheral.getType( sSide ) == "modem" then
sFreeSide = sSide
if rednet.isOpen( sSide ) then
bOpen = true
break
end
end
end
if not bOpen then
if sFreeSide then
term.clear()
term.setCursorPos(1,1)
cPrint("+------------------------------------+")
cPrint("| Opening Modem on "..sFreeSide.." |")
cPrint("+------------------------------------+")
rednet.open( sFreeSide )
sOpenedSide = sFreeSide
sleep(2)
return true
else
print( "No modem attached. Please try again." )
sleep(2)
os.reboot()
end
end
return true
end
if sConfig == "config" then editConfig()
end
local tArgs = { ... }
local sOpenedSide = nil
local sInterval = tonumber(tArgs[1])
local sConfig = tArgs[2]
config.load("configs","Timer.cfg")
if #tArgs < 1 and config.readVal("sInterval") == nil then
config.save()
printUsage()
return false
end
config.save()
if mId == nil then
mId = 0
end
if tArgs[1] ~= nil then
config.load("configs","Timer.cfg")
config.writeVal("sInterval",tArgs[1])
config.save()
end
if not rednet.broadcast("PING") then pWrapper() end
readConfig()
term.clear()
term.setCursorPos(1,1)
cPrint("+--------------------+")
cPrint("| Triggers Done: 0 |")
cPrint("+--------------------+")
local spaceTimerLength, spaceTimer, pulseTimer, pulseCount = 0.8, nil, nil, 0
local updateInterval, updateTarget = 100, mId
rednet.send(updateTarget,"timer_check_in_"..os.computerID())
os.unloadAPI("config")
while true do
e, p1, p2 = os.pullEvent()
if e == "timer" then
if p1 == spaceTimer then
redstone.setOutput("back", true)
pulseTimer = os.startTimer(0.1)
elseif p1 == pulseTimer then
redstone.setOutput("back", false)
spaceTimer = os.startTimer(spaceTimerLength)
pulseCount = pulseCount + 1
term.setCursorPos(1,2)
term.clearLine()
cPrint("| Triggers Done: "..pulseCount.." |")
if pulseCount % updateInterval == 0 then
rednet.send(updateTarget, tostring(pulseCount / updateInterval))
end
end
elseif e == "rednet_message" then
if p1 == updateTarget and p2 == "reset_"..os.computerID() then
pulseCount = 0
term.setCursorPos(1,2)
term.clearLine()
cPrint("| Triggers Done: "..pulseCount.." |")
elseif p1 == updateTarget and p2 == "stop_"..os.computerID() then
spaceTimer = nil
pulseTimer = nil
redstone.setOutput("back", false)
elseif p1 == updateTarget and p2 == "start_"..os.computerID() then
spaceTimer = os.startTimer(0)
end
end
end