SHOW:
|
|
- or go back to the newest paste.
1 | - | --[[ |
1 | + | |
2 | - | Author: NeverCast |
2 | + | |
3 | - | Last Edited: 22/07/13 |
3 | + | os.run( {}, "rom/programs/lua" ) |
4 | - | Published: 2/11/12 |
4 | + | |
5 | - | You're welcome to use this code however you like, but please leave my credit at the top. Thanks |
5 | + | |
6 | - | --]] |
6 | + | |
7 | -- Feel free to set this to false if you don't want the text printed | |
8 | - | --[[ |
8 | + | |
9 | - | Changes: |
9 | + | |
10 | ||
11 | - | 1.Replacing the for-loop with a while-loop to not limit the iterations required in finding the parent shell |
11 | + | |
12 | - | 2.Removing Rednet and reloading it to fix the already running issue. |
12 | + | |
13 | - | 3.Now clears the myEnv global variable once injection is complete. |
13 | + | |
14 | end | |
15 | - | Thanks KaoS and TheOriginalBit for code fixes and bug reports. |
15 | + | |
16 | - | --]] |
16 | + | |
17 | return | |
18 | - | -- Prior code writing hypothosis: |
18 | + | |
19 | - | -- How to become top level, |
19 | + | |
20 | local prevState = {} | |
21 | - | -- Climb stack, Find single shell instance |
21 | + | |
22 | - | -- Kill shell instance, override pullEvent |
22 | + | |
23 | - | -- Override os.shutdown |
23 | + | |
24 | - | -- Exit code |
24 | + | |
25 | - | -- Wait for Bios to quit and hook that to fire up your own functions |
25 | + | |
26 | end | |
27 | - | -- Add the functions here that you want to run once the environment has been overridden |
27 | + | |
28 | - | -- In this bios this was shell and rednet.run, I've removed rednet.run as an example |
28 | + | |
29 | - | -- Any functions here will be top level and recieve all the events! |
29 | + | |
30 | local function getParentShell() | |
31 | local at=0 | |
32 | - | os.run( {}, "rom/programs/shell" ) |
32 | + | |
33 | at=at+1 | |
34 | local ok,env = pcall(function() return getfenv(at) end) | |
35 | if not ok then break end | |
36 | if table.size(env) == 1 then | |
37 | local i,v = next(env) -- Grab first | |
38 | if i == "shell" then | |
39 | return v | |
40 | end | |
41 | end | |
42 | end | |
43 | return nil | |
44 | end | |
45 | ||
46 | local function recover() | |
47 | -- Set flag | |
48 | os.myEnv = true | |
49 | -- Put back the trampled environment | |
50 | os.startTimer = prevState.startTimer | |
51 | os.shutdown = prevState.shutdown | |
52 | os.pullEvent = prevState.pullEvent | |
53 | -- Launch shell like nothing happened | |
54 | ||
55 | prevState = nil | |
56 | ||
57 | term.setCursorPos(1,1) | |
58 | term.clear() | |
59 | ||
60 | if showMessages then | |
61 | -- Feel free to remove this line, It's just a proof thing | |
62 | print"Look at me, I load before shell does" | |
63 | end | |
64 | ||
65 | -- Because we killed rednet, we have to remove it and then reload it | |
66 | _G['rednet'] = nil | |
67 | os.loadAPI('/rom/apis/rednet') | |
68 | ||
69 | local ok, err = pcall( function() | |
70 | parallel.waitForAny( | |
71 | unpack(loadPool) | |
72 | ) | |
73 | end ) | |
74 | end | |
75 | ||
76 | os.stage = {} | |
77 | ||
78 | -- Stages: | |
79 | -- injected: Overriding os functions | |
80 | -- shutdown: Shutdown program has been called | |
81 | -- jstincse: Shell is doing it's just-in-case | |
82 | -- bioswait: Bios is waiting for a key press | |
83 | -- biosexit: Bios has quit | |
84 | -- complete: fully injected | |
85 | ||
86 | ||
87 | local function setStage(stage) | |
88 | os.stage.currentStage = stage | |
89 | end | |
90 | ||
91 | local function getStage() | |
92 | return os.stage.currentStage | |
93 | end | |
94 | ||
95 | local function _os_pullEvent(_filter) | |
96 | _filter = _filter or "" | |
97 | if _filter == "key" then | |
98 | setStage("bioswait") | |
99 | return "key", 0 | |
100 | elseif _filter == "timer" then | |
101 | setStage("shutdown") | |
102 | return "timer", 0 | |
103 | end | |
104 | end | |
105 | ||
106 | local function _replSleep(dur) | |
107 | local timer = prevState.startTimer( dur ) | |
108 | repeat | |
109 | local sEvent, param = prevState.pullEvent( "timer" ) | |
110 | until param == timer | |
111 | end | |
112 | ||
113 | local function _os_shutdown() | |
114 | if getStage() == "shutdown" then | |
115 | setStage("jstincse") | |
116 | elseif getStage() == "bioswait" then | |
117 | setStage("biosexit") | |
118 | end | |
119 | if getStage() == "biosexit" then | |
120 | recover() | |
121 | end | |
122 | end | |
123 | ||
124 | local function _os_startTimer(seconds) | |
125 | return 0 | |
126 | end | |
127 | ||
128 | local function inject() | |
129 | prevState.startTimer = os.startTimer | |
130 | prevState.shutdown = os.shutdown | |
131 | prevState.pullEvent = os.pullEvent | |
132 | os.shutdown = _os_shutdown | |
133 | os.pullEvent = _os_pullEvent | |
134 | os.startTimer = _os_startTimer | |
135 | setStage("injected") | |
136 | local shellImpl = getParentShell() | |
137 | shellImpl.exit() | |
138 | end | |
139 | ||
140 | -- Start everything | |
141 | inject() |