The start into connected multi-server. The client is told by the server to disconnect, and connect to another server given by IP/name, and a given port. The client can chose to ignore this. If the client does switch, a disconnect message will notify the old server, which could optionally notify the new server in turn.
This is the minimal in-game support needed to allow for Mods that span mutiple servers. Server-server interaction can be implented in the Game DLL. Persistence is possible. All that is needed is minimal support in the Q3 server/client, to avoid the need of client side proxies.
Abuse by bad map design is countered by allowing the client to simply ignore that message.
The current connect/disconnect handling would have to be extended by one message. A minimal response in terms of acknowledge/disconnect/connect on the client side, based on existing code, has to be available.
unsigned int SVC_SW_ID; char new_server; int port; int player_id; // assigned by serverThis is an offer to the client. If the client ignores it, nothing happens. The server will not disconnect the client.
unsigned int CLC_SW_ID int player_key; // assigned by clientWhy? If we want to transfer client data from one server to another, we need multiserver interaction in the Game DLL. If the server thinks there is a switch, and notifies the new_server, but the client never appears, we might get confusion. However, maybe the client does try, but does not succeed. Thus we also need a switch timeout implemented in all server-server interaction. All this can be done in a modified Game DLL as long as the main engine provides id/key pairs.
unsigned int CLC_SWC_ID int player_id; int player_key;
set switch "0" // prevents switching set switch "250" // maybe check ping?so the player who does not want this will not be transferred. yp>
void (*switch)( char new_server, int port, int player_id );It does not seem useful to add complexity to existing mechanisms (special stufftexts, configstrings). Note that the Game DLL should verify that the new server is up and running prior to sending a switch message to the client.
void (*ClientDisconnect) (edict_t *ent, int player_key );It gets the ACK/player_key (if we want one), or -1 of it was a regular disconnect.
void (*ClientConnect) (edict_t *ent, int player_id, int player_key );The player_id is dynamically assigned by the server, it is not "your id", but "you in this game, today, this server". It does not make sense to store it in gclient_t, as it is only temporary. The player_key would make sure that a client is authentical. If nessary, this could be an encrypted player_id response. Both are transferred from the previous server and the client to the new_server.
In the minimal form (the mod does nothing), this would allow for moving from one map to another without persistence, just spanning servers. If the mod provides all the server-server interaction, you could extend at your hearts content.
In this protocol the client does not tell the new_server where it comes from, and the old server pushes the content on the new server. Alternatively, the client would name the previous server on connect, and the new server would ask for the data, and for authentification.
There is a Server State Passover proposal that could be partly implemented using this mechanism, when the modified DLL also does sufficiently detailed (savegame) state dump. The Passover proposal aims at builtin support to move an ongoing game to another server, which might be relevant for commercial purposes.
This is a simple, completely standalone modification that allows multi-server webs now, and experimentation within the Q3 networking that would benefit the seamless multi server Trinity is aimed at. Various ways to address server-server dependencies, map changes based on available connections, protocols etc. could be experimented with within a mod, given this basic support.
Submitted 980328, revised 980406, revised 980420, comments to Bernd Kreimeier.