Forum

FuhQuake: Server Aliases as Temporary

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

FuhQuake: Server Aliases as Temporary

Postby Baker » Tue Jan 05, 2010 6:37 am

Most of the Quakeworld engines clear server aliases on map change.

According to Spike, I guess the main driver of this is that Quakeworld engines save aliases to a config.

I'm more interested in this functionality to avoid infinite accumulation of aliases in a NetQuake client that connects from server to server or even if the server performs a mod switch (which doesn't really happen today, but that's going to be changing).

In NetQuake and probably original Quakeworld, if you connect to a server, it might send you several aliases to play the mod more efficiently. Some mods have a ton of these like CRMOD, CTF, RuneQuake, NQ Team Fortress.

If you switch to a different server, these aliases persist and the effects of the alias on the new server you have connected to is impredictable.

For instance:

This might be what is sent to a client on some server with a hook.

ALIAS +HOOK "IMPULSE 97"
ALIAS -HOOK "IMPULSE 98"

If you connect to a different server with no hook, and you have +hook bound to a key, what is going to do on this no hook server?

Impulse 97 might something like detonate a bomb or go observer or even an admin impulse. You don't know.


FuhQuake implementation

Studying the FuhQuake implementation I see in cmd.c ...

//Creates a new command that executes a command string (possibly ; separated)
void Cmd_Alias_f (void) {
cmd_alias_t *a;
char *s;
int c, key;

c = Cmd_Argc();
if (c == 1) {
Com_Printf ("%s <name> <command> : create or modify an alias\n", Cmd_Argv(0));
Com_Printf ("aliaslist : list all aliases\n");
return;
}

s = Cmd_Argv(1);
if (strlen(s) >= MAX_ALIAS_NAME) {
Com_Printf ("Alias name is too long\n");
return;
}

key = Com_HashKey(s);

// if the alias already exists, reuse it
for (a = cmd_alias_hash[key]; a; a = a->hash_next) {
if (!Q_strcasecmp(a->name, s)) {
Z_Free (a->value);
break;
}
}

if (!a) {
a = Z_Malloc (sizeof(cmd_alias_t));
a->next = cmd_alias;
cmd_alias = a;
a->hash_next = cmd_alias_hash[key];
cmd_alias_hash[key] = a;
}
strcpy (a->name, s);

a->flags = 0;
if (!Q_strcasecmp(Cmd_Argv(0), "aliasa"))
a->flags |= ALIAS_ARCHIVE;

#ifndef SERVERONLY
if (cbuf_current == &cbuf_svc)
a->flags |= ALIAS_SERVER;
// Baker: flag aliases as from server

if (!Q_strcasecmp(Cmd_Argv(0), "tempalias"))
a->flags |= ALIAS_TEMP;
#endif


// copy the rest of the command line
a->value = CopyString (Cmd_MakeArgs(2));
}


And if a disconnect occurs ...

void CL_Disconnect (void) {
byte final[10];

connect_time = 0;
cl.teamfortress = false;

VID_SetCaption("FuhQuake");

// stop sounds (especially looping!)
S_StopAllSounds (true);

MT_Disconnect();

if (cls.demorecording && cls.state != ca_disconnected)
CL_Stop_f();

if (cls.demoplayback) {
CL_StopPlayback();
} else if (cls.state != ca_disconnected) {
final[0] = clc_stringcmd;
strcpy (final + 1, "drop");
Netchan_Transmit (&cls.netchan, 6, final);
Netchan_Transmit (&cls.netchan, 6, final);
Netchan_Transmit (&cls.netchan, 6, final);
}

memset(&cls.netchan, 0, sizeof(cls.netchan));
cls.state = ca_disconnected;

Cam_Reset();

if (cls.download) {
fclose(cls.download);
cls.download = NULL;
}

CL_StopUpload();
DeleteServerAliases(); \\ Baker: this deletes the server aliases on disconnect
}


And then look through all the aliases and delete where applicable:

Code: Select all
void DeleteServerAliases(void) {
   extern cmd_alias_t *cmd_alias;
   cmd_alias_t   *a;

   for (a = cmd_alias; a; a = a->next) {
      if (a->flags & ALIAS_SERVER)
         Cmd_DeleteAlias(a->name);
   }
}


Some NQ engines have unalias and unaliasall type of commands already, although this is not a feature of GLQuake. FitzQuake for sure. ProQuake 4 has unalias but not unaliasall (couldn't think of a need for that at the time). Qrack has neither.
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby r00k » Tue Jan 05, 2010 6:48 am

i use the "unalias" commands.
Code: Select all
/*
===============
Cmd_Unaliasall_f -- johnfitz
===============
*/
void Cmd_Unaliasall_f (void)
{
   cmdalias_t   *blah;

   while (cmd_alias)
   {
      blah = cmd_alias->next;
      Z_Free(cmd_alias->value);
      Z_Free(cmd_alias);
      cmd_alias = blah;
   }
}

and this just use this
Code: Select all
void CL_Disconnect_f (void)
{
   // We have to shut down webdownloading first
   if( cls.download.web )
   {
      cls.download.disconnect = true;
      return;
   }
   
   Cbuf_InsertText ("unaliasall\n");//R00k Clean out alias commands from server to server.

   CL_Disconnect ();
   if (sv.active)
      Host_ShutdownServer (false);
}


poof no alias carry over from crmod to ca to runequake :)
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby Baker » Tue Jan 05, 2010 6:55 am

I think the above would need modification to mark server aliases. Otherwise you are going to lose them all, even the ones in a player's autoexec.cfg file.

/I checked for the unalias command in Qrack but I guess I have 1.85 on this machine and not the current version. Oops! :(
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest