View difference between Paste ID: QKSH9E3S and GweLdEAQ
SHOW: | | - or go back to the newest paste.
1
2
-- Install lua parts of the os api
3
function os.version()
4
	if turtle then
5
		return "TurtleOS 1.3"
6
	end
7
	return "CraftOS 1.3"
8
end
9
10
function os.pullEventRaw( _sFilter )
11
	return coroutine.yield( _sFilter )
12
end
13
14
function os.pullEvent( _sFilter )
15
	local event, p1, p2, p3, p4, p5 = os.pullEventRaw( _sFilter )
16
	if event == "terminate" then
17
		print( "Terminated" )
18
		error()
19
	end
20
	return event, p1, p2, p3, p4, p5
21
end
22
23
-- Install globals
24
function sleep( _nTime )
25
    local timer = os.startTimer( _nTime )
26
	repeat
27
		local sEvent, param = os.pullEvent( "timer" )
28
	until param == timer
29
end
30
31
function write( sText )
32
	local w,h = term.getSize()		
33
	local x,y = term.getCursorPos()
34
	
35
	local nLinesPrinted = 0
36
	local function newLine()
37
		if y + 1 <= h then
38
			term.setCursorPos(1, y + 1)
39
		else
40
			term.scroll(1)
41
			term.setCursorPos(1, h)
42
		end
43
		x, y = term.getCursorPos()
44
		nLinesPrinted = nLinesPrinted + 1
45
	end
46
	
47
	-- Print the line with proper word wrapping
48
	while string.len(sText) > 0 do
49
		local whitespace = string.match( sText, "^[ \t]+" )
50
		if whitespace then
51
			-- Print whitespace
52
			term.write( whitespace )
53
			x,y = term.getCursorPos()
54
			sText = string.sub( sText, string.len(whitespace) + 1 )
55
		end
56
		
57
		local newline = string.match( sText, "^\n" )
58
		if newline then
59
			-- Print newlines
60
			newLine()
61
			sText = string.sub( sText, 2 )
62
		end
63
		
64
		local text = string.match( sText, "^[^ \t\n]+" )
65
		if text then
66
			sText = string.sub( sText, string.len(text) + 1 )
67
			if string.len(text) > w then
68
				-- Print a multiline word				
69
				while string.len( text ) > 0 do
70
				if x > w then
71
					newLine()
72
				end
73
					term.write( text )
74
					text = string.sub( text, (w-x) + 2 )
75
					x,y = term.getCursorPos()
76
				end
77
			else
78
				-- Print a word normally
79
				if x + string.len(text) > w then
80
					newLine()
81
				end
82
				term.write( text )
83
				x,y = term.getCursorPos()
84
			end
85
		end
86
	end
87
	
88
	return nLinesPrinted
89
end
90
91
function print( ... )
92
	local nLinesPrinted = 0
93
	for n,v in ipairs( { ... } ) do
94
		nLinesPrinted = nLinesPrinted + write( tostring( v ) )
95
	end
96
	nLinesPrinted = nLinesPrinted + write( "\n" )
97
	return nLinesPrinted
98
end
99
100
function read( _sReplaceChar, _tHistory )	
101
	term.setCursorBlink( true )
102
103
    local sLine = ""
104
	local nHistoryPos = nil
105
	local nPos = 0
106
    if _sReplaceChar then
107
		_sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
108
	end
109
	
110
	local w, h = term.getSize()
111
	local sx, sy = term.getCursorPos()	
112
	local function redraw()
113
		local nScroll = 0
114
		if sx + nPos >= w then
115
			nScroll = (sx + nPos) - w
116
		end
117
			
118
		term.setCursorPos( sx, sy )
119
		term.write( string.rep(" ", w - sx + 1) )
120
		term.setCursorPos( sx, sy )
121
		if _sReplaceChar then
122
			term.write( string.rep(_sReplaceChar, string.len(sLine) - nScroll) )
123
		else
124
			term.write( string.sub( sLine, nScroll + 1 ) )
125
		end
126
		term.setCursorPos( sx + nPos - nScroll, sy )
127
	end
128
	
129
	while true do
130
		local sEvent, param = os.pullEvent()
131
		if sEvent == "char" then
132
			sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
133
			nPos = nPos + 1
134
			redraw()
135
			
136
		elseif sEvent == "key" then
137
		    if param == 28 then
138
				-- Enter
139
				break
140
			elseif param == 15 then
141
				-- Tab
142
				sLine = string.sub( sLine, 1, nPos ) .. "  " .. string.sub( sLine, nPos + 1 )
143
				nPos = nPos + 2
144
				redraw()
145
			elseif param == 199 then
146
				-- Home
147
				nPos=0
148
				redraw()
149
			elseif param == 207 then
150
				-- End
151
				nPos=string.len(sLine)
152
				redraw()
153
			elseif param == 203 then
154
				-- Left
155
				if nPos > 0 then
156
					nPos = nPos - 1
157
					redraw()
158
				end
159
				
160
			elseif param == 205 then
161
				-- Right				
162
				if nPos < string.len(sLine) then
163
					nPos = nPos + 1
164
					redraw()
165
				end
166
			
167
			elseif param == 200 or param == 208 then
168
                -- Up or down
169
				if _tHistory then
170
					if param == 200 then
171
						-- Up
172
						if nHistoryPos == nil then
173
							if #_tHistory > 0 then
174
								nHistoryPos = #_tHistory
175
							end
176
						elseif nHistoryPos > 1 then
177
							nHistoryPos = nHistoryPos - 1
178
						end
179
					else
180
						-- Down
181
						if nHistoryPos == #_tHistory then
182
							nHistoryPos = nil
183
						elseif nHistoryPos ~= nil then
184
							nHistoryPos = nHistoryPos + 1
185
						end						
186
					end
187
					
188
					if nHistoryPos then
189
                    	sLine = _tHistory[nHistoryPos]
190
                    	nPos = string.len( sLine ) 
191
                    else
192
						sLine = ""
193
						nPos = 0
194
					end
195
					redraw()
196
                end
197
            elseif param == 211 then
198
            	-- Delete
199
            	if nPos < string.len(sLine) then
200
            		sLine = string.sub(sLine,1,nPos) .. string.sub(sLine,nPos+2)
201
            		redraw()
202
            	end
203
			elseif param == 14 then
204
				-- Backspace
205
				if nPos > 0 then
206
					sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
207
					nPos = nPos - 1
208
					redraw()
209
				end
210
			end
211
		end
212
	end
213
	
214
	term.setCursorBlink( false )
215
	term.setCursorPos( w + 1, sy )
216
	print()
217
	
218
	return sLine
219
end
220
221
loadfile = function( _sFile )
222
	local file = fs.open( _sFile, "r" )
223
	if file then
224
		local func, err = loadstring( file.readAll(), fs.getName( _sFile ) )
225
		file.close()
226
		return func, err
227
	end
228
	return nil, "File not found"
229
end
230
231
dofile = function( _sFile )
232
	local fnFile, e = loadfile( _sFile )
233
	if fnFile then
234
		setfenv( fnFile, getfenv(2) )
235
		fnFile()
236
	else
237
		error( e )
238
	end
239
end
240
241
-- Install the rest of the OS api
242
function os.run( _tEnv, _sPath, ... )
243
    local tArgs = { ... }
244
    local fnFile, err = loadfile( _sPath )
245
    if fnFile then
246
        local tEnv = _tEnv
247
        setmetatable( tEnv, { __index = _G } )
248
        setfenv( fnFile, tEnv )
249
        local ok, err = pcall( function()
250
        	fnFile( unpack( tArgs ) )
251
        end )
252
        if not ok then
253
        	if err and err ~= "" then
254
	        	print( err )
255
	        end
256
        	return false
257
        end
258
        return true
259
    end
260
    if err and err ~= "" then
261
		print( err )
262
	end
263
    return false
264
end
265
266
local nativegetmetatable = getmetatable
267
function getmetatable( _t )
268
	if type( _t ) == "string" then
269
		error( "Attempt to access string metatable" )
270
	end
271
	return nativegetmetatable( _t )
272
end
273
274
local bProtected = true
275
local function protect( _t )
276
	local meta = getmetatable( _t )
277
	if meta == "Protected" then
278
		-- already protected
279
		return
280
	end
281
	
282
	setmetatable( _t, {
283
		__newindex = function( t, k, v )
284
			if bProtected then
285
				error( "Attempt to write to global" )
286
			else
287
				rawset( t, k, v )
288
			end
289
		end,
290
		__metatable = "Protected",
291
	} )
292
end
293
294
local tAPIsLoading = {}
295
function os.loadAPI( _sPath )
296
	local sName = fs.getName( _sPath )
297
	if tAPIsLoading[sName] == true then
298
		print( "API "..sName.." is already being loaded" )
299
		return false
300
	end
301
	tAPIsLoading[sName] = true
302
		
303
	local tEnv = {}
304
	setmetatable( tEnv, { __index = _G } )
305
	local fnAPI, err = loadfile( _sPath )
306
	if fnAPI then
307
		setfenv( fnAPI, tEnv )
308
		fnAPI()
309
	else
310
		print( err )
311
		return false
312
	end
313
	
314
	local tAPI = {}
315
	for k,v in pairs( tEnv ) do
316
		tAPI[k] =  v
317
	end
318
	protect( tAPI )
319
	
320
	bProtected = false
321
	_G[sName] = tAPI
322
	bProtected = true
323
	
324
	tAPIsLoading[sName] = nil
325
	return true
326
end
327
328
function os.unloadAPI( _sName )
329
	if _sName ~= "_G" and type(_G[_sName]) == "table" then
330
		bProtected = false
331
		_G[_sName] = nil
332
		bProtected = true
333
	end
334
end
335
336
function os.sleep( _nTime )
337
	sleep( _nTime )
338
end
339
340
local nativeShutdown = os.shutdown
341
function os.shutdown()
342
	nativeShutdown()
343
	while true do
344
		coroutine.yield()
345
	end
346
end
347
348
-- Install the lua part of the HTTP api (if enabled)
349
if http then
350
	local function wrapRequest( _url, _post )
351
		local requestID = http.request( _url, _post )
352
		while true do
353
			local event, param1, param2 = os.pullEvent()
354
			if event == "http_success" and param1 == _url then
355
				return param2
356
			elseif event == "http_failure" and param1 == _url then
357
				return nil
358
			end
359
		end		
360
	end
361
	
362
	http.get = function( _url )
363
		return wrapRequest( _url, nil )
364
	end
365
366
	http.post = function( _url, _post )
367
		return wrapRequest( _url, _post or "" )
368
	end
369
end
370
371
-- Install the lua part of the peripheral api
372
peripheral.wrap = function( _sSide )
373
	if peripheral.isPresent( _sSide ) then
374
		local tMethods = peripheral.getMethods( _sSide )
375
		local tResult = {}
376
		for n,sMethod in ipairs( tMethods ) do
377
			tResult[sMethod] = function( ... )
378
				return peripheral.call( _sSide, sMethod, ... )
379
			end
380
		end
381
		tResult.type = peripheral.getType(_sSide)
382
		tResult["getType"] = function() return peripheral.getType( _sSide ) end
383
		tResult["getMethods"] = function() return peripheral.getMethods( _sSide ) end
384
		tResult["isPresent"] = function() return peripheral.isPresent( _sSide ) end
385
		return tResult
386
	end
387
	return nil
388
end
389
390
-- Protect the global table against modifications
391
protect( _G )
392
for k,v in pairs( _G ) do
393
	if type(v) == "table" then
394
		protect( v )
395
	end
396
end
397
398
-- Load APIs
399
local tApis = fs.list( "rom/apis" )
400
for n,sFile in ipairs( tApis ) do
401
	if string.sub( sFile, 1, 1 ) ~= "." then
402
		local sPath = fs.combine( "rom/apis", sFile )
403
		if not fs.isDir( sPath ) then
404
			os.loadAPI( sPath )
405
		end
406
	end
407
end
408
409
if turtle then
410
	local tApis = fs.list( "rom/apis/turtle" )
411
	for n,sFile in ipairs( tApis ) do
412
		if string.sub( sFile, 1, 1 ) ~= "." then
413
			local sPath = fs.combine( "rom/apis/turtle", sFile )
414
			if not fs.isDir( sPath ) then
415
				os.loadAPI( sPath )
416
			end
417
		end
418
	end
419
end
420
421
-- Run the shell
422
local ok, err = pcall( function()
423
	parallel.waitForAny(
424
		function()
425
			rednet.run()
426
		end,
427
		function()
428
			os.run( {}, "rom/programs/shell" )
429
		end
430
	)
431
end )
432
433
-- If the shell errored, let the user read it.
434
if not ok then
435
	print( err )
436
end
437
438
pcall( function()
439
	term.setCursorBlink( false )
440
	print( "Press any key to continue" )
441
	os.pullEvent( "key" ) 
442
end )
443
os.shutdown()