Page 1 of 1

New ACS features for 1.3 - Databases and Accounts

Posted: Sat Dec 06, 2014 2:45 am
by AlexMax
So...yeah, Zandronum 1.3 has been out for a while, and one of the lesser-known features that came with it is the new ACS functions that deal with databases and accounts.

What do the database functions allow you to do? It allows you to save data that you can retrieve at a later date, even after having restarted the server. So you could...say...keep a high score list for a game mode. Or maybe keep track of a player's inventory after they've disconnected. Or maybe keep track of experience points. Or do some other sort of long-term stat tracking, like number of frags per weapon. Lots of possibilities. You can even share data between multiple servers if you want (and if you're careful).

Of course, if you want to tie anything to a particular player, not only does it help if you can save data between servers and across server restarts, but it helps to be able to tell who a player is. This problem is solved by the new account system, and this account system has ACS hooks that allows you to tell what account a player is using - if they're even using an account at all.

In order to use this new functionality, you need a new version of the zdefs.acs and zspecials.acs files for acc. You can grab them below:

I wrote a wiki article that has a short overview of the database functions here:

Wiki Article: Database

...however, it's only a summary and has considerable room for improvement. However, you don't need to memorize all those functions at once - you can simply start with the functions labeled Data retrieval and saving and go from there.

The accounts API doesn't even need its own article, as there are only two functions and their use is simple:

  • PlayerIsLoggedIn(int pid) -> bool loggedin?
  • GetPlayerAccountName(int pid) -> string name
Pass a player id, get the expected result out. You do not need to communicate with the login server yourself, all that is handled for you.

Feel free to ask any questions about either new feature in this thread. As for why I'm posting this - I figured the new features could use some much needed exposure.

RE: New ACS features for 1.3 - Databases and Accounts

Posted: Sat Dec 06, 2014 4:13 pm
by Jwarrier
Just going to mention that I like the idea of account systems and databases, they will bring this port to another level, however it is not logical to have accounts for every server, or every server cluster. Accounts should be global, they should be utilized universally across the port. It would be frustrating to have to type a log in command every time you join a server. Even in the NJ duel test server that was setup recently I would get frustrated when you joined and had to type it in.

I truly believe that Zdaemon's account based system was good, but what could be done with Zandronum could go above and beyond that idea. What are the most common problems right now? Aliasers and ban evaders (IP proxy, IP change). With an account system like Zdameon your account forced your player name. Dumb. Why not allow anyone to use any alias they want, however if they are logged into an account a simple identify command could show any person the master account tied to it. Take this a step further, make every account require an email with verification BEFORE the account is active, thus minimizing the multiple accounts per user (Nothing is perfect of course). Lastly, optional accounts? I say force them. You want to play on a server listed on master server? Login required. The time it would take for a registration, activation, verification is probably 5 minutes tops, and from that point on everything is as usual.

Databases are useful on a per server basis for stat tracking on stats that are not global but things like frags, deaths, points, captures, shot counts per weapon, accuracy, assists those could be centrally stored as well as stored on per server basis. Rant over and out.

P.S. Great work AlexMax!

RE: New ACS features for 1.3 - Databases and Accounts

Posted: Sat Dec 06, 2014 6:26 pm
by AlexMax
This thread was really intended to help introduce modders to the possibilities of using the ACS database and account functions. Nevertheless, I'll see if I can answer your questions.
Jwarrier wrote: Just going to mention that I like the idea of account systems and databases, they will bring this port to another level, however it is not logical to have accounts for every server, or every server cluster. Accounts should be global, they should be utilized universally across the port. It would be frustrating to have to type a log in command every time you join a server. Even in the NJ duel test server that was setup recently I would get frustrated when you joined and had to type it in.
I agree with you! I anticipate that Zandronum.com will eventually run the canonical authentication server and all servers will point to that one authentication server.

For now, I would suggest binding the login command to a key so you can easily log in when you join a server.
Why not allow anyone to use any alias they want, however if they are logged into an account a simple identify command could show any person the master account tied to it.
I think this should be a feature that is built into the current "player info" command, and should be viewable by other clients. I...don't think I've vocalized this request in the tracker though, thanks for reminding me of it.
Take this a step further, make every account require an email with verification BEFORE the account is active, thus minimizing the multiple accounts per user (Nothing is perfect of course).
This already exists, actually. The only issue is that none of the auth servers enable the mailserver support, to my knowledge, and I personally haven't done it for my auth server because the only server I run that requires it is an ELO duel test server, and I would rather signing up be easy so people can help test. I anticipate that the Zandronum.com auth server will enable this feature.
Lastly, optional accounts? I say force them. You want to play on a server listed on master server? Login required. The time it would take for a registration, activation, verification is probably 5 minutes tops, and from that point on everything is as usual.
I disagree - it should be up to the individual server administrator if players are required to log in before playing. I would not have even agreed to work on this account system if that's the way it was headed. Server administrators can already prevent players from joining the game unless they're logged in. In the future, I anticipate that more features will become available, such as the ability to prevent people from connecting unless they authenticate, and the ability to whitelist or blacklist certain accounts from connecting or joining by account name.
Databases are useful on a per server basis for stat tracking on stats that are not global but things like frags, deaths, points, captures, shot counts per weapon, accuracy, assists those could be centrally stored as well as stored on per server basis. Rant over and out.
That's a whole other kettle of fish. Stat collection and experience requires a level of trust (you don't want a server to send you fake data) but personally, I never liked how ZDaemon kept such tight control over which servers were allowed to have experience and which ones weren't. I think server owners should be able to collect experience and stats on their own, and if groups of server owners want to aggregate their stats together, that's their business.

How would you aggregate stats to one place? Zandronum databases do not support networking, but they're just normal SQLite3 files that can be looked at with any language with SQLite3 bindings available. You could probably create a python script that reads stats out of the database and then sends them over the network to someplace centralized. But I don't think Zandronum.com is necessarily the best place to store these stats.

RE: New ACS features for 1.3 - Databases and Accounts

Posted: Sat Dec 06, 2014 9:31 pm
by Tiger
Thank you for adding the information on to the Zandronum Wiki :)

RE: New ACS features for 1.3 - Databases and Accounts

Posted: Sun Dec 07, 2014 12:53 am
by ibm5155
Is there a kind of information limit? (like I can just store 10 vars by user) and can a mod crash a database? (like addding too much data on it)
idk how does it work but it would be something like this
int x=0;
while(true){
x=rand(0,99999999999999999999999999999999999999999999999999999999);
add_data(player_name,x,rand(0,99999999999999);
delay(1);
}
where x would be the data name ( ex: "higher jump")

at the end I'm just curious if it's exploit free :S

RE: New ACS features for 1.3 - Databases and Accounts

Posted: Sun Dec 07, 2014 3:30 am
by Hypnotoad
If you spam too many database queries a tic it will slow down the server, causing ping spikes for everyone. There is a max size the database can be, set by some server variable.

RE: New ACS features for 1.3 - Databases and Accounts

Posted: Sun Dec 07, 2014 3:38 am
by Watermelon
ibm5155 wrote: Is there a kind of information limit? (like I can just store 10 vars by user) and can a mod crash a database? (like addding too much data on it)
idk how does it work but it would be something like this
int x=0;
while(true){
x=rand(0,99999999999999999999999999999999999999999999999999999999);
add_data(player_name,x,rand(0,99999999999999);
delay(1);
}
where x would be the data name ( ex: "higher jump")

at the end I'm just curious if it's exploit free :S
Pro tip

USE SPACES IN CODE SO IT DOESN'T MAKE US WANT TO RIP OUR EYES OUT

Is it so hard to type

Code: Select all

int x = 0;
while (true) {
x = rand(0, 123456789);
add_data(player_name, x, rand(0, 123456789)); // Missing a bracket
delay(1);
}
Look how nice that is to read!

RE: New ACS features for 1.3 - Databases and Accounts

Posted: Sun Dec 07, 2014 6:12 am
by AlexMax
ibm5155 wrote: Is there a kind of information limit? (like I can just store 10 vars by user) and can a mod crash a database? (like addding too much data on it)
idk how does it work but it would be something like this
int x=0;
while(true){
x=rand(0,99999999999999999999999999999999999999999999999999999999);
add_data(player_name,x,rand(0,99999999999999);
delay(1);
}
where x would be the data name ( ex: "higher jump")

at the end I'm just curious if it's exploit free :S
You are limited to a mere 18,446,744,073,709,551,616 rows per database file (this is inclusive of all namespaces and keys). The database file can be no larger than 140 terabytes. Namespace, key and value names are limited to 2,147,483,647 characters. Hopefully, this will be large enough for your uses.

That said, keep in mind that every database query you make will pause the game until the database query is complete. If you want to write a bunch of data to the database all at once, use transactions. The good news is that transactions are REALLY easy to use:

Code: Select all

BeginDBTransaction();

// Add all your data here
for (int i = 0;i < 64;i++) {
    SetDBEntry("lastscores", player_name[i], player_score[i]);
}

EndDBTransaction();
When you begin a transaction, any "Set" function you use afterwards won't actually write anything to the database until you end of the transaction, at which point all of the data is written at once. So in the pseudo-code above, instead of doing 64 separate writes, it will do one big write of all the data at the very bottom of the script. This one big write in a transaction is MUCH faster than 64 separate writes.

Transactions not only make things faster, they can ensure that your database is not left in a broken state! Here's another example.

Code: Select all

// One player buys a weapon from another player

BeginDBTransaction();

// Remove the amount of cash from the buyer's wallet.
IncrementDBEntry("money", player_names[buyer], price * -1);

// Give the buying player a weapon.
IncrementDBEntry("inventory", player_names[buyer] .. "_weapons", 1);

// Add the amount of cash to the seller's wallet.
IncrementDBEntry("money", player_names[seller], price);

// Remove a weapon from the seller's inventory.
IncrementDBEntry("inventory", player_names[seller] .. "_weapons", -1);

EndDBTransaction();
Imagine what would happen if Zandronum crashed in the middle of that function. If there were no transactions, when you bring the server back up you might see an anomaly like a weapon being duplicated or the seller not having the correct funds added to his wallet.

However, with a transaction, if Zandronum crashes in the middle of that function, nothing is written to the database and things remain consistent.