mirror of
https://github.com/LDDestroier/CC/
synced 2024-12-04 23:39:58 +00:00
1042 lines
27 KiB
Lua
1042 lines
27 KiB
Lua
--[[
|
|
Sinelock v1.3
|
|
The *COOLEST* computer/door lock ever!
|
|
Now with slightly less seizure!
|
|
|
|
pastebin get XDgeSDTq sinelock
|
|
std pb XDgeSDTq sinelock
|
|
std ld sinelock sinelock
|
|
|
|
Now with salting!
|
|
--]]
|
|
local scr_x, scr_y = term.getSize() --Gets screen size. Don't modify this
|
|
|
|
--Config variables start!
|
|
local terminateMode = 2 --0 enables termination, 1 blocks it, 2 provides a taunting screen.
|
|
local passFile = ".sl_password" --The ABSOLUTE path of the password file.
|
|
local saltFile = ".sl_salt" --The ABSOLUTE path of the salt file.
|
|
local characterLimit = 1024 --The cap of characters at the read() prompt. Set this to prevent crashes.
|
|
local runProgram = "" --Set to something to run it when correct, and not using doors.
|
|
local dahChar = "*" --The character used to hide characters when typed.
|
|
local doKeyCards = true --Whether or not the lock also accepts keycards (floppy disks) as well as passwords.
|
|
local doEjectDisk = false --Whether or not to eject a keycard after it's accepted, just to speed things up a bit.
|
|
local doorSides = {} --If it has anything, the lock will open the doors instead of unlocking the PC.
|
|
local doInvertSignal = false --If true, it will invert the redstone signal of the door, in case you need to.
|
|
local doShowDoorSides = true --If true, will show the door sides being opened. Set to false if you are paranoid.
|
|
local beWavey = true --Whether or not to animate the sine wave.
|
|
local readYpos = scr_y-2 --The Y position of the read() prompt
|
|
local requireAllPasswords = false --Whether or not the lock asks for ONE of the multiple passwords, or ALL of them in order.
|
|
local badlength = 4 --The length in seconds that you have to wait to try again.
|
|
local goodlength = 6 --The length in seconds that doors will stay open.
|
|
local sineFrameDelay = 0.15 --The amount of time between sine animation frames. Tradeoff of purty vs performance.
|
|
local palate = {
|
|
frontsine = colors.lightGray,
|
|
backsine = colors.gray,
|
|
background = colors.black,
|
|
rainColor = colors.gray,
|
|
rainChar = "|",
|
|
promptBG = colors.gray,
|
|
promptTXT = colors.white,
|
|
wrongBG = colors.black,
|
|
wrongTXT = colors.gray,
|
|
}
|
|
local language = "english"
|
|
local lang = {
|
|
english = {
|
|
wrong1 = "YOU ARE WRONG.",
|
|
wrong2 = "YOU ARE WRONG. AS ALWAYS.",
|
|
right1 = "Correct!",
|
|
right2 = "Correct, finally!",
|
|
},
|
|
spanish = {
|
|
wrong1 = "ESTA USTED EQUIVOCADO.",
|
|
wrong2 = "ESTA USTED EQUIVOCADO. TODAVIA OTRA VEZ.",
|
|
right1 = "Correcto!",
|
|
right2 = "Asi es, por fin!",
|
|
noTerminate = "No termine!",
|
|
},
|
|
german = {
|
|
wrong1 = "SIE LIEGEN FALSCH.",
|
|
wrong2 = "SIE LIEGEN FALSCH. WIE IMMER.",
|
|
right1 = "Richtig!",
|
|
right2 = "Richtig, endlich!",
|
|
noTerminate = "Nicht zu beenden!",
|
|
},
|
|
dutch = {
|
|
wrong1 = "U BENT ONJUIST.",
|
|
wrong2 = "JE BENT ONJUIST, ALS ALTIJD.",
|
|
right1 = "Dat is juist!",
|
|
right2 = "Dat is juist, eindelijk!",
|
|
noTerminate = "Niet te beeindigen!",
|
|
},
|
|
latin = { --As a joke
|
|
wrong1 = "ERRAS",
|
|
wrong2 = "TU DEFICIENTES!",
|
|
right1 = "Quod suus 'verum!",
|
|
right2 = "Quod suus 'verum, demum!",
|
|
noTerminate = "Vade futuo te ipsum!",
|
|
},
|
|
italian = {
|
|
wrong1 = "HAI SBAGLIATO.",
|
|
wrong2 = "HAI SBAGLIATO, COME SEMPRE D'ALTRONDE.",
|
|
right1 = "CORRETTO!",
|
|
right2 = "CORRETTO, FINALMENTE!",
|
|
noTerminate = "Non cercare di terminarmi",
|
|
},
|
|
}
|
|
|
|
-- Config variables end. Don't touch anything else, m'kay?
|
|
if not _VERSION then
|
|
return printError("Sorry, only CC 1.7 and later supported.")
|
|
end
|
|
local csv, salt, doSine
|
|
local floor, ceil, random, abs = math.floor, math.ceil, math.random, math.abs
|
|
local sin, cos = math.sin, math.cos
|
|
local rhite = term.write
|
|
local setTextColor, setBackgroundColor, getTextColor, getBackgroundColor = term.setTextColor, term.setBackgroundColor, term.getTextColor, term.getBackgroundColor
|
|
local setCursorPos, setCursorBlink, getCursorPos, getSize = term.setCursorPos, term.setCursorBlink, term.getCursorPos, term.getSize
|
|
local sineLevel = 1
|
|
local isTerminable = false
|
|
local kaykaycoolcool = true
|
|
if term.current().setVisible then
|
|
csv = true
|
|
else
|
|
csv = false
|
|
end
|
|
|
|
local writeError = function(...)
|
|
local tx,bg = getTextColor(),getBackgroundColor()
|
|
if term.isColor() then
|
|
setTextColor(colors.red)
|
|
else
|
|
setTextColor(colors.white)
|
|
end
|
|
rhite(table.concat(arg," "))
|
|
setTextColor(tx)
|
|
setBackgroundColor(bg)
|
|
end
|
|
|
|
local goodPullEvent
|
|
if terminateMode == 1 then
|
|
if os.pullEvent ~= os.pullEventRaw then
|
|
goodPullEvent = os.pullEvent
|
|
end
|
|
os.pullEvent = os.pullEventRaw
|
|
end
|
|
|
|
local keepLooping = true
|
|
|
|
---- SHA256 START ----
|
|
--SHA256 implementation done by GravityScore.
|
|
|
|
local MOD = 2^32
|
|
local MODM = MOD-1
|
|
|
|
local function memoize(f)
|
|
local mt = {}
|
|
local t = setmetatable({}, mt)
|
|
function mt:__index(k)
|
|
local v = f(k)
|
|
t[k] = v
|
|
return v
|
|
end
|
|
return t
|
|
end
|
|
|
|
local function make_bitop_uncached(t, m)
|
|
local function bitop(a, b)
|
|
local res,p = 0,1
|
|
while a ~= 0 and b ~= 0 do
|
|
local am, bm = a % m, b % m
|
|
res = res + t[am][bm] * p
|
|
a = (a - am) / m
|
|
b = (b - bm) / m
|
|
p = p*m
|
|
end
|
|
res = res + (a + b) * p
|
|
return res
|
|
end
|
|
return bitop
|
|
end
|
|
|
|
local function make_bitop(t)
|
|
local op1 = make_bitop_uncached(t,2^1)
|
|
local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)
|
|
return make_bitop_uncached(op2, 2 ^ (t.n or 1))
|
|
end
|
|
|
|
local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})
|
|
|
|
local function bxor(a, b, c, ...)
|
|
local z = nil
|
|
if b then
|
|
a = a % MOD
|
|
b = b % MOD
|
|
z = bxor1(a, b)
|
|
if c then z = bxor(z, c, ...) end
|
|
return z
|
|
elseif a then return a % MOD
|
|
else return 0 end
|
|
end
|
|
|
|
local function band(a, b, c, ...)
|
|
local z
|
|
if b then
|
|
a = a % MOD
|
|
b = b % MOD
|
|
z = ((a + b) - bxor1(a,b)) / 2
|
|
if c then z = bit32_band(z, c, ...) end
|
|
return z
|
|
elseif a then return a % MOD
|
|
else return MODM end
|
|
end
|
|
|
|
local function bnot(x) return (-1 - x) % MOD end
|
|
|
|
local function rshift1(a, disp)
|
|
if disp < 0 then return lshift(a,-disp) end
|
|
return floor(a % 2 ^ 32 / 2 ^ disp)
|
|
end
|
|
|
|
local function rshift(x, disp)
|
|
if disp > 31 or disp < -31 then return 0 end
|
|
return rshift1(x % MOD, disp)
|
|
end
|
|
|
|
local function lshift(a, disp)
|
|
if disp < 0 then return rshift(a,-disp) end
|
|
return (a * 2 ^ disp) % 2 ^ 32
|
|
end
|
|
|
|
local function rrotate(x, disp)
|
|
x = x % MOD
|
|
disp = disp % 32
|
|
local low = band(x, 2 ^ disp - 1)
|
|
return rshift(x, disp) + lshift(low, 32 - disp)
|
|
end
|
|
|
|
local k = {
|
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
|
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
|
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
|
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
|
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
}
|
|
|
|
local function str2hexa(s)
|
|
return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end))
|
|
end
|
|
|
|
local function num2s(l, n)
|
|
local s = ""
|
|
for i = 1, n do
|
|
local rem = l % 256
|
|
s = string.char(rem) .. s
|
|
l = (l - rem) / 256
|
|
end
|
|
return s
|
|
end
|
|
|
|
local function s232num(s, i)
|
|
local n = 0
|
|
for i = i, i + 3 do n = n*256 + string.byte(s, i) end
|
|
return n
|
|
end
|
|
|
|
local function preproc(msg, len)
|
|
local extra = 64 - ((len + 9) % 64)
|
|
len = num2s(8 * len, 8)
|
|
msg = msg .. "\128" .. string.rep("\0", extra) .. len
|
|
assert(#msg % 64 == 0)
|
|
return msg
|
|
end
|
|
|
|
local function initH256(H)
|
|
H[1] = 0x6a09e667
|
|
H[2] = 0xbb67ae85
|
|
H[3] = 0x3c6ef372
|
|
H[4] = 0xa54ff53a
|
|
H[5] = 0x510e527f
|
|
H[6] = 0x9b05688c
|
|
H[7] = 0x1f83d9ab
|
|
H[8] = 0x5be0cd19
|
|
return H
|
|
end
|
|
|
|
local function digestblock(msg, i, H)
|
|
local w = {}
|
|
for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end
|
|
for j = 17, 64 do
|
|
local v = w[j - 15]
|
|
local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
|
|
v = w[j - 2]
|
|
w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
|
|
end
|
|
|
|
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]
|
|
for i = 1, 64 do
|
|
local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
|
|
local maj = bxor(band(a, b), band(a, c), band(b, c))
|
|
local t2 = s0 + maj
|
|
local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
|
|
local ch = bxor (band(e, f), band(bnot(e), g))
|
|
local t1 = h + s1 + ch + k[i] + w[i]
|
|
h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
|
|
end
|
|
|
|
H[1] = band(H[1] + a)
|
|
H[2] = band(H[2] + b)
|
|
H[3] = band(H[3] + c)
|
|
H[4] = band(H[4] + d)
|
|
H[5] = band(H[5] + e)
|
|
H[6] = band(H[6] + f)
|
|
H[7] = band(H[7] + g)
|
|
H[8] = band(H[8] + h)
|
|
end
|
|
|
|
local function sha256(...)
|
|
local msg = table.concat(arg,",")
|
|
msg = preproc(msg, #msg)
|
|
local H = initH256({})
|
|
for i = 1, #msg, 64 do digestblock(msg, i, H) end
|
|
return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
|
|
num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
|
|
end
|
|
|
|
---- SHA256 END ----
|
|
|
|
local terminates = 0
|
|
local sillyTerminate = function()
|
|
local goodpull = _G.os.pullEvent
|
|
os.pullEvent = os.pullEventRaw
|
|
terminates = terminates + 1
|
|
local script = {
|
|
"You shall not pass!",
|
|
"THOU shalt not pass!",
|
|
"Stop trying to pass!",
|
|
"...maybe I'm not clear.",
|
|
"YOU. SHALL NOT. PASS!!",
|
|
"Pass thou shalt not!",
|
|
"Hey, piss off, will ya?",
|
|
"I haven't got all day.",
|
|
"...no, shut up. I don't.",
|
|
"I won't tell you it!",
|
|
"No password for you.",
|
|
"It's been hashed!",
|
|
"Hashed...with a salt!",
|
|
"I'll never tell you the salt.",
|
|
"You know why?",
|
|
"Because that requires passing!",
|
|
"WHICH THOU SHALT NOT DO!",
|
|
"(oh btw don't pass k?)",
|
|
"You! Don't pass!",
|
|
"That means YOU!",
|
|
"Cut it out!",
|
|
"Re: Cut it out!",
|
|
"Perhaps if you keep it up...",
|
|
"..hmm...",
|
|
"..oh I give up.",
|
|
"<bullshitterm>",
|
|
"What? Is this what you wanted?",
|
|
"Huh? No? I-it's not?",
|
|
"Well then...!",
|
|
"<toobad>",
|
|
"YEAH I SAID IT",
|
|
"You think you're a terminating machine!",
|
|
"You think you're above consequence!",
|
|
"...w-...",
|
|
"eat my shorts",
|
|
"Your attempts are futile anyhow.",
|
|
"Here I am getting drunk off your sweat,",
|
|
"...while you push CTRL and T.",
|
|
"Or maybe you're pressing that [T] button.",
|
|
"Like, um, in CCEmuRedux.",
|
|
"But it matters not!",
|
|
"For you see, my defences are great!",
|
|
"Nothing can bust my rock-hard abs!",
|
|
"<fuckinghell>",
|
|
"Oh bualls.",
|
|
"That was embarrasing.",
|
|
"...?",
|
|
"What're YOU lookin' at??",
|
|
"You callin' me UNSTABLE!?",
|
|
"HUH!??",
|
|
"...",
|
|
"...w-well at least I admit it",
|
|
"...b-bakka",
|
|
".......",
|
|
"Hey, have you ever played EarthBound?",
|
|
"(Yes. I'm gonna rant.)",
|
|
"It's an RPG on the Super Nintendo.",
|
|
"Like, instead of fighting fantasy demons,",
|
|
"you fight stop signs and cars and shit",
|
|
"And, like, you hit rabid dogs with a bat",
|
|
"And you have magical PSI spells",
|
|
"...speaking of PSI, I happen to use it a lot.",
|
|
"...er, *I* as in the coder of this lock...",
|
|
"And by PSI, I mean the mod.",
|
|
"You don't see too many psychic locks these days.",
|
|
"A shame, really.",
|
|
"I bet a PSI lock could act as a heater with PSI Fire.",
|
|
"Or maybe it can kill rats with PSI Ground or Thunder",
|
|
"Maybe, you can get a psychic KEY lock, so, like,",
|
|
"you could put it on that Psychonauts head door thing.",
|
|
"...WHAT!? just a suggestion.",
|
|
"Psychonauts is another game I reccommend.",
|
|
"It has some really clever dialogue.",
|
|
"I'm sure you'd like it quite a lot.",
|
|
"I know, because you've been here for ten fucking minutes.",
|
|
"And you're not ONE STEP closer to getting the password",
|
|
"Which I've been guarding very, very closely.",
|
|
"Yes. Extremely closely.",
|
|
"Excrutiatingly, some would say.",
|
|
"You know, I should probably get to shouting.",
|
|
"*ahem*",
|
|
"...",
|
|
"*aahhhechhemmemmhmm*",
|
|
"*aachkskacehchachkhackcoughfartfuckdammitaaucahkh*",
|
|
"...",
|
|
"STAHP IT",
|
|
"STAHP TEHRMINATIN",
|
|
"do it for the CHILDREN",
|
|
"okay fuck the children, who needs 'em",
|
|
"then",
|
|
"um",
|
|
"THINK OF THE...THE...",
|
|
"the babies...?",
|
|
"um",
|
|
"<abuseofcommunity>",
|
|
"That's a fucking horrible idea.",
|
|
"I'd rather eat my own brain then think about that.",
|
|
"I'd sooner kiss a pig!",
|
|
"I'd sooner swallow an avocado pit!",
|
|
"...",
|
|
"You know, you suck so much.",
|
|
"You suck so much, and I'm sick of writing this script",
|
|
"If my knuckles bleed, you're paying my insurance",
|
|
"In order to save time, money, and my joints,",
|
|
"I believe it would be in order to...",
|
|
"...to say,",
|
|
"NO TERMINATING.",
|
|
}
|
|
setCursorBlink(false)
|
|
local mess
|
|
if terminates > #script then
|
|
mess = script[#script]
|
|
else
|
|
mess = script[terminates]
|
|
end
|
|
if mess == "<bullshitterm>" then
|
|
setBackgroundColor(colors.black)
|
|
if term.isColor() then
|
|
setTextColor(colors.yellow)
|
|
else
|
|
setTextColor(colors.white)
|
|
end
|
|
term.clear()
|
|
setCursorPos(1,1)
|
|
print(os.version())
|
|
write("> ")
|
|
setTextColor(colors.white)
|
|
read()
|
|
printError("shell:350: Unable to pass")
|
|
sleep(2)
|
|
elseif mess == "<toobad>" then
|
|
setBackgroundColor(colors.black)
|
|
if term.isColor() then
|
|
setTextColor(colors.red)
|
|
else
|
|
setTextColor(colors.white)
|
|
end
|
|
term.clear()
|
|
setCursorPos(1,scr_y/2)
|
|
local toobad = " T"..("O"):rep(scr_x-8).." BAD!"
|
|
for a = 1, #toobad do
|
|
for y = 1, scr_y do
|
|
setCursorPos(a,y)
|
|
rhite(toobad:sub(a,a))
|
|
end
|
|
sleep(0)
|
|
end
|
|
sleep(1.5)
|
|
for a = 1, 16 do
|
|
if a%3 == 0 then
|
|
setBackgroundColor(colors.white)
|
|
elseif a%3 == 1 then
|
|
setBackgroundColor(colors.black)
|
|
else
|
|
if term.isColor() then
|
|
setBackgroundColor(colors.red)
|
|
else
|
|
setBackgroundColor(colors.gray)
|
|
end
|
|
end
|
|
term.clear()
|
|
sleep(0)
|
|
end
|
|
elseif mess == "<fuckinghell>" then
|
|
writeError("Terminated")
|
|
setBackgroundColor(colors.black)
|
|
setTextColor(colors.white)
|
|
term.blit(">","4","f")
|
|
read()
|
|
sleep(0.75)
|
|
for a = 1, 2 do
|
|
sleep(0.05)
|
|
term.scroll(1)
|
|
end
|
|
for a = 1, scr_y do
|
|
sleep(0.05)
|
|
term.scroll(-1)
|
|
end
|
|
sleep(0.25)
|
|
setBackgroundColor(colors.gray)
|
|
term.clear()
|
|
sleep(0.1)
|
|
setBackgroundColor(colors.lightGray)
|
|
term.clear()
|
|
sleep(0.1)
|
|
setBackgroundColor(colors.white)
|
|
term.clear()
|
|
sleep(0.25)
|
|
local msg = "taht didn't happan"
|
|
term.setCursorPos(scr_x-#msg,scr_y)
|
|
setTextColor(colors.black)
|
|
rhite(msg)
|
|
sleep(1)
|
|
elseif mess == "<abuseofcommunity>" then
|
|
setBackgroundColor(colors.white)
|
|
setTextColor(colors.black)
|
|
term.clear()
|
|
setCursorPos(2,3)
|
|
print("Since you're such a smart bastard, why don't you come up with something objectionable to think about?\n")
|
|
setBackgroundColor(colors.gray)
|
|
setTextColor(colors.white)
|
|
term.clearLine()
|
|
local yourFuckingShittyAssResponceThatSucksSoMuchBallsThatIWouldRatherListenToThatFuckingOwlFromOcarinaOfTimeBlatherAboutHisFuckingDayThanSitWithYouForAnotherGoddamnedSecondReeeeee = read()
|
|
setBackgroundColor(colors.white)
|
|
setTextColor(colors.black)
|
|
for a = 1, 5 do
|
|
sleep(0.6)
|
|
write(".")
|
|
end
|
|
sleep(1)
|
|
term.setTextColor(colors.red)
|
|
for a = 1, 20 do
|
|
sleep(0.05)
|
|
write(".")
|
|
end
|
|
sleep(0.5)
|
|
else
|
|
setBackgroundColor(colors.gray)
|
|
setTextColor(colors.white)
|
|
setCursorPos(math.max(1,(scr_x/2)-(#mess/2)),scr_y/2)
|
|
if language == "english" then
|
|
write(mess)
|
|
else
|
|
write(lang[language].noTerminate)
|
|
end
|
|
sleep(1.5)
|
|
end
|
|
os.pullEvent = goodpull
|
|
return terminates
|
|
end
|
|
|
|
local shuffle = function(txt)
|
|
local output = ""
|
|
for a = 1, #txt do
|
|
if a % 2 == 0 then
|
|
output = output..txt:sub(a,a)
|
|
else
|
|
output = txt:sub(a,a)..output
|
|
end
|
|
end
|
|
return output
|
|
end
|
|
|
|
local goodpass = function(pswd,count)
|
|
isTerminable = true
|
|
doSine = false
|
|
setCursorBlink(false)
|
|
local flashes = {
|
|
colors.white,
|
|
colors.lightGray,
|
|
colors.gray,
|
|
}
|
|
if type(pswd) == "table" then
|
|
pswd = pswd[1]
|
|
end
|
|
setTextColor(colors.black)
|
|
local correctmsg
|
|
if count < 10 then
|
|
correctmsg = lang[language].right1
|
|
else
|
|
correctmsg = lang[language].right2
|
|
end
|
|
for a = 1, #flashes do
|
|
setBackgroundColor(flashes[#flashes-(a-1)])
|
|
term.clear()
|
|
setCursorPos((scr_x/2)-(#correctmsg/2),scr_y/2)
|
|
rhite(correctmsg)
|
|
sleep(0)
|
|
end
|
|
if #doorSides == 0 then
|
|
sleep(0.4)
|
|
keepLooping = false
|
|
else
|
|
local doormsg
|
|
if doShowDoorSides then
|
|
doormsg = "Applying RS to "..table.concat(doorSides,", ").."."
|
|
else
|
|
doormsg = "Applying redstone."
|
|
end
|
|
setCursorPos((scr_x/2)-(#doormsg/2),(scr_y/2)+2)
|
|
rhite(doormsg)
|
|
for a = 1, #doorSides do
|
|
redstone.setOutput(doorSides[a],not doInvertSignal)
|
|
end
|
|
if terminateMode == 1 then
|
|
os.pullEvent = goodPullEvent
|
|
end
|
|
sleep(goodlength)
|
|
if terminateMode == 1 then
|
|
os.pullEvent = os.pullEventRaw
|
|
end
|
|
for a = 1, #doorSides do
|
|
redstone.setOutput(doorSides[a],doInvertSignal)
|
|
end
|
|
end
|
|
for a = 1, #flashes do
|
|
setBackgroundColor(flashes[a])
|
|
term.clear()
|
|
setCursorPos((scr_x/2)-(#correctmsg/2),scr_y/2)
|
|
rhite(correctmsg)
|
|
sleep(0)
|
|
end
|
|
setBackgroundColor(colors.black)
|
|
term.clear()
|
|
setCursorPos(1,1)
|
|
if terminateMode == 1 and goodPullEvent and (#doorSides == 0) then
|
|
os.pullEvent = goodPullEvent
|
|
end
|
|
setCursorBlink(true)
|
|
isTerminable = false
|
|
return true
|
|
end
|
|
|
|
local badpass = function(pswd,count)
|
|
doSine = false
|
|
local getevent = os.pullEvent
|
|
os.pullEvent = os.pullEventRaw
|
|
setCursorBlink(false)
|
|
setBackgroundColor(palate.wrongBG)
|
|
setTextColor(palate.wrongTXT)
|
|
term.clear()
|
|
if type(pswd) == "table" then
|
|
pswd = pswd[1]
|
|
end
|
|
local badmsg
|
|
if count < 10 then
|
|
if pswd == sha256("bepis",salt) then
|
|
badmsg = "Bepis."
|
|
else
|
|
badmsg = lang[language].wrong1
|
|
end
|
|
else
|
|
if pswd == sha256("bepis",salt) then
|
|
badmsg = "BEPIS!"
|
|
else
|
|
badmsg = lang[language].wrong2
|
|
end
|
|
end
|
|
setCursorPos((scr_x/2)-(#badmsg/2),scr_y/2)
|
|
rhite(badmsg)
|
|
sleep(badlength)
|
|
doSine = true
|
|
setCursorBlink(true)
|
|
os.pullEvent = getevent
|
|
return "man you suck"
|
|
end
|
|
|
|
local readPassFile = function()
|
|
local _output, _salt
|
|
if fs.exists(passFile) then
|
|
local file = fs.open(passFile,"r")
|
|
_output = file.readLine()
|
|
file.close()
|
|
end
|
|
if fs.exists(saltFile) then
|
|
local file = fs.open(saltFile,"r")
|
|
_salt = file.readLine()
|
|
file.close()
|
|
end
|
|
return _output, _salt
|
|
end
|
|
|
|
local addNewPassword = function(pword,_path)
|
|
local file = fs.open(_path or passFile,"a")
|
|
file.write( sha256(pword,salt) )
|
|
file.close()
|
|
end
|
|
|
|
local rendersine = function(move)
|
|
move = move or 0
|
|
local res1,res2,x,y
|
|
if csv then term.current().setVisible(false) end
|
|
setBackgroundColor(colors.black)
|
|
setCursorBlink(false)
|
|
for a = 1, scr_y do
|
|
if a ~= readYpos then
|
|
for b = 1, scr_x do
|
|
x = b+floor(scr_x/2)
|
|
y = a-floor(scr_y/2)
|
|
res1 = abs( floor(sin((x/(scr_x/7.3))+move)*scr_y/4) - y ) <= 2
|
|
setCursorPos(b,a)
|
|
if res1 then
|
|
setBackgroundColor(palate.backsine)
|
|
else
|
|
setBackgroundColor(palate.background)
|
|
end
|
|
rhite(" ")
|
|
res2 = abs( floor(cos((x/(scr_x/12.75))+(move*4))*scr_y/7) - y+2 ) <= 1
|
|
setCursorPos(b,a)
|
|
if res2 then
|
|
setBackgroundColor(palate.frontsine)
|
|
rhite(" ")
|
|
elseif not res1 then
|
|
setBackgroundColor(palate.background)
|
|
setTextColor(palate.rainColor)
|
|
if (x % 2 == 0) and ((y+floor(move*-10)+(x % 5)) % 5 <= 1) then
|
|
rhite(palate.rainChar)
|
|
else
|
|
rhite(" ")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if csv then term.current().setVisible(true) end
|
|
setCursorBlink(true)
|
|
end
|
|
|
|
local sine = function()
|
|
doSine = true
|
|
while true do
|
|
if sineLevel > 900 then
|
|
sineLevel = 1
|
|
end
|
|
if doSine then
|
|
local cX,cY = getCursorPos()
|
|
local bg,txt = getBackgroundColor(),getTextColor()
|
|
rendersine(sineLevel/10)
|
|
setCursorPos(cX,cY)
|
|
setBackgroundColor(bg)
|
|
setTextColor(txt)
|
|
end
|
|
sleep(sineFrameDelay)
|
|
if kaykaycoolcool then
|
|
sineLevel = sineLevel + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
local funcread = function(repchar,rHistory,doFunc,noNewLine,writeFunc,cursorAdjFunc,doFuncEvent,charLimit)
|
|
local scr_x,scr_y = term.getSize()
|
|
local sx,sy = term.getCursorPos()
|
|
local cursor = 1
|
|
local rCursor = #rHistory+1
|
|
local output = ""
|
|
term.setCursorBlink(true)
|
|
local rite = writeFunc or term.write
|
|
cursorAdjFunc = cursorAdjFunc or function() return 0 end
|
|
while true do
|
|
local evt,key = os.pullEvent()
|
|
if evt == doFuncEvent then
|
|
pleaseDoFunc = true
|
|
elseif evt == "key" then
|
|
if key == keys.enter then
|
|
if not noNewLine then
|
|
write("\n")
|
|
end
|
|
term.setCursorBlink(false)
|
|
return output
|
|
elseif key == keys.left then
|
|
if cursor-1 >= 1 then
|
|
cursor = cursor - 1
|
|
end
|
|
elseif key == keys.right then
|
|
if cursor <= #output then
|
|
cursor = cursor + 1
|
|
end
|
|
elseif key == keys.up then
|
|
if rCursor > 1 then
|
|
rCursor = rCursor - 1
|
|
term.setCursorPos(sx,sy)
|
|
rite((" "):rep(#output))
|
|
output = (rHistory[rCursor] or ""):sub(1,charLimit or -1)
|
|
cursor = #output+1
|
|
pleaseDoFunc = true
|
|
end
|
|
elseif key == keys.down then
|
|
term.setCursorPos(sx,sy)
|
|
rite((" "):rep(#output))
|
|
if rCursor < #rHistory then
|
|
rCursor = rCursor + 1
|
|
output = (rHistory[rCursor] or ""):sub(1,charLimit or -1)
|
|
cursor = #output+1
|
|
pleaseDoFunc = true
|
|
else
|
|
rCursor = #rHistory+1
|
|
output = ""
|
|
cursor = 1
|
|
end
|
|
elseif key == keys.backspace then
|
|
if cursor > 1 and #output > 0 then
|
|
output = (output:sub(1,cursor-2)..output:sub(cursor)):sub(1,charLimit or -1)
|
|
cursor = cursor - 1
|
|
pleaseDoFunc = true
|
|
end
|
|
elseif key == keys.delete then
|
|
if #output:sub(cursor,cursor) == 1 then
|
|
output = (output:sub(1,cursor-1)..output:sub(cursor+1)):sub(1,charLimit or -1)
|
|
pleaseDoFunc = true
|
|
end
|
|
end
|
|
elseif evt == "char" or evt == "paste" then
|
|
output = (output:sub(1,cursor-1)..key..output:sub(cursor+(#key-1))):sub(1,charLimit or -1)
|
|
cursor = math.min(#output+1,cursor+#key)
|
|
pleaseDoFunc = true
|
|
end
|
|
local pOut = (output or ""):sub(math.max( 1,(#output+sx)-scr_x) )
|
|
if pleaseDoFunc then
|
|
pleaseDoFunc = false
|
|
if type(doFunc) == "function" then
|
|
doFunc(output:sub(1,charLimit or -1))
|
|
end
|
|
term.setCursorPos(sx,sy)
|
|
if repchar then
|
|
rite(repchar:sub(1,1):rep(#pOut))
|
|
else
|
|
rite(pOut)
|
|
end
|
|
term.write(" ")
|
|
end
|
|
term.setCursorPos(sx+cursorAdjFunc(pOut)+cursor-math.max( 1,(#output+sx)-scr_x),sy)
|
|
end
|
|
end
|
|
|
|
local arse, arseSHA, passes
|
|
|
|
local awaitKeyCard = function()
|
|
local bwop,_,side
|
|
repeat
|
|
_,side = os.pullEvent("disk")
|
|
if side then
|
|
bwop = fs.combine(disk.getMountPath(side),".sinepw") --bwop!
|
|
else
|
|
bwop = ""
|
|
end
|
|
until fs.exists(bwop) and not fs.isDir(bwop)
|
|
local file = fs.open(bwop,"r")
|
|
local output = file.readLine()
|
|
file.close()
|
|
arseSHA = output
|
|
if doEjectDisk then disk.eject(side) end
|
|
end
|
|
|
|
local passwordPrompt = function()
|
|
if requireAllPasswords then
|
|
arse = {}
|
|
arseSHA = ""
|
|
for a = 1, ceil(#passes/64) do
|
|
setCursorPos(1,readYpos)
|
|
setBackgroundColor(palate.promptBG)
|
|
term.clearLine()
|
|
setTextColor(palate.promptTXT)
|
|
write("P"..a..">")
|
|
arse[#arse+1] = read(dahChar)
|
|
arseSHA = arseSHA..sha256(arse[#arse],salt)
|
|
end
|
|
else
|
|
setCursorPos(1,readYpos)
|
|
setBackgroundColor(palate.promptBG)
|
|
term.clearLine()
|
|
setTextColor(palate.promptTXT)
|
|
write(">")
|
|
arse = funcread(dahChar,{},nil,true,nil,nil,nil,characterLimit)
|
|
arseSHA = sha256(arse,salt)
|
|
end
|
|
end
|
|
|
|
local count = 0
|
|
|
|
local lock = function()
|
|
if #doorSides > 0 then
|
|
for a = 1, #doorSides do
|
|
redstone.setOutput(doorSides[a],doInvertSignal)
|
|
end
|
|
end
|
|
while true do
|
|
passes, salt = readPassFile()
|
|
count = count + 1
|
|
if doKeyCards then
|
|
parallel.waitForAny(passwordPrompt,awaitKeyCard)
|
|
else
|
|
passwordPrompt()
|
|
end
|
|
local good
|
|
if requireAllPasswords then
|
|
if passes == arseSHA then
|
|
good = true
|
|
else
|
|
good = false
|
|
end
|
|
else
|
|
if string.find(passes,arseSHA) then
|
|
good = true
|
|
else
|
|
good = false
|
|
end
|
|
end
|
|
if good then
|
|
goodpass(arseSHA,count)
|
|
if #doorSides == 0 then
|
|
return true
|
|
else
|
|
doSine = true
|
|
end
|
|
else
|
|
badpass(arseSHA,count)
|
|
end
|
|
end
|
|
end
|
|
|
|
local choice = function(input)
|
|
repeat
|
|
event, key = os.pullEvent("key")
|
|
if type(key) == "number" then key = keys.getName(key) end
|
|
if key == nil then key = " " end
|
|
until string.find(input, key)
|
|
return key
|
|
end
|
|
|
|
if not fs.exists(saltFile) then
|
|
local file = fs.open(saltFile,"w")
|
|
for a = 1, 128 do
|
|
local c = string.char(random(1,255))
|
|
file.write(c)
|
|
end
|
|
file.close()
|
|
local f = fs.open(saltFile,"r")
|
|
salt = f.readLine()
|
|
f.close()
|
|
end
|
|
|
|
passes, salt = readPassFile()
|
|
|
|
local tArg = {...}
|
|
if tArg[1] == "addpass" then
|
|
if tArg[2] then
|
|
print("Really add password? [Y,N]")
|
|
local answer = choice("yn")
|
|
if answer == "n" then
|
|
sleep(0)
|
|
return print("Oh, okay.")
|
|
else
|
|
table.remove(tArg,1)
|
|
addNewPassword(table.concat(tArg," "))
|
|
sleep(0)
|
|
return print("Added password.")
|
|
end
|
|
else
|
|
sleep(0)
|
|
return print("Expected a new password...")
|
|
end
|
|
elseif tArg[1] == "keymake" then
|
|
if tArg[2] then
|
|
print("Really add to disk?")
|
|
print("Keep in mind the password has to be manually added for the keycard to work.\n[Y,N]")
|
|
local answer = choice("yn")
|
|
if answer == "n" then
|
|
sleep(0)
|
|
return print("Oh, okay.")
|
|
else
|
|
print("Please insert a disk or pocket computer.")
|
|
local _,side = os.pullEvent("disk")
|
|
local diskPassPath = fs.combine(disk.getMountPath(side),".sinepw")
|
|
table.remove(tArg,1)
|
|
addNewPassword(table.concat(tArg," "),diskPassPath)
|
|
if not disk.getLabel(side) then
|
|
disk.setLabel(side,"slkey-"..random(1,1000))
|
|
end
|
|
sleep(0)
|
|
print("Added password.")
|
|
if not doKeyCards then
|
|
print("Key cards aren't enabled, though.")
|
|
end
|
|
return
|
|
end
|
|
else
|
|
sleep(0)
|
|
return print("Expected a password...")
|
|
end
|
|
end
|
|
|
|
if not fs.exists(passFile) then
|
|
local progname = fs.getName(shell.getRunningProgram())
|
|
return print("No password file found.\nRun '"..progname.." addpass <password>' to add a password.")
|
|
end
|
|
|
|
setBackgroundColor(colors.black)
|
|
term.clear()
|
|
|
|
local parafunky = { --it looks kinda funky, but it tastes funKAY!
|
|
sine,
|
|
lock,
|
|
}
|
|
|
|
if not beWavey then table.remove(parafunky,1) end --not funky, man
|
|
local staytis, errawr
|
|
while keepLooping do
|
|
kaykaycoolcool = true
|
|
staytis, errawr = pcall(parallel.waitForAny,unpack(parafunky))
|
|
if keepLooping == false then break else
|
|
if terminateMode == 2 then
|
|
kaykaycoolcool = false
|
|
if not isTerminable then
|
|
sillyTerminate()
|
|
else
|
|
keepLooping = false
|
|
setBackgroundColor(colors.black)
|
|
term.clear()
|
|
setTextColor(colors.white)
|
|
setCursorPos(1,1)
|
|
break
|
|
end
|
|
else
|
|
keepLooping = false
|
|
setBackgroundColor(colors.black)
|
|
term.clear()
|
|
setTextColor(colors.white)
|
|
setCursorPos(1,1)
|
|
if not staytis then
|
|
printError(errawr)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if runProgram and (runProgram ~= "") then
|
|
shell.run(runProgram)
|
|
end |