]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - host_cmd.c
removed trailing comments on cvar declarations and Cmd_AddCommand calls
[xonotic/darkplaces.git] / host_cmd.c
index 5f93996d0734f199c6f2607757607459b3b2af2a..e954d15e0299d8c720e0db1165940b44b87a10b5 100644 (file)
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 int current_skill;
 cvar_t sv_cheats = {0, "sv_cheats", "0", "enables cheat commands in any game, and cheat impulses in dpmod"};
+cvar_t sv_adminnick = {CVAR_SAVE, "sv_adminnick", "", "nick name to use for admin messages instead of host name"};
 cvar_t rcon_password = {CVAR_PRIVATE, "rcon_password", "", "password to authenticate rcon commands"};
 cvar_t rcon_address = {0, "rcon_address", "", "server address to send rcon commands to (when not connected to a server)"};
 cvar_t team = {CVAR_USERINFO | CVAR_SAVE, "team", "none", "QW team (4 character limit, example: blue)"};
@@ -91,7 +92,7 @@ void Host_Status_f (void)
                }
                else
                        hours = 0;
-               print ("#%-3u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->fields.server->frags, hours, minutes, seconds);
+               print ("#%-3u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, client->frags, hours, minutes, seconds);
                print ("   %s\n", client->netconnection ? client->netconnection->address : "botclient");
        }
 }
@@ -370,36 +371,38 @@ This is sent just before a server changes levels
 */
 void Host_Reconnect_f (void)
 {
+       char temp[128];
+       // if not connected, reconnect to the most recent server
+       if (!cls.netcon)
+       {
+               // if we have connected to a server recently, the userinfo
+               // will still contain its IP address, so get the address...
+               InfoString_GetValue(cls.userinfo, "*ip", temp, sizeof(temp));
+               if (temp[0])
+                       CL_EstablishConnection(temp);
+               else
+                       Con_Printf("Reconnect to what server?  (you have not connected to a server yet)\n");
+               return;
+       }
+       // if connected, do something based on protocol
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
+               // quakeworld can just re-login
                if (cls.qw_downloadmemory)  // don't change when downloading
                        return;
 
                S_StopAllSounds();
 
-               if (cls.netcon)
+               if (cls.state == ca_connected && cls.signon < SIGNONS)
                {
-                       if (cls.state == ca_connected && cls.signon < SIGNONS)
-                       {
-                               Con_Printf("reconnecting...\n");
-                               MSG_WriteChar(&cls.netcon->message, qw_clc_stringcmd);
-                               MSG_WriteString(&cls.netcon->message, "new");
-                       }
-                       else
-                       {
-                               char temp[128];
-                               // if we have connected to a server recently, the userinfo
-                               // will still contain its IP address, so get the address...
-                               InfoString_GetValue(cls.userinfo, "*ip", temp, sizeof(temp));
-                               if (temp[0])
-                                       CL_EstablishConnection(temp);
-                               else
-                                       Con_Printf("Reconnect to what server?  (you have not connected to a server yet)\n");
-                       }
+                       Con_Printf("reconnecting...\n");
+                       MSG_WriteChar(&cls.netcon->message, qw_clc_stringcmd);
+                       MSG_WriteString(&cls.netcon->message, "new");
                }
        }
        else
        {
+               // netquake uses reconnect on level changes (silly)
                if (Cmd_Argc() != 1)
                {
                        Con_Print("reconnect : wait for signon messages again\n");
@@ -753,7 +756,7 @@ void Host_Loadgame_f (void)
 Host_Name_f
 ======================
 */
-cvar_t cl_name = {CVAR_SAVE, "_cl_name", "player", "internal storage cvar for current player name (changed by name command)"};
+cvar_t cl_name = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_name", "player", "internal storage cvar for current player name (changed by name command)"};
 void Host_Name_f (void)
 {
        int i, j;
@@ -810,7 +813,7 @@ void Host_Name_f (void)
 Host_Playermodel_f
 ======================
 */
-cvar_t cl_playermodel = {CVAR_SAVE, "_cl_playermodel", "", "internal storage cvar for current player model in Nexuiz (changed by playermodel command)"};
+cvar_t cl_playermodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_playermodel", "", "internal storage cvar for current player model in Nexuiz (changed by playermodel command)"};
 // the old cl_playermodel in cl_main has been renamed to __cl_playermodel
 void Host_Playermodel_f (void)
 {
@@ -852,8 +855,8 @@ void Host_Playermodel_f (void)
 
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel));
-       if( eval_playermodel )
-               PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PRVM_SetEngineString(host_client->playermodel);
+       if( prog->fieldoffsets.playermodel >= 0 )
+               PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playermodel)->string = PRVM_SetEngineString(host_client->playermodel);
        if (strcmp(host_client->old_model, host_client->playermodel))
        {
                strlcpy(host_client->old_model, host_client->playermodel, sizeof(host_client->old_model));
@@ -869,7 +872,7 @@ void Host_Playermodel_f (void)
 Host_Playerskin_f
 ======================
 */
-cvar_t cl_playerskin = {CVAR_SAVE, "_cl_playerskin", "", "internal storage cvar for current player skin in Nexuiz (changed by playerskin command)"};
+cvar_t cl_playerskin = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_playerskin", "", "internal storage cvar for current player skin in Nexuiz (changed by playerskin command)"};
 void Host_Playerskin_f (void)
 {
        int i, j;
@@ -910,8 +913,8 @@ void Host_Playerskin_f (void)
 
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin));
-       if( eval_playerskin )
-               PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PRVM_SetEngineString(host_client->playerskin);
+       if( prog->fieldoffsets.playerskin >= 0 )
+               PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playerskin)->string = PRVM_SetEngineString(host_client->playerskin);
        if (strcmp(host_client->old_skin, host_client->playerskin))
        {
                //if (host_client->spawned)
@@ -969,6 +972,8 @@ void Host_Say(qboolean teamonly)
        // note this uses the chat prefix \001
        if (!fromServer)
                dpsnprintf (text, sizeof(text), "\001%s" STRING_COLOR_DEFAULT_STR ": %s", host_client->name, p1);
+       else if(*(sv_adminnick.string))
+               dpsnprintf (text, sizeof(text), "\001<%s" STRING_COLOR_DEFAULT_STR "> %s", sv_adminnick.string, p1);
        else
                dpsnprintf (text, sizeof(text), "\001<%s" STRING_COLOR_DEFAULT_STR "> %s", hostname.string, p1);
        p2 = text + strlen(text);
@@ -984,7 +989,7 @@ void Host_Say(qboolean teamonly)
        // note: save is not a valid edict if fromServer is true
        save = host_client;
        for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
-               if (host_client->spawned && (!teamonly || host_client->edict->fields.server->team == save->edict->fields.server->team))
+               if (host_client->active && (!teamonly || host_client->edict->fields.server->team == save->edict->fields.server->team))
                        SV_ClientPrint(text);
        host_client = save;
 
@@ -1007,6 +1012,9 @@ void Host_Say_Team_f(void)
 
 void Host_Tell_f(void)
 {
+       const char *playername_start = NULL;
+       size_t playername_length = 0;
+       int playernumber = 0;
        client_t *save;
        int j;
        const char *p1, *p2;
@@ -1024,22 +1032,83 @@ void Host_Tell_f(void)
                }
        }
 
-       if (Cmd_Argc () < 3)
+       if (Cmd_Argc () < 2)
                return;
 
        // note this uses the chat prefix \001
        if (!fromServer)
                sprintf (text, "\001%s tells you: ", host_client->name);
+       else if(*(sv_adminnick.string))
+               sprintf (text, "\001<%s tells you> ", sv_adminnick.string);
        else
                sprintf (text, "\001<%s tells you> ", hostname.string);
 
        p1 = Cmd_Args();
        p2 = p1 + strlen(p1);
        // remove the target name
-       while (p1 < p2 && *p1 != ' ')
+       while (p1 < p2 && *p1 == ' ')
                p1++;
+       if(*p1 == '#')
+       {
+               ++p1;
+               while (p1 < p2 && *p1 == ' ')
+                       p1++;
+               while (p1 < p2 && isdigit(*p1))
+               {
+                       playernumber = playernumber * 10 + (*p1 - '0');
+                       p1++;
+               }
+               --playernumber;
+       }
+       else if(*p1 == '"')
+       {
+               ++p1;
+               playername_start = p1;
+               while (p1 < p2 && *p1 != '"')
+                       p1++;
+               playername_length = p1 - playername_start;
+               if(p1 < p2)
+                       p1++;
+       }
+       else
+       {
+               playername_start = p1;
+               while (p1 < p2 && *p1 != ' ')
+                       p1++;
+               playername_length = p1 - playername_start;
+       }
        while (p1 < p2 && *p1 == ' ')
                p1++;
+       if(playername_start)
+       {
+               // set playernumber to the right client
+               char namebuf[128];
+               if(playername_length >= sizeof(namebuf))
+               {
+                       if (fromServer)
+                               Con_Print("Host_Tell: too long player name/ID\n");
+                       else
+                               SV_ClientPrint("Host_Tell: too long player name/ID\n");
+                       return;
+               }
+               memcpy(namebuf, playername_start, playername_length);
+               namebuf[playername_length] = 0;
+               for (playernumber = 0; playernumber < svs.maxclients; playernumber++)
+               {
+                       if (!svs.clients[playernumber].active)
+                               continue;
+                       if (strcasecmp(svs.clients[playernumber].name, namebuf) == 0)
+                               break;
+               }
+       }
+       if(playernumber < 0 || playernumber >= svs.maxclients || !(svs.clients[playernumber].active))
+       {
+               if (fromServer)
+                       Con_Print("Host_Tell: invalid player name/ID\n");
+               else
+                       SV_ClientPrint("Host_Tell: invalid player name/ID\n");
+               return;
+       }
        // remove trailing newlines
        while (p2 > p1 && (p2[-1] == '\n' || p2[-1] == '\r'))
                p2--;
@@ -1056,15 +1125,16 @@ void Host_Tell_f(void)
        }
        while (p2 > p1 && (p2[-1] == '\n' || p2[-1] == '\r'))
                p2--;
+       if(p1 == p2)
+               return; // empty say
        for (j = (int)strlen(text);j < (int)(sizeof(text) - 2) && p1 < p2;)
                text[j++] = *p1++;
        text[j++] = '\n';
        text[j++] = 0;
 
        save = host_client;
-       for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
-               if (host_client->spawned && !strcasecmp(host_client->name, Cmd_Argv(1)))
-                       SV_ClientPrint(text);
+       host_client = svs.clients + playernumber;
+       SV_ClientPrint(text);
        host_client = save;
 }
 
@@ -1074,12 +1144,10 @@ void Host_Tell_f(void)
 Host_Color_f
 ==================
 */
-cvar_t cl_color = {CVAR_SAVE, "_cl_color", "0", "internal storage cvar for current player colors (changed by color command)"};
+cvar_t cl_color = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_color", "0", "internal storage cvar for current player colors (changed by color command)"};
 void Host_Color(int changetop, int changebottom)
 {
        int top, bottom, playercolor;
-       mfunction_t *f;
-       func_t SV_ChangeTeam;
 
        // get top and bottom either from the provided values or the current values
        // (allows changing only top or bottom, or both at once)
@@ -1114,20 +1182,20 @@ void Host_Color(int changetop, int changebottom)
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
                return;
 
-       if (host_client->edict && (f = PRVM_ED_FindFunction ("SV_ChangeTeam")) && (SV_ChangeTeam = (func_t)(f - prog->functions)))
+       if (host_client->edict && prog->funcoffsets.SV_ChangeTeam)
        {
                Con_DPrint("Calling SV_ChangeTeam\n");
                prog->globals.server->time = sv.time;
                prog->globals.generic[OFS_PARM0] = playercolor;
                prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
-               PRVM_ExecuteProgram (SV_ChangeTeam, "QC function SV_ChangeTeam is missing");
+               PRVM_ExecuteProgram(prog->funcoffsets.SV_ChangeTeam, "QC function SV_ChangeTeam is missing");
        }
        else
        {
                prvm_eval_t *val;
                if (host_client->edict)
                {
-                       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
+                       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.clientcolors)))
                                val->_float = playercolor;
                        host_client->edict->fields.server->team = bottom + 1;
                }
@@ -1188,7 +1256,7 @@ void Host_BottomColor_f(void)
        Host_Color(-1, atoi(Cmd_Argv(1)));
 }
 
-cvar_t cl_rate = {CVAR_SAVE, "_cl_rate", "10000", "internal storage cvar for current rate (changed by rate command)"};
+cvar_t cl_rate = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_rate", "10000", "internal storage cvar for current rate (changed by rate command)"};
 void Host_Rate_f(void)
 {
        int rate;
@@ -1257,7 +1325,7 @@ LordHavoc: only supported for Nehahra, I personally think this is dumb, but Mind
 LordHavoc: correction, Mindcrime will be removing pmodel in the future, but it's still stuck here for compatibility.
 ======================
 */
-cvar_t cl_pmodel = {CVAR_SAVE, "_cl_pmodel", "0", "internal storage cvar for current player model number in nehahra (changed by pmodel command)"};
+cvar_t cl_pmodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_pmodel", "0", "internal storage cvar for current player model number in nehahra (changed by pmodel command)"};
 static void Host_PModel_f (void)
 {
        int i;
@@ -1280,7 +1348,7 @@ static void Host_PModel_f (void)
                return;
        }
 
-       if (host_client->edict && (val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_pmodel)))
+       if (host_client->edict && (val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.pmodel)))
                val->_float = i;
 }
 
@@ -1320,8 +1388,6 @@ void Host_Spawn_f (void)
 {
        int i;
        client_t *client;
-       func_t RestoreGame;
-       mfunction_t *f;
        int stats[MAX_CL_STATS];
 
        if (host_client->spawned)
@@ -1346,13 +1412,12 @@ void Host_Spawn_f (void)
                // if this is the last client to be connected, unpause
                sv.paused = false;
 
-               if ((f = PRVM_ED_FindFunction ("RestoreGame")))
-               if ((RestoreGame = (func_t)(f - prog->functions)))
+               if (prog->funcoffsets.RestoreGame)
                {
                        Con_DPrint("Calling RestoreGame\n");
                        prog->globals.server->time = sv.time;
                        prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
-                       PRVM_ExecuteProgram (RestoreGame, "QC function RestoreGame is missing");
+                       PRVM_ExecuteProgram(prog->funcoffsets.RestoreGame, "QC function RestoreGame is missing");
                }
        }
        else
@@ -1611,7 +1676,7 @@ void Host_Give_f (void)
                break;
 
        case 's':
-               if (gamemode == GAME_ROGUE && (val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_shells1)))
+               if (gamemode == GAME_ROGUE && (val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_shells1)))
                        val->_float = v;
 
                host_client->edict->fields.server->ammo_shells = v;
@@ -1619,7 +1684,7 @@ void Host_Give_f (void)
        case 'n':
                if (gamemode == GAME_ROGUE)
                {
-                       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_nails1)))
+                       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_nails1)))
                        {
                                val->_float = v;
                                if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
@@ -1634,7 +1699,7 @@ void Host_Give_f (void)
        case 'l':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_lava_nails);
+                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_lava_nails);
                        if (val)
                        {
                                val->_float = v;
@@ -1646,7 +1711,7 @@ void Host_Give_f (void)
        case 'r':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_rockets1);
+                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_rockets1);
                        if (val)
                        {
                                val->_float = v;
@@ -1662,7 +1727,7 @@ void Host_Give_f (void)
        case 'm':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_multi_rockets);
+                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_multi_rockets);
                        if (val)
                        {
                                val->_float = v;
@@ -1677,7 +1742,7 @@ void Host_Give_f (void)
        case 'c':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_cells1);
+                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_cells1);
                        if (val)
                        {
                                val->_float = v;
@@ -1693,7 +1758,7 @@ void Host_Give_f (void)
        case 'p':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_plasma);
+                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_plasma);
                        if (val)
                        {
                                val->_float = v;
@@ -1860,7 +1925,7 @@ void Host_Startdemos_f (void)
 {
        int             i, c;
 
-       if (cls.state == ca_dedicated || COM_CheckParm("-listen") || COM_CheckParm("-benchmark") || COM_CheckParm("-demo") || COM_CheckParm("-demolooponly"))
+       if (cls.state == ca_dedicated || COM_CheckParm("-listen") || COM_CheckParm("-benchmark") || COM_CheckParm("-demo"))
                return;
 
        c = Cmd_Argc() - 1;
@@ -1928,11 +1993,18 @@ void Host_SendCvar_f (void)
 
        if(Cmd_Argc() != 2)
                return;
-       if(!(c = Cvar_FindVar(Cmd_Argv(1))) || (c->flags & CVAR_PRIVATE))
+       c = Cvar_FindVar(Cmd_Argv(1));
+       if (cls.state == ca_connected)
+       {
+               // LordHavoc: if there is no such cvar or if it is private, send a
+               // reply indicating that it has no value
+               if(!c || (c->flags & CVAR_PRIVATE))
+                       Cmd_ForwardStringToServer(va("sentcvar %s\n", c->name));
+               else
+                       Cmd_ForwardStringToServer(va("sentcvar %s \"%s\"\n", c->name, c->string));
                return;
-       if (cls.state != ca_dedicated)
-               Cmd_ForwardStringToServer(va("sentcvar %s %s\n", c->name, c->string));
-       if(!sv.active)// || !SV_ParseClientCommandQC)
+       }
+       if(!sv.active)// || !prog->funcoffsets.SV_ParseClientCommand)
                return;
 
        old = host_client;
@@ -2353,7 +2425,7 @@ void Host_InitCommands (void)
        Cmd_AddCommand ("restart", Host_Restart_f, "restart current level");
        Cmd_AddCommand ("changelevel", Host_Changelevel_f, "change to another level, bringing along all connected clients");
        Cmd_AddCommand ("connect", Host_Connect_f, "connect to a server by IP address or hostname");
-       Cmd_AddCommand ("reconnect", Host_Reconnect_f, "reset signon level in preparation for a new level (do not use)");
+       Cmd_AddCommand ("reconnect", Host_Reconnect_f, "reconnect to the last server you were on, or resets a quakeworld connection (do not use if currently playing on a netquake server)");
        Cmd_AddCommand ("version", Host_Version_f, "print engine version");
        Cmd_AddCommand_WithClientCommand ("say", Host_Say_f, Host_Say_f, "send a chat message to everyone on the server");
        Cmd_AddCommand_WithClientCommand ("say_team", Host_Say_Team_f, Host_Say_Team_f, "send a chat message to your team on the server");
@@ -2397,7 +2469,7 @@ void Host_InitCommands (void)
        Cmd_AddCommand_WithClientCommand ("begin", NULL, Host_Begin_f, "signon 3 (client asks server to start sending entities, and will go to signon 4 (playing) when the first entity update is received)");
        Cmd_AddCommand ("maxplayers", MaxPlayers_f, "sets limit on how many players (or bots) may be connected to the server at once");
 
-       Cmd_AddCommand ("sendcvar", Host_SendCvar_f, "sends the value of a cvar to the server as a sentcvar command, for use by QuakeC");       // By [515]
+       Cmd_AddCommand ("sendcvar", Host_SendCvar_f, "sends the value of a cvar to the server as a sentcvar command, for use by QuakeC");
 
        Cvar_RegisterVariable (&rcon_password);
        Cvar_RegisterVariable (&rcon_address);
@@ -2419,5 +2491,6 @@ void Host_InitCommands (void)
        Cvar_RegisterVariable (&noaim);
 
        Cvar_RegisterVariable(&sv_cheats);
+       Cvar_RegisterVariable(&sv_adminnick);
 }