View difference between Paste ID: 2TxciCtZ and 2yWNZWY2
SHOW: | | - or go back to the newest paste.
1
--License:
2
--The code of "EnderOS" in any form is intellectual
3
--property of SuicidalSTDz. You may not reproduce,
4
--redistribute, or modify it in any way!
5
6
--This OS stores User information in a hashed form. Making "hackers" tremble in fear >:) Not really...
7
--The hash that EnderOS uses is Sha-256 and makes storage safer :)
8
9
10
11
os.pullEvent = os.pullEventRaw
12
if fs.exists("/.Installer/.installer") then
13
	local open = io.open("/.Installer/.installer", "r")
14
	file = open:read()
15
	open:close()
16
	if shell.run("delete",file) == true then
17
		shell.run("delete",file)
18
	else
19
		print("Expected file not found! Ignoring...")
20
		sleep(1.5)
21
	end
22
end
23
term.clear()
24
term.setCursorPos(1,1)
25
function sha256(msg)
26
	function band(int1, int2, int3, ...)
27
		local ret =
28
		((int1%0x00000002>=0x00000001 and int2%0x00000002>=0x00000001 and 0x00000001) or 0)+
29
		((int1%0x00000004>=0x00000002 and int2%0x00000004>=0x00000002 and 0x00000002) or 0)+
30
		((int1%0x00000008>=0x00000004 and int2%0x00000008>=0x00000004 and 0x00000004) or 0)+
31
		((int1%0x00000010>=0x00000008 and int2%0x00000010>=0x00000008 and 0x00000008) or 0)+
32
		((int1%0x00000020>=0x00000010 and int2%0x00000020>=0x00000010 and 0x00000010) or 0)+
33
		((int1%0x00000040>=0x00000020 and int2%0x00000040>=0x00000020 and 0x00000020) or 0)+
34
		((int1%0x00000080>=0x00000040 and int2%0x00000080>=0x00000040 and 0x00000040) or 0)+
35
		((int1%0x00000100>=0x00000080 and int2%0x00000100>=0x00000080 and 0x00000080) or 0)+
36
		((int1%0x00000200>=0x00000100 and int2%0x00000200>=0x00000100 and 0x00000100) or 0)+
37
		((int1%0x00000400>=0x00000200 and int2%0x00000400>=0x00000200 and 0x00000200) or 0)+
38
		((int1%0x00000800>=0x00000400 and int2%0x00000800>=0x00000400 and 0x00000400) or 0)+
39
		((int1%0x00001000>=0x00000800 and int2%0x00001000>=0x00000800 and 0x00000800) or 0)+
40
		((int1%0x00002000>=0x00001000 and int2%0x00002000>=0x00001000 and 0x00001000) or 0)+
41
		((int1%0x00004000>=0x00002000 and int2%0x00004000>=0x00002000 and 0x00002000) or 0)+
42
		((int1%0x00008000>=0x00004000 and int2%0x00008000>=0x00004000 and 0x00004000) or 0)+
43
		((int1%0x00010000>=0x00008000 and int2%0x00010000>=0x00008000 and 0x00008000) or 0)+
44
		((int1%0x00020000>=0x00010000 and int2%0x00020000>=0x00010000 and 0x00010000) or 0)+
45
		((int1%0x00040000>=0x00020000 and int2%0x00040000>=0x00020000 and 0x00020000) or 0)+
46
		((int1%0x00080000>=0x00040000 and int2%0x00080000>=0x00040000 and 0x00040000) or 0)+
47
		((int1%0x00100000>=0x00080000 and int2%0x00100000>=0x00080000 and 0x00080000) or 0)+
48
		((int1%0x00200000>=0x00100000 and int2%0x00200000>=0x00100000 and 0x00100000) or 0)+
49
		((int1%0x00400000>=0x00200000 and int2%0x00400000>=0x00200000 and 0x00200000) or 0)+
50
		((int1%0x00800000>=0x00400000 and int2%0x00800000>=0x00400000 and 0x00400000) or 0)+
51
		((int1%0x01000000>=0x00800000 and int2%0x01000000>=0x00800000 and 0x00800000) or 0)+
52
		((int1%0x02000000>=0x01000000 and int2%0x02000000>=0x01000000 and 0x01000000) or 0)+
53
		((int1%0x04000000>=0x02000000 and int2%0x04000000>=0x02000000 and 0x02000000) or 0)+
54
		((int1%0x08000000>=0x04000000 and int2%0x08000000>=0x04000000 and 0x04000000) or 0)+
55
		((int1%0x10000000>=0x08000000 and int2%0x10000000>=0x08000000 and 0x08000000) or 0)+
56
		((int1%0x20000000>=0x10000000 and int2%0x20000000>=0x10000000 and 0x10000000) or 0)+
57
		((int1%0x40000000>=0x20000000 and int2%0x40000000>=0x20000000 and 0x20000000) or 0)+
58
		((int1%0x80000000>=0x40000000 and int2%0x80000000>=0x40000000 and 0x40000000) or 0)+
59
		((int1>=0x80000000 and int2>=0x80000000 and 0x80000000) or 0)
60
61
		return (int3 and band(ret, int3, ...)) or ret
62
	end
63
64
	local function bxor(int1, int2, int3, ...)
65
		local ret =
66
		((int1%0x00000002>=0x00000001 ~= (int2%0x00000002>=0x00000001) and 0x00000001) or 0)+
67
		((int1%0x00000004>=0x00000002 ~= (int2%0x00000004>=0x00000002) and 0x00000002) or 0)+
68
		((int1%0x00000008>=0x00000004 ~= (int2%0x00000008>=0x00000004) and 0x00000004) or 0)+
69
		((int1%0x00000010>=0x00000008 ~= (int2%0x00000010>=0x00000008) and 0x00000008) or 0)+
70
		((int1%0x00000020>=0x00000010 ~= (int2%0x00000020>=0x00000010) and 0x00000010) or 0)+
71
		((int1%0x00000040>=0x00000020 ~= (int2%0x00000040>=0x00000020) and 0x00000020) or 0)+
72
		((int1%0x00000080>=0x00000040 ~= (int2%0x00000080>=0x00000040) and 0x00000040) or 0)+
73
		((int1%0x00000100>=0x00000080 ~= (int2%0x00000100>=0x00000080) and 0x00000080) or 0)+
74
		((int1%0x00000200>=0x00000100 ~= (int2%0x00000200>=0x00000100) and 0x00000100) or 0)+
75
		((int1%0x00000400>=0x00000200 ~= (int2%0x00000400>=0x00000200) and 0x00000200) or 0)+
76
		((int1%0x00000800>=0x00000400 ~= (int2%0x00000800>=0x00000400) and 0x00000400) or 0)+
77
		((int1%0x00001000>=0x00000800 ~= (int2%0x00001000>=0x00000800) and 0x00000800) or 0)+
78
		((int1%0x00002000>=0x00001000 ~= (int2%0x00002000>=0x00001000) and 0x00001000) or 0)+
79
		((int1%0x00004000>=0x00002000 ~= (int2%0x00004000>=0x00002000) and 0x00002000) or 0)+
80
		((int1%0x00008000>=0x00004000 ~= (int2%0x00008000>=0x00004000) and 0x00004000) or 0)+
81
		((int1%0x00010000>=0x00008000 ~= (int2%0x00010000>=0x00008000) and 0x00008000) or 0)+
82
		((int1%0x00020000>=0x00010000 ~= (int2%0x00020000>=0x00010000) and 0x00010000) or 0)+
83
		((int1%0x00040000>=0x00020000 ~= (int2%0x00040000>=0x00020000) and 0x00020000) or 0)+
84
		((int1%0x00080000>=0x00040000 ~= (int2%0x00080000>=0x00040000) and 0x00040000) or 0)+
85
		((int1%0x00100000>=0x00080000 ~= (int2%0x00100000>=0x00080000) and 0x00080000) or 0)+
86
		((int1%0x00200000>=0x00100000 ~= (int2%0x00200000>=0x00100000) and 0x00100000) or 0)+
87
		((int1%0x00400000>=0x00200000 ~= (int2%0x00400000>=0x00200000) and 0x00200000) or 0)+
88
		((int1%0x00800000>=0x00400000 ~= (int2%0x00800000>=0x00400000) and 0x00400000) or 0)+
89
		((int1%0x01000000>=0x00800000 ~= (int2%0x01000000>=0x00800000) and 0x00800000) or 0)+
90
		((int1%0x02000000>=0x01000000 ~= (int2%0x02000000>=0x01000000) and 0x01000000) or 0)+
91
		((int1%0x04000000>=0x02000000 ~= (int2%0x04000000>=0x02000000) and 0x02000000) or 0)+
92
		((int1%0x08000000>=0x04000000 ~= (int2%0x08000000>=0x04000000) and 0x04000000) or 0)+
93
		((int1%0x10000000>=0x08000000 ~= (int2%0x10000000>=0x08000000) and 0x08000000) or 0)+
94
		((int1%0x20000000>=0x10000000 ~= (int2%0x20000000>=0x10000000) and 0x10000000) or 0)+
95
		((int1%0x40000000>=0x20000000 ~= (int2%0x40000000>=0x20000000) and 0x20000000) or 0)+
96
		((int1%0x80000000>=0x40000000 ~= (int2%0x80000000>=0x40000000) and 0x40000000) or 0)+
97
		((int1>=0x80000000 ~= (int2>=0x80000000) and 0x80000000) or 0)
98
99
		return (int3 and bxor(ret, int3, ...)) or ret
100
	end
101
102
	local function bnot(int)
103
		return 4294967295 - int
104
	end
105
106
	local function rshift(int, by)
107
		local shifted = int / (2 ^ by)
108
		return shifted - shifted % 1
109
	end
110
111
	local function rrotate(int, by)
112
		local shifted = int / (2 ^ by)
113
		local fraction = shifted % 1
114
		return (shifted - fraction) + fraction * (2 ^ 32)
115
	end
116
117
	local k = {
118
		0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
119
		0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
120
		0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
121
		0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
122
		0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
123
		0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
124
		0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
125
		0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
126
		0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
127
		0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
128
		0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
129
		0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
130
		0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
131
		0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
132
		0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
133
		0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
134
	}
135
136
	local function str2hexa(s)
137
		local h = string.gsub(s, ".", function(c)
138
			return string.format("%02x", string.byte(c))
139
		end)
140
		return h
141
	end
142
143
	local function num2s(l, n)
144
		local s = ""
145
		for i = 1, n do
146
			local rem = l % 256
147
			s = string.char(rem) .. s
148
			l = (l - rem) / 256
149
		end
150
		return s
151
	end
152
153
	local function s232num(s, i)
154
		local n = 0
155
		for i = i, i + 3 do n = n*256 + string.byte(s, i) end
156
		return n
157
	end
158
159
	local function preproc(msg, len)
160
		local extra = 64 - ((len + 1 + 8) % 64)
161
		len = num2s(8 * len, 8)
162
		msg = msg .. "\128" .. string.rep("\0", extra) .. len
163
		return msg
164
	end
165
166
	local function initH256(H)
167
		H[1] = 0x6a09e667
168
		H[2] = 0xbb67ae85
169
		H[3] = 0x3c6ef372
170
		H[4] = 0xa54ff53a
171
		H[5] = 0x510e527f
172
		H[6] = 0x9b05688c
173
		H[7] = 0x1f83d9ab
174
		H[8] = 0x5be0cd19
175
		return H
176
	end
177
178
	local function digestblock(msg, i, H)
179
		local w = {}
180
		for j = 1, 16 do w[j] = s232num(msg, i + (j - 1) * 4) end
181
		for j = 17, 64 do
182
			local v = w[j - 15]
183
			local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
184
			v = w[j - 2]
185
			local s1 = bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
186
			w[j] = w[j - 16] + s0 + w[j - 7] + s1
187
		end
188
189
		local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
190
		for i = 1, 64 do
191
			local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
192
			local maj = bxor(band(a, b), band(a, c), band(b, c))
193
			local t2 = s0 + maj
194
			local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
195
			local ch = bxor (band(e, f), band(bnot(e), g))
196
			local t1 = h + s1 + ch + k[i] + w[i]
197
			h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
198
		end
199
200
		H[1] = band(H[1], a)
201
		H[2] = band(H[2], b)
202
		H[3] = band(H[3], c)
203
		H[4] = band(H[4], d)
204
		H[5] = band(H[5], e)
205
		H[6] = band(H[6], f)
206
		H[7] = band(H[7], g)
207
		H[8] = band(H[8], h)
208
	end
209
210
	msg = preproc(msg, #msg)
211
	local H = initH256({})
212
	for i = 1, #msg, 64 do digestblock(msg, i, H) end
213
	return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
214
		num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
215
end
216
saltHash = "T01hFg62zY"
217
function settingsChangeUser()
218
reset()
219
term.setTextColor(colors.orange)
220
local passFile = io.open("/.EnderOS/.passInfo", "r")
221
local passContents = passFile:read()
222
passFile:close()
223
print("Please enter your password: ")
224
term.setTextColor(colors.white)
225
local input = read("*")
226
local hash = sha256(input)
227
  if hash..saltHash ~= passContents then
228
	term.setTextColor(colors.red)
229
    print("Invalid password")
230
    sleep(1.5)
231
    settingsChangeUser()
232
  else
233
    local user = ("/.EnderOS/.userInfo")
234
    local username = io.open(user, "w")
235
	term.setTextColor(colors.orange)
236
    print("Enter new username: ")
237
	term.setTextColor(colors.white)
238
    writeUser = read()
239
	local hash = sha256(writeUser)
240
    writeN = username:write(hash..saltHash)
241
    username:close()
242
	term.setTextColor(colors.lightBlue)
243
    print("Your new username is "..writeUser)
244
    sleep(2)
245
    startScreen()
246
  end
247
  term.setTextColor(colors.white)
248
end
249
function settingsChangePass()
250
reset()
251
term.setTextColor(colors.orange)
252
local passFile = io.open("/.EnderOS/.passInfo", "r")
253
local passContents = passFile:read()
254
passFile:close()
255
print("Please enter your password: ")
256
term.setTextColor(colors.white)
257
local input = read("*")
258
local hash = sha256(input)
259
  if hash..saltHash ~= passContents then
260
	term.setTextColor(colors.red)
261
    print("Invalid password")
262
    sleep(1.5)
263
    settingsChangePass()
264
  else
265
    local pass = ("/.EnderOS/.passInfo")
266
    local password = io.open(pass, "w")
267
	term.setTextColor(colors.orange)
268
    print("Enter new password: ")
269
	term.setTextColor(colors.white)
270
    local writePass = read("*")
271
	local hash = sha256(writePass)
272
    local writeN = password:write(hash..saltHash)
273
    password:close()
274
	term.setTextColor(colors.lightBlue)
275
    print("Your new password is "..writePass)
276
    sleep(2)
277
    startScreen()
278
  end
279
  term.setTextColor(colors.white)
280
end
281
function settingsChangeHint()
282
reset()
283
term.setTextColor(colors.orange)
284
local passFile = io.open("/.EnderOS/.passInfo", "r")
285
local passContents = passFile:read()
286
passFile:close()
287
print("Please enter your password: ")
288
term.setTextColor(colors.white)
289
local input = read("*")
290
local hash = sha256(input)
291
  if hash..saltHash ~= passContents then
292
	term.setTextColor(colors.red)
293
    print("Invalid password")
294
    sleep(1.5)
295
    settingsChangeHint()
296
  else
297
    local hint = ("/.EnderOS/.userHint")
298
    local uHint = io.open(hint, "w")
299
	term.setTextColor(colors.orange)
300
    print("Enter new hint: ")
301
	term.setTextColor(colors.white)
302
    local writeHint = read()
303
	if #writeHint >30 then
304
		term.setTextColor(colors.red)
305
		print("This Hint exceeds the max hint length of 30!")
306
		sleep(3)
307
		uHint:close()
308
		settingsChangeHint()
309
	else
310
		local writeN = uHint:write(writeHint)
311
		uHint:close()
312
		term.setTextColor(colors.lightBlue)
313
		print("Your new hint is "..writeHint)
314
		sleep(2)
315
		startScreen()
316
	end
317
  end
318
  term.setTextColor(colors.white)
319
end
320-
version = "v2.2"
320+
version = "v2.3"
321
userfile = shell.getRunningProgram()
322
local v = ".(Period)"
323
function Edit()
324
reset()
325
term.setTextColor(colors.orange)
326
print("What file do you wish to edit?")
327
-- Get file to edit
328
term.setTextColor(colors.white)
329
local input = read()
330
if #input == 0 then
331
	term.setTextColor(colors.red)
332
	print( "Usage: edit <path>" )
333
	term.setTextColor(colors.white)
334
	startScreen()
335
end
336
reset()
337
338
-- Error checking
339
local sPath = shell.resolve(input)
340
local bReadOnly = fs.isReadOnly( sPath )
341
if fs.exists( sPath ) and fs.isDir( sPath ) then
342
	term.setTextColor(colors.red)
343
 print( "Cannot edit a directory." )
344
 term.setTextColor(colors.white)
345
	return
346
end
347
if sPath == "Edit" then
348
  term.setTextColor(colors.orange)
349
  print("Cannot edit the file: "..sPath)
350
  term.setTextColor(colors.white)
351
  return
352
end
353
local x,y = 1,1
354
local w,h = term.getSize()
355
local scrollX, scrollY = 0,0
356
357
local tLines = {}
358
local bRunning = true
359
360
-- Colours
361
local highlightColour, keywordColour, commentColour, textColour, bgColour
362
if term.isColour() then
363
	bgColour = colours.black
364
	textColour = colours.white
365
	highlightColour = colours.orange
366
	keywordColour = colours.lightBlue
367
	commentColour = colours.lime
368
	stringColour = colours.red
369
else
370
	bgColour = colours.black
371
	textColour = colours.white
372
	highlightColour = colours.white
373
	keywordColour = colours.white
374
	commentColour = colours.white
375
	stringColour = colours.white
376
end
377
378
-- Menus
379
local bMenu = false
380
local nMenuItem = 1
381
local tMenuItems = {"Save", "Exit", "Print"}
382
local sStatus = "Press Ctrl to access menu"
383
384
local function load(_sPath)
385
	tLines = {}
386
	if fs.exists( _sPath ) then
387
		local file = io.open( _sPath, "r" )
388
		local sLine = file:read()
389
		while sLine do
390
			table.insert( tLines, sLine )
391
			sLine = file:read()
392
		end
393
		file:close()
394
	end
395
	
396
	if #tLines == 0 then
397
		table.insert( tLines, "" )
398
	end
399
end
400
401
local function save( _sPath )
402
	-- Create intervening folder
403
	local sDir = sPath:sub(1, sPath:len() - fs.getName(sPath):len() )
404
	if not fs.exists( sDir ) then
405
		fs.makeDir( sDir )
406
	end
407
408
	-- Save
409
	local file = nil
410
	local function innerSave()
411
		file = fs.open( _sPath, "w" )
412
		if file then
413
			for n, sLine in ipairs( tLines ) do
414
				file.write( sLine .. "\n" )
415
			end
416
		else
417
			term.setTextColor(colors.red)
418
			error( "EnderOS failed to open ".._sPath )
419
			term.setTextColor(colors.white)
420
		end
421
	end
422
	
423
	local ok = pcall( innerSave )
424
	if file then 
425
		file.close()
426
	end
427
	return ok
428
end
429
430
local tKeywords = {
431
	["and"] = true,
432
	["break"] = true,
433
	["do"] = true,
434
	["else"] = true,
435
	["elseif"] = true,
436
	["end"] = true,
437
	["false"] = true,
438
	["for"] = true,
439
	["function"] = true,
440
	["if"] = true,
441
	["in"] = true,
442
	["local"] = true,
443
	["nil"] = true,
444
	["not"] = true,
445
	["or"] = true,
446
	["repeat"] = true,
447
	["return"] = true,
448
	["then"] = true,
449
	["true"] = true,
450
	["until"]= true,
451
	["while"] = true,
452
}
453
454
local function tryWrite( sLine, regex, colour )
455
	local match = string.match( sLine, regex )
456
	if match then
457
		if type(colour) == "number" then
458
			term.setTextColour( colour )
459
		else
460
			term.setTextColour( colour(match) )
461
		end
462
		term.write( match )
463
		term.setTextColour( textColour )
464
		return string.sub( sLine, string.len(match) + 1 )
465
	end
466
	return nil
467
end
468
469
local function writeHighlighted( sLine )
470
	while string.len(sLine) > 0 do	
471
		sLine = 
472
			tryWrite( sLine, "^%-%-%[%[.-%]%]", commentColour ) or
473
			tryWrite( sLine, "^%-%-.*", commentColour ) or
474
			tryWrite( sLine, "^\".-[^\\]\"", stringColour ) or
475
			tryWrite( sLine, "^\'.-[^\\]\'", stringColour ) or
476
			tryWrite( sLine, "^%[%[.-%]%]", stringColour ) or
477
			tryWrite( sLine, "^[%w_]+", function( match )
478
				if tKeywords[ match ] then
479
					return keywordColour
480
				end
481
				return textColour
482
			end ) or
483
			tryWrite( sLine, "^[^%w_]", textColour )
484
	end
485
end
486
487
local function redrawText()
488
	for y=1,h-1 do
489
		term.setCursorPos( 1 - scrollX, y )
490
		term.clearLine()
491
492
		local sLine = tLines[ y + scrollY ]
493
		if sLine ~= nil then
494
			writeHighlighted( sLine )
495
		end
496
	end
497
	term.setCursorPos( x - scrollX, y - scrollY )
498
end
499
500
local function redrawLine(_nY)
501
	local sLine = tLines[_nY]
502
	term.setCursorPos( 1 - scrollX, _nY - scrollY )
503
	term.clearLine()
504
	writeHighlighted( sLine )
505
	term.setCursorPos( x - scrollX, _nY - scrollY )
506
end
507
508
local function setLeftStatus()
509
end
510
511
local function redrawMenu()
512
    term.setCursorPos( 1, h )
513
	term.clearLine()
514
515
	local sLeft, sRight
516
	local nLeftColour, nLeftHighlight1, nLeftHighlight2
517
	if bMenu then
518
		local sMenu = ""
519
		for n,sItem in ipairs( tMenuItems ) do
520
			if n == nMenuItem then
521
				nLeftHighlight1 = sMenu:len() + 1
522
				nLeftHighlight2 = sMenu:len() + sItem:len() + 2
523
			end
524
			sMenu = sMenu.." "..sItem.." "
525
		end
526
		sLeft = sMenu
527
		nLeftColour = textColour
528
	else
529
		sLeft = sStatus
530
		nLeftColour = highlightColour
531
	end
532
	
533
	-- Left goes last so that it can overwrite the line numbers.
534
	sRight = "Ln "..y
535
	term.setTextColour( highlightColour )
536
	term.setCursorPos( w-sRight:len() + 1, h )
537
	term.write(sRight)
538
539
	sRight = tostring(y)
540
	term.setTextColour( textColour )
541
	term.setCursorPos( w-sRight:len() + 1, h )
542
	term.write(sRight)
543
544
	if sLeft then
545
		term.setCursorPos( 1, h )
546
		term.setTextColour( nLeftColour )
547
		term.write(sLeft)		
548
		if nLeftHighlight1 then
549
			term.setTextColour( highlightColour )
550
			term.setCursorPos( nLeftHighlight1, h )
551
			term.write( "[" )
552
			term.setCursorPos( nLeftHighlight2, h )
553
			term.write( "]" )
554
		end
555
		term.setTextColour( textColour )
556
	end
557
	
558
	-- Cursor highlights selection
559
	term.setCursorPos( x - scrollX, y - scrollY )
560
end
561
562
local tMenuFuncs = { 
563
	Save=function()
564
		if bReadOnly then
565
			sStatus = "You cannot access this file!"
566
		else
567
			local ok, err = save( sPath )
568
			if ok then
569
				sStatus="EnderOS saved this file to "..sPath
570
			else
571
				sStatus="EnderOS could not save this file to "..sPath
572
			end
573
		end
574
		redrawMenu()
575
	end,
576
	Print=function()
577
		local sPrinterSide = nil
578
		for n,sSide in ipairs(rs.getSides()) do
579
			if peripheral.isPresent(sSide) and peripheral.getType(sSide) == "printer" then
580
				sPrinterSide = sSide
581
				break
582
			end
583
		end
584
		
585
		if not sPrinterSide then
586
			sStatus = "EnderOS could not find any printers!"
587
			return
588
		end
589
590
		local nPage = 0
591
		local sName = fs.getName( sPath )
592
		local printer = peripheral.wrap(sPrinterSide)
593
		if printer.getInkLevel() < 1 then
594
			sStatus = "EnderOS detected no ink!"
595
			return
596
		elseif printer.getPaperLevel() < 1 then
597
			sStatus = "EnderOS detected no paper!"
598
			return
599
		end
600
		
601
		local terminal = {
602
			getCursorPos = printer.getCursorPos,
603
			setCursorPos = printer.setCursorPos,
604
			getSize = printer.getPageSize,
605
			write = printer.write,
606
		}
607
		terminal.scroll = function()
608
			if nPage == 1 then
609
				printer.setPageTitle( sName.." (page "..nPage..")" )			
610
			end
611
			
612
			while not printer.newPage()	do
613
				if printer.getInkLevel() < 1 then
614
					sStatus = "EnderOS has detected low ink levels, please refill"
615
				elseif printer.getPaperLevel() < 1 then
616
					sStatus = "EnderOS has detected low paper levels, please refill"
617
				else
618
					sStatus = "EnderOS has detected a full output tray, please empty"
619
				end
620
	
621
				term.restore()
622
				redrawMenu()
623
				term.redirect( terminal )
624
				
625
				local timer = os.startTimer(0.5)
626
				sleep(0.5)
627
			end
628
629
			nPage = nPage + 1
630
			if nPage == 1 then
631
				printer.setPageTitle( sName )
632
			else
633
				printer.setPageTitle( sName.." (page "..nPage..")" )
634
			end
635
		end
636
		
637
		bMenu = false
638
		term.redirect( terminal )
639
		local ok, error = pcall( function()
640
			term.scroll()
641
			for n, sLine in ipairs( tLines ) do
642
				print( sLine )
643
			end
644
		end )
645
		term.restore()
646
		if not ok then
647
			print( error )
648
		end
649
		
650
		while not printer.endPage() do
651
			sStatus = "EnderOS has detected a full output tray, please empty"
652
			redrawMenu()
653
			sleep( 0.5 )
654
		end
655
		bMenu = true
656
			
657
		if nPage > 1 then
658
			sStatus = "EnderOS printed "..nPage.." Pages"
659
		else
660
			sStatus = "EnderOS printed 1 Page"
661
		end
662
		redrawMenu()
663
	end,
664
	Exit=function()
665
		bRunning = false
666
	end
667
}
668
669
local function doMenuItem( _n )
670
	tMenuFuncs[tMenuItems[_n]]()
671
	if bMenu then
672
		bMenu = false
673
		term.setCursorBlink( true )
674
	end
675
	redrawMenu()
676
end
677
678
local function setCursor( x, y )
679
	local screenX = x - scrollX
680
	local screenY = y - scrollY
681
	
682
	local bRedraw = false
683
	if screenX < 1 then
684
		scrollX = x - 1
685
		screenX = 1
686
		bRedraw = true
687
	elseif screenX > w then
688
		scrollX = x - w
689
		screenX = w
690
		bRedraw = true
691
	end
692
	
693
	if screenY < 1 then
694
		scrollY = y - 1
695
		screenY = 1
696
		bRedraw = true
697
	elseif screenY > h-1 then
698
		scrollY = y - (h-1)
699
		screenY = h-1
700
		bRedraw = true
701
	end
702
	
703
	if bRedraw then
704
		redrawText()
705
	end
706
	term.setCursorPos( screenX, screenY )
707
	
708
	-- Statusbar now pertains to menu, it would probably be safe to redraw the menu on every key event.
709
	redrawMenu()
710
end
711
712
-- Actual program functionality begins
713
load(sPath)
714
715
term.setBackgroundColour( bgColour )
716
term.clear()
717
term.setCursorPos(x,y)
718
term.setCursorBlink( true )
719
720
redrawText()
721
redrawMenu()
722
723
-- Handle input
724
while bRunning do
725
	local sEvent, param, param2, param3 = os.pullEvent()
726
	if sEvent == "key" then
727
		if param == keys.up then
728
			-- Up
729
			if not bMenu then
730
				if y > 1 then
731
					-- Move cursor up
732
					y = y - 1
733
					x = math.min( x, string.len( tLines[y] ) + 1 )
734
					setCursor( x, y )
735
				end
736
			end
737
		elseif param == keys.down then
738
			-- Down
739
			if not bMenu then
740
				-- Move cursor down
741
				if y < #tLines then
742
					y = y + 1
743
					x = math.min( x, string.len( tLines[y] ) + 1 )
744
					setCursor( x, y )
745
				end
746
			end
747
		elseif param == keys.tab then
748
			-- Tab
749
			if not bMenu then
750
				local sLine = tLines[y]
751
752
				-- Indent line
753
				-- IN CASE OF INSERT TAB IN PLACE:
754
				-- tLines[y] = string.sub(sLine,1,x-1) .. "  " .. string.sub(sLine,x)
755
				tLines[y]="  "..tLines[y]
756
				x = x + 2
757
				setCursor( x, y )
758
				redrawLine(y)
759
			end
760
		elseif param == keys.pageUp then
761
			-- Page Up
762
			if not bMenu then
763
				-- Move up a page
764
				local sx,sy=term.getSize()
765
				y=y-sy-1
766
				if y<1 then	y=1 end
767
				x = math.min( x, string.len( tLines[y] ) + 1 )
768
				setCursor( x, y )
769
			end
770
		elseif param == keys.pageDown then
771
			-- Page Down
772
			if not bMenu then
773
				-- Move down a page
774
				local sx,sy=term.getSize()
775
				if y<#tLines-sy-1 then
776
					y = y+sy-1
777
				else
778
					y = #tLines
779
				end
780
				x = math.min( x, string.len( tLines[y] ) + 1 )
781
				setCursor( x, y )
782
			end
783
		elseif param == keys.home then
784
			-- Home
785
			if not bMenu then
786
				-- Move cursor to the beginning
787
				x=1
788
				setCursor(x,y)
789
			end
790
		elseif param == keys["end"] then
791
			-- End
792
			if not bMenu then
793
				-- Move cursor to the end
794
				x = string.len( tLines[y] ) + 1
795
				setCursor(x,y)
796
			end
797
		elseif param == keys.left then
798
			-- Left
799
			if not bMenu then
800
				if x > 1 then
801
					-- Move cursor left
802
					x = x - 1
803
				elseif x==1 and y>1 then
804
					x = string.len( tLines[y-1] ) + 1
805
					y = y - 1
806
				end
807
				setCursor( x, y )
808
			else
809
				-- Move menu left
810
				nMenuItem = nMenuItem - 1
811
				if nMenuItem < 1 then
812
					nMenuItem = #tMenuItems
813
				end
814
				redrawMenu()
815
			end
816
		elseif param == keys.right then
817
			-- Right
818
			if not bMenu then
819
				if x < string.len( tLines[y] ) + 1 then
820
					-- Move cursor right
821
					x = x + 1
822
				elseif x==string.len( tLines[y] ) + 1 and y<#tLines then
823
					x = 1
824
					y = y + 1
825
				end
826
				setCursor( x, y )
827
			else
828
				-- Move menu right
829
				nMenuItem = nMenuItem + 1
830
				if nMenuItem > #tMenuItems then
831
					nMenuItem = 1
832
				end
833
				redrawMenu()
834
			end
835
		elseif param == keys.delete then
836
			-- Delete
837
			if not bMenu then
838
				if  x < string.len( tLines[y] ) + 1 then
839
					local sLine = tLines[y]
840
					tLines[y] = string.sub(sLine,1,x-1) .. string.sub(sLine,x+1)
841
					redrawLine(y)
842
				elseif y<#tLines then
843
					tLines[y] = tLines[y] .. tLines[y+1]
844
					table.remove( tLines, y+1 )
845
					redrawText()
846
					redrawMenu()
847
				end
848
			end
849
		elseif param == keys.backspace then
850
			-- Backspace
851
			if not bMenu then
852
				if x > 1 then
853
					-- Remove character
854
					local sLine = tLines[y]
855
					tLines[y] = string.sub(sLine,1,x-2) .. string.sub(sLine,x)
856
					redrawLine(y)
857
			
858
					x = x - 1
859
					setCursor( x, y )
860
				elseif y > 1 then
861
					-- Remove newline
862
					local sPrevLen = string.len( tLines[y-1] )
863
					tLines[y-1] = tLines[y-1] .. tLines[y]
864
					table.remove( tLines, y )
865
					redrawText()
866
				
867
					x = sPrevLen + 1
868
					y = y - 1
869
					setCursor( x, y )
870
				end
871
			end
872
		elseif param == keys.enter then
873
			-- Enter
874
			if not bMenu then
875
				-- Newline
876
				local sLine = tLines[y]
877
				local _,spaces=string.find(sLine,"^[ ]+")
878
				if not spaces then
879
					spaces=0
880
				end
881
				tLines[y] = string.sub(sLine,1,x-1)
882
				table.insert( tLines, y+1, string.rep(' ',spaces)..string.sub(sLine,x) )
883
				redrawText()
884
			
885
				x = spaces+1
886
				y = y + 1
887
				setCursor( x, y )
888
			else
889
				-- Menu selection
890
				doMenuItem( nMenuItem )
891
			end
892
		elseif param == keys.leftCtrl or param == keys.rightCtrl then
893
			-- Menu toggle
894
			bMenu = not bMenu
895
			if bMenu then
896
				term.setCursorBlink( false )
897
				nMenuItem = 1
898
			else
899
				term.setCursorBlink( true )
900
			end
901
			redrawMenu()
902
		end
903
		
904
	elseif sEvent == "char" then
905
		if not bMenu then
906
			-- Input text
907
			local sLine = tLines[y]
908
			tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x)
909
			redrawLine(y)
910
		
911
			x = x + string.len( param )
912
			setCursor( x, y )
913
		else
914
			-- Select menu items
915
			for n,sMenuItem in ipairs( tMenuItems ) do
916
				if string.lower(string.sub(sMenuItem,1,1)) == string.lower(param) then
917
					doMenuItem( n )
918
					break
919
				end
920
			end
921
		end
922
		
923
	elseif sEvent == "mouse_click" then
924
		if not bMenu then
925
			if param == 1 then
926
				-- Left click
927
				local cx,cy = param2, param3
928
				if cy < h then
929
					y = math.min( math.max( scrollY + cy, 1 ), #tLines )
930
					x = math.min( math.max( scrollX + cx, 1 ), string.len( tLines[y] ) + 1 )
931
					setCursor( x, y )
932
				end
933
			end
934
		end
935
		
936
	elseif sEvent == "mouse_scroll" then
937
		if not bMenu then
938
			if param == -1 then
939
				-- Scroll up
940
				if scrollY > 0 then
941
					-- Move cursor up
942
					scrollY = scrollY - 1
943
					redrawText()
944
				end
945
			
946
			elseif param == 1 then
947
				-- Scroll down
948
				local nMaxScroll = #tLines - (h-1)
949
				if scrollY < nMaxScroll then
950
					-- Move cursor down
951
					scrollY = scrollY + 1
952
					redrawText()
953
				end
954
				
955
			end
956
		end
957
	end
958
end
959
960
-- Cleanup
961
term.clear()
962
term.setCursorBlink( false )
963
term.setCursorPos( 1, 1 )
964
startScreen()
965
end
966
function programs()
967
term.setTextColor(colors.purple)
968
frame()
969
term.setCursorPos(17,1)
970
term.setTextColor(colors.lime)
971
print("[User Programs]")
972
term.setCursorPos(3,1)
973
term.setTextColor(colors.orange)
974
term.write("[Back]")
975
term.setTextColor(colors.white)
976
local programs = shell.programs()
977
term.setCursorPos(3,3)
978
local pTable = textutils.pagedTabulate(programs)
979
term.setCursorPos(3,3)
980
print(pTable)
981
local event, button, xPos, yPos = os.pullEvent("mouse_click")
982
	if button == 1 then
983
		if (xPos >=3 and xPos <=8 and yPos == 1) then
984
			startScreen()
985
		else
986
			programs()
987
		end
988
	else
989
		programs()
990
	end
991
end
992
function reset()
993
term.clear()
994
term.setCursorPos(1,1)
995
end
996
function userInfo()
997
reset()
998
fs.makeDir("/.EnderOS/")
999
user = ("/.EnderOS/.userInfo")
1000
username = io.open(user, "w")
1001
print("Please enter your desired Username")
1002
writeUser = read()
1003
local hash = sha256(writeUser)
1004
writeIsFailUser = username:write(hash..saltHash)
1005
username:close()
1006
pass = ("/.EnderOS/.passInfo")
1007
password = io.open(pass, "w")
1008
print("Please enter your desired Password")
1009
writePass = read("*")
1010
local hash = sha256(writePass)
1011
writeIsFailPass = password:write(hash..saltHash)
1012
password:close()
1013
hint = ("/.EnderOS/.userHint")
1014
uHint = io.open(hint, "w")
1015
print("Please enter your desired Password hint")
1016
writeHint = read()
1017
	if #writeHint >30 then
1018
		print("This Hint exceeds the max hint length of 30!")
1019
		shell.run("delete","/.EnderOS/.userInfo")
1020
		shell.run("delete","/.EnderOS/.passInfo")
1021
		uHint:close()
1022
		sleep(2)
1023
		userInfo()
1024
	else
1025
		writeIsFailHint = uHint:write(writeHint)
1026
		uHint:close()
1027
		local installC = fs.open("/.EnderOS/.EnderOSisInstalled", "w")
1028
		installC:close()
1029
	end
1030
end
1031
function frame()
1032
print("+-------------------------------------------------+")
1033
	for i = 1,17 do
1034
		print("|                                                 |")
1035
	end
1036
term.write("+-------------------------------------------------+")
1037
end
1038
function no()
1039
term.clear()
1040
term.setTextColor(colors.red)
1041
term.setCursorPos(1,1)
1042
print("Sorry, I have not coded this in yet. Please be patient.")
1043
sleep(3)
1044
end
1045
function screen()
1046
reset()
1047
term.setTextColor(colors.lime)
1048
print("+-------------------------------------------------+")
1049
print("|                                                 |")
1050
print("|                 ")
1051
term.setCursorPos(19,3)
1052
term.setTextColor(colors.purple)
1053
write("EnderOS "..version)
1054
term.setTextColor(colors.lime)
1055
term.setCursorPos(31,3)
1056
print("                    |")
1057
print("|                                                 |")
1058
print("|                                                 |")
1059
print("|                                                 |")
1060
print("|                                                 |")
1061
print("|        ")
1062
term.setCursorPos(10,8)
1063
term.setTextColor(colors.orange)
1064
print("Username:")
1065
term.setCursorPos(19,8)
1066
print("                               ")
1067
term.setCursorPos(50,8)
1068
term.setTextColor(colors.lime)
1069
print(" |")
1070
print("|                                                 |")
1071
print("|        ")
1072
term.setTextColor(colors.orange)
1073
term.setCursorPos(10,10)
1074
print("Password:")
1075
term.setCursorPos(19,10)
1076
print("                               ")
1077
term.setCursorPos(50,10)
1078
term.setTextColor(colors.lime)
1079
print(" |")
1080
print("|                                                 |")
1081
print("|                                                 |")
1082
print("|     ")
1083
term.setCursorPos(8,13)
1084
term.setTextColor(colors.blue)
1085
print("forgot password                      ")
1086
term.setCursorPos(50,13)
1087
term.setTextColor(colors.lime)
1088
print(" |")
1089
print("|                                                 |")
1090
print("|                                                 |")
1091
print("|                                                 |")
1092
print("|                                                 |")
1093
print("|                                                 |")
1094
write("+-------------------------------------------------+")
1095
end
1096
function click()
1097
local userHint = io.open("/.EnderOS/.userHint", "r")
1098
hintContents = userHint:read()
1099
userHint:close()
1100
local event, button, xPos, yPos = os.pullEvent("mouse_click")
1101
  if button == 1 then
1102
    if (xPos >=8 and xPos <=22 and yPos == 13) then
1103
      term.setCursorPos(10,15)
1104
	  term.setTextColor(colors.lightGray)
1105
      print("Hint: "..hintContents)
1106
	  term.setTextColor(colors.white)
1107
      click()
1108
    elseif (xPos >=10 and xPos <=18 and yPos == 8) then
1109
      term.setCursorPos(20,8)
1110
    else
1111
      screen()
1112
      click()
1113
    end
1114
  else
1115
    click()
1116
  end
1117
end
1118
function login()
1119
click()
1120
local userFile = io.open("/.EnderOS/.userInfo", "r")
1121
userContents = userFile:read()
1122
userFile:close()
1123
local passFile = io.open("/.EnderOS/.passInfo", "r")
1124
passContents = passFile:read()
1125
passFile:close()
1126
term.setTextColor(colors.white)
1127
local input = read()
1128
local hash = sha256(input)
1129
	if hash..saltHash == userContents then
1130
		term.setCursorPos(8,8)
1131
		term.setTextColor(colors.lime)
1132
		term.write("O")
1133
		term.setTextColor(colors.white)
1134
		term.setCursorPos(20,10)
1135
		local input = read("*")
1136
		local hash = sha256(input)
1137
		if hash..saltHash == passContents then
1138
			term.setCursorPos(8,10)
1139
			term.setTextColor(colors.lime)
1140
			term.write("O")
1141
			term.setTextColor(colors.white)
1142
			sleep(0.8)
1143
			term.clear()
1144
			term.setCursorPos(19,9)
1145
			x,y = term.getCursorPos()
1146
			print("Logging in")
1147
			term.setCursorPos(x+10,9)
1148
			sleep(0.7)
1149
			print(".")
1150
			sleep(0.7)
1151
			term.setCursorPos(x+11,9)
1152
			print(".")
1153
			sleep(0.7)
1154
			term.setCursorPos(x+12,9)
1155
			print(".")
1156
			sleep(0.7)
1157
			reset()
1158
			startScreen()
1159
		else
1160
			term.setCursorPos(8,10)
1161
			term.setTextColor(colors.red)
1162
			term.write("X")
1163
			sleep(0.5)
1164
			term.setTextColor(colors.white)
1165
			screen()
1166
			login()
1167
		end
1168
	else
1169
		term.setCursorPos(8,8)
1170
		term.setTextColor(colors.red)
1171
		term.write("X")
1172
		sleep(0.5)
1173
		term.setTextColor(colors.white)
1174
		screen()
1175
		login()
1176
	end
1177
end
1178
function settings()
1179
term.setTextColor(colors.purple)
1180
frame()
1181
term.setCursorPos(17,1)
1182
term.setTextColor(colors.lime)
1183
print("[EnderOS Settings]")
1184
term.setCursorPos(7,3)
1185
print("{Change Username}   {Change Password}")
1186
term.setCursorPos(15,5)
1187
print("{Change Password Hint}")
1188
term.setCursorPos(3,1)
1189
term.setTextColor(colors.orange)
1190
term.write("[Back]")
1191
term.setTextColor(colors.white)
1192
local event, button, xPos, yPos = os.pullEvent("mouse_click")
1193
  if button == 1 then
1194
    if (xPos >=7 and xPos <=23 and yPos == 3) then
1195
      settingsChangeUser()
1196
    elseif (xPos >=27 and xPos <=43 and yPos == 3) then
1197
      settingsChangePass()
1198
    elseif (xPos >=15 and xPos <=36 and yPos == 5) then
1199
		settingsChangeHint()
1200
	elseif (xPos >=3 and xPos <=9 and yPos == 1) then
1201
		startScreen()
1202
    else
1203
		settings()
1204
	end
1205
  else
1206
    settings()
1207
  end
1208
end
1209
function games()
1210
term.setTextColor(colors.purple)
1211
frame()
1212
term.setCursorPos(18,1)
1213
term.setTextColor(colors.lime)
1214
print("[EnderOS Games]")
1215
term.setCursorPos(3,3)
1216
print("{SkullPong}")
1217
term.setCursorPos(3,1)
1218
term.setTextColor(colors.orange)
1219
term.write("[Back]")
1220
local event, button, xPos, yPos = os.pullEvent("mouse_click")
1221
	if button == 1 then
1222
		if (xPos >=3 and xPos <=13 and yPos == 3) then
1223
			SkullPong()
1224
		elseif (xPos >=3 and xPos <=9 and yPos == 1) then
1225
			startScreen()
1226
		else
1227
			games()
1228
		end
1229
	else
1230
		games()
1231
	end
1232
end
1233
function startScreen()
1234
reset()
1235
term.setTextColor(colors.purple)
1236
frame()
1237
term.setCursorPos(3,19)
1238
term.setTextColor(colors.orange)
1239
term.write("[Log Out]")
1240
term.setCursorPos(17,1)
1241
term.setTextColor(colors.lime)
1242
print("[EnderOS Commands]")
1243
term.setCursorPos(3,3)
1244
print("{Settings}   {Games}   {Edit}   {Programs}")
1245
term.setCursorPos(3,5)
1246
print("{Exit}")
1247
local event, button, xPos, yPos = os.pullEvent("mouse_click")
1248
	if button == 1 then
1249
		if (xPos >=3 and xPos <=12 and yPos == 3) then --SETTINGS
1250
			settings()
1251
		elseif (xPos >=16 and xPos <=22 and yPos == 3) then --GAMES
1252
			games()
1253
		elseif (xPos >=26 and xPos <=31 and yPos == 3) then --EDIT
1254
			Edit()
1255
		elseif (xPos >=35 and xPos <=44 and yPos == 3) then
1256
			programs()
1257
		elseif (xPos >=3 and xPos <=8 and yPos  == 5) then --EXIT
1258
			reset()
1259
		elseif (xPos >=3 and xPos <=11 and yPos == 19) then --LOG OFF
1260
			reset()
1261
			screen()
1262
			login()
1263
		else
1264
			startScreen()
1265
		end
1266
	else
1267
		startScreen()
1268
	end
1269
end
1270
function SkullPong()
1271
--Code By SkullBlade(Skullblade213)
1272
--You are allowed to modify and redistribute
1273
--You are not allowed to modify this header
1274
function Draw()
1275
	term.setBackgroundColor(counter)
1276
	term.clear()
1277
	term.setBackgroundColor(colors.white)
1278
	term.setCursorPos(Ball[1], Ball[2])
1279
	print(" ")
1280
	term.setBackgroundColor(colors.lime)
1281
	term.setCursorPos(You[1], You[2])
1282
	print(" ")
1283
	term.setCursorPos(You[1], You[3])
1284
	print(" ")
1285
	term.setCursorPos(You[1], You[4])
1286
	print(" ")
1287
	term.setBackgroundColor(colors.red)
1288
	term.setCursorPos(Op[1], Op[2])
1289
	print(" ")
1290
	term.setCursorPos(Op[1], Op[3])
1291
	print(" ")
1292
	term.setCursorPos(Op[1], Op[4])
1293
	print(" ")
1294
end
1295
function Update()
1296
	Ball={Ball[1]+Ball[3],Ball[2]+Ball[4],Ball[3],Ball[4]}
1297
	if Ball[1]==3 or Ball[1]==49 then
1298
		if Ball[1]==3 then
1299
			Check="L"
1300
		end
1301
		if Ball[1]==49 then
1302
			Check="R"
1303
		end
1304
		if (Ball[2]==You[2] and Check=="L") or (Ball[2]==Op[2] and Check=="R") then
1305
			Ball[3]=Ball[3]*-1
1306
			Ball[4]=-1
1307
			rans=math.random(1,5)
1308
		end
1309
		if (Ball[2]==You[3] and Check=="L") or (Ball[2]==Op[3] and Check=="R") then
1310
			Ball[3]=Ball[3]*-1
1311
			Ball[4]=Ball[4]*-1
1312
		end
1313
		if (Ball[2]==You[4] and Check=="L") or (Ball[2]==Op[4] and Check=="R") then
1314
			Ball[3]=Ball[3]*-1
1315
			Ball[4]=1
1316
		end
1317
	end
1318
	if Ball[2]==1 or Ball[2]==18 or Ball[2]==0 or Ball[2]==19 then
1319
		Ball[4]=Ball[4]*-1
1320
	end
1321
	if Ball[1]==1 then
1322
		score2=score2+1
1323
		Start()
1324
	end
1325
	if Ball[1]==51 then
1326
		score=score+1
1327
		Start()
1328
	end
1329
end
1330
function Move()
1331
	if key==200 then
1332
		You[2]=You[2]-1
1333
	end
1334
	if key==208 then
1335
		You[2]=You[2]+1
1336
	end
1337
end
1338
function AI()
1339
	if Ball[2]+Ball[4]>Op[2]+2 then
1340
		if Op[2]+3~=19 then
1341
			Op={Op[1],Op[2]+1,Op[2]+2,Op[2]+3}
1342
		end
1343
	end
1344
	if Ball[2]+Ball[4]<Op[2] then
1345
		if Op[2]-1~=0 then
1346
			Op={Op[1],Op[2]-1,Op[2],Op[2]+1}
1347
		end
1348
	end
1349
end
1350
function Start()
1351
	You={2,9,10,11}
1352
	Op={50,9,10,11}
1353
	ran=math.random(-1,1)
1354
	ran2=math.random(-1,1)
1355
	while ran==0 do
1356
		ran=math.random(-1,1)
1357
	end
1358
	while ran2==0 do
1359
		ran2=math.random(-1,1)
1360
	end
1361
	Ball={25,10,ran,ran2}
1362
	term.setCursorPos(20,10)
1363
	print(score.."   VS   "..score2)
1364
	if vars=="surv" and score2==1 then
1365
		ends="true"
1366
	end
1367
	sleep(1)
1368
end
1369
function Single(v)
1370
	vars=v
1371
	ends="false"
1372
	score=0
1373
	score2=0
1374
	if resume~="true" then
1375
		Start()
1376
	end
1377
	counter=1
1378
	breaks="false"
1379
	while true do
1380
		if vars=="surv" then
1381
			counter=counter*2
1382
			if counter==32 or counter==16384 then
1383
				counter=counter*2
1384
			end
1385
			if counter==32768 then
1386
				counter=2
1387
			end
1388
			term.setBackgroundColor(counter)
1389
		end
1390
		if vars~="surv" then
1391
			counter=32768
1392
		end
1393
		Draw()
1394
		os.startTimer(.1)
1395
		while true do
1396
			event, key = os.pullEvent()
1397
			if event=="key" then
1398
				if vars~="Local" then
1399
					Move()
1400
				end
1401
				if key==59 and (vars=="surv" or vars=="norm" or vars=="Local") then
1402
					Menu("Paused","Resume","Info/Help","Quit")
1403
					breaks="true"
1404
					break
1405
				end
1406
				if vars=="Local" then
1407
					if key==17 then
1408
						You[2]=You[2]-1
1409
					end
1410
					if key==31 then
1411
						You[2]=You[2]+1
1412
					end
1413
					if key==200 then
1414
						Op[2]=Op[2]-1
1415
					end
1416
					if key==208 then
1417
						Op[2]=Op[2]+1
1418
					end
1419
					if You[2]==0 then
1420
						You[2]=1
1421
					end
1422
					if You[2]==17 then
1423
						You[2]=16
1424
					end
1425
					if Op[2]==0 then
1426
						Op[2]=1
1427
					end
1428
					if Op[2]==17 then
1429
						Op[2]=16
1430
					end
1431
					You={You[1],You[2],You[2]+1,You[2]+2}
1432
					Op={Op[1],Op[2],Op[2]+1,Op[2]+2}
1433
				end
1434
				if You[2]==0 then
1435
					You[2]=1
1436
				end
1437
				if You[2]==17 then
1438
					You[2]=16
1439
				end
1440
				You={You[1],You[2],You[2]+1,You[2]+2}
1441
			end
1442
			if event=="timer" then
1443
				break
1444
			end
1445
		end
1446
		if breaks=="true" then
1447
			break
1448
		end
1449
		if vars~="Local" then
1450
			AI()
1451
		end
1452
		Update()
1453
		if ends=="true" then
1454
			ends="false"
1455
			Menu("SinglePlayer","Normal","Survival","Back")
1456
			break
1457
		end
1458
	end
1459
end
1460
function Set(x1,y1)
1461
	x=x1
1462
	y=y1
1463
	term.setCursorPos(x1,y1)
1464
end
1465
function PrintCenter(text)
1466
	textLen=string.len(text)
1467
    x = ((51-textLen)/2)
1468
    term.setCursorPos(x,y)
1469
    print(text)
1470
	y=y+1
1471
end
1472
function Menu(title,opt1,opt2,opt3)
1473
	resume="false"
1474
	term.setBackgroundColor(colors.black)
1475
	select=1
1476
	while true do
1477
	term.clear()
1478
	term.setCursorPos(1,1)
1479
	term.setTextColor(colors.lime)
1480
	print("SkullPong V1.10")
1481
	Set(1,6)
1482
	PrintCenter(title)
1483
	PrintCenter("------------")
1484
	term.setTextColor(colors.white)
1485
	PrintCenter(opt1)
1486
	PrintCenter(opt2)
1487
	PrintCenter(opt3)
1488
		if select==1 then
1489
			Set(1,8)
1490
			term.setTextColor(colors.blue)
1491
			PrintCenter(opt1)
1492
			term.setTextColor(colors.white)
1493
		end
1494
		if select==2 then
1495
			Set(1,9)
1496
			term.setTextColor(colors.blue)
1497
			PrintCenter(opt2)
1498
			term.setTextColor(colors.white)
1499
		end
1500
		if select==3 then
1501
			Set(1,10)
1502
			term.setTextColor(colors.blue)
1503
			PrintCenter(opt3)
1504
			term.setTextColor(colors.white)
1505
		end
1506
		event, param1, param2, param3 = os.pullEvent()
1507
		if event=="mouse_click" then
1508
			if param3==8 or param3==9 or param3==10 then
1509
				sel=select
1510
				if param3==8 then
1511
					text=opt1
1512
					select=1
1513
				end
1514
				if param3==9 then
1515
					text=opt2
1516
					select=2
1517
				end
1518
				if param3==10 then
1519
					text=opt3
1520
					select=3
1521
				end
1522
				strLen=string.len(text)
1523
				start=(51-strLen)/2-1
1524
				if param2>start and param2<start+strLen then
1525
					if select==1 then
1526
					if opt1=="SinglePlayer" then
1527
						Menu("SinglePlayer","Normal","Survival","Back")
1528
						break
1529
					end
1530
					if opt1=="Normal" then
1531
						Single("norm")
1532
						break
1533
					end
1534
					if opt1=="Resume" then
1535
						resume="true"
1536
						Single(vars)
1537
						break
1538
					end
1539
					if opt1=="Local" then
1540
						Single("Local")
1541
						break
1542
					end
1543
				end
1544
				if select==2 then
1545
					if opt1=="SinglePlayer" then
1546
						Menu("MultiPlayer","Local","Rednet","Back")
1547
						break
1548
					end
1549
					if opt1=="Normal" then
1550
						Single("surv")
1551
						break
1552
					end
1553
					if opt1=="Resume" then
1554
						if vars~="Local" then
1555
							term.clear()
1556
							term.setTextColor(colors.lime)
1557
							term.setBackgroundColor(colors.black)
1558
							term.setCursorPos(1,1)
1559
							
1560
							print("SkullPong V1.10")
1561
							print("Help")
1562
							print("---------------")
1563
							term.setTextColor(colors.white)
1564
							print("")
1565
							print("Controls")
1566
							print("UpArrow: Paddle Up")
1567
							print("DownArrow: Paddle Down")
1568
							print("Objective")
1569
							print("Don't let the ball get pass the green paddle{You}")
1570
							print("Get the ball pass the red paddle{AI}")
1571
							print("")
1572
							print("Press any key to continue")
1573
							os.pullEvent("key")
1574
						end
1575
						if vars=="Local" then
1576
							term.clear()
1577
							term.setTextColor(colors.lime)
1578
							term.setBackgroundColor(colors.black)
1579
							term.setCursorPos(1,1)
1580
							print("SkullPong V1.10")
1581
							print("Help")
1582
							print("---------------")
1583
							term.setTextColor(colors.white)
1584
							print("")
1585
							print("Controls")
1586
							print("UpArrow: Paddle Up-Red")
1587
							print("DownArrow: Paddle Down-Red")
1588
							print("W: Paddle Up-Green")
1589
							print("A: Paddle Down-Green")
1590
							print("Objective")
1591
							print("Don't let the ball get pass the your paddle")
1592
							print("Get the ball pass your opponent's paddle")
1593
							print("")
1594
							print("Press any key to continue")
1595
							os.pullEvent("key")
1596
						end
1597
					end
1598
					if opt1=="Local" then
1599
						error("Not Implimented!")
1600
					end
1601
				end
1602
				if select==3 then
1603
					if opt1=="SinglePlayer" then
1604
						term.clear()
1605
						term.setCursorPos(1,1)
1606
						break
1607
					else
1608
						Menu("Start","SinglePlayer","MultiPlayer","Quit")
1609
						break
1610
					end
1611
				end
1612
				else
1613
					select=sel
1614
				end
1615
			end
1616
		end
1617
		if event=="key" then
1618
			if param1==200 then
1619
				select=select-1
1620
			end
1621
			if param1==208 then
1622
				select=select+1
1623
			end
1624
			if param1==28 then
1625
				if select==1 then
1626
					if opt1=="SinglePlayer" then
1627
						Menu("SinglePlayer","Normal","Survival","Back")
1628
						break
1629
					end
1630
					if opt1=="Normal" then
1631
						Single("norm")
1632
						break
1633
					end
1634
					if opt1=="Resume" then
1635
						resume="true"
1636
						Single(vars)
1637
						break
1638
					end
1639
					if opt1=="Local" then
1640
						Single("Local")
1641
						break
1642
					end
1643
				end
1644
				if select==2 then
1645
					if opt1=="SinglePlayer" then
1646
						Menu("MultiPlayer","Local","Rednet","Back")
1647
						break
1648
					end
1649
					if opt1=="Normal" then
1650
						Single("surv")
1651
						break
1652
					end
1653
					if opt1=="Resume" then
1654
						if vars~="Local" then
1655
							term.clear()
1656
							term.setTextColor(colors.lime)
1657
							term.setBackgroundColor(colors.black)
1658
							term.setCursorPos(1,1)
1659
							
1660
							print("SkullPong V1.10")
1661
							print("Help")
1662
							print("---------------")
1663
							term.setTextColor(colors.white)
1664
							print("")
1665
							print("Controls")
1666
							print("UpArrow: Paddle Up")
1667
							print("DownArrow: Paddle Down")
1668
							print("Objective")
1669
							print("Don't let the ball get pass the green paddle{You}")
1670
							print("Get the ball pass the red paddle{AI}")
1671
							print("")
1672
							print("Press any key to continue")
1673
							os.pullEvent("key")
1674
						end
1675
						if vars=="Local" then
1676
							term.clear()
1677
							term.setTextColor(colors.lime)
1678
							term.setBackgroundColor(colors.black)
1679
							term.setCursorPos(1,1)
1680
							print("SkullPong V1.10")
1681
							print("Help")
1682
							print("---------------")
1683
							term.setTextColor(colors.white)
1684
							print("")
1685
							print("Controls")
1686
							print("UpArrow: Paddle Up-Red")
1687
							print("DownArrow: Paddle Down-Red")
1688
							print("W: Paddle Up-Green")
1689
							print("A: Paddle Down-Green")
1690
							print("Objective")
1691
							print("Don't let the ball get pass the your paddle")
1692
							print("Get the ball pass your opponent's paddle")
1693
							print("")
1694
							print("Press any key to continue")
1695
							os.pullEvent("key")
1696
						end
1697
					end
1698
					if opt1=="Local" then
1699
						error("Not Implimented!")
1700
					end
1701
				end
1702
				if select==3 then
1703
					if opt1=="SinglePlayer" then
1704
						term.clear()
1705
						term.setCursorPos(1,1)
1706
						break
1707
					else
1708
						Menu("Start","SinglePlayer","MultiPlayer","Quit")
1709
						break
1710
					end
1711
				end
1712
			end
1713
			if select==0 then
1714
				select=3
1715
			end
1716
			if select==4 then
1717
				select=1
1718
			end
1719
		end
1720
	end
1721
end
1722
Menu("Start","SinglePlayer","MultiPlayer","Quit")
1723
games()
1724
end
1725
 
1726
 --EnderOS
1727
if not term.isColor() then
1728
  term.clear()
1729
  term.setCursorPos(1,1)
1730
  print("EnderOS does not support non-color computers!")
1731
  sleep(3)
1732
  os.shutdown()
1733
end
1734
if shell.getRunningProgram() ~= "startup" then	
1735
	term.clear()
1736
	term.setCursorPos(1,1)
1737
	print("It is recommended that this file is named startup!")
1738
	sleep(5)
1739
end
1740
if not fs.exists("/.EnderOS/.EnderOSisInstalled") then
1741
  userInfo()
1742
end
1743
reset()
1744
term.setTextColor(colors.purple)
1745
term.setCursorPos(13,7)
1746
print("EnderOS "..version.." Initializing")
1747
term.setTextColor(colors.white)
1748
term.setBackgroundColor(colors.lime)
1749
for i = 14,36 do
1750
  term.setCursorPos(i,9)
1751
  term.write(" ")
1752
  sleep(0.3)
1753
end
1754
term.setBackgroundColor(colors.black)
1755
sleep(0.5)
1756
screen()
1757
login()
1758
startScreen()