ElDewrito / ElDorito

A Halo Online modification
725 stars 142 forks source link

Presence Discussion #77

Closed kiwidoggie closed 7 years ago

kiwidoggie commented 9 years ago

The current system of things is very messy, also currently does not support all configurations (inbound ports need to be opened, and if a network or configuration is restrictive enough this will not work). There will be quite a few things that we will need to keep track of with this setup.

I suppose that there should be a multiple server-style layout, where there will be a master server that may or may not be public facing to handle all server-server sessions. This will allow one server in this layout without potentially taking down the whole system. For example, if we have user's already active and playing we could take down the login servers for updating, and everyone who is signed in at the time of the take down will stay signed in via sessions until the session is lost or times out, stat's, joining should not be affected.

So these different sections should be (rattling off the top of my head, so feel free to give input) User (logins/acc's) Stats Presence

This should be a very fault tolerable system, so I'm going for a request based system where the client requests for everything, and if anything isn't correct server side then reject the client. Never, EVER, trust the client.

Stuff just got complicated.

emoose commented 9 years ago

Well user logins won't be happening in ED unless we can figure out some decentralized way of doing it. I've seen way too many mod projects that depend on a central server fail because the server was taken down/owners stopped supporting it/etc.

Stats

The way I'd planned for stats is for an RSA keypair to be generated the first time they run the game, with a SHA256 hash of the public key being used as an identifier (only the first 8 bytes are used ingame right now, but I think we could extend it to the full hash)

Then when certain events happen in the game (user killed player, user died, user got a medal..) the client would announce this event to each of the master servers, along with a signature of the event and the public key. Master servers verify the signature with the key and store the event under the key's hash. (if they have stat tracking enabled, none do right now... despite the stats stuff pretty much being done on the client side, and code for verifying signatures already in the master server)

This way nobody can tamper with the stats besides the user, and if they're hacking their stats it's only them that'd be losing out, by not being able to see their legit stats. We can probably detect stat hackers with a few different ways though (anticheat dll, making clients report events for every user and making sure the events corroborate..)

I chose this because it's the only way I can see to be sure that nobody else is tampering with stats, if we made servers report stats I could see modded lobbies making a return, where the server owner could use a modded ED to report 999+ kills for everyone, or maybe someone would make a bad server that reports 999 deaths for everyone.

Like I said the majority of it is already done, we have the keypair generating + data signing stuff ready, and the game currently sends out the players stats at the end of the game, but no master servers are tracking it. (Despite me asking people to wait until a stats server was setup before we released, 0.4.7 got pushed out to the main branch, and was way too early imo...)

Only thing that's missing is code to track the events. ED isn't really setup for events but I suppose something could be added in, but DR has a pretty good events system which would be perfect, we just need to find a hook for the games event system and pass them along to DR's event system.

Presence

I was thinking about using Tox for a presence/friends system. It's decentralized so it'd be perfect to use. Only issue is that it uses 16 byte IDs instead of usernames, so adding friends could be a hassle. I suppose we could probably add another ingame ID field to the games packets and get something in so you can add someone in your current game as a friend though.

kiwidoggie commented 9 years ago

@emoose user login's could easily be done in a decentralized way, part of the backend should be open sourced anyway, if ED's server's go down a admin should be able to spin up their own backend with a few modifications for user login's etc and continue on from there.

Stat's are easy to spoof no matter how you do it, instead of being more restrictive about things like this, you can have a "privileged" server (matchmaking, ran by ED team etc), and then unprivileged servers (custom games, forge etc), where they could be tracked in 2 different area's. With any of these type's of setups, there will need to be server-side verification. (eg, if we find someone boosting a priv'd server, revert stat's changes and revoke priv's access)

Decentralizing everything is not the way to go, it may seem like it in the short run, but they rarely work out as planned. Personally I feel like the backend services/servers should be decentralized, and the client and the api still be centralized. Ex, Client's have to connect to a specified server (can make it configurable), but all other services etc can just "find" each other, or does not need any specific configuration to lets say setup a backend on a local machine or vps.

emoose commented 9 years ago

With a signed stats system it means that nobody else can tamper with it, so the only person who can ruin their stats is themselves, I can't see any other way to do this.

Once we have some anticheat measures in place it'd probably only be a slim minority who'd even be able to mod their stats, which is better than people setting up "MODDED LOBBY 100+ KILLS PER KILL" servers which others can easily join to cheat their stats.

If we did setup a privileged server area/matchmaking maybe we could make those servers use server side stats, but for custom games we shouldn't rely on servers giving legit info.

I don't see any issue with decentralizing everything. There's not really that many services we need, only:

We already have our server browser semi-decentralized by having ~7 master servers, all run by all different people with probably more to come. We'd only have any issues if all of those servers went down at once, but the chance of that happening is much less than one single server going down.

Matchmaking could even work with this system, with the masters handling setting up lobbies and directing them to a server hosted by someone trusted.

Stats has already been done to work with these masters, although if the master is down or fails to connect when the stats announcements are made then the server would be out of sync, I was planning on a way to sync stats between servers though (and because they're signed we can be sure nobody has tampered with them too)

Presence/friends related stuff can be entirely decentralized by piggybacking on Tox's network, only issue with that is the Tox ID stuff I mentioned before, but maybe we could setup a sort of phonebook on the master servers. When a client makes a server list request it passes along their Tox ID and current player name, and the master updates its phonebook with those details. Then when a user wants to find someone by name they can just query all the masters which'd return all the users with that name.

If we were to have a user system and handle presence ourselves we'd have to code up an account system and presence/messaging system, and decentralizing that would be even more work (I'm not even sure how we'd share login details across different servers safely, and then there's the risk of one of the servers being hacked and all the login details compromised/someone leaking them all..), which would all be a large time sink when we already have a Tox library we can use, and building in a phonebook system into the masters would be simple.

TL;DR: we already have a semi-decentralized backend, and presence stuff can be sort-of decentralized too by combining Tox with our backend. I don't really see a need for a user system when there's other ways we can do it which don't need passwords.

Also when I say decentralized I just meant not being run by a single person, I'm fine with us having our backend open source and semi-decentralizing it across several hosts, as long as the game isn't hardcoded to work with only one. Having a fully decentralized system would be nice though, where every user would also act like a master, but that'd be a lot of work to make sure it works right.

kiwidoggie commented 9 years ago

That work would also leave multiple issues, I'm thinking more from a security standpoint of never trust the client. I am fine with the idea of using the key's, but what if I delete my local client file, or somehow becomes corrupted, there is now no way to get that account back. Unless I am missing something here, the point would be is one of the services (account info etc, does not even have to be set up with a password, etc but would solely rely on a user's email never to be compromised), where asymmetric keys could maintain security, whilst also providing a way for a user to recover an account.

emoose commented 9 years ago

The only part we'd need to trust them for is the stats, and I'd rather trust the client that needs to actually hunt down the hack and make sure it still works after we added anticheat etc, which is better than the server that ~16 people can join and automatically get boosted without needing to do anything other than join a server.

The lost key problem is a problem I've thought of, not really sure of the best way to fix it. The email idea is a nice idea actually.. maybe we could add a way for servers to store encrypted private keys (using the password as a crypto key) along with the email, if a user loses their key they can give their email and password, and the master that has the key would decrypt it and send it to their email.

Or we could just use a user/password system for that, where it'd just look up the encrypted private key for that user and try decrypting with their password, if it decrypts properly it'd send it as the response to their request, no need for emails.

I can see a few issues with this system though:

Maybe the bruteforcing problem wouldn't be that bad if we had some decent password requirements though (although I hate password requirements on places I might never use...)

Actually

The email + password idea might be better actually, seeing as the only recipient of the key would be the actual owner. Maybe we could do a system where:

Then if a user loses their keys, they can do a request to the masters for a key recovery. If a master sends back a response that the key was sent then the client won't ask any other masters (to make sure they don't get 7+ emails of the same thing..)

When the user gets their email it'll say something like "Save the following data as keyrecovery.txt, when you launch ElDewrito it'll ask you to input your password. If your password is correct then your keys will recovered."

This way would be pretty secure, since we'd mainly be relying on the users email provider to store the key for us, and they'd need to login to that email provider properly before they get access to the encrypted key blob, meaning the only people who could bruteforce it are the master servers (who we should mostly be able to trust.. mostly) and the user themselves (along with any faulty email providers/NSA who might be listening of course)

kiwidoggie commented 7 years ago

Closing issue because ElDorito is finished development.