SHOW:
|
|
- or go back to the newest paste.
1 | --[[ | |
2 | Sinelock v1.3 | |
3 | The *COOLEST* computer/door lock ever! | |
4 | Now with slightly less seizure! | |
5 | ||
6 | - | pastebin get XDgeSDTq sinelock |
6 | + | pastebin get my79ZLZb slb |
7 | - | std pb XDgeSDTq sinelock |
7 | + | std pb my79ZLZb slb |
8 | std ld sinelock sinelock | |
9 | ||
10 | Now with salting! | |
11 | --]] | |
12 | local scr_x, scr_y = term.getSize() --Gets screen size. Don't modify this | |
13 | ||
14 | --Config variables start! | |
15 | local terminateMode = 2 --0 enables termination, 1 blocks it, 2 provides a taunting screen. | |
16 | local passFile = ".sl_password" --The ABSOLUTE path of the password file. | |
17 | local saltFile = ".sl_salt" --The ABSOLUTE path of the salt file. | |
18 | local characterLimit = 1024 --The cap of characters at the read() prompt. Set this to prevent crashes. | |
19 | local runProgram = "" --Set to something to run it when correct, and not using doors. | |
20 | local dahChar = "*" --The character used to hide characters when typed. | |
21 | local doKeyCards = true --Whether or not the lock also accepts keycards (floppy disks) as well as passwords. | |
22 | - | local doEjectDisk = false --Whether or not to eject a keycard after it's accepted, just to speed things up a bit. |
22 | + | local doEjectDisk = true --Whether or not to eject a keycard after it's accepted, just to speed things up a bit. |
23 | local doorSides = {} --If it has anything, the lock will open the doors instead of unlocking the PC. | |
24 | local doInvertSignal = false --If true, it will invert the redstone signal of the door, in case you need to. | |
25 | local doShowDoorSides = true --If true, will show the door sides being opened. Set to false if you are paranoid. | |
26 | local beWavey = true --Whether or not to animate the sine wave. | |
27 | local readYpos = scr_y-2 --The Y position of the read() prompt | |
28 | local requireAllPasswords = false --Whether or not the lock asks for ONE of the multiple passwords, or ALL of them in order. | |
29 | local badlength = 4 --The length in seconds that you have to wait to try again. | |
30 | local goodlength = 6 --The length in seconds that doors will stay open. | |
31 | local sineFrameDelay = 0.15 --The amount of time between sine animation frames. Tradeoff of purty vs performance. | |
32 | local palate = { | |
33 | frontsine = colors.lightGray, | |
34 | backsine = colors.gray, | |
35 | background = colors.black, | |
36 | rainColor = colors.gray, | |
37 | rainChar = "|", | |
38 | promptBG = colors.gray, | |
39 | promptTXT = colors.white, | |
40 | wrongBG = colors.black, | |
41 | wrongTXT = colors.gray, | |
42 | } | |
43 | local language = "english" | |
44 | local lang = { | |
45 | english = { | |
46 | wrong1 = "YOU ARE WRONG.", | |
47 | wrong2 = "YOU ARE WRONG. AS ALWAYS.", | |
48 | right1 = "Correct!", | |
49 | right2 = "Correct, finally!", | |
50 | }, | |
51 | spanish = { | |
52 | wrong1 = "ESTA USTED EQUIVOCADO.", | |
53 | wrong2 = "ESTA USTED EQUIVOCADO. TODAVIA OTRA VEZ.", | |
54 | right1 = "Correcto!", | |
55 | right2 = "Asi es, por fin!", | |
56 | noTerminate = "No termine!", | |
57 | }, | |
58 | german = { | |
59 | wrong1 = "SIE LIEGEN FALSCH.", | |
60 | wrong2 = "SIE LIEGEN FALSCH. WIE IMMER.", | |
61 | right1 = "Richtig!", | |
62 | right2 = "Richtig, endlich!", | |
63 | noTerminate = "Nicht zu beenden!", | |
64 | }, | |
65 | dutch = { | |
66 | wrong1 = "U BENT ONJUIST.", | |
67 | wrong2 = "JE BENT ONJUIST, ALS ALTIJD.", | |
68 | right1 = "Dat is juist!", | |
69 | right2 = "Dat is juist, eindelijk!", | |
70 | noTerminate = "Niet te beeindigen!", | |
71 | }, | |
72 | latin = { --As a joke | |
73 | wrong1 = "ERRAS", | |
74 | wrong2 = "TU DEFICIENTES!", | |
75 | right1 = "Quod suus 'verum!", | |
76 | right2 = "Quod suus 'verum, demum!", | |
77 | noTerminate = "Vade futuo te ipsum!", | |
78 | }, | |
79 | italian = { | |
80 | wrong1 = "HAI SBAGLIATO.", | |
81 | wrong2 = "HAI SBAGLIATO, COME SEMPRE D'ALTRONDE.", | |
82 | right1 = "CORRETTO!", | |
83 | right2 = "CORRETTO, FINALMENTE!", | |
84 | noTerminate = "Non cercare di terminarmi", | |
85 | }, | |
86 | } | |
87 | ||
88 | -- Config variables end. Don't touch anything else, m'kay? | |
89 | if not _VERSION then | |
90 | return printError("Sorry, only CC 1.7 and later supported.") | |
91 | end | |
92 | local csv, salt, doSine | |
93 | local floor, ceil, random, abs = math.floor, math.ceil, math.random, math.abs | |
94 | local sin, cos = math.sin, math.cos | |
95 | local rhite = term.write | |
96 | local setTextColor, setBackgroundColor, getTextColor, getBackgroundColor = term.setTextColor, term.setBackgroundColor, term.getTextColor, term.getBackgroundColor | |
97 | local setCursorPos, setCursorBlink, getCursorPos, getSize = term.setCursorPos, term.setCursorBlink, term.getCursorPos, term.getSize | |
98 | local sineLevel = 1 | |
99 | local isTerminable = false | |
100 | local kaykaycoolcool = true | |
101 | if term.current().setVisible then | |
102 | csv = true | |
103 | else | |
104 | csv = false | |
105 | end | |
106 | ||
107 | local writeError = function(...) | |
108 | local tx,bg = getTextColor(),getBackgroundColor() | |
109 | if term.isColor() then | |
110 | setTextColor(colors.red) | |
111 | else | |
112 | setTextColor(colors.white) | |
113 | end | |
114 | rhite(table.concat(arg," ")) | |
115 | setTextColor(tx) | |
116 | setBackgroundColor(bg) | |
117 | end | |
118 | ||
119 | local goodPullEvent | |
120 | if terminateMode == 1 then | |
121 | if os.pullEvent ~= os.pullEventRaw then | |
122 | goodPullEvent = os.pullEvent | |
123 | end | |
124 | os.pullEvent = os.pullEventRaw | |
125 | end | |
126 | ||
127 | local keepLooping = true | |
128 | ||
129 | ---- SHA256 START ---- | |
130 | --SHA256 implementation done by GravityScore. | |
131 | ||
132 | local MOD = 2^32 | |
133 | local MODM = MOD-1 | |
134 | ||
135 | local function memoize(f) | |
136 | local mt = {} | |
137 | local t = setmetatable({}, mt) | |
138 | function mt:__index(k) | |
139 | local v = f(k) | |
140 | t[k] = v | |
141 | return v | |
142 | end | |
143 | return t | |
144 | end | |
145 | ||
146 | local function make_bitop_uncached(t, m) | |
147 | local function bitop(a, b) | |
148 | local res,p = 0,1 | |
149 | while a ~= 0 and b ~= 0 do | |
150 | local am, bm = a % m, b % m | |
151 | res = res + t[am][bm] * p | |
152 | a = (a - am) / m | |
153 | b = (b - bm) / m | |
154 | p = p*m | |
155 | end | |
156 | res = res + (a + b) * p | |
157 | return res | |
158 | end | |
159 | return bitop | |
160 | end | |
161 | ||
162 | local function make_bitop(t) | |
163 | local op1 = make_bitop_uncached(t,2^1) | |
164 | local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end) | |
165 | return make_bitop_uncached(op2, 2 ^ (t.n or 1)) | |
166 | end | |
167 | ||
168 | local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4}) | |
169 | ||
170 | local function bxor(a, b, c, ...) | |
171 | local z = nil | |
172 | if b then | |
173 | a = a % MOD | |
174 | b = b % MOD | |
175 | z = bxor1(a, b) | |
176 | if c then z = bxor(z, c, ...) end | |
177 | return z | |
178 | elseif a then return a % MOD | |
179 | else return 0 end | |
180 | end | |
181 | ||
182 | local function band(a, b, c, ...) | |
183 | local z | |
184 | if b then | |
185 | a = a % MOD | |
186 | b = b % MOD | |
187 | z = ((a + b) - bxor1(a,b)) / 2 | |
188 | if c then z = bit32_band(z, c, ...) end | |
189 | return z | |
190 | elseif a then return a % MOD | |
191 | else return MODM end | |
192 | end | |
193 | ||
194 | local function bnot(x) return (-1 - x) % MOD end | |
195 | ||
196 | local function rshift1(a, disp) | |
197 | if disp < 0 then return lshift(a,-disp) end | |
198 | return floor(a % 2 ^ 32 / 2 ^ disp) | |
199 | end | |
200 | ||
201 | local function rshift(x, disp) | |
202 | if disp > 31 or disp < -31 then return 0 end | |
203 | return rshift1(x % MOD, disp) | |
204 | end | |
205 | ||
206 | local function lshift(a, disp) | |
207 | if disp < 0 then return rshift(a,-disp) end | |
208 | return (a * 2 ^ disp) % 2 ^ 32 | |
209 | end | |
210 | ||
211 | local function rrotate(x, disp) | |
212 | x = x % MOD | |
213 | disp = disp % 32 | |
214 | local low = band(x, 2 ^ disp - 1) | |
215 | return rshift(x, disp) + lshift(low, 32 - disp) | |
216 | end | |
217 | ||
218 | local k = { | |
219 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | |
220 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | |
221 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | |
222 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | |
223 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | |
224 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | |
225 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | |
226 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | |
227 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | |
228 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | |
229 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | |
230 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | |
231 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | |
232 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | |
233 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | |
234 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, | |
235 | } | |
236 | ||
237 | local function str2hexa(s) | |
238 | return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end)) | |
239 | end | |
240 | ||
241 | local function num2s(l, n) | |
242 | local s = "" | |
243 | for i = 1, n do | |
244 | local rem = l % 256 | |
245 | s = string.char(rem) .. s | |
246 | l = (l - rem) / 256 | |
247 | end | |
248 | return s | |
249 | end | |
250 | ||
251 | local function s232num(s, i) | |
252 | local n = 0 | |
253 | for i = i, i + 3 do n = n*256 + string.byte(s, i) end | |
254 | return n | |
255 | end | |
256 | ||
257 | local function preproc(msg, len) | |
258 | local extra = 64 - ((len + 9) % 64) | |
259 | len = num2s(8 * len, 8) | |
260 | msg = msg .. "\128" .. string.rep("\0", extra) .. len | |
261 | assert(#msg % 64 == 0) | |
262 | return msg | |
263 | end | |
264 | ||
265 | local function initH256(H) | |
266 | H[1] = 0x6a09e667 | |
267 | H[2] = 0xbb67ae85 | |
268 | H[3] = 0x3c6ef372 | |
269 | H[4] = 0xa54ff53a | |
270 | H[5] = 0x510e527f | |
271 | H[6] = 0x9b05688c | |
272 | H[7] = 0x1f83d9ab | |
273 | H[8] = 0x5be0cd19 | |
274 | return H | |
275 | end | |
276 | ||
277 | local function digestblock(msg, i, H) | |
278 | local w = {} | |
279 | for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end | |
280 | for j = 17, 64 do | |
281 | local v = w[j - 15] | |
282 | local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3)) | |
283 | v = w[j - 2] | |
284 | w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10)) | |
285 | end | |
286 | ||
287 | 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] | |
288 | for i = 1, 64 do | |
289 | local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22)) | |
290 | local maj = bxor(band(a, b), band(a, c), band(b, c)) | |
291 | local t2 = s0 + maj | |
292 | local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25)) | |
293 | local ch = bxor (band(e, f), band(bnot(e), g)) | |
294 | local t1 = h + s1 + ch + k[i] + w[i] | |
295 | h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2 | |
296 | end | |
297 | ||
298 | H[1] = band(H[1] + a) | |
299 | H[2] = band(H[2] + b) | |
300 | H[3] = band(H[3] + c) | |
301 | H[4] = band(H[4] + d) | |
302 | H[5] = band(H[5] + e) | |
303 | H[6] = band(H[6] + f) | |
304 | H[7] = band(H[7] + g) | |
305 | H[8] = band(H[8] + h) | |
306 | end | |
307 | ||
308 | local function sha256(...) | |
309 | local msg = table.concat(arg,",") | |
310 | msg = preproc(msg, #msg) | |
311 | local H = initH256({}) | |
312 | for i = 1, #msg, 64 do digestblock(msg, i, H) end | |
313 | return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) .. | |
314 | num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4)) | |
315 | end | |
316 | ||
317 | ---- SHA256 END ---- | |
318 | ||
319 | local terminates = 0 | |
320 | local sillyTerminate = function() | |
321 | local goodpull = _G.os.pullEvent | |
322 | os.pullEvent = os.pullEventRaw | |
323 | terminates = terminates + 1 | |
324 | local script = { | |
325 | "You shall not pass!", | |
326 | "THOU shalt not pass!", | |
327 | "Stop trying to pass!", | |
328 | "...maybe I'm not clear.", | |
329 | "YOU. SHALL NOT. PASS!!", | |
330 | "Pass thou shalt not!", | |
331 | "Hey, piss off, will ya?", | |
332 | "I haven't got all day.", | |
333 | "...no, shut up. I don't.", | |
334 | "I won't tell you it!", | |
335 | "No password for you.", | |
336 | "It's been hashed!", | |
337 | "Hashed...with a salt!", | |
338 | "I'll never tell you the salt.", | |
339 | "You know why?", | |
340 | "Because that requires passing!", | |
341 | "WHICH THOU SHALT NOT DO!", | |
342 | "(oh btw don't pass k?)", | |
343 | "You! Don't pass!", | |
344 | "That means YOU!", | |
345 | "Cut it out!", | |
346 | "Re: Cut it out!", | |
347 | "Perhaps if you keep it up...", | |
348 | "..hmm...", | |
349 | "..oh I give up.", | |
350 | "<bullshitterm>", | |
351 | "What? Is this what you wanted?", | |
352 | "Huh? No? I-it's not?", | |
353 | "Well then...!", | |
354 | "<toobad>", | |
355 | "YEAH I SAID IT", | |
356 | "You think you're a terminating machine!", | |
357 | "You think you're above consequence!", | |
358 | "...w-...", | |
359 | "eat my shorts", | |
360 | "Your attempts are futile anyhow.", | |
361 | "Here I am getting drunk off your sweat,", | |
362 | "...while you push CTRL and T.", | |
363 | "Or maybe you're pressing that [T] button.", | |
364 | "Like, um, in CCEmuRedux.", | |
365 | "But it matters not!", | |
366 | "For you see, my defences are great!", | |
367 | "Nothing can bust my rock-hard abs!", | |
368 | "<fuckinghell>", | |
369 | "Oh bualls.", | |
370 | "That was embarrasing.", | |
371 | "...?", | |
372 | "What're YOU lookin' at??", | |
373 | "You callin' me UNSTABLE!?", | |
374 | "HUH!??", | |
375 | "...", | |
376 | "...w-well at least I admit it", | |
377 | "...b-bakka", | |
378 | ".......", | |
379 | "Hey, have you ever played EarthBound?", | |
380 | "(Yes. I'm gonna rant.)", | |
381 | "It's an RPG on the Super Nintendo.", | |
382 | "Like, instead of fighting fantasy demons,", | |
383 | "you fight stop signs and cars and shit", | |
384 | "And, like, you hit rabid dogs with a bat", | |
385 | "And you have magical PSI spells", | |
386 | "...speaking of PSI, I happen to use it a lot.", | |
387 | "...er, *I* as in the coder of this lock...", | |
388 | "And by PSI, I mean the mod.", | |
389 | "You don't see too many psychic locks these days.", | |
390 | "A shame, really.", | |
391 | "I bet a PSI lock could act as a heater with PSI Fire.", | |
392 | "Or maybe it can kill rats with PSI Ground or Thunder", | |
393 | "Maybe, you can get a psychic KEY lock, so, like,", | |
394 | "you could put it on that Psychonauts head door thing.", | |
395 | "...WHAT!? just a suggestion.", | |
396 | "Psychonauts is another game I reccommend.", | |
397 | "It has some really clever dialogue.", | |
398 | "I'm sure you'd like it quite a lot.", | |
399 | "I know, because you've been here for ten fucking minutes.", | |
400 | "And you're not ONE STEP closer to getting the password", | |
401 | "Which I've been guarding very, very closely.", | |
402 | "Yes. Extremely closely.", | |
403 | "Excrutiatingly, some would say.", | |
404 | "You know, I should probably get to shouting.", | |
405 | "*ahem*", | |
406 | "...", | |
407 | "*aahhhechhemmemmhmm*", | |
408 | "*aachkskacehchachkhackcoughfartfuckdammitaaucahkh*", | |
409 | "...", | |
410 | "STAHP IT", | |
411 | "STAHP TEHRMINATIN", | |
412 | "do it for the CHILDREN", | |
413 | "okay fuck the children, who needs 'em", | |
414 | "then", | |
415 | "um", | |
416 | "THINK OF THE...THE...", | |
417 | "the babies...?", | |
418 | "um", | |
419 | "<abuseofcommunity>", | |
420 | "That's a fucking horrible idea.", | |
421 | "I'd rather eat my own brain then think about that.", | |
422 | "I'd sooner kiss a pig!", | |
423 | "I'd sooner swallow an avocado pit!", | |
424 | "...", | |
425 | "You know, you suck so much.", | |
426 | "You suck so much, and I'm sick of writing this script", | |
427 | "If my knuckles bleed, you're paying my insurance", | |
428 | "In order to save time, money, and my joints,", | |
429 | "I believe it would be in order to...", | |
430 | "...to say,", | |
431 | "NO TERMINATING.", | |
432 | } | |
433 | setCursorBlink(false) | |
434 | local mess | |
435 | if terminates > #script then | |
436 | mess = script[#script] | |
437 | else | |
438 | mess = script[terminates] | |
439 | end | |
440 | if mess == "<bullshitterm>" then | |
441 | setBackgroundColor(colors.black) | |
442 | if term.isColor() then | |
443 | setTextColor(colors.yellow) | |
444 | else | |
445 | setTextColor(colors.white) | |
446 | end | |
447 | term.clear() | |
448 | setCursorPos(1,1) | |
449 | print(os.version()) | |
450 | write("> ") | |
451 | setTextColor(colors.white) | |
452 | read() | |
453 | printError("shell:350: Unable to pass") | |
454 | sleep(2) | |
455 | elseif mess == "<toobad>" then | |
456 | setBackgroundColor(colors.black) | |
457 | if term.isColor() then | |
458 | setTextColor(colors.red) | |
459 | else | |
460 | setTextColor(colors.white) | |
461 | end | |
462 | term.clear() | |
463 | setCursorPos(1,scr_y/2) | |
464 | local toobad = " T"..("O"):rep(scr_x-8).." BAD!" | |
465 | for a = 1, #toobad do | |
466 | for y = 1, scr_y do | |
467 | setCursorPos(a,y) | |
468 | rhite(toobad:sub(a,a)) | |
469 | end | |
470 | sleep(0) | |
471 | end | |
472 | sleep(1.5) | |
473 | for a = 1, 16 do | |
474 | if a%3 == 0 then | |
475 | setBackgroundColor(colors.white) | |
476 | elseif a%3 == 1 then | |
477 | setBackgroundColor(colors.black) | |
478 | else | |
479 | if term.isColor() then | |
480 | setBackgroundColor(colors.red) | |
481 | else | |
482 | setBackgroundColor(colors.gray) | |
483 | end | |
484 | end | |
485 | term.clear() | |
486 | sleep(0) | |
487 | end | |
488 | elseif mess == "<fuckinghell>" then | |
489 | writeError("Terminated") | |
490 | setBackgroundColor(colors.black) | |
491 | setTextColor(colors.white) | |
492 | term.blit(">","4","f") | |
493 | read() | |
494 | sleep(0.75) | |
495 | for a = 1, 2 do | |
496 | sleep(0.05) | |
497 | term.scroll(1) | |
498 | end | |
499 | for a = 1, scr_y do | |
500 | sleep(0.05) | |
501 | term.scroll(-1) | |
502 | end | |
503 | sleep(0.25) | |
504 | setBackgroundColor(colors.gray) | |
505 | term.clear() | |
506 | sleep(0.1) | |
507 | setBackgroundColor(colors.lightGray) | |
508 | term.clear() | |
509 | sleep(0.1) | |
510 | setBackgroundColor(colors.white) | |
511 | term.clear() | |
512 | sleep(0.25) | |
513 | local msg = "taht didn't happan" | |
514 | term.setCursorPos(scr_x-#msg,scr_y) | |
515 | setTextColor(colors.black) | |
516 | rhite(msg) | |
517 | sleep(1) | |
518 | elseif mess == "<abuseofcommunity>" then | |
519 | setBackgroundColor(colors.white) | |
520 | setTextColor(colors.black) | |
521 | term.clear() | |
522 | setCursorPos(2,3) | |
523 | - | print("Since you're such a smart bastard, why don't you come up with something objectionable to think about?\n") |
523 | + | print("Since you're such a smart bastard, why don't you come up with a petty, moralistic cause for the apathetic masses to think of?\n") |
524 | setBackgroundColor(colors.gray) | |
525 | setTextColor(colors.white) | |
526 | term.clearLine() | |
527 | - | local yourFuckingShittyAssResponceThatSucksSoMuchBallsThatIWouldRatherListenToThatFuckingOwlFromOcarinaOfTimeBlatherAboutHisFuckingDayThanSitWithYouForAnotherGoddamnedSecondReeeeee = read() |
527 | + | local yourFuckingShittyAssResponceThatSucksSoMuchBallsThatIWouldRatherListenToThatFuckingOwlFromOcarinaOfTimeBlatherAboutHisFuckingDayThanSitWithYouForAnotherGoddamnedSecond = read() |
528 | setBackgroundColor(colors.white) | |
529 | setTextColor(colors.black) | |
530 | for a = 1, 5 do | |
531 | sleep(0.6) | |
532 | write(".") | |
533 | end | |
534 | sleep(1) | |
535 | term.setTextColor(colors.red) | |
536 | for a = 1, 20 do | |
537 | sleep(0.05) | |
538 | write(".") | |
539 | end | |
540 | sleep(0.5) | |
541 | else | |
542 | setBackgroundColor(colors.gray) | |
543 | setTextColor(colors.white) | |
544 | setCursorPos(math.max(1,(scr_x/2)-(#mess/2)),scr_y/2) | |
545 | if language == "english" then | |
546 | write(mess) | |
547 | else | |
548 | write(lang[language].noTerminate) | |
549 | end | |
550 | sleep(1.5) | |
551 | end | |
552 | os.pullEvent = goodpull | |
553 | return terminates | |
554 | end | |
555 | ||
556 | local shuffle = function(txt) | |
557 | local output = "" | |
558 | for a = 1, #txt do | |
559 | if a % 2 == 0 then | |
560 | output = output..txt:sub(a,a) | |
561 | else | |
562 | output = txt:sub(a,a)..output | |
563 | end | |
564 | end | |
565 | return output | |
566 | end | |
567 | ||
568 | local goodpass = function(pswd,count) | |
569 | isTerminable = true | |
570 | doSine = false | |
571 | setCursorBlink(false) | |
572 | local flashes = { | |
573 | colors.white, | |
574 | colors.lightGray, | |
575 | colors.gray, | |
576 | } | |
577 | if type(pswd) == "table" then | |
578 | pswd = pswd[1] | |
579 | end | |
580 | setTextColor(colors.black) | |
581 | local correctmsg | |
582 | if count < 10 then | |
583 | correctmsg = lang[language].right1 | |
584 | else | |
585 | correctmsg = lang[language].right2 | |
586 | end | |
587 | for a = 1, #flashes do | |
588 | setBackgroundColor(flashes[#flashes-(a-1)]) | |
589 | term.clear() | |
590 | setCursorPos((scr_x/2)-(#correctmsg/2),scr_y/2) | |
591 | rhite(correctmsg) | |
592 | sleep(0) | |
593 | end | |
594 | if #doorSides == 0 then | |
595 | sleep(0.4) | |
596 | keepLooping = false | |
597 | else | |
598 | local doormsg | |
599 | if doShowDoorSides then | |
600 | doormsg = "Applying RS to "..table.concat(doorSides,", ").."." | |
601 | else | |
602 | doormsg = "Applying redstone." | |
603 | end | |
604 | setCursorPos((scr_x/2)-(#doormsg/2),(scr_y/2)+2) | |
605 | rhite(doormsg) | |
606 | for a = 1, #doorSides do | |
607 | redstone.setOutput(doorSides[a],not doInvertSignal) | |
608 | end | |
609 | if terminateMode == 1 then | |
610 | os.pullEvent = goodPullEvent | |
611 | end | |
612 | sleep(goodlength) | |
613 | if terminateMode == 1 then | |
614 | os.pullEvent = os.pullEventRaw | |
615 | end | |
616 | for a = 1, #doorSides do | |
617 | redstone.setOutput(doorSides[a],doInvertSignal) | |
618 | end | |
619 | end | |
620 | for a = 1, #flashes do | |
621 | setBackgroundColor(flashes[a]) | |
622 | term.clear() | |
623 | setCursorPos((scr_x/2)-(#correctmsg/2),scr_y/2) | |
624 | rhite(correctmsg) | |
625 | sleep(0) | |
626 | end | |
627 | setBackgroundColor(colors.black) | |
628 | term.clear() | |
629 | setCursorPos(1,1) | |
630 | if terminateMode == 1 and goodPullEvent and (#doorSides == 0) then | |
631 | os.pullEvent = goodPullEvent | |
632 | end | |
633 | setCursorBlink(true) | |
634 | isTerminable = false | |
635 | return true | |
636 | end | |
637 | ||
638 | local badpass = function(pswd,count) | |
639 | doSine = false | |
640 | local getevent = os.pullEvent | |
641 | os.pullEvent = os.pullEventRaw | |
642 | setCursorBlink(false) | |
643 | setBackgroundColor(palate.wrongBG) | |
644 | setTextColor(palate.wrongTXT) | |
645 | term.clear() | |
646 | if type(pswd) == "table" then | |
647 | pswd = pswd[1] | |
648 | end | |
649 | local badmsg | |
650 | if count < 10 then | |
651 | if pswd == sha256("bepis",salt) then | |
652 | badmsg = "Bepis." | |
653 | else | |
654 | badmsg = lang[language].wrong1 | |
655 | end | |
656 | else | |
657 | if pswd == sha256("bepis",salt) then | |
658 | badmsg = "BEPIS!" | |
659 | else | |
660 | badmsg = lang[language].wrong2 | |
661 | end | |
662 | end | |
663 | setCursorPos((scr_x/2)-(#badmsg/2),scr_y/2) | |
664 | rhite(badmsg) | |
665 | sleep(badlength) | |
666 | doSine = true | |
667 | setCursorBlink(true) | |
668 | os.pullEvent = getevent | |
669 | return "man you suck" | |
670 | end | |
671 | ||
672 | local readPassFile = function() | |
673 | local _output, _salt | |
674 | if fs.exists(passFile) then | |
675 | local file = fs.open(passFile,"r") | |
676 | _output = file.readLine() | |
677 | file.close() | |
678 | end | |
679 | if fs.exists(saltFile) then | |
680 | local file = fs.open(saltFile,"r") | |
681 | _salt = file.readLine() | |
682 | file.close() | |
683 | end | |
684 | return _output, _salt | |
685 | end | |
686 | ||
687 | local addNewPassword = function(pword,_path) | |
688 | local file = fs.open(_path or passFile,"a") | |
689 | file.write( sha256(pword,salt) ) | |
690 | file.close() | |
691 | end | |
692 | ||
693 | local rendersine = function(move) | |
694 | move = move or 0 | |
695 | local res1,res2,x,y | |
696 | if csv then term.current().setVisible(false) end | |
697 | setBackgroundColor(colors.black) | |
698 | setCursorBlink(false) | |
699 | for a = 1, scr_y do | |
700 | if a ~= readYpos then | |
701 | for b = 1, scr_x do | |
702 | x = b+floor(scr_x/2) | |
703 | y = a-floor(scr_y/2) | |
704 | res1 = abs( floor(sin((x/(scr_x/7.3))+move)*scr_y/4) - y ) <= 2 | |
705 | setCursorPos(b,a) | |
706 | if res1 then | |
707 | setBackgroundColor(palate.backsine) | |
708 | else | |
709 | setBackgroundColor(palate.background) | |
710 | end | |
711 | rhite(" ") | |
712 | res2 = abs( floor(cos((x/(scr_x/12.75))+(move*4))*scr_y/7) - y+2 ) <= 1 | |
713 | setCursorPos(b,a) | |
714 | if res2 then | |
715 | setBackgroundColor(palate.frontsine) | |
716 | rhite(" ") | |
717 | elseif not res1 then | |
718 | setBackgroundColor(palate.background) | |
719 | setTextColor(palate.rainColor) | |
720 | if (x % 2 == 0) and ((y+floor(move*-10)+(x % 5)) % 5 <= 1) then | |
721 | rhite(palate.rainChar) | |
722 | else | |
723 | rhite(" ") | |
724 | end | |
725 | end | |
726 | end | |
727 | end | |
728 | end | |
729 | if csv then term.current().setVisible(true) end | |
730 | setCursorBlink(true) | |
731 | end | |
732 | ||
733 | local sine = function() | |
734 | doSine = true | |
735 | while true do | |
736 | if sineLevel > 900 then | |
737 | sineLevel = 1 | |
738 | end | |
739 | if doSine then | |
740 | local cX,cY = getCursorPos() | |
741 | local bg,txt = getBackgroundColor(),getTextColor() | |
742 | rendersine(sineLevel/10) | |
743 | setCursorPos(cX,cY) | |
744 | setBackgroundColor(bg) | |
745 | setTextColor(txt) | |
746 | end | |
747 | sleep(sineFrameDelay) | |
748 | if kaykaycoolcool then | |
749 | sineLevel = sineLevel + 1 | |
750 | end | |
751 | end | |
752 | end | |
753 | ||
754 | local funcread = function(repchar,rHistory,doFunc,noNewLine,writeFunc,cursorAdjFunc,doFuncEvent,charLimit) | |
755 | local scr_x,scr_y = term.getSize() | |
756 | local sx,sy = term.getCursorPos() | |
757 | local cursor = 1 | |
758 | local rCursor = #rHistory+1 | |
759 | local output = "" | |
760 | term.setCursorBlink(true) | |
761 | local rite = writeFunc or term.write | |
762 | cursorAdjFunc = cursorAdjFunc or function() return 0 end | |
763 | while true do | |
764 | local evt,key = os.pullEvent() | |
765 | if evt == doFuncEvent then | |
766 | pleaseDoFunc = true | |
767 | elseif evt == "key" then | |
768 | if key == keys.enter then | |
769 | if not noNewLine then | |
770 | write("\n") | |
771 | end | |
772 | term.setCursorBlink(false) | |
773 | return output | |
774 | elseif key == keys.left then | |
775 | if cursor-1 >= 1 then | |
776 | cursor = cursor - 1 | |
777 | end | |
778 | elseif key == keys.right then | |
779 | if cursor <= #output then | |
780 | cursor = cursor + 1 | |
781 | end | |
782 | elseif key == keys.up then | |
783 | if rCursor > 1 then | |
784 | rCursor = rCursor - 1 | |
785 | term.setCursorPos(sx,sy) | |
786 | rite((" "):rep(#output)) | |
787 | output = (rHistory[rCursor] or ""):sub(1,charLimit or -1) | |
788 | cursor = #output+1 | |
789 | pleaseDoFunc = true | |
790 | end | |
791 | elseif key == keys.down then | |
792 | term.setCursorPos(sx,sy) | |
793 | rite((" "):rep(#output)) | |
794 | if rCursor < #rHistory then | |
795 | rCursor = rCursor + 1 | |
796 | output = (rHistory[rCursor] or ""):sub(1,charLimit or -1) | |
797 | cursor = #output+1 | |
798 | pleaseDoFunc = true | |
799 | else | |
800 | rCursor = #rHistory+1 | |
801 | output = "" | |
802 | cursor = 1 | |
803 | end | |
804 | elseif key == keys.backspace then | |
805 | if cursor > 1 and #output > 0 then | |
806 | output = (output:sub(1,cursor-2)..output:sub(cursor)):sub(1,charLimit or -1) | |
807 | cursor = cursor - 1 | |
808 | pleaseDoFunc = true | |
809 | end | |
810 | elseif key == keys.delete then | |
811 | if #output:sub(cursor,cursor) == 1 then | |
812 | output = (output:sub(1,cursor-1)..output:sub(cursor+1)):sub(1,charLimit or -1) | |
813 | pleaseDoFunc = true | |
814 | end | |
815 | end | |
816 | elseif evt == "char" or evt == "paste" then | |
817 | output = (output:sub(1,cursor-1)..key..output:sub(cursor+(#key-1))):sub(1,charLimit or -1) | |
818 | cursor = math.min(#output+1,cursor+#key) | |
819 | pleaseDoFunc = true | |
820 | end | |
821 | local pOut = (output or ""):sub(math.max( 1,(#output+sx)-scr_x) ) | |
822 | if pleaseDoFunc then | |
823 | pleaseDoFunc = false | |
824 | if type(doFunc) == "function" then | |
825 | doFunc(output:sub(1,charLimit or -1)) | |
826 | end | |
827 | term.setCursorPos(sx,sy) | |
828 | if repchar then | |
829 | rite(repchar:sub(1,1):rep(#pOut)) | |
830 | else | |
831 | rite(pOut) | |
832 | end | |
833 | term.write(" ") | |
834 | end | |
835 | term.setCursorPos(sx+cursorAdjFunc(pOut)+cursor-math.max( 1,(#output+sx)-scr_x),sy) | |
836 | end | |
837 | end | |
838 | ||
839 | local arse, arseSHA, passes | |
840 | ||
841 | local awaitKeyCard = function() | |
842 | local bwop,_,side | |
843 | repeat | |
844 | _,side = os.pullEvent("disk") | |
845 | if side then | |
846 | bwop = fs.combine(disk.getMountPath(side),".sinepw") --bwop! | |
847 | else | |
848 | bwop = "" | |
849 | end | |
850 | until fs.exists(bwop) and not fs.isDir(bwop) | |
851 | local file = fs.open(bwop,"r") | |
852 | local output = file.readLine() | |
853 | file.close() | |
854 | arseSHA = output | |
855 | if doEjectDisk then disk.eject(side) end | |
856 | end | |
857 | ||
858 | local passwordPrompt = function() | |
859 | if requireAllPasswords then | |
860 | arse = {} | |
861 | arseSHA = "" | |
862 | for a = 1, ceil(#passes/64) do | |
863 | setCursorPos(1,readYpos) | |
864 | setBackgroundColor(palate.promptBG) | |
865 | term.clearLine() | |
866 | setTextColor(palate.promptTXT) | |
867 | write("P"..a..">") | |
868 | arse[#arse+1] = read(dahChar) | |
869 | arseSHA = arseSHA..sha256(arse[#arse],salt) | |
870 | end | |
871 | else | |
872 | setCursorPos(1,readYpos) | |
873 | setBackgroundColor(palate.promptBG) | |
874 | term.clearLine() | |
875 | setTextColor(palate.promptTXT) | |
876 | write(">") | |
877 | arse = funcread(dahChar,{},nil,true,nil,nil,nil,characterLimit) | |
878 | arseSHA = sha256(arse,salt) | |
879 | end | |
880 | end | |
881 | ||
882 | local count = 0 | |
883 | ||
884 | local lock = function() | |
885 | if #doorSides > 0 then | |
886 | for a = 1, #doorSides do | |
887 | redstone.setOutput(doorSides[a],doInvertSignal) | |
888 | end | |
889 | end | |
890 | while true do | |
891 | passes, salt = readPassFile() | |
892 | count = count + 1 | |
893 | if doKeyCards then | |
894 | parallel.waitForAny(passwordPrompt,awaitKeyCard) | |
895 | else | |
896 | passwordPrompt() | |
897 | end | |
898 | local good | |
899 | if requireAllPasswords then | |
900 | if passes == arseSHA then | |
901 | good = true | |
902 | else | |
903 | good = false | |
904 | end | |
905 | else | |
906 | if string.find(passes,arseSHA) then | |
907 | good = true | |
908 | else | |
909 | good = false | |
910 | end | |
911 | end | |
912 | if good then | |
913 | goodpass(arseSHA,count) | |
914 | if #doorSides == 0 then | |
915 | return true | |
916 | else | |
917 | doSine = true | |
918 | end | |
919 | else | |
920 | badpass(arseSHA,count) | |
921 | end | |
922 | end | |
923 | end | |
924 | ||
925 | local choice = function(input) | |
926 | repeat | |
927 | event, key = os.pullEvent("key") | |
928 | if type(key) == "number" then key = keys.getName(key) end | |
929 | if key == nil then key = " " end | |
930 | until string.find(input, key) | |
931 | return key | |
932 | end | |
933 | ||
934 | if not fs.exists(saltFile) then | |
935 | local file = fs.open(saltFile,"w") | |
936 | for a = 1, 128 do | |
937 | local c = string.char(random(1,255)) | |
938 | file.write(c) | |
939 | end | |
940 | file.close() | |
941 | local f = fs.open(saltFile,"r") | |
942 | salt = f.readLine() | |
943 | f.close() | |
944 | end | |
945 | ||
946 | passes, salt = readPassFile() | |
947 | ||
948 | local tArg = {...} | |
949 | if tArg[1] == "addpass" then | |
950 | if tArg[2] then | |
951 | print("Really add password? [Y,N]") | |
952 | local answer = choice("yn") | |
953 | if answer == "n" then | |
954 | sleep(0) | |
955 | return print("Oh, okay.") | |
956 | else | |
957 | table.remove(tArg,1) | |
958 | addNewPassword(table.concat(tArg," ")) | |
959 | sleep(0) | |
960 | return print("Added password.") | |
961 | end | |
962 | else | |
963 | sleep(0) | |
964 | return print("Expected a new password...") | |
965 | end | |
966 | elseif tArg[1] == "keymake" then | |
967 | if tArg[2] then | |
968 | print("Really add to disk?") | |
969 | print("Keep in mind the password has to be manually added for the keycard to work.\n[Y,N]") | |
970 | local answer = choice("yn") | |
971 | if answer == "n" then | |
972 | sleep(0) | |
973 | return print("Oh, okay.") | |
974 | else | |
975 | - | print("Please insert a disk or pocket computer.") |
975 | + | print("Please insert a disk.") |
976 | local _,side = os.pullEvent("disk") | |
977 | local diskPassPath = fs.combine(disk.getMountPath(side),".sinepw") | |
978 | table.remove(tArg,1) | |
979 | addNewPassword(table.concat(tArg," "),diskPassPath) | |
980 | if not disk.getLabel(side) then | |
981 | disk.setLabel(side,"slkey-"..random(1,1000)) | |
982 | end | |
983 | sleep(0) | |
984 | print("Added password.") | |
985 | if not doKeyCards then | |
986 | print("Key cards aren't enabled, though.") | |
987 | end | |
988 | return | |
989 | end | |
990 | else | |
991 | sleep(0) | |
992 | return print("Expected a password...") | |
993 | end | |
994 | end | |
995 | ||
996 | if not fs.exists(passFile) then | |
997 | local progname = fs.getName(shell.getRunningProgram()) | |
998 | return print("No password file found.\nRun '"..progname.." addpass <password>' to add a password.") | |
999 | end | |
1000 | ||
1001 | setBackgroundColor(colors.black) | |
1002 | term.clear() | |
1003 | ||
1004 | local parafunky = { --it looks kinda funky, but it tastes funKAY! | |
1005 | sine, | |
1006 | lock, | |
1007 | } | |
1008 | ||
1009 | if not beWavey then table.remove(parafunky,1) end --not funky, man | |
1010 | local staytis, errawr | |
1011 | while keepLooping do | |
1012 | kaykaycoolcool = true | |
1013 | staytis, errawr = pcall(parallel.waitForAny,unpack(parafunky)) | |
1014 | if keepLooping == false then break else | |
1015 | if terminateMode == 2 then | |
1016 | kaykaycoolcool = false | |
1017 | if not isTerminable then | |
1018 | sillyTerminate() | |
1019 | else | |
1020 | keepLooping = false | |
1021 | setBackgroundColor(colors.black) | |
1022 | term.clear() | |
1023 | setTextColor(colors.white) | |
1024 | setCursorPos(1,1) | |
1025 | break | |
1026 | end | |
1027 | else | |
1028 | keepLooping = false | |
1029 | setBackgroundColor(colors.black) | |
1030 | term.clear() | |
1031 | setTextColor(colors.white) | |
1032 | setCursorPos(1,1) | |
1033 | if not staytis then | |
1034 | printError(errawr) | |
1035 | end | |
1036 | break | |
1037 | end | |
1038 | end | |
1039 | end | |
1040 | if runProgram and (runProgram ~= "") then | |
1041 | shell.run(runProgram) | |
1042 | end |