- Switch master server protocol to dpmaster for better game separation. Based partly on patch by Zack Middleton

- Get rid of ugly cvars sv_heartbeat and cl_gamename and replace with single com_gamename
- Remove sv_flatline. Flatlines are ignored by dpmaster and are considered to be insecure because flatlines can be udp-spoofed.
This commit is contained in:
Thilo Schulz 2011-07-29 13:46:50 +00:00
parent 23f6fd1633
commit ba385fa43c
9 changed files with 41 additions and 45 deletions

28
README
View file

@ -120,8 +120,6 @@ New cvars
cl_mouseAccelStyle - Set to 1 for QuakeLive mouse acceleration cl_mouseAccelStyle - Set to 1 for QuakeLive mouse acceleration
behaviour, 0 for standard q3 behaviour, 0 for standard q3
cl_mouseAccelOffset - Tuning the acceleration curve, see below cl_mouseAccelOffset - Tuning the acceleration curve, see below
cl_gamename - Gamename sent to master server in
getserversExt query
in_joystickUseAnalog - Do not translate joystick axis events in_joystickUseAnalog - Do not translate joystick axis events
to keyboard commands to keyboard commands
@ -197,6 +195,10 @@ New cvars
through which other processes can control through which other processes can control
the server while it is running. the server while it is running.
Nonfunctional on Windows. Nonfunctional on Windows.
com_gamename - Gamename sent to master server in
getservers[Ext] query and infoResponse
"gamename" infostring value. Also used
for filtering local network games.
com_protocol - Specify protocol version number for com_protocol - Specify protocol version number for
current ioquake3 protocol, see current ioquake3 protocol, see
"Network protocols" section below "Network protocols" section below
@ -210,9 +212,6 @@ New cvars
holds custom pk3 files for your server holds custom pk3 files for your server
sv_banFile - Name of the file that is used for storing sv_banFile - Name of the file that is used for storing
the server bans the server bans
sv_heartbeat - Heartbeat string sent to master server
sv_flatline - Heartbeat string sent to master server
when server is killed
net_ip6 - IPv6 address to bind to net_ip6 - IPv6 address to bind to
net_port6 - port to bind to using the ipv6 address net_port6 - port to bind to using the ipv6 address
@ -527,25 +526,18 @@ Creating standalone games
+set com_homepath <homedirname> +set com_homepath <homedirname>
to the command line. You can also control which kind of messages to send to to the command line. You can also control which game name to use when talking
the master server: to the master server:
+set sv_heartbeat <heartbeat> +set sv_flatline <flatline> +set com_gamename <gamename>
+set cl_gamename <gamename>
The <heartbeat> and <flatline> message can be specific to your game. The So clients requesting a server list will only receive servers that have a
flatline message is sent to signal the master server that the game server is matching game name.
quitting. Vanilla quake3 uses "QuakeArena-1" both for the heartbeat and
flatline messages.
The cl_gamename message is for dpmaster to specify which game the client
wants a server list for. It is only used in the new ipv6 based getServersExt
query.
Example line: Example line:
+set com_basegame basefoo +set com_homepath .foo +set com_basegame basefoo +set com_homepath .foo
+set sv_heartbeat fooalive +set sv_flatline foodead +set com_gamename foo
+set cl_gamename foo
If you really changed parts that would make vanilla ioquake3 incompatible with If you really changed parts that would make vanilla ioquake3 incompatible with

View file

@ -109,8 +109,6 @@ cvar_t *cl_guidServerUniq;
cvar_t *cl_consoleKeys; cvar_t *cl_consoleKeys;
cvar_t *cl_gamename;
clientActive_t cl; clientActive_t cl;
clientConnection_t clc; clientConnection_t clc;
clientStatic_t cls; clientStatic_t cls;
@ -2306,9 +2304,9 @@ void CL_CheckForResend( void ) {
#endif #endif
// The challenge request shall be followed by a client challenge so no malicious server can hijack this connection. // The challenge request shall be followed by a client challenge so no malicious server can hijack this connection.
// Add the heartbeat gamename so the server knows we're running the correct game and can reject the client // Add the gamename so the server knows we're running the correct game or can reject the client
// with a meaningful message // with a meaningful message
Com_sprintf(data, sizeof(data), "getchallenge %d %s", clc.challenge, Cvar_VariableString("sv_heartbeat")); Com_sprintf(data, sizeof(data), "getchallenge %d %s", clc.challenge, com_gamename->string);
NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "%s", data); NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "%s", data);
break; break;
@ -3472,8 +3470,6 @@ void CL_Init( void ) {
// ~ and `, as keys and characters // ~ and `, as keys and characters
cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "~ ` 0x7e 0x60", CVAR_ARCHIVE); cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "~ ` 0x7e 0x60", CVAR_ARCHIVE);
cl_gamename = Cvar_Get("cl_gamename", GAMENAME_FOR_MASTER, CVAR_TEMP);
// userinfo // userinfo
Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE );
@ -3696,9 +3692,19 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
char info[MAX_INFO_STRING]; char info[MAX_INFO_STRING];
char *infoString; char *infoString;
int prot; int prot;
char *gamename;
infoString = MSG_ReadString( msg ); infoString = MSG_ReadString( msg );
// if this isn't the correct gamename, ignore it
gamename = Info_ValueForKey( infoString, "gamename" );
if (gamename && *gamename && strcmp(gamename, com_gamename->string))
{
Com_DPrintf( "Game mismatch in info packet: %s\n", infoString );
return;
}
// if this isn't the correct protocol version, ignore it // if this isn't the correct protocol version, ignore it
prot = atoi( Info_ValueForKey( infoString, "protocol" ) ); prot = atoi( Info_ValueForKey( infoString, "protocol" ) );
@ -4078,16 +4084,17 @@ void CL_GlobalServers_f( void ) {
if(v4enabled) if(v4enabled)
{ {
Com_sprintf(command, sizeof(command), "getserversExt %s %s", Com_sprintf(command, sizeof(command), "getserversExt %s %s",
cl_gamename->string, Cmd_Argv(2)); com_gamename->string, Cmd_Argv(2));
} }
else else
{ {
Com_sprintf(command, sizeof(command), "getserversExt %s %s ipv6", Com_sprintf(command, sizeof(command), "getserversExt %s %s ipv6",
cl_gamename->string, Cmd_Argv(2)); com_gamename->string, Cmd_Argv(2));
} }
} }
else else
Com_sprintf(command, sizeof(command), "getservers %s", Cmd_Argv(2)); Com_sprintf(command, sizeof(command), "getservers %s %s",
com_gamename->string, Cmd_Argv(2));
for (i=3; i < count; i++) for (i=3; i < count; i++)
{ {

View file

@ -85,6 +85,7 @@ cvar_t *com_minimized;
cvar_t *com_maxfpsMinimized; cvar_t *com_maxfpsMinimized;
cvar_t *com_abnormalExit; cvar_t *com_abnormalExit;
cvar_t *com_standalone; cvar_t *com_standalone;
cvar_t *com_gamename;
cvar_t *com_protocol; cvar_t *com_protocol;
#ifdef LEGACY_PROTOCOL #ifdef LEGACY_PROTOCOL
cvar_t *com_legacyprotocol; cvar_t *com_legacyprotocol;
@ -2793,6 +2794,7 @@ void Com_Init( char *commandLine ) {
s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ ); s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ );
com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO ); com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO );
com_gamename = Cvar_Get("com_gamename", GAMENAME_FOR_MASTER, CVAR_SERVERINFO | CVAR_INIT);
com_protocol = Cvar_Get("com_protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO | CVAR_INIT); com_protocol = Cvar_Get("com_protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO | CVAR_INIT);
#ifdef LEGACY_PROTOCOL #ifdef LEGACY_PROTOCOL
com_legacyprotocol = Cvar_Get("com_legacyprotocol", va("%i", PROTOCOL_LEGACY_VERSION), CVAR_INIT); com_legacyprotocol = Cvar_Get("com_legacyprotocol", va("%i", PROTOCOL_LEGACY_VERSION), CVAR_INIT);

View file

@ -31,27 +31,26 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define BASEGAME "foobar" #define BASEGAME "foobar"
#define CLIENT_WINDOW_TITLE "changeme" #define CLIENT_WINDOW_TITLE "changeme"
#define CLIENT_WINDOW_MIN_TITLE "changeme2" #define CLIENT_WINDOW_MIN_TITLE "changeme2"
#define GAMENAME_FOR_MASTER "iofoo3" // must NOT contain whitespaces
#define HEARTBEAT_FOR_MASTER GAMENAME_FOR_MASTER
#define FLATLINE_FOR_MASTER GAMENAME_FOR_MASTER "dead"
#define HOMEPATH_NAME_UNIX ".foo" #define HOMEPATH_NAME_UNIX ".foo"
#define HOMEPATH_NAME_WIN "FooBar" #define HOMEPATH_NAME_WIN "FooBar"
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
#define GAMENAME_FOR_MASTER "foobar" // must NOT contain whitespace
// #define LEGACY_PROTOCOL // You probably don't need this for your standalone game // #define LEGACY_PROTOCOL // You probably don't need this for your standalone game
#else #else
#define PRODUCT_NAME "ioq3" #define PRODUCT_NAME "ioq3"
#define BASEGAME "baseq3" #define BASEGAME "baseq3"
#define CLIENT_WINDOW_TITLE "ioquake3" #define CLIENT_WINDOW_TITLE "ioquake3"
#define CLIENT_WINDOW_MIN_TITLE "ioq3" #define CLIENT_WINDOW_MIN_TITLE "ioq3"
#define GAMENAME_FOR_MASTER "Quake3Arena"
#define HEARTBEAT_FOR_MASTER "QuakeArena-1"
#define FLATLINE_FOR_MASTER HEARTBEAT_FOR_MASTER
#define HOMEPATH_NAME_UNIX ".q3a" #define HOMEPATH_NAME_UNIX ".q3a"
#define HOMEPATH_NAME_WIN "Quake3" #define HOMEPATH_NAME_WIN "Quake3"
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
#define GAMENAME_FOR_MASTER "Quake3Arena"
#define LEGACY_PROTOCOL #define LEGACY_PROTOCOL
#endif #endif
// Heartbeat for dpmaster protocol. You shouldn't change this unless you know what you're doing
#define HEARTBEAT_FOR_MASTER "DarkPlaces"
#define BASETA "missionpack" #define BASETA "missionpack"
#ifndef PRODUCT_VERSION #ifndef PRODUCT_VERSION

View file

@ -870,6 +870,7 @@ extern cvar_t *sv_paused;
extern cvar_t *cl_packetdelay; extern cvar_t *cl_packetdelay;
extern cvar_t *sv_packetdelay; extern cvar_t *sv_packetdelay;
extern cvar_t *com_gamename;
extern cvar_t *com_protocol; extern cvar_t *com_protocol;
#ifdef LEGACY_PROTOCOL #ifdef LEGACY_PROTOCOL
extern cvar_t *com_legacyprotocol; extern cvar_t *com_legacyprotocol;

View file

@ -294,8 +294,6 @@ extern cvar_t *sv_lanForceRate;
extern cvar_t *sv_strictAuth; extern cvar_t *sv_strictAuth;
#endif #endif
extern cvar_t *sv_banFile; extern cvar_t *sv_banFile;
extern cvar_t *sv_heartbeat;
extern cvar_t *sv_flatline;
extern serverBan_t serverBans[SERVER_MAXBANS]; extern serverBan_t serverBans[SERVER_MAXBANS];
extern int serverBansCount; extern int serverBansCount;

View file

@ -70,10 +70,10 @@ void SV_GetChallenge(netadr_t from)
if(gameName && *gameName) if(gameName && *gameName)
{ {
// reject client if the heartbeat string sent by the client doesn't match ours // reject client if the heartbeat string sent by the client doesn't match ours
if(strcmp(gameName, sv_heartbeat->string)) if(strcmp(gameName, com_gamename->string))
{ {
NET_OutOfBandPrint(NS_SERVER, from, "print\nGame mismatch: This is a %s server\n", NET_OutOfBandPrint(NS_SERVER, from, "print\nGame mismatch: This is a %s server\n",
sv_heartbeat->string); com_gamename->string);
return; return;
} }
} }

View file

@ -686,8 +686,6 @@ void SV_Init (void)
sv_strictAuth = Cvar_Get ("sv_strictAuth", "1", CVAR_ARCHIVE ); sv_strictAuth = Cvar_Get ("sv_strictAuth", "1", CVAR_ARCHIVE );
#endif #endif
sv_banFile = Cvar_Get("sv_banFile", "serverbans.dat", CVAR_ARCHIVE); sv_banFile = Cvar_Get("sv_banFile", "serverbans.dat", CVAR_ARCHIVE);
sv_heartbeat = Cvar_Get("sv_heartbeat", HEARTBEAT_FOR_MASTER, CVAR_INIT);
sv_flatline = Cvar_Get("sv_flatline", FLATLINE_FOR_MASTER, CVAR_INIT);
// initialize bot cvars so they are listed and can be set before loading the botlib // initialize bot cvars so they are listed and can be set before loading the botlib
SV_BotInitCvars(); SV_BotInitCvars();

View file

@ -61,9 +61,6 @@ cvar_t *sv_lanForceRate; // dedicated 1 (LAN) server forces local client rates t
cvar_t *sv_strictAuth; cvar_t *sv_strictAuth;
#endif #endif
cvar_t *sv_banFile; cvar_t *sv_banFile;
cvar_t *sv_heartbeat; // Heartbeat string that is sent to the master
cvar_t *sv_flatline; // If the master server supports it we can send a flatline
// when server is killed
serverBan_t serverBans[SERVER_MAXBANS]; serverBan_t serverBans[SERVER_MAXBANS];
int serverBansCount = 0; int serverBansCount = 0;
@ -338,11 +335,11 @@ Informs all masters that this server is going down
void SV_MasterShutdown( void ) { void SV_MasterShutdown( void ) {
// send a hearbeat right now // send a hearbeat right now
svs.nextHeartbeatTime = -9999; svs.nextHeartbeatTime = -9999;
SV_MasterHeartbeat(sv_flatline->string); SV_MasterHeartbeat(HEARTBEAT_FOR_MASTER);
// send it again to minimize chance of drops // send it again to minimize chance of drops
svs.nextHeartbeatTime = -9999; svs.nextHeartbeatTime = -9999;
SV_MasterHeartbeat(sv_flatline->string); SV_MasterHeartbeat(HEARTBEAT_FOR_MASTER);
// when the master tries to poll the server, it won't respond, so // when the master tries to poll the server, it won't respond, so
// it will be removed from the list // it will be removed from the list
@ -644,6 +641,8 @@ void SVC_Info( netadr_t from ) {
// to prevent timed spoofed reply packets that add ghost servers // to prevent timed spoofed reply packets that add ghost servers
Info_SetValueForKey( infostring, "challenge", Cmd_Argv(1) ); Info_SetValueForKey( infostring, "challenge", Cmd_Argv(1) );
Info_SetValueForKey( infostring, "gamename", com_gamename->string );
#ifdef LEGACY_PROTOCOL #ifdef LEGACY_PROTOCOL
if(com_legacyprotocol->integer > 0) if(com_legacyprotocol->integer > 0)
Info_SetValueForKey(infostring, "protocol", va("%i", com_legacyprotocol->integer)); Info_SetValueForKey(infostring, "protocol", va("%i", com_legacyprotocol->integer));
@ -1154,7 +1153,7 @@ void SV_Frame( int msec ) {
SV_SendClientMessages(); SV_SendClientMessages();
// send a heartbeat to the master if needed // send a heartbeat to the master if needed
SV_MasterHeartbeat(sv_heartbeat->string); SV_MasterHeartbeat(HEARTBEAT_FOR_MASTER);
} }
/* /*