200 posts
Location
Scotland
Posted 05 July 2013 - 08:29 AM
Hello, I'm trying to secure one of my programs from the dreaded [ctrl] + T.
It originally used pcall to stop [ctrl] + T on the read function however in the latest versions of computercraft pcall is not working as it used too.
I have tried to use os.pullEvent = os.pullEventRaw however my program is running in parallel so I get a "parallel: 22 Expected string" error.
I could write a coroutine function myself but I have little understanding (even after reading a tutorial) of how they work.
Any help is much appreciated :)/>
Edit: I also tried making a loop that listens for the [ctrl] key and shuts down straight away, but it proved to be very unreliable.
———————————————-
The fix for this was quite simple.
- Declare os.pullEvent = os.pullEventRaw
- Make sure all your event driven loops check the event they are driven by!
- £££ Profit!
1114 posts
Location
UK
Posted 05 July 2013 - 12:40 PM
I did this too, I have a script here:
Spoiler
local function create( first, ... )
if first ~= nil then
return coroutine.create(first), create( ... )
end
return nil
end
local function runUntilLimit( _routines, _limit )
local count = #_routines
local living = count
local tFilters = {}
local eventData = {}
while true do
for n=1,count do
local r = _routines[n]
if r then
if tFilters[r] == nil or tFilters[r] == eventData[1] then
local ok, param = coroutine.resume( r, unpack(eventData) )
if not ok then
error( param )
else
tFilters[r] = param
end
if coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
end
end
for n=1,count do
local r = _routines[n]
if r and coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
eventData = { os.pullEventRaw() }
end
end
function waitForAny( ... )
local routines = { create( ... ) }
return runUntilLimit( routines, #routines - 1 )
end
function waitForAll( ... )
local routines = { create( ... ) }
runUntilLimit( routines, 0 )
end
It is safe against ctrl-t and works the same as the original parallel api
200 posts
Location
Scotland
Posted 05 July 2013 - 01:03 PM
Thank you that looks promising, however something I noticed was by changing the order of the functions passed to the parallel api, [ctrl] + T doesn't have an effect.
I have no idea why.
Edit: Maybe not, on further testing I could not replicate the same outcome
200 posts
Location
Scotland
Posted 05 July 2013 - 01:50 PM
I did this too, I have a script here:
Spoiler
local function create( first, ... )
if first ~= nil then
return coroutine.create(first), create( ... )
end
return nil
end
local function runUntilLimit( _routines, _limit )
local count = #_routines
local living = count
local tFilters = {}
local eventData = {}
while true do
for n=1,count do
local r = _routines[n]
if r then
if tFilters[r] == nil or tFilters[r] == eventData[1] then
local ok, param = coroutine.resume( r, unpack(eventData) )
if not ok then
error( param )
else
tFilters[r] = param
end
if coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
end
end
for n=1,count do
local r = _routines[n]
if r and coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
eventData = { os.pullEventRaw() }
end
end
function waitForAny( ... )
local routines = { create( ... ) }
return runUntilLimit( routines, #routines - 1 )
end
function waitForAll( ... )
local routines = { create( ... ) }
runUntilLimit( routines, 0 )
end
It is safe against ctrl-t and works the same as the original parallel api
Where does this differ from the parallel api?
8543 posts
Posted 05 July 2013 - 11:24 PM
Please post your code.
200 posts
Location
Scotland
Posted 06 July 2013 - 09:06 AM
Please post your code.
https://raw.github.com/darkrising/darkprograms/darkprograms/darksecurity/clientIt's one of my base security programs, I used to use pcall but it seems to be the parallel api that is exiting.
1114 posts
Location
UK
Posted 06 July 2013 - 11:27 AM
I did this too, I have a script here:
Spoiler
local function create( first, ... )
if first ~= nil then
return coroutine.create(first), create( ... )
end
return nil
end
local function runUntilLimit( _routines, _limit )
local count = #_routines
local living = count
local tFilters = {}
local eventData = {}
while true do
for n=1,count do
local r = _routines[n]
if r then
if tFilters[r] == nil or tFilters[r] == eventData[1] then
local ok, param = coroutine.resume( r, unpack(eventData) )
if not ok then
error( param )
else
tFilters[r] = param
end
if coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
end
end
for n=1,count do
local r = _routines[n]
if r and coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
eventData = { os.pullEventRaw() }
end
end
function waitForAny( ... )
local routines = { create( ... ) }
return runUntilLimit( routines, #routines - 1 )
end
function waitForAll( ... )
local routines = { create( ... ) }
runUntilLimit( routines, 0 )
end
It is safe against ctrl-t and works the same as the original parallel api
Where does this differ from the parallel api?
There is a line, I can't remember where, which was different. I think it waited for an event, and then checked to see if it was the correct event before terminating.
7508 posts
Location
Australia
Posted 06 July 2013 - 11:39 AM
There is a line, I can't remember where, which was different. I think it waited for an event, and then checked to see if it was the correct event before terminating.
Nope, looks identical to the parallel API to me! :P/>
1114 posts
Location
UK
Posted 06 July 2013 - 12:32 PM
There is a line, I can't remember where, which was different. I think it waited for an event, and then checked to see if it was the correct event before terminating.
Nope, looks identical to the parallel API to me! :P/>
It works for me though!
200 posts
Location
Scotland
Posted 06 July 2013 - 12:54 PM
-snip-
Doesn't work for me, on further testing it seems that it is only when the username and password loop + disk checking loop are running together the program can be [ctrl] + T however when both options are running by themselves the program seems to be quite secure.
I don't know why it is doing this.
8543 posts
Posted 06 July 2013 - 03:49 PM
Line 54 allows it to terminate. When that function receives a terminate event, line 54 will throw an "expected string" error, since you aren't verifying that you're actually getting a disk event.
1114 posts
Location
UK
Posted 07 July 2013 - 03:53 AM
Line 54 allows it to terminate. When that function receives a terminate event, line 54 will throw an "expected string" error, since you aren't verifying that you're actually getting a disk event.
That is weird, because it has always worked for me.
200 posts
Location
Scotland
Posted 07 July 2013 - 06:30 AM
Line 54 allows it to terminate. When that function receives a terminate event, line 54 will throw an "expected string" error, since you aren't verifying that you're actually getting a disk event.
Thank you very much, the problem is now solved. I didn't realize os.pullEventRaw responds to the terminate event aswell.
A short loop to check the event later and the probem has been solved.
Thank you to all that helped :)/>