This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Justforlawls's profile picture

Auto-shutdown when not in use

Started by Justforlawls, 17 April 2012 - 02:04 AM
Justforlawls #1
Posted 17 April 2012 - 04:04 AM
Hello, I'm fairly new to CC, and I'm currently using it as part of the Tekkit modpack. I understand that my CC 1.3 may be modified for space of comparability reasons within my modpack.

However, I have run into a nearly devastating problem at this point. My roomate (ingame, IRL, he's just a friend) is slightly -scratch that- VERY clumsy, careless and clueless when it comes to some things. We have managed to grow a huge amount of wealth on the server, and are at this point building 'fun stuff' since we're at a standstill due to a rank system blocking some of our goals.

Anyways, we have built an underground high-tech high-speed hidden-by-piston minecart track, which starts at spawn and leads right to our (potentially griefable) back door. There are some other people I have granted access to the house, but I don't want them on my computer which controls the pistons hiding our railroad, some hidden doors in other places, and other important things.

I have programmer a 'false OS' that appears to be a custom OS that displays 4 programs upon the programs command: 'go', 'touch', 'yourself', and 'intruder' (roomate's ideas). When you enter our slightly inappropriate password, it will exit the program (ctrl+T proof, of course) and give access to the real computer. This program runs on startup, so it of course only works when the computer has been shut down. This gets us back to the clueless roomate problem.

My question is, can I set something up that makes the computer shut down when not in use, or even after a few minutes of inactivity?

Thanks,
Justforlawls

TL;DR? No problem! Just read the last paragraph.
cant_delete_account #2
Posted 17 April 2012 - 04:41 AM
Here (it should shutdown after roughly 1 minute of non-usage, add it to startup file):

os.pullEvent = os.pullEventRaw
while true do
sleep(0)
local event, p = os.pullEventRaw()
local timer = os.startTimer(60)
if event == "timer" and p == timer then
  os.shutdown()
end
end
Justforlawls #3
Posted 17 April 2012 - 05:09 AM
Is there any chance that this could interfere with what is already in my startup file? Unfortunately I just quickly typed out a program and don't have a copy of it anywhere, and my computer is hibernating.

Here's some sudocode:

Event=EventRaw
Clear screen
Put LawlsOS 1.1 in the corner
Start loop
If programs is entered, list fake programs
If input isn't programs or <password> return No such program
end loop when input = <password>
slowprint access granted, opening computer, (generic wastes of time)

Would I just add your code to the very end, after my false system?
Wolvan #4
Posted 17 April 2012 - 08:16 AM
yep after the slow print.
@thesbros Can You still access every program? And it shuts down itself even if you typed something?
OminousPenguin #5
Posted 17 April 2012 - 04:02 PM
Modified from Cloudy's code here

local timer
function getInput()
  local input
  while true do
    term.write("> ")
    input = io.read()
    timer = nil
    shell.run(input)
    timer = os.startTimer(10) -- Idle time before shutdown in seconds
  end
end
function checkTimer()
  local event, param
  while true do
    event, param = os.pullEvent()
    if event == "timer" and param == timer then
      os.shutdown()
    end
  end
end
while true do
  parallel.waitForAll(getInput, checkTimer)
end

Just add that to your startup file after the slowprint.
Wolvan #6
Posted 17 April 2012 - 04:30 PM
Your code isn't abel to run Programs with parameters like edit or copy
OminousPenguin #7
Posted 17 April 2012 - 04:33 PM
Ah of course. That would just involve a bit of regexing. If someone wants to add that go ahead.

Or you could just modify /rom/programs/shell to include the timeout

Edit: There we go:
local timer
local tCommandHistory = {}
function getInput()
  local sLine
  while true do
    term.write("> ")
    sLine = read( nil, tCommandHistory )
    timer = nil
    table.insert( tCommandHistory, sLine )
    local tWords = {}
    for match in string.gmatch(sLine, "[^ t]+") do
      table.insert( tWords, match )
    end
    local sCommand = tWords[1]
    if sCommand then
      shell.run( sCommand, unpack( tWords, 2 ) )
    end
    timer = os.startTimer(10) -- Idle time before shutdown in seconds
  end
end
function checkTimer()
  local event, param
  while true do
    event, param = os.pullEvent()
    if event == "timer" and param == timer then
      os.shutdown()
    end
  end
end
while true do
  parallel.waitForAll(getInput, checkTimer)
end
MysticT #8
Posted 17 April 2012 - 06:49 PM
There's an alternative to the above code:

os.pullEvent = function(filter)
  local timer = os.startTimer(60) -- change the time to whatever you want
  local evt, p1, p2, p3, p4, p5 = os.pullEventRaw()
  if evt = "terminate" then
	error("Terminate")
  elseif evt == "timer" and p1 == timer then
	os.shutdown()
  end
  timer = os.startTimer(60) -- change the time again
  return evt, p1, p2, p3, p4, p5
end
Put that on the startup file (after it finishes, so it's still Ctrl+T proof), and it will shutdown the computer if there's no events for the time you set. (Not tested, but it should work)
Cloudy #9
Posted 17 April 2012 - 08:03 PM
I still think overriding the os.pullEvent is ugly. Especially as you don't put it back again after you've altered it. This would be my preferred method:


local timer
timer = os.startTimer(60)
function checkTimer()
  local event, param
  while true do
    event, param = os.pullEvent()
    if event == "timer" then
      if param == timer then
        os.shutdown()
      end
    -- could be a timer left behind from resetting - would still trigger an event! Meaning it would never time out. Hence why nothing is done if its a timer which isn't our timer!
    else
      timer = os.startTimer(60) -- reset the timer on any other event except timer
    end
  end
end
while true do
  parallel.waitForAll(function() shell.run("shell") end, checkTimer)
end
MysticT #10
Posted 17 April 2012 - 09:10 PM
I still think overriding the os.pullEvent is ugly. Especially as you don't put it back again after you've altered it.
So it's better to run a shell inside a shell in parallel with another function than just overriding a function?
And it's not suppose to be put back, since it has to change for every program.
I've never done this before, but I would preffer to do it that way, I think it's more efficient.
Cloudy #11
Posted 17 April 2012 - 10:08 PM
Neither way is more efficient. I just don't like overwriting globals except where necessary.

Either works, it is just personal choice.
Justforlawls #12
Posted 18 April 2012 - 04:04 AM
I still think overriding the os.pullEvent is ugly. Especially as you don't put it back again after you've altered it. This would be my preferred method:

Spoiler

local timer
timer = os.startTimer(60)
function checkTimer()
  local event, param
  while true do
    event, param = os.pullEvent()
    if event == "timer" then
      if param == timer then
        os.shutdown()
      end
    -- could be a timer left behind from resetting - would still trigger an event! Meaning it would never time out. Hence why nothing is done if its a timer which isn't our timer!
    else
      timer = os.startTimer(60) -- reset the timer on any other event except timer
    end
  end
end
while true do
  parallel.waitForAll(function() shell.run("shell") end, checkTimer)
end

I wasn't able to implement this today due to a horrible creeper attack. I'm ready to do it tomorrow, and eager to make my computer more secure. I just wanted to verify that this will still shutdown after running programs. Are there any limitations?
OminousPenguin #13
Posted 18 April 2012 - 04:11 PM
I just wanted to verify that this will still shutdown after running programs. Are there any limitations?

Yes it will, even during the running of programs. And no limitations that I can think of.