ID:114840
 
A friend of mine (Monty2) brought to my attention a great idea for a password login system allowing you to play your character despite your BYONDkey. It was bugged and unreliable, and she asked me to correct this system and reprogram it myself.

Throughout extensive testing, I have found my system reliable and seemingly bug-free.

I don't intend to take credit for the idea, I just wanted to challenge myself to fix a good idea someone else started and didn't follow through with until it was usable.

Comments? Gripes? Let's hear 'em!

Pretty messy, but it's good try at it. You could also stack password_login() by spamming no username, just thought I'd mention that. I'd handle it a bit differently like below.

var/database/database = new

database
proc
account_exists(var/username)
return fexists("accounts/[username].sav")

delete(var/username)
return fdel("accounts/[username].sav")

create_account(var/username, var/password, mob/user)
if(account_exists(username))
alert(user, "An account with that username already exists.")

return 0

var/savefile/F = new("accounts/[username].sav")

F["password"] << md5(password)

return 1

login(var/username, var/password, mob/user)
if(!account_exists(username)) return 0

var/savefile/F = new("accounts/[username].sav")

if(md5(password) != F["password"])
alert(user, "Incorrect username/password combination.")

return 0

return 1

mob
Login()
while( !account_login() )
sleep(1)

alert(src, "Successfully logged in.")

proc/account_login()
var/username = input(src, "Enter the username of the account you would like to create or access.")

if(!username) return 0

var/password = input(src, "Enter the password for this account.")

if(!password) return 0

if(database.account_exists(username))
return database.login(username, password, src)

return database.create_account(username, password, src)


I wouldn't use local saves myself, I'd use a mysql database along with an interface setup to handle the account logins instead of the input pop-ups. The while loop in the login is probably a bit inefficient but it's just to show how it could be done.
You'd probably ship account login into it's own datum. The rationale for this is there are quite a few different ways the developer would like to handle login:

- Keep trying regardless.
- Disconnect after 3 failed attempts.
- Keep trying but disconnect after 3 failed attempts to the same account.
- Disconnect on any failure.

And so on and so forth. The datum lets the developer apply their own logic, and still fit your library.

Further to that, login UI should probably go into it's own datum again, as there are many ways of doing that. If neatly separated, the developer can mix and match UIs and login procedures (or in all likelihood, make their own UI and pick a pre-made login procedure).
Hey I appreciate all of the input. I'm still a novice programmer and am currently toying with my abilities and trying to step outside of my comfort zone on occasions.

My password login system may have been better classified as a demo other than a library. I actually made it in about 20 minutes.

I have only been programming with DM for about a year, which is sad seeing my decade spent (off and on) here with BYOND.

I'm still studying, improving and learning mostly every day.

Thanks again for the input and hopefully we'll be having this discussion soon about a couple of projects I've been working on recently.