mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
Revert protocol 69 pending further discussion (#4962)
This commit is contained in:
parent
88693f9abd
commit
d34c6b7e0b
12 changed files with 247 additions and 508 deletions
382
README
382
README
|
@ -214,15 +214,9 @@ New cvars
|
|||
ipv6 servers on the local network
|
||||
net_mcastiface - outgoing interface to use for scan
|
||||
|
||||
oldprotocol - when encountering a server/client that
|
||||
only supports the version configured in
|
||||
this cvar, ioquake3 will use the old and
|
||||
less secure protocol from quake3 1.32c.
|
||||
protocol - Allow changing protocol version
|
||||
(startup only)
|
||||
|
||||
protocol - Allow changing protocol version that is
|
||||
sent to the server (startup only)
|
||||
|
||||
r_allowResize - make window resizable (SDL only)
|
||||
r_ext_texture_filter_anisotropic - anisotropic texture filtering
|
||||
r_zProj - distance of observer camera to projection
|
||||
|
@ -283,8 +277,7 @@ New commands
|
|||
|
||||
which <filename/path> - print out the path on disk to a loaded item
|
||||
|
||||
|
||||
--------------------------------------------------------- README for Users -----
|
||||
------------------------------------------------------------ Miscellaneous -----
|
||||
|
||||
Using shared libraries instead of qvm
|
||||
To force Q3 to use shared libraries instead of qvms run it with the following
|
||||
|
@ -312,6 +305,175 @@ Help! Ioquake3 won't give me an fps of X anymore when setting com_maxfps!
|
|||
In this case you can always revert back to the old behaviour by setting the
|
||||
cvar com_busyWait to 1.
|
||||
|
||||
QuakeLive mouse acceleration (patch and this text written by TTimo from id)
|
||||
I've been using an experimental mouse acceleration code for a while, and
|
||||
decided to make it available to everyone. Don't be too worried if you don't
|
||||
understand the explanations below, this is mostly intended for advanced
|
||||
players:
|
||||
To enable it, set cl_mouseAccelStyle 1 (0 is the default/legacy behavior)
|
||||
|
||||
New style is controlled with 3 cvars:
|
||||
|
||||
sensitivity
|
||||
cl_mouseAccel
|
||||
cl_mouseAccelOffset
|
||||
|
||||
The old code (cl_mouseAccelStyle 0) can be difficult to calibrate because if
|
||||
you have a base sensitivity setup, as soon as you set a non zero acceleration
|
||||
your base sensitivity at low speeds will change as well. The other problem
|
||||
with style 0 is that you are stuck on a square (power of two) acceleration
|
||||
curve.
|
||||
|
||||
The new code tries to solve both problems:
|
||||
|
||||
Once you setup your sensitivity to feel comfortable and accurate enough for
|
||||
low mouse deltas with no acceleration (cl_mouseAccel 0), you can start
|
||||
increasing cl_mouseAccel and tweaking cl_mouseAccelOffset to get the
|
||||
amplification you want for high deltas with little effect on low mouse deltas.
|
||||
|
||||
cl_mouseAccel is a power value. Should be >= 1, 2 will be the same power curve
|
||||
as style 0. The higher the value, the faster the amplification grows with the
|
||||
mouse delta.
|
||||
|
||||
cl_mouseAccelOffset sets how much base mouse delta will be doubled by
|
||||
acceleration. The closer to zero you bring it, the more acceleration will
|
||||
happen at low speeds. This is also very useful if you are changing to a new
|
||||
mouse with higher dpi, if you go from 500 to 1000 dpi, you can divide your
|
||||
cl_mouseAccelOffset by two to keep the same overall 'feel' (you will likely
|
||||
gain in precision when you do that, but that is not related to mouse
|
||||
acceleration).
|
||||
|
||||
Mouse acceleration is tricky to configure, and when you do you'll have to
|
||||
re-learn your aiming. But you will find that it's very much forth it in the
|
||||
long run.
|
||||
|
||||
If you try the new acceleration code and start using it, I'd be very
|
||||
interested by your feedback.
|
||||
|
||||
64bit mods
|
||||
If you wish to compile external mods as shared libraries on a 64bit platform,
|
||||
and the mod source is derived from the id Q3 SDK, you will need to modify the
|
||||
interface code a little. Open the files ending in _syscalls.c and change
|
||||
every instance of int to intptr_t in the declaration of the syscall function
|
||||
pointer and the dllEntry function. Also find the vmMain function for each
|
||||
module (usually in cg_main.c g_main.c etc.) and similarly replace the return
|
||||
value in the prototype with intptr_t (arg0, arg1, ...stay int).
|
||||
|
||||
Add the following code snippet to q_shared.h:
|
||||
|
||||
#ifdef Q3_VM
|
||||
typedef int intptr_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
Note if you simply wish to run mods on a 64bit platform you do not need to
|
||||
recompile anything since by default Q3 uses a virtual machine system.
|
||||
|
||||
Creating mods compatible with Q3 1.32b
|
||||
If you're using this package to create mods for the last official release of
|
||||
Q3, it is necessary to pass the commandline option '-vq3' to your invocation
|
||||
of q3asm. This is because by default q3asm outputs an updated qvm format that
|
||||
is necessary to fix a bug involving the optimizing pass of the x86 vm JIT
|
||||
compiler.
|
||||
|
||||
Creating standalone games
|
||||
Have you finished the daunting task of removing all dependencies on the Q3
|
||||
game data? You probably now want to give your users the opportunity to play
|
||||
the game without owning a copy of Q3, which consequently means removing cd-key
|
||||
and authentication server checks. In addition to being a straightforward Q3
|
||||
client, ioquake3 also purports to be a reliable and stable code base on which
|
||||
to base your game project.
|
||||
|
||||
However, before you start compiling your own version of ioquake3, you have to
|
||||
ask yourself: Have we changed or will we need to change anything of importance
|
||||
in the engine?
|
||||
|
||||
If your answer to this question is "no", it probably makes no sense to build
|
||||
your own binaries. Instead, you can just use the pre-built binaries on the
|
||||
website. Just make sure the game is called with:
|
||||
|
||||
+set com_basegame <yournewbase>
|
||||
|
||||
in any links/scripts you install for your users to start the game. The
|
||||
binary must not detect any original quake3 game pak files. If this
|
||||
condition is met, the game will set com_standalone to 1 and is then running
|
||||
in stand alone mode.
|
||||
|
||||
If you want the engine to use a different directory in your homepath than
|
||||
e.g. "Quake3" on Windows or ".q3a" on Linux, then set a new name at startup
|
||||
by adding
|
||||
|
||||
+set com_homepath <homedirname>
|
||||
|
||||
to the command line. Then you can control which kind of messages to send to
|
||||
the master server:
|
||||
|
||||
+set sv_heartbeat <heartbeat> +set sv_flatline <flatline>
|
||||
+set cl_gamename <gamename>
|
||||
|
||||
The <heartbeat> and <flatline> message can be specific to your game. The
|
||||
flatline message is sent to signal the master server that the game server is
|
||||
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:
|
||||
|
||||
+set com_basegame basefoo +set com_homepath .foo
|
||||
+set sv_heartbeat fooalive +set sv_flatline foodead
|
||||
+set cl_gamename foo
|
||||
|
||||
|
||||
If you really changed parts that would make vanilla ioquake3 incompatible with
|
||||
your mod, we have included another way to conveniently build a stand-alone
|
||||
binary. Just run make with the option BUILD_STANDALONE=1. Don't forget to edit
|
||||
the PRODUCT_NAME and subsequent #defines in qcommon/q_shared.h with
|
||||
information appropriate for your project.
|
||||
|
||||
While a lot of work has been put into ioquake3 that you can benefit from free
|
||||
of charge, it does not mean that you have no obligations to fulfil. Please be
|
||||
aware that as soon as you start distributing your game with an engine based on
|
||||
our sources we expect you to fully comply with the requirements as stated in
|
||||
the GPL. That includes making sources and modifications you made to the
|
||||
ioquake3 engine as well as the game-code used to compile the .qvm files for
|
||||
the game logic freely available to everyone. Furthermore, note that the "QIIIA
|
||||
Game Source License" prohibits distribution of mods that are intended to
|
||||
operate on a version of Q3 not sanctioned by id software:
|
||||
|
||||
"with this Agreement, ID grants to you the non-exclusive and limited right
|
||||
to distribute copies of the Software ... for operation only with the full
|
||||
version of the software game QUAKE III ARENA"
|
||||
|
||||
This means that if you're creating a standalone game, you cannot use said
|
||||
license on any portion of the product. As the only other license this code has
|
||||
been released under is the GPL, this is the only option.
|
||||
|
||||
This does NOT mean that you cannot market this game commercially. The GPL does
|
||||
not prohibit commercial exploitation and all assets (e.g. textures, sounds,
|
||||
maps) created by yourself are your property and can be sold like every other
|
||||
game you find in stores.
|
||||
|
||||
cl_guid Support
|
||||
cl_guid is a cvar which is part of the client's USERINFO string. Its value
|
||||
is a 32 character string made up of [a-f] and [0-9] characters. This
|
||||
value is pseudo-unique for every player. Id's Quake 3 Arena client also
|
||||
sets cl_guid, but only if Punkbuster is enabled on the client.
|
||||
|
||||
If cl_guidServerUniq is non-zero (the default), then this value is also
|
||||
pseudo-unique for each server a client connects to (based on IP:PORT of
|
||||
the server).
|
||||
|
||||
The purpose of cl_guid is to add an identifier for each player on
|
||||
a server. This value can be reset by the client at any time so it's not
|
||||
useful for blocking access. However, it can have at least two uses in
|
||||
your mod's game code:
|
||||
1) improve logging to allow statistical tools to index players by more
|
||||
than just name
|
||||
2) granting some weak admin rights to players without requiring passwords
|
||||
|
||||
Using HTTP/FTP Download Support (Server)
|
||||
You can enable redirected downloads on your server even if it's not
|
||||
an ioquake3 server. You simply need to use the 'sets' command to put
|
||||
|
@ -415,208 +577,6 @@ SDL Keyboard Differences
|
|||
text. Also, in addition to the nominated console keys, Shift-ESC is hard
|
||||
coded to always toggle the console.
|
||||
|
||||
QuakeLive mouse acceleration (patch and this text written by TTimo from id)
|
||||
I've been using an experimental mouse acceleration code for a while, and
|
||||
decided to make it available to everyone. Don't be too worried if you don't
|
||||
understand the explanations below, this is mostly intended for advanced
|
||||
players:
|
||||
To enable it, set cl_mouseAccelStyle 1 (0 is the default/legacy behavior)
|
||||
|
||||
New style is controlled with 3 cvars:
|
||||
|
||||
sensitivity
|
||||
cl_mouseAccel
|
||||
cl_mouseAccelOffset
|
||||
|
||||
The old code (cl_mouseAccelStyle 0) can be difficult to calibrate because if
|
||||
you have a base sensitivity setup, as soon as you set a non zero acceleration
|
||||
your base sensitivity at low speeds will change as well. The other problem
|
||||
with style 0 is that you are stuck on a square (power of two) acceleration
|
||||
curve.
|
||||
|
||||
The new code tries to solve both problems:
|
||||
|
||||
Once you setup your sensitivity to feel comfortable and accurate enough for
|
||||
low mouse deltas with no acceleration (cl_mouseAccel 0), you can start
|
||||
increasing cl_mouseAccel and tweaking cl_mouseAccelOffset to get the
|
||||
amplification you want for high deltas with little effect on low mouse deltas.
|
||||
|
||||
cl_mouseAccel is a power value. Should be >= 1, 2 will be the same power curve
|
||||
as style 0. The higher the value, the faster the amplification grows with the
|
||||
mouse delta.
|
||||
|
||||
cl_mouseAccelOffset sets how much base mouse delta will be doubled by
|
||||
acceleration. The closer to zero you bring it, the more acceleration will
|
||||
happen at low speeds. This is also very useful if you are changing to a new
|
||||
mouse with higher dpi, if you go from 500 to 1000 dpi, you can divide your
|
||||
cl_mouseAccelOffset by two to keep the same overall 'feel' (you will likely
|
||||
gain in precision when you do that, but that is not related to mouse
|
||||
acceleration).
|
||||
|
||||
Mouse acceleration is tricky to configure, and when you do you'll have to
|
||||
re-learn your aiming. But you will find that it's very much forth it in the
|
||||
long run.
|
||||
|
||||
If you try the new acceleration code and start using it, I'd be very
|
||||
interested by your feedback.
|
||||
|
||||
|
||||
---------------------------------------------------- README for Developers -----
|
||||
|
||||
64bit mods
|
||||
If you wish to compile external mods as shared libraries on a 64bit platform,
|
||||
and the mod source is derived from the id Q3 SDK, you will need to modify the
|
||||
interface code a little. Open the files ending in _syscalls.c and change
|
||||
every instance of int to intptr_t in the declaration of the syscall function
|
||||
pointer and the dllEntry function. Also find the vmMain function for each
|
||||
module (usually in cg_main.c g_main.c etc.) and similarly replace the return
|
||||
value in the prototype with intptr_t (arg0, arg1, ...stay int).
|
||||
|
||||
Add the following code snippet to q_shared.h:
|
||||
|
||||
#ifdef Q3_VM
|
||||
typedef int intptr_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
Note if you simply wish to run mods on a 64bit platform you do not need to
|
||||
recompile anything since by default Q3 uses a virtual machine system.
|
||||
|
||||
Creating mods compatible with Q3 1.32b
|
||||
If you're using this package to create mods for the last official release of
|
||||
Q3, it is necessary to pass the commandline option '-vq3' to your invocation
|
||||
of q3asm. This is because by default q3asm outputs an updated qvm format that
|
||||
is necessary to fix a bug involving the optimizing pass of the x86 vm JIT
|
||||
compiler.
|
||||
|
||||
Creating standalone games
|
||||
Have you finished the daunting task of removing all dependencies on the Q3
|
||||
game data? You probably now want to give your users the opportunity to play
|
||||
the game without owning a copy of Q3, which consequently means removing cd-key
|
||||
and authentication server checks. In addition to being a straightforward Q3
|
||||
client, ioquake3 also purports to be a reliable and stable code base on which
|
||||
to base your game project.
|
||||
|
||||
However, before you start compiling your own version of ioquake3, you have to
|
||||
ask yourself: Have we changed or will we need to change anything of importance
|
||||
in the engine?
|
||||
|
||||
If your answer to this question is "no", it probably makes no sense to build
|
||||
your own binaries. Instead, you can just use the pre-built binaries on the
|
||||
website. Just make sure the game is called with:
|
||||
|
||||
+set com_basegame <yournewbase>
|
||||
|
||||
in any links/scripts you install for your users to start the game. The
|
||||
binary must not detect any original quake3 game pak files. If this
|
||||
condition is met, the game will set com_standalone to 1 and is then running
|
||||
in stand alone mode.
|
||||
|
||||
If you want the engine to use a different directory in your homepath than
|
||||
e.g. "Quake3" on Windows or ".q3a" on Linux, then set a new name at startup
|
||||
by adding
|
||||
|
||||
+set com_homepath <homedirname>
|
||||
|
||||
to the command line. You can also control which kind of messages to send to
|
||||
the master server:
|
||||
|
||||
+set sv_heartbeat <heartbeat> +set sv_flatline <flatline>
|
||||
+set cl_gamename <gamename>
|
||||
|
||||
The <heartbeat> and <flatline> message can be specific to your game. The
|
||||
flatline message is sent to signal the master server that the game server is
|
||||
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:
|
||||
|
||||
+set com_basegame basefoo +set com_homepath .foo
|
||||
+set sv_heartbeat fooalive +set sv_flatline foodead
|
||||
+set cl_gamename foo
|
||||
|
||||
|
||||
If you really changed parts that would make vanilla ioquake3 incompatible with
|
||||
your mod, we have included another way to conveniently build a stand-alone
|
||||
binary. Just run make with the option BUILD_STANDALONE=1. Don't forget to edit
|
||||
the PRODUCT_NAME and subsequent #defines in qcommon/q_shared.h with
|
||||
information appropriate for your project.
|
||||
|
||||
While a lot of work has been put into ioquake3 that you can benefit from free
|
||||
of charge, it does not mean that you have no obligations to fulfil. Please be
|
||||
aware that as soon as you start distributing your game with an engine based on
|
||||
our sources we expect you to fully comply with the requirements as stated in
|
||||
the GPL. That includes making sources and modifications you made to the
|
||||
ioquake3 engine as well as the game-code used to compile the .qvm files for
|
||||
the game logic freely available to everyone. Furthermore, note that the "QIIIA
|
||||
Game Source License" prohibits distribution of mods that are intended to
|
||||
operate on a version of Q3 not sanctioned by id software:
|
||||
|
||||
"with this Agreement, ID grants to you the non-exclusive and limited right
|
||||
to distribute copies of the Software ... for operation only with the full
|
||||
version of the software game QUAKE III ARENA"
|
||||
|
||||
This means that if you're creating a standalone game, you cannot use said
|
||||
license on any portion of the product. As the only other license this code has
|
||||
been released under is the GPL, this is the only option.
|
||||
|
||||
This does NOT mean that you cannot market this game commercially. The GPL does
|
||||
not prohibit commercial exploitation and all assets (e.g. textures, sounds,
|
||||
maps) created by yourself are your property and can be sold like every other
|
||||
game you find in stores.
|
||||
|
||||
Network protocols
|
||||
There are now two cvars that give you some degree of freedom over the reported
|
||||
protocol versions between clients and servers: "protocol" and "oldprotocol".
|
||||
The reason for this is that some standalone games increased the protocol
|
||||
number even though nothing really changed in their protocol and the ioquake3
|
||||
engine is still fully compatible.
|
||||
|
||||
In order to fix a vulnerability in the network protocol as outlined in
|
||||
|
||||
http://aluigi.altervista.org/papers/q3noclient.txt
|
||||
|
||||
a new network protocol was introduced that defends against such attacks.
|
||||
Unfortunately, this protocol will be incompatible to the original quake3 1.32c
|
||||
which is the latest official release from id.
|
||||
Luckily, ioquake3 has backwards compatibility, on the client as well as on the
|
||||
server. This means ioquake3 players can play on old servers just as ioquake3
|
||||
servers are able to service old clients.
|
||||
|
||||
The cvar "protocol" denotes the protocol version for the new hardened
|
||||
protocol, whereas the "oldprotocol" cvar denotes the protocol version for the
|
||||
legacy protocol.
|
||||
If the value for "oldprotocol" and "protocol" is identical, then the legacy
|
||||
protocol is always used. If oldprotocol is set to 0, then support for the
|
||||
legacy protocol is disabled.
|
||||
|
||||
Mods that use a standalone engine obviously do not require dual protocol
|
||||
support, and it is turned off if the engine is compiled with STANDALONE per
|
||||
default. You can enable it in q_shared.h if desired by defining
|
||||
PROTOCOL_SUPPORT_OLD.
|
||||
|
||||
cl_guid Support
|
||||
cl_guid is a cvar which is part of the client's USERINFO string. Its value
|
||||
is a 32 character string made up of [a-f] and [0-9] characters. This
|
||||
value is pseudo-unique for every player. Id's Quake 3 Arena client also
|
||||
sets cl_guid, but only if Punkbuster is enabled on the client.
|
||||
|
||||
If cl_guidServerUniq is non-zero (the default), then this value is also
|
||||
pseudo-unique for each server a client connects to (based on IP:PORT of
|
||||
the server).
|
||||
|
||||
The purpose of cl_guid is to add an identifier for each player on
|
||||
a server. This value can be reset by the client at any time so it's not
|
||||
useful for blocking access. However, it can have at least two uses in
|
||||
your mod's game code:
|
||||
1) improve logging to allow statistical tools to index players by more
|
||||
than just name
|
||||
2) granting some weak admin rights to players without requiring passwords
|
||||
|
||||
PNG support
|
||||
ioquake3 supports the use of PNG (Portable Network Graphic) images as
|
||||
textures. It should be noted that the use of such images in a map will
|
||||
|
|
|
@ -533,6 +533,7 @@ void CL_WriteDemoMessage ( msg_t *msg, int headerBytes ) {
|
|||
len = clc.serverMessageSequence;
|
||||
swlen = LittleLong( len );
|
||||
FS_Write (&swlen, 4, clc.demofile);
|
||||
|
||||
// skip the packet sequencing information
|
||||
len = msg->cursize - headerBytes;
|
||||
swlen = LittleLong(len);
|
||||
|
@ -635,24 +636,14 @@ void CL_Record_f( void ) {
|
|||
if ( Cmd_Argc() == 2 ) {
|
||||
s = Cmd_Argv(1);
|
||||
Q_strncpyz( demoName, s, sizeof( demoName ) );
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(clc.compat)
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_oldprotocol->integer);
|
||||
else
|
||||
#endif
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer);
|
||||
Com_sprintf (name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer );
|
||||
} else {
|
||||
int number;
|
||||
|
||||
// scan for a free demo name
|
||||
for ( number = 0 ; number <= 9999 ; number++ ) {
|
||||
CL_DemoFilename( number, demoName );
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(clc.compat)
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_oldprotocol->integer);
|
||||
else
|
||||
#endif
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer);
|
||||
Com_sprintf (name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer );
|
||||
|
||||
if (!FS_FileExists(name))
|
||||
break; // file doesn't exist
|
||||
|
@ -674,6 +665,7 @@ void CL_Record_f( void ) {
|
|||
clc.spDemoRecording = qfalse;
|
||||
}
|
||||
|
||||
|
||||
Q_strncpyz( clc.demoName, demoName, sizeof( clc.demoName ) );
|
||||
|
||||
// don't start saving messages until a non-delta compressed message is received
|
||||
|
@ -897,62 +889,36 @@ void CL_ReadDemoMessage( void ) {
|
|||
CL_WalkDemoExt
|
||||
====================
|
||||
*/
|
||||
static int CL_WalkDemoExt(char *arg, char *name, int *demofile)
|
||||
static void CL_WalkDemoExt(char *arg, char *name, int *demofile)
|
||||
{
|
||||
int i = 0;
|
||||
*demofile = 0;
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(com_oldprotocol->integer > 0)
|
||||
{
|
||||
Com_sprintf(name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, com_oldprotocol->integer);
|
||||
FS_FOpenFileRead(name, demofile, qtrue);
|
||||
|
||||
if (*demofile)
|
||||
{
|
||||
Com_Printf("Demo file: %s\n", name);
|
||||
return com_oldprotocol->integer;
|
||||
}
|
||||
}
|
||||
|
||||
if(com_protocol->integer != com_oldprotocol->integer)
|
||||
#endif
|
||||
{
|
||||
Com_sprintf(name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, com_protocol->integer);
|
||||
FS_FOpenFileRead(name, demofile, qtrue);
|
||||
Com_sprintf (name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, com_protocol->integer);
|
||||
|
||||
if (*demofile)
|
||||
{
|
||||
Com_Printf("Demo file: %s\n", name);
|
||||
return com_protocol->integer;
|
||||
}
|
||||
FS_FOpenFileRead( name, demofile, qtrue );
|
||||
|
||||
if (*demofile)
|
||||
{
|
||||
Com_Printf("Demo file: %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf("Not found: %s\n", name);
|
||||
|
||||
while(demo_protocols[i])
|
||||
{
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(demo_protocols[i] == com_oldprotocol->integer)
|
||||
continue;
|
||||
#endif
|
||||
if(demo_protocols[i] == com_protocol->integer)
|
||||
continue;
|
||||
|
||||
Com_sprintf (name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, demo_protocols[i]);
|
||||
FS_FOpenFileRead( name, demofile, qtrue );
|
||||
if (*demofile)
|
||||
{
|
||||
Com_Printf("Demo file: %s\n", name);
|
||||
|
||||
return demo_protocols[i];
|
||||
break;
|
||||
}
|
||||
else
|
||||
Com_Printf("Not found: %s\n", name);
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1012,11 +978,7 @@ void CL_PlayDemo_f( void ) {
|
|||
break;
|
||||
}
|
||||
|
||||
if(demo_protocols[i] || protocol == com_protocol->integer
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
|| protocol == com_oldprotocol->integer
|
||||
#endif
|
||||
)
|
||||
if(demo_protocols[i] || protocol == com_protocol->integer)
|
||||
{
|
||||
Com_sprintf(name, sizeof(name), "demos/%s", arg);
|
||||
FS_FOpenFileRead(name, &clc.demofile, qtrue);
|
||||
|
@ -1033,11 +995,11 @@ void CL_PlayDemo_f( void ) {
|
|||
|
||||
Q_strncpyz(retry, arg, len + 1);
|
||||
retry[len] = '\0';
|
||||
protocol = CL_WalkDemoExt(retry, name, &clc.demofile);
|
||||
CL_WalkDemoExt(retry, name, &clc.demofile);
|
||||
}
|
||||
}
|
||||
else
|
||||
protocol = CL_WalkDemoExt(arg, name, &clc.demofile);
|
||||
CL_WalkDemoExt(arg, name, &clc.demofile);
|
||||
|
||||
if (!clc.demofile) {
|
||||
Com_Error( ERR_DROP, "couldn't open %s", name);
|
||||
|
@ -1051,13 +1013,6 @@ void CL_PlayDemo_f( void ) {
|
|||
clc.demoplaying = qtrue;
|
||||
Q_strncpyz( cls.servername, Cmd_Argv(1), sizeof( cls.servername ) );
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(protocol <= com_oldprotocol->integer)
|
||||
clc.compat = qtrue;
|
||||
else
|
||||
clc.compat = qfalse;
|
||||
#endif
|
||||
|
||||
// read demo messages until connected
|
||||
while ( cls.state >= CA_CONNECTED && cls.state < CA_PRIMED ) {
|
||||
CL_ReadDemoMessage();
|
||||
|
@ -2198,16 +2153,7 @@ void CL_CheckForResend( void ) {
|
|||
port = Cvar_VariableValue ("net_qport");
|
||||
|
||||
Q_strncpyz( info, Cvar_InfoString( CVAR_USERINFO ), sizeof( info ) );
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(com_oldprotocol->integer == com_protocol->integer)
|
||||
clc.compat = qtrue;
|
||||
|
||||
if(clc.compat)
|
||||
Info_SetValueForKey(info, "protocol", va("%i", com_oldprotocol->integer));
|
||||
else
|
||||
#endif
|
||||
Info_SetValueForKey(info, "protocol", va("%i", com_protocol->integer));
|
||||
Info_SetValueForKey( info, "protocol", va("%i", com_protocol->integer ) );
|
||||
Info_SetValueForKey( info, "qport", va("%i", port ) );
|
||||
Info_SetValueForKey( info, "challenge", va("%i", clc.challenge ) );
|
||||
|
||||
|
@ -2448,7 +2394,6 @@ Responses to broadcasts, etc
|
|||
void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
||||
char *s;
|
||||
char *c;
|
||||
int challenge;
|
||||
|
||||
MSG_BeginReadingOOB( msg );
|
||||
MSG_ReadLong( msg ); // skip the -1
|
||||
|
@ -2470,33 +2415,18 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
return;
|
||||
}
|
||||
|
||||
c = Cmd_Argv(2);
|
||||
if(*c)
|
||||
challenge = atoi(c);
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(!clc.compat)
|
||||
if(!NET_CompareAdr(from, clc.serverAddress))
|
||||
{
|
||||
if(!*c || challenge != clc.challenge)
|
||||
{
|
||||
Com_Printf("Bad challenge for challengeResponse. Ignored.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(!NET_CompareAdr(from, clc.serverAddress))
|
||||
{
|
||||
// This challenge response is not coming from the expected address.
|
||||
// Check whether we have a matching client challenge to prevent
|
||||
// connection hi-jacking.
|
||||
// This challenge response is not coming from the expected address.
|
||||
// Check whether we have a matching client challenge to prevent
|
||||
// connection hi-jacking.
|
||||
|
||||
if(!*c || challenge != clc.challenge)
|
||||
{
|
||||
Com_DPrintf("Challenge response received from unexpected source. Ignored.\n");
|
||||
return;
|
||||
}
|
||||
c = Cmd_Argv(2);
|
||||
|
||||
if(!*c || atoi(c) != clc.challenge)
|
||||
{
|
||||
Com_DPrintf("Challenge response received from unexpected source. Ignored.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2527,34 +2457,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
Com_Printf( "connectResponse from wrong address. Ignored.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(!clc.compat)
|
||||
{
|
||||
c = Cmd_Argv(1);
|
||||
|
||||
if(*c)
|
||||
challenge = atoi(c);
|
||||
else
|
||||
{
|
||||
Com_Printf("Bad connectResponse received. Ignored.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(challenge != clc.challenge)
|
||||
{
|
||||
Com_Printf("ConnectResponse with bad challenge received. Ignored.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Netchan_Setup(NS_CLIENT, &clc.netchan, from, Cvar_VariableValue("net_qport"),
|
||||
clc.challenge, clc.compat);
|
||||
#else
|
||||
Netchan_Setup(NS_CLIENT, &clc.netchan, from, Cvar_VariableValue("net_qport"),
|
||||
clc.challenge);
|
||||
#endif
|
||||
|
||||
Netchan_Setup (NS_CLIENT, &clc.netchan, from, Cvar_VariableValue( "net_qport" ) );
|
||||
cls.state = CA_CONNECTED;
|
||||
clc.lastPacketSentTime = -9999; // send first packet immediately
|
||||
return;
|
||||
|
@ -2572,6 +2475,13 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
return;
|
||||
}
|
||||
|
||||
// a disconnect message from the server, which will happen if the server
|
||||
// dropped the connection but it is still getting packets from us
|
||||
if (!Q_stricmp(c, "disconnect")) {
|
||||
CL_DisconnectPacket( from );
|
||||
return;
|
||||
}
|
||||
|
||||
// echo request from server
|
||||
if ( !Q_stricmp(c, "echo") ) {
|
||||
NET_OutOfBandPrint( NS_CLIENT, from, "%s", Cmd_Argv(1) );
|
||||
|
@ -2591,33 +2501,10 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
}
|
||||
|
||||
// echo request from server
|
||||
if(!Q_stricmp(c, "print")){
|
||||
if ( !Q_stricmp(c, "print") ) {
|
||||
s = MSG_ReadString( msg );
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
// Hack to detect legacy server protocol
|
||||
if(cls.state == CA_CHALLENGING && com_oldprotocol->integer > 0)
|
||||
{
|
||||
char buf[128];
|
||||
int len;
|
||||
|
||||
len = Com_sprintf(buf, sizeof(buf), "Server uses protocol version %d",
|
||||
com_oldprotocol->integer);
|
||||
|
||||
if(len < sizeof(buf) && !Q_strncmp(s, buf, len) && !isdigit(s[len]))
|
||||
{
|
||||
// This is an old, but compatible protocol version.
|
||||
// Go back to connecting state.
|
||||
clc.compat = qtrue;
|
||||
cls.state = CA_CONNECTING;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_strncpyz( clc.serverMessage, s, sizeof( clc.serverMessage ) );
|
||||
Com_Printf( "%s", s );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3558,13 +3445,7 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
|||
|
||||
// if this isn't the correct protocol version, ignore it
|
||||
prot = atoi( Info_ValueForKey( infoString, "protocol" ) );
|
||||
|
||||
if(prot != com_protocol->integer
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
&& prot != com_oldprotocol->integer
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if ( prot != com_protocol->integer ) {
|
||||
Com_DPrintf( "Different protocol info packet: %s\n", infoString );
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -147,6 +147,9 @@ void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ) {
|
|||
Netchan_Transmit( chan, msg->cursize, msg->data );
|
||||
}
|
||||
|
||||
extern int oldsize;
|
||||
int newsize = 0;
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_Netchan_Process
|
||||
|
@ -158,8 +161,7 @@ qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
ret = Netchan_Process( chan, msg );
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
|
||||
CL_Netchan_Decode( msg );
|
||||
|
||||
newsize += msg->cursize;
|
||||
return qtrue;
|
||||
}
|
||||
|
|
|
@ -260,10 +260,6 @@ typedef struct {
|
|||
float voipPower;
|
||||
#endif
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
qboolean compat;
|
||||
#endif
|
||||
|
||||
// big stuff at end of structure so most offsets are 15 bits or less
|
||||
netchan_t netchan;
|
||||
} clientConnection_t;
|
||||
|
|
|
@ -32,7 +32,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#endif
|
||||
|
||||
int demo_protocols[] =
|
||||
{ 67, 66, 0 };
|
||||
{ 66, 67, 68, 0 };
|
||||
|
||||
#define MAX_NUM_ARGVS 50
|
||||
|
||||
|
@ -86,9 +86,6 @@ cvar_t *com_maxfpsMinimized;
|
|||
cvar_t *com_abnormalExit;
|
||||
cvar_t *com_standalone;
|
||||
cvar_t *com_protocol;
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
cvar_t *com_oldprotocol;
|
||||
#endif
|
||||
cvar_t *com_basegame;
|
||||
cvar_t *com_homepath;
|
||||
cvar_t *com_busyWait;
|
||||
|
@ -2713,9 +2710,6 @@ void Com_Init( char *commandLine ) {
|
|||
s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ );
|
||||
com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO );
|
||||
com_protocol = Cvar_Get ("protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO | CVAR_INIT);
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
com_oldprotocol = Cvar_Get ("oldprotocol", va("%i", PROTOCOL_OLD_VERSION), CVAR_INIT);
|
||||
#endif
|
||||
|
||||
Sys_Init();
|
||||
|
||||
|
|
|
@ -1030,11 +1030,6 @@ qboolean FS_IsDemoExt(const char *filename, int namelen)
|
|||
if(protocol == com_protocol->integer)
|
||||
return qtrue;
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(protocol == PROTOCOL_OLD_VERSION)
|
||||
return qtrue;
|
||||
#endif
|
||||
|
||||
for(index = 0; demo_protocols[index]; index++)
|
||||
{
|
||||
if(demo_protocols[index] == protocol)
|
||||
|
|
|
@ -83,12 +83,7 @@ Netchan_Setup
|
|||
called to open a channel to a remote system
|
||||
==============
|
||||
*/
|
||||
void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int challenge
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
, qboolean compat
|
||||
#endif
|
||||
)
|
||||
{
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport ) {
|
||||
Com_Memset (chan, 0, sizeof(*chan));
|
||||
|
||||
chan->sock = sock;
|
||||
|
@ -96,10 +91,6 @@ void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int
|
|||
chan->qport = qport;
|
||||
chan->incomingSequence = 0;
|
||||
chan->outgoingSequence = 1;
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
chan->compat = compat;
|
||||
chan->challenge = challenge;
|
||||
#endif
|
||||
}
|
||||
|
||||
// TTimo: unused, commenting out to make gcc happy
|
||||
|
@ -199,24 +190,17 @@ void Netchan_TransmitNextFragment( netchan_t *chan ) {
|
|||
msg_t send;
|
||||
byte send_buf[MAX_PACKETLEN];
|
||||
int fragmentLength;
|
||||
int outgoingSequence;
|
||||
|
||||
// write the packet header
|
||||
MSG_InitOOB (&send, send_buf, sizeof(send_buf)); // <-- only do the oob here
|
||||
|
||||
outgoingSequence = chan->outgoingSequence | FRAGMENT_BIT;
|
||||
MSG_WriteLong(&send, outgoingSequence);
|
||||
MSG_WriteLong( &send, chan->outgoingSequence | FRAGMENT_BIT );
|
||||
|
||||
// send the qport if we are a client
|
||||
if ( chan->sock == NS_CLIENT ) {
|
||||
MSG_WriteShort( &send, qport->integer );
|
||||
}
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(!chan->compat)
|
||||
#endif
|
||||
MSG_WriteLong(&send, NETCHAN_GENCHECKSUM(chan->challenge, chan->outgoingSequence));
|
||||
|
||||
// copy the reliable message to the packet first
|
||||
fragmentLength = FRAGMENT_SIZE;
|
||||
if ( chan->unsentFragmentStart + fragmentLength > chan->unsentLength ) {
|
||||
|
@ -284,17 +268,12 @@ void Netchan_Transmit( netchan_t *chan, int length, const byte *data ) {
|
|||
MSG_InitOOB (&send, send_buf, sizeof(send_buf));
|
||||
|
||||
MSG_WriteLong( &send, chan->outgoingSequence );
|
||||
chan->outgoingSequence++;
|
||||
|
||||
// send the qport if we are a client
|
||||
if(chan->sock == NS_CLIENT)
|
||||
MSG_WriteShort(&send, qport->integer);
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(!chan->compat)
|
||||
#endif
|
||||
MSG_WriteLong(&send, NETCHAN_GENCHECKSUM(chan->challenge, chan->outgoingSequence));
|
||||
|
||||
chan->outgoingSequence++;
|
||||
if ( chan->sock == NS_CLIENT ) {
|
||||
MSG_WriteShort( &send, qport->integer );
|
||||
}
|
||||
|
||||
MSG_WriteData( &send, data, length );
|
||||
|
||||
|
@ -348,17 +327,6 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
qport = MSG_ReadShort( msg );
|
||||
}
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(!chan->compat)
|
||||
#endif
|
||||
{
|
||||
int checksum = MSG_ReadLong(msg);
|
||||
|
||||
// UDP spoofing protection
|
||||
if(NETCHAN_GENCHECKSUM(chan->challenge, sequence) != checksum)
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// read the fragment information
|
||||
if ( fragmented ) {
|
||||
fragmentStart = MSG_ReadShort( msg );
|
||||
|
|
|
@ -962,7 +962,7 @@ int Q_CountChar(const char *string, char tocount)
|
|||
return count;
|
||||
}
|
||||
|
||||
int QDECL Com_sprintf(char *dest, int size, const char *fmt, ...)
|
||||
void QDECL Com_sprintf(char *dest, int size, const char *fmt, ...)
|
||||
{
|
||||
int len;
|
||||
va_list argptr;
|
||||
|
@ -973,8 +973,6 @@ int QDECL Com_sprintf(char *dest, int size, const char *fmt, ...)
|
|||
|
||||
if(len >= size)
|
||||
Com_Printf("Com_sprintf: Output length %d too short, require %d bytes.\n", size, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -34,7 +34,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#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 PROTOCOL_SUPPORT_OLD // You probably don't need this for your standalone game
|
||||
#else
|
||||
#define PRODUCT_NAME "ioq3"
|
||||
#define BASEGAME "baseq3"
|
||||
|
@ -43,7 +42,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define GAMENAME_FOR_MASTER "Quake3Arena"
|
||||
#define HEARTBEAT_FOR_MASTER "QuakeArena-1"
|
||||
#define FLATLINE_FOR_MASTER HEARTBEAT_FOR_MASTER
|
||||
#define PROTOCOL_SUPPORT_OLD
|
||||
#endif
|
||||
|
||||
#define BASETA "missionpack"
|
||||
|
@ -684,7 +682,7 @@ void Parse2DMatrix (char **buf_p, int y, int x, float *m);
|
|||
void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m);
|
||||
int Com_HexStrToInt( const char *str );
|
||||
|
||||
int QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
char *Com_SkipTokens( char *s, int numTokens, char *sep );
|
||||
char *Com_SkipCharset( char *s, char *sep );
|
||||
|
|
|
@ -194,8 +194,7 @@ void NET_Sleep(int msec);
|
|||
|
||||
#define MAX_DOWNLOAD_WINDOW 8 // max of eight download frames
|
||||
#define MAX_DOWNLOAD_BLKSIZE 2048 // 2048 byte block chunks
|
||||
|
||||
#define NETCHAN_GENCHECKSUM(challenge, sequence) ((challenge) ^ ((sequence) * (challenge)))
|
||||
|
||||
|
||||
/*
|
||||
Netchan handles packet fragmentation and out of order / duplicate suppression
|
||||
|
@ -224,20 +223,10 @@ typedef struct {
|
|||
int unsentFragmentStart;
|
||||
int unsentLength;
|
||||
byte unsentBuffer[MAX_MSGLEN];
|
||||
|
||||
int challenge;
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
qboolean compat;
|
||||
#endif
|
||||
} netchan_t;
|
||||
|
||||
void Netchan_Init( int qport );
|
||||
void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int challenge
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
, qboolean compat
|
||||
#endif
|
||||
);
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport );
|
||||
|
||||
void Netchan_Transmit( netchan_t *chan, int length, const byte *data );
|
||||
void Netchan_TransmitNextFragment( netchan_t *chan );
|
||||
|
@ -253,8 +242,7 @@ PROTOCOL
|
|||
==============================================================
|
||||
*/
|
||||
|
||||
#define PROTOCOL_VERSION 69
|
||||
#define PROTOCOL_OLD_VERSION 68
|
||||
#define PROTOCOL_VERSION 68
|
||||
// 1.31 - 67
|
||||
|
||||
// maintain a list of compatible protocols for demo playing
|
||||
|
@ -869,9 +857,6 @@ extern cvar_t *cl_packetdelay;
|
|||
extern cvar_t *sv_packetdelay;
|
||||
|
||||
extern cvar_t *com_protocol;
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
extern cvar_t *com_oldprotocol;
|
||||
#endif
|
||||
|
||||
// com_speeds times
|
||||
extern int time_game;
|
||||
|
|
|
@ -188,11 +188,7 @@ typedef struct client_s {
|
|||
#endif
|
||||
|
||||
int oldServerTime;
|
||||
qboolean csUpdated[MAX_CONFIGSTRINGS+1];
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
qboolean compat;
|
||||
#endif
|
||||
qboolean csUpdated[MAX_CONFIGSTRINGS+1];
|
||||
} client_t;
|
||||
|
||||
//=============================================================================
|
||||
|
@ -201,11 +197,7 @@ typedef struct client_s {
|
|||
// MAX_CHALLENGES is made large to prevent a denial
|
||||
// of service attack that could cycle all of them
|
||||
// out before legitimate users connected
|
||||
#define MAX_CHALLENGES 2048
|
||||
// Allow a certain amount of challenges to have the same IP address
|
||||
// to make it a bit harder to DOS one single IP address from connecting
|
||||
// while not allowing a single ip to grab all challenge resources
|
||||
#define MAX_CHALLENGES_MULTI (MAX_CHALLENGES / 2)
|
||||
#define MAX_CHALLENGES 1024
|
||||
|
||||
#define AUTHORIZE_TIMEOUT 5000
|
||||
|
||||
|
|
|
@ -55,10 +55,8 @@ void SV_GetChallenge(netadr_t from)
|
|||
int i;
|
||||
int oldest;
|
||||
int oldestTime;
|
||||
int oldestClientTime;
|
||||
int clientChallenge;
|
||||
const char *clientChallenge = Cmd_Argv(1);
|
||||
challenge_t *challenge;
|
||||
qboolean wasfound = qfalse;
|
||||
|
||||
// ignore if we are in single player
|
||||
if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
|
||||
|
@ -66,30 +64,15 @@ void SV_GetChallenge(netadr_t from)
|
|||
}
|
||||
|
||||
oldest = 0;
|
||||
oldestClientTime = oldestTime = 0x7fffffff;
|
||||
oldestTime = 0x7fffffff;
|
||||
|
||||
// see if we already have a challenge for this ip
|
||||
challenge = &svs.challenges[0];
|
||||
clientChallenge = atoi(Cmd_Argv(1));
|
||||
|
||||
for(i = 0 ; i < MAX_CHALLENGES ; i++, challenge++)
|
||||
{
|
||||
if(!challenge->connected && NET_CompareAdr(from, challenge->adr))
|
||||
{
|
||||
wasfound = qtrue;
|
||||
|
||||
if(challenge->time < oldestClientTime)
|
||||
oldestClientTime = challenge->time;
|
||||
}
|
||||
|
||||
if(wasfound && i >= MAX_CHALLENGES_MULTI)
|
||||
{
|
||||
i = MAX_CHALLENGES;
|
||||
for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) {
|
||||
if (!challenge->connected && NET_CompareAdr( from, challenge->adr ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(challenge->time < oldestTime)
|
||||
{
|
||||
if ( challenge->time < oldestTime ) {
|
||||
oldestTime = challenge->time;
|
||||
oldest = i;
|
||||
}
|
||||
|
@ -99,16 +82,17 @@ void SV_GetChallenge(netadr_t from)
|
|||
{
|
||||
// this is the first time this client has asked for a challenge
|
||||
challenge = &svs.challenges[oldest];
|
||||
challenge->clientChallenge = clientChallenge;
|
||||
challenge->clientChallenge = 0;
|
||||
challenge->adr = from;
|
||||
challenge->firstTime = svs.time;
|
||||
challenge->time = svs.time;
|
||||
challenge->connected = qfalse;
|
||||
}
|
||||
|
||||
// always generate a new challenge number, so the client cannot circumvent sv_maxping
|
||||
challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time;
|
||||
challenge->wasrefused = qfalse;
|
||||
challenge->time = svs.time;
|
||||
|
||||
|
||||
#ifndef STANDALONE
|
||||
// Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
|
||||
|
@ -137,7 +121,7 @@ void SV_GetChallenge(netadr_t from)
|
|||
// if they have been challenging for a long time and we
|
||||
// haven't heard anything from the authorize server, go ahead and
|
||||
// let them in, assuming the id server is down
|
||||
else if(svs.time - oldestClientTime > AUTHORIZE_TIMEOUT)
|
||||
else if(svs.time - challenge->firstTime > AUTHORIZE_TIMEOUT)
|
||||
Com_DPrintf( "authorize server timed out\n" );
|
||||
else
|
||||
{
|
||||
|
@ -145,6 +129,10 @@ void SV_GetChallenge(netadr_t from)
|
|||
cvar_t *fs;
|
||||
char game[1024];
|
||||
|
||||
// If the client provided us with a client challenge, store it...
|
||||
if(*clientChallenge)
|
||||
challenge->clientChallenge = atoi(clientChallenge);
|
||||
|
||||
Com_DPrintf( "sending getIpAuthorize for %s\n", NET_AdrToString( from ));
|
||||
|
||||
strcpy(game, BASEGAME);
|
||||
|
@ -165,7 +153,7 @@ void SV_GetChallenge(netadr_t from)
|
|||
#endif
|
||||
|
||||
challenge->pingTime = svs.time;
|
||||
NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %d", challenge->challenge, clientChallenge);
|
||||
NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %s", challenge->challenge, clientChallenge);
|
||||
}
|
||||
|
||||
#ifndef STANDALONE
|
||||
|
@ -301,9 +289,6 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
intptr_t denied;
|
||||
int count;
|
||||
char *ip;
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
qboolean compat = qfalse;
|
||||
#endif
|
||||
|
||||
Com_DPrintf ("SVC_DirectConnect ()\n");
|
||||
|
||||
|
@ -316,21 +301,11 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
|
||||
Q_strncpyz( userinfo, Cmd_Argv(1), sizeof(userinfo) );
|
||||
|
||||
version = atoi(Info_ValueForKey(userinfo, "protocol"));
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(version > 0 && com_oldprotocol->integer == version)
|
||||
compat = qtrue;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(version != com_protocol->integer)
|
||||
{
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "print\nServer uses protocol version %i "
|
||||
"(yours is %i).\n", com_protocol->integer, version);
|
||||
Com_DPrintf(" rejected connect from version %i\n", version);
|
||||
return;
|
||||
}
|
||||
version = atoi( Info_ValueForKey( userinfo, "protocol" ) );
|
||||
if ( version != com_protocol->integer ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "print\nServer uses protocol version %i (yours is %i).\n", com_protocol->integer, version );
|
||||
Com_DPrintf (" rejected connect from version %i\n", version);
|
||||
return;
|
||||
}
|
||||
|
||||
challenge = atoi( Info_ValueForKey( userinfo, "challenge" ) );
|
||||
|
@ -512,12 +487,7 @@ gotnewcl:
|
|||
newcl->challenge = challenge;
|
||||
|
||||
// save the address
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
newcl->compat = compat;
|
||||
Netchan_Setup(NS_SERVER, &newcl->netchan, from, qport, challenge, compat);
|
||||
#else
|
||||
Netchan_Setup(NS_SERVER, &newcl->netchan, from, qport, challenge);
|
||||
#endif
|
||||
Netchan_Setup (NS_SERVER, &newcl->netchan , from, qport);
|
||||
// init the netchan queue
|
||||
newcl->netchan_end_queue = &newcl->netchan_start_queue;
|
||||
|
||||
|
@ -538,7 +508,7 @@ gotnewcl:
|
|||
SV_UserinfoChanged( newcl );
|
||||
|
||||
// send the connect packet to the client
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "connectResponse %d", challenge);
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "connectResponse" );
|
||||
|
||||
Com_DPrintf( "Going from CS_FREE to CS_CONNECTED for %s\n", newcl->name );
|
||||
|
||||
|
|
Loading…
Reference in a new issue