melia
melia copied to clipboard
Add basic social server
The social server is a server shared between a group of zones that acts as a hub for social interactions involving multiple servers, such as communication between players crossing channels. It's also what we need for the client to stop spamming me about not being able to connect to it with bright yellow log messages.
Since support for multiple zones is currently limited, we don't need a full-featured social server yet, but we should prepare it for development. This issue for the basic implementation will be considered completed once we don't see yellow anymore and clients are able to log into the social server and communicate with it.
We have an old branch (old/social-server) where we started work on this, but it's very bare-bones and would also need to be updated for our new networking code.
After spending some time with the social server (thanks @SalmanTKhan for the base implementation) I've come to the realization that the current design isn't going to work out well and will require a drastic redesign. This server has special requirements that require it to have constant access to accounts, friends list, chat rooms and more regardless of whether all of the associated users are online. The current solution to this issue is rather suboptimal and not only requires a lot of redundant code, but also constant queries to lists and the database. Even operations that feel like they should be simple require a lot of care.
For example: When someone accepts a friend request we first update the friends list of the user who accepted. Since they are online at that moment this is a simple operation. However, next we have to update the other account. For this operation we first need to figure out whether the other user, who sent the request, is online. If they are, we can update their friends list and send an update to their client. If they aren't online we need to query their friend entry from the database, update it, and then save it again.
This process feels very clunky and is a bit error prone, as one action, updating the friends lists of two users, requires different approaches depending on the state of the accounts. I believe a better solution would be to load users, chat rooms, friends, etc. into the social server to have everything available and then attach connecting players to these objects. This way you could get a user at all times from the user manager, regardless of whether they're online or not. You could update their friends list, reference them in messages and chats, and so on, and if they're online, and a connection is attached to that existing user, then they dynamically receive updates based on the changes made.
This will require a couple modifications to the architecture of the social server, the managers, and the packet handlers, but continuing with the current approach will just create code that's difficult to maintain. And since only basic befriending functions are really working so far, we'll wait with merging the social server branch until these changes were made. The rest should then be fairly simple, when we don't have to fight the architecture anymore.