Replacing a quake3 function

nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Replacing a quake3 function

Post by nexus024 »

Does anyone know if its possible to replace

Code: Select all

   1.
      void trap_SendServerCommand( int clientNum, const char *text ) {
   2.
              syscall( G_SEND_SERVER_COMMAND, clientNum, text );
   3.
      } 
With this code

Code: Select all

   1.
      void trap_SendServerCommand( int clientNum, const char *text ) {
   2.
              // rain - hack - commands over 1022 chars will crash the
   3.
              // client upon receipt, so ignore them
   4.
              if( strlen( text ) > 1022 ) {
   5.
                      G_LogPrintf( "trap_SendServerCommand( %d, ... ) length exceeds 1022.\n", clientNum );
   6.
                      G_LogPrintf( "text [%s]\n", text );
   7.
                      return;
   8.
              }
   9.
              syscall( G_SEND_SERVER_COMMAND, clientNum, text );
  10.
      } 
This is a fix for the q3msgboom bug.
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

It'll only work when building a DLL, QVMs incorporate g_syscalls.asm instead. You could write a wrapper function that checks the length of the string, then calls trap_SendServerCommand(). Next up, replace all the calls to trap_SendServerCommand() in calls to your wrapper - except the call to it in your wrapper, of course.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

I am a bit unsure of what you are referring to as a wrapper. It sounds though that I would still have to recompile this new wrapper function with the source???
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

Correct, sir. A wrapper is merely a function that calls another function, massaging the input where it sees fit.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Ok, please let me know if I am on the right track here.

g_syscalls.c

Code: Select all

void trap_SendServerCommand( int clientNum, const char *text ) {

	syscall( G_SEND_SERVER_COMMAND, clientNum, text );

} 


void wrapper( int clientNum, const char *text ) {
	if( strlen( text ) < 1022 ) {
		trap_SendServerCommand( clientNum, text );
	}
	else if( strlen( text ) > 1022 ) {
		G_LogPrintf( "trap_SendServerCommand( %d, ... ) length exceeds 1022.\n", clientNum );
   		G_LogPrintf( "text [%s]\n", text );
   		return; 
	}
}
I found calls to trap_sendservercommand in g_bot.c, g_cmds.c, g_rankings.c, and g_target.c. I changed each one to point to my wrapper function instead of the sendservercommand function.

Another question... what q3 source must I use to compile this. I currently have the quake3 1.32b source code and the quake3 sdk for linux, but am unsure of which to use. All I am trying to do is patch my server so people can't use the q3msgboom and "kill" my server. I am assuming this is the correct approach?
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

Ok, please let me know if I am on the right track here.
You are. I'd suggest renaming the wrapper function to something like trap_SendServerCommandWrapper() as it makes its purpose a bit more obvious.
I am assuming this is the correct approach?
It is.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Any ideas?

Code: Select all

[root@localhost code]# make
WARNING: build system doesn't rely on GNU make. Spawning cons
  use ./unix/cons -h for help
./unix/cons
cpu : x86
OS  : Linux
libc: 2.3
configured for debug build
CFLAGS: -pipe -fsigned-char -g -Wall -Werror -O
gcc -pipe -fsigned-char -g -Wall -Werror -O -fPIC -Icgame -Igame -Iq3_ui -c debug-x86-Linux-2.3/Q3/game/game/ai_dmq3.c -o debug-x86-Linux-2.3/Q3/game/game/ai_dmq3.o
debug-x86-Linux-2.3/Q3/game/game/ai_dmq3.c:4433:8: extra tokens at end of #endif directive
cons: *** [debug-x86-Linux-2.3/Q3/game/game/ai_dmq3.o] Error 1
cons: errors constructing debug-x86-Linux-2.3/Q3/game/game/ai_dmq3.o
make: *** [default] Error 2
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

Yes. Take a look at game/ai_dmq3.c, line 4433. I wager there's something after the #endif directive that's not commented out.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Code: Select all

debug-x86-Linux-2.3/Q3/game/game/g_bot.c: In function `Svcmd_AddBot_f':
debug-x86-Linux-2.3/Q3/game/game/g_bot.c:737: warning: implicit declaration of function `wrapper'
cons: *** [debug-x86-Linux-2.3/Q3/game/game/g_bot.o] Error 1
cons: errors constructing debug-x86-Linux-2.3/Q3/game/game/g_bot.o
make: *** [default] Error 2
g_bot.c

Code: Select all

// if this was issued during gameplay and we are playing locally,
	// go ahead and load the bot's media immediately
	if ( level.time - level.startTime > 1000 &&
		trap_Cvar_VariableIntegerValue( "cl_running" ) ) {
		wrapper( -1, "loaddefered\n" );	// FIXME: spelled wrong, but not changing for demo
	}
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Did I not setup my function correctly?
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

I have been reading about this particular error message and it says to create a prototype for the function. I am unsure if that is the solution and if it is I don't know how to create a prototype for my function.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Any suggestions?
torhu
Posts: 76
Joined: Thu Jun 16, 2005 7:57 pm

Post by torhu »

A function prototype is just the function header without the body.

Just put this line in g_local.h, at the end is fine. Note the semicolon at the end:

Code: Select all

void trap_SendServerCommandWrapper( int clientNum, const char *text );
Whenever you call a function that's defined in another file, the compiler looks for a prototype like this so it can check that you're using the right number and types of arguments. But if I recall correctly, it's not mandatory. It's just considered a bad idea to leave it out. If there's no prototype, the compiler will assume that the arguments you give the function are what it expects, and that it returns an int.

Prototypes are also called declarations, like in the error message.
[url=http://www.smokin-guns.org]Smokin' Guns[/url]
[url=https://sites.google.com/site/monsterbrowser//]Monster Browser[/url]
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

torhu wrote:But if I recall correctly, it's not mandatory.
It indeed isn't (but it is regarded as very bad practice). If you don't declare a prototype, the compiler will assume:

Code: Select all

int foo(...);
That is, a function returning int, taking any number of arguments.
Silicone_Milk
Posts: 2237
Joined: Sat Mar 12, 2005 10:49 pm

Post by Silicone_Milk »

wouldn't an example like the int foo(); function be a good thing at certain times?

Like say, for instance, that we wanted a function that added any numbers we give it together regardless of how many ints given as an argument.

In psuedo-code:

Code: Select all

    int foo(...) {
        if(argument # > 0){ 
            if(argument # = 1){
                argument0 + 0; //first argument  + nothing since we dont have another argument to add. 
                }
            else{
                 while(argument # != max_arguments){
                      the_argument = first argument + next argument;
                      the_argument = the_argument + next argument after last added argument; 
                      return the_argument; 
                   }
}
 
        
Although, I kinda think this would be a retarded way of going about doing things. Hypothetically, however, could this not be a useful thing to do?
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Thank you all for your help... it finally compiled with no errors!!!

I notice that in /install/baseq3 there are three files: cgamei386.so, qagamei386.so , and uii386.so. Also there is a vm folder that contains cgame.qvm and ui.qvm files. In looking at my quake3 server the only file I use out of all of those is the qagamei386.so in my baseq3 folder. Does this mean I just replace my old file with this new patched one and the q3msgboom problem is solved? Or is there something I must do with these qvm files?
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

Hmm, what point release are you running? QVMs (Q3 virtual machine files) have been the standard for a long, long time now.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Q3 Linux 1.32c
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

In that case you can safely delete the shared object (the .so). Place the *.qvm files in a directory 'vm', zip it up and save with the extension .pk3 and your mod is ready for distribution.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Ok that might be a problem.... I just realized that the .so file is required for my q3as 1.99q mod that I run. What needs to be done so I can continue using q3as 1.99q mod?
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

You can't, really. Either you use your qagame.qvm or the q3as qagame.so but not both.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

I know this can be done because I know of a server running the q3as mod and they have their server patched. Can you think of any way they accomplished this?
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

Not possible unless you have access to the q3as source (or if you were willing to do a total rewrite of it).
AnthonyJ
Posts: 130
Joined: Wed Nov 15, 2006 7:51 pm

Post by AnthonyJ »

Its corrected engineside in ioq3 - rev 95 of trunk/code/server/sv_main.c, so that'll be how the other server is patched, I guess.

FWIW, the actual issue is that its exceeding sizeof( client->reliableCommands[index] ) as used in *_AddServerCommand() - which is MAX_STRING_CHARS (1024) bytes long.

Something downstream in the client end probably doesnt like the incomplete command.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Since the fix is engine side, as you say, can i just replace sv_main.c with the rev 95 version, recompile the source again and use that somehow with the q3as mod? I'm also using point release 1.32c on my server.
Locked