ID:2130967
 
Concept: There are multiple banks in the game. Users can open an account at the bank, and are given an account number and password. Users can log in to their account to deposit, withdraw or transfer money to other accounts. If the user is careless, someone else can log into their account and steal their money.

Proposed Solution: Use a datum for the accounts and account actions, create a savefile for individual accounts.
Account
var
accOwner // Instant access to account
accBank
accNum
accPass
accCash = 0

New(mob/M,bank)
accOwner = M
accBank = bank
accNum = randomlyGenerated()
accPass = randomlyGenerated()
update()

proc
addCash() // Also update the cash display
// of the owner of the account
removeCash()

update()
var/savefile/F = new/savefile("[accBank]/[accNum].sav")
F << src


Then allow access to the account if you have the account number and password.
proc/accessAccount(bank,accountNumber,accountPassword)
if(fexists("[bank]/[accNum].sav")
var/savefile/F = new/savefile("[bank]/[accNum].sav")
var/Account/a = null
F >> a
if(accountPassword==a.accPass)
//access



So yeah, just wondering if this is the best direction to go in for something like this. Perhaps I should be keeping track of which account the user is currently accessing?

I've been out of the programming game for a while and it's taking some time to get my bearings, so I appreciate the input.
Is theft a mechanic of the game? If so, is there a way for players to acquire this information without being forced to use real-world social engineering techniques to get it? Is there a point where someone having their accounts hacked would lead to frustration of the person being stolen from's part and feel like they were being griefed?

If this isn't a mechanic of the game, then why even bother thinking about this? Bank security could easily be tied to overall account security so you could kill two birds with one stone.
In response to Kats
Kats wrote:
Is theft a mechanic of the game? If so, is there a way for players to acquire this information without being forced to use real-world social engineering techniques to get it? Is there a point where someone having their accounts hacked would lead to frustration of the person being stolen from's part and feel like they were being griefed?

If this isn't a mechanic of the game, then why even bother thinking about this? Bank security could easily be tied to overall account security so you could kill two birds with one stone.

has a point
Yes indeed, theft is a mechanic of the game. All information relating to a users bank accounts can be gained in-game and there will also be safeguards that users can apply to protect their money.

The issue I'm having is not really with the concept itself, but wether or not I am implimenting it in the best way possible.
I was gonna say, I hope you warn your users well enough that their passwords are meant to be stolen; but after actually looking at the code, account names and passwords are randomly generated, so it should be fine as a game mechanic.

About the code itself, there is one major flaw: you're saving and loading the mob with the account. If an account owner is logged in, and someone accesses the account, what probably happens is:
1. The Account is loaded from a savefile.
2. The account owner, "accOwner", refers to a mob, and is loaded along with the Account.
3. The loaded mob is loaded with the mob.key that was saved with it.
4. Any connected client with that key is forced to log out of their current mob, and into the loaded mob. This happens whenever a mob's key is set, such as when it is loaded from a savefile.
5. The account owner is now in control of the mob from the time the account was last updated. (assuming you're not doing character handling in mob/Login(), which is terrible too)

The best solution I've found for this is to either save the key instead of the mob, or manage a set of unique object IDs that is saved and loaded with the world and with the objects themselves, and is capable of locating the object with that ID at any time. There should be no references to players being saved and loaded in a system that can exist without the player.
Yeah, there will be no case where a user has to create his/her own password. Furthermore, the users own account number and password will be automatically entered into the banks login system when they enter, so there is no need for the owner of an account to remember their own login details.

I knew there had to be an issue in there somewhere, so I'm glad I gave the small examples of code. Appreciate the feedback Kaiochao, I'll make sure to address that issue.
When people first think of banking their instinct seems to be first create a Bank object. In reality (at least to me) it makes much more sense to define bank information within the player.

Here's what I mean.

# Case 1 #

You have 5000 player save files. When you start your server you create a Bank object with a list of accounts. That list will be at least 5000 accounts long.

# Case 2 #

You have 5000 player save files. When a player logs-in an account object is created and stored as a Player variable. Any deposits they make go into Player.Deposit(money). There is no bank object. Only an illusion.

When 50 people are on your server there are 50 account objects and 4950 accounts saved in player save files.
In response to Zecronious
For case 1, in my circumstances I wouldn't do it like this. The reason being is that there will be 5 different banks, and I wouldn't want to create massive lists of account numbers and passwords.

Case 2 wouldn't really work for me either as the accounts need to be accessible regardless of wether the account owner is logged in or not.

The way I intended was to create the savefile when the account is created, and load it only when the account number is accessed. That being said, I'm not sure what sort of performance issues or likely bugs this could cause.
In response to Danny Roe
Why does the account need to be accessible when the player is offline?

For example player A is offline and player B online. B sends a $50 deposit to player A. The server recognizes the player is offline and saves to 'playerA deposits.sav'. When player A logs in all deposits in 'playerA deposits.sav' are added to his account.
In response to Zecronious
Danny Roe wrote:
If the user is careless, someone else can log into their account and steal their money.

Danny Roe wrote:
Yes indeed, theft is a mechanic of the game.

In response to Danny Roe
Any thefts can be credited to the player's save file.
In response to Zecronious
Personally, I'd do it much simpler and just have the bank accounts as a separate sav file that just holds a vector of all of the player's bank objects and their respective account info. That way there's no caching or waiting to deposit, it just goes into the bank straight away because it's not explicitly connected to the player.
This would be a good spot to use SQLite, no?
In response to Nadrew
Most people on BYOND don't know how to use the savefiles let alone how to use SQL. I don't usually mention it but yes anywhere you're saving large amounts of data you should probably be using a DBMS.
In response to Kats
You could possibly do that but imagine how large that file is going to be as you go from hundreds of players to thousands.

You could possibly have so many conflicts of people who all want to write to the bank file at the same time and the file is getting so large that each time someone writes, it now takes longer for the next person to write and so it continues.

That suggestion works but it's not very scalable . If each player manages their own banks that's a lot more scalable because you can write in parallel to multiple accounts.

Also, writing to a file is the time expensive write you can possibly do on a computer. SSDs make it better but it's still not very fast. Best to handle as much in-game in main memory and only leave off-line account transactions for save files.