From: cloudwalk Date: Tue, 23 Jun 2020 03:54:38 +0000 (+0000) Subject: Eradicated the CVAR_NQUSERINFOHACK flag, for good X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=28b6442c3d8b337e36a8b402c55b47696fb9085a Eradicated the CVAR_NQUSERINFOHACK flag, for good This is a massive commit, admittedly. But pretty much every single change goes together and this could not be split up, unfortunately. I implemented a few new functions and turned a lot of the userinfo keys into cvars, just like their QW counterparts. CMD_INITWAIT is also gone and replaced by CMD_USERINFO to denote special server-from-client commands that specifically change a userinfo string of a given client. I'm sure there's a cleaner way to do this, especially the holy callback trinity I implemented to avoid an infinite loop when synchronizing topcolor and bottomcolor with _cl_color and vice versa. But, if this gets rid of decade old legacy cruft, and makes it all easier to maintain down the road, that's a plus for me. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12722 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_input.c b/cl_input.c index 8ccd3477..c940395a 100644 --- a/cl_input.c +++ b/cl_input.c @@ -2114,7 +2114,7 @@ void CL_SendMove(void) // send the reliable message (forwarded commands) if there is one if (buf.cursize || cls.netcon->message.cursize) - NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, max(20*(buf.cursize+40), cl_rate.integer), cl_rate_burstsize.integer, false); + NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, max(20*(buf.cursize+40), rate.integer), rate_burstsize.integer, false); if (quemove) { diff --git a/cl_main.c b/cl_main.c index 9958ecd5..77467bfb 100644 --- a/cl_main.c +++ b/cl_main.c @@ -209,6 +209,9 @@ void CL_ClearState(void) CL_Screen_NewMap(); } +extern cvar_t topcolor; +extern cvar_t bottomcolor; + void CL_SetInfo(const char *key, const char *value, qboolean send, qboolean allowstarkey, qboolean allowmodel, qboolean quiet) { int i; @@ -255,11 +258,13 @@ void CL_SetInfo(const char *key, const char *value, qboolean send, qboolean allo } else if (!strcasecmp(key, "topcolor")) { - // don't send anything, the combined color code will be updated manually + MSG_WriteByte(&cls.netcon->message, clc_stringcmd); + MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "color %i %i", atoi(value), bottomcolor.integer)); } else if (!strcasecmp(key, "bottomcolor")) { - // don't send anything, the combined color code will be updated manually + MSG_WriteByte(&cls.netcon->message, clc_stringcmd); + MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "color %i %i", topcolor.integer, atoi(value))); } else if (!strcasecmp(key, "rate")) { diff --git a/cl_parse.c b/cl_parse.c index d7c97f7e..d3b0ea8a 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -1564,35 +1564,37 @@ static void CL_DownloadFinished_f(cmd_state_t *cmd) CL_BeginDownloads(false); } +extern cvar_t topcolor; +extern cvar_t bottomcolor; static void CL_SendPlayerInfo(void) { char vabuf[1024]; MSG_WriteByte (&cls.netcon->message, clc_stringcmd); - MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "name \"%s\"", cl_name.string)); + MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "name \"%s\"", name.string)); MSG_WriteByte (&cls.netcon->message, clc_stringcmd); - MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "color %i %i", cl_color.integer >> 4, cl_color.integer & 15)); + MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "color %i %i", topcolor.integer, bottomcolor.integer)); MSG_WriteByte (&cls.netcon->message, clc_stringcmd); - MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "rate %i", cl_rate.integer)); + MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "rate %i", rate.integer)); MSG_WriteByte (&cls.netcon->message, clc_stringcmd); - MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "rate_burstsize %i", cl_rate_burstsize.integer)); + MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "rate_burstsize %i", rate_burstsize.integer)); - if (cl_pmodel.integer) + if (pmodel.integer) { MSG_WriteByte (&cls.netcon->message, clc_stringcmd); - MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "pmodel %i", cl_pmodel.integer)); + MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "pmodel %i", pmodel.integer)); } - if (*cl_playermodel.string) + if (*playermodel.string) { MSG_WriteByte (&cls.netcon->message, clc_stringcmd); - MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "playermodel %s", cl_playermodel.string)); + MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "playermodel %s", playermodel.string)); } - if (*cl_playerskin.string) + if (*playerskin.string) { MSG_WriteByte (&cls.netcon->message, clc_stringcmd); - MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "playerskin %s", cl_playerskin.string)); + MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "playerskin %s", playerskin.string)); } } diff --git a/cl_screen.c b/cl_screen.c index 2b0dfe46..312c68e2 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -343,7 +343,7 @@ static void SCR_DrawNetGraph (void) graphwidth = 120; graphheight = 70; graphscale = 1.0f / 1500.0f; - graphlimit = cl_rate.integer; + graphlimit = rate.integer; netgraphsperrow = (vid_conwidth.integer + separator2) / (graphwidth * 2 + separator1 + separator2); netgraphsperrow = max(netgraphsperrow, 1); diff --git a/client.h b/client.h index f505f216..835acc9a 100644 --- a/client.h +++ b/client.h @@ -1458,13 +1458,13 @@ client_state_t; // // cvars // -extern cvar_t cl_name; +extern cvar_t name; extern cvar_t cl_color; -extern cvar_t cl_rate; -extern cvar_t cl_rate_burstsize; -extern cvar_t cl_pmodel; -extern cvar_t cl_playermodel; -extern cvar_t cl_playerskin; +extern cvar_t rate; +extern cvar_t rate_burstsize; +extern cvar_t pmodel; +extern cvar_t playermodel; +extern cvar_t playerskin; extern cvar_t rcon_password; extern cvar_t rcon_address; diff --git a/cmd.c b/cmd.c index 095d63b5..ea0b608e 100644 --- a/cmd.c +++ b/cmd.c @@ -1520,7 +1520,7 @@ void Cmd_Init(void) // server commands received from clients have no reason to access cvars, cvar expansion seems perilous. cmd_serverfromclient.cvars = &cvars_null; cmd_serverfromclient.cvars_flagsmask = 0; - cmd_serverfromclient.cmd_flags = CMD_SERVER_FROM_CLIENT; + cmd_serverfromclient.cmd_flags = CMD_SERVER_FROM_CLIENT | CMD_USERINFO; cmd_serverfromclient.userdefined = &cmd_userdefined_null; // diff --git a/cmd.h b/cmd.h index 4ada5896..72f481b6 100644 --- a/cmd.h +++ b/cmd.h @@ -46,7 +46,7 @@ struct cmd_state_s; #define CMD_SERVER (1<<1) #define CMD_CLIENT_FROM_SERVER (1<<2) #define CMD_SERVER_FROM_CLIENT (1<<3) -#define CMD_INITWAIT (1<<4) +#define CMD_USERINFO (1<<4) #define CMD_CHEAT (1<<5) diff --git a/cvar.c b/cvar.c index 5c9e0d47..905fa758 100644 --- a/cvar.c +++ b/cvar.c @@ -373,10 +373,8 @@ Cvar_Set extern cvar_t sv_disablenotify; static void Cvar_SetQuick_Internal (cvar_t *var, const char *value) { - cvar_state_t *cvars = &cvars_all; qboolean changed; size_t valuelen; - char vabuf[1024]; char new_value[MAX_INPUTLINE]; changed = strcmp(var->string, value) != 0; @@ -416,50 +414,8 @@ static void Cvar_SetQuick_Internal (cvar_t *var, const char *value) } } #endif - if ((var->flags & CVAR_USERINFO) && cls.state != ca_dedicated) + if (var->flags & CVAR_USERINFO) CL_SetInfo(var->name, var->string, true, false, false, false); - else if ((var->flags & CVAR_NQUSERINFOHACK) && cls.state != ca_dedicated) - { - // update the cls.userinfo to have proper values for the - // silly nq config variables. - // - // this is done when these variables are changed rather than at - // connect time because if the user or code checks the userinfo and it - // holds weird values it may cause confusion... - if (!strcmp(var->name, "_cl_color")) - { - int top = (var->integer >> 4) & 15, bottom = var->integer & 15; - CL_SetInfo("topcolor", va(vabuf, sizeof(vabuf), "%i", top), true, false, false, false); - CL_SetInfo("bottomcolor", va(vabuf, sizeof(vabuf), "%i", bottom), true, false, false, false); - if (cls.protocol != PROTOCOL_QUAKEWORLD && cls.netcon) - { - MSG_WriteByte(&cls.netcon->message, clc_stringcmd); - MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "color %i %i", top, bottom)); - } - } - else if (!strcmp(var->name, "_cl_rate")) - CL_SetInfo("rate", va(vabuf, sizeof(vabuf), "%i", var->integer), true, false, false, false); - else if (!strcmp(var->name, "_cl_rate_burstsize")) - CL_SetInfo("rate_burstsize", va(vabuf, sizeof(vabuf), "%i", var->integer), true, false, false, false); - else if (!strcmp(var->name, "_cl_playerskin")) - CL_SetInfo("playerskin", var->string, true, false, false, false); - else if (!strcmp(var->name, "_cl_playermodel")) - CL_SetInfo("playermodel", var->string, true, false, false, false); - else if (!strcmp(var->name, "_cl_name")) - CL_SetInfo("name", var->string, true, false, false, false); - else if (!strcmp(var->name, "rcon_secure")) - { - // whenever rcon_secure is changed to 0, clear rcon_password for - // security reasons (prevents a send-rcon-password-as-plaintext - // attack based on NQ protocol session takeover and svc_stufftext) - if(var->integer <= 0) - Cvar_Set(cvars, "rcon_password", ""); - } -#ifdef CONFIG_MENU - else if (!strcmp(var->name, "net_slist_favorites")) - NetConn_UpdateFavorites(); -#endif - } Cvar_UpdateAutoCvar(var); } @@ -490,6 +446,14 @@ void Cvar_Set(cvar_state_t *cvars, const char *var_name, const char *value) Cvar_SetQuick(var, value); } +void Cvar_Set_NoCallback(cvar_t *var, const char *value) +{ + void (*callback_save)(char *) = var->callback; + var->callback = NULL; + Cvar_SetQuick_Internal(var, value); + var->callback = callback_save; +} + /* ============ Cvar_SetValue diff --git a/cvar.h b/cvar.h index 752c2277..e7234b17 100644 --- a/cvar.h +++ b/cvar.h @@ -68,16 +68,14 @@ interface from being ambiguous. #define CVAR_USERINFO 16 // CVAR_PRIVATE means do not $ expand or sendcvar this cvar under any circumstances (rcon_password uses this) #define CVAR_PRIVATE 32 -// this means that this cvar should update a userinfo key but the name does not correspond directly to the userinfo key to update, and may require additional conversion ("_cl_color" for example should update "topcolor" and "bottomcolor") -#define CVAR_NQUSERINFOHACK 64 // for engine-owned cvars that must not be reset on gametype switch (e.g. scr_screenshot_name, which otherwise isn't set to the mod name properly) -#define CVAR_NORESETTODEFAULTS 128 +#define CVAR_NORESETTODEFAULTS 64 // cvar is accessible in client -#define CVAR_CLIENT 256 +#define CVAR_CLIENT 128 // cvar is accessible in dedicated server -#define CVAR_SERVER 512 +#define CVAR_SERVER 256 // used to determine if flags is valid -#define CVAR_MAXFLAGSVAL 1023 +#define CVAR_MAXFLAGSVAL 511 // for internal use only! #define CVAR_DEFAULTSET (1<<30) #define CVAR_ALLOCATED (1<<31) @@ -132,6 +130,7 @@ typedef struct cvar_s const char *defstring; void (*callback)(char *value); + qboolean ignore_callback; char **aliases; int aliasindex; @@ -191,6 +190,7 @@ qboolean Cvar_Readonly (cvar_t *var, const char *cmd_name); /// equivelant to " " typed at the console void Cvar_Set (cvar_state_t *cvars, const char *var_name, const char *value); +void Cvar_Set_NoCallback (cvar_t *var, const char *value); /// expands value to a string and calls Cvar_Set void Cvar_SetValue (cvar_state_t *cvars, const char *var_name, float value); diff --git a/host_cmd.c b/host_cmd.c index c7f36efd..53e35a3b 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -30,29 +30,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mdfour.h" #include -int current_skill; extern cvar_t sv_adminnick; extern cvar_t sv_status_privacy; extern cvar_t sv_status_show_qcstatus; extern cvar_t sv_namechangetimer; cvar_t rcon_password = {CVAR_CLIENT | CVAR_SERVER | CVAR_PRIVATE, "rcon_password", "", "password to authenticate rcon commands; NOTE: changing rcon_secure clears rcon_password, so set rcon_secure always before rcon_password; may be set to a string of the form user1:pass1 user2:pass2 user3:pass3 to allow multiple user accounts - the client then has to specify ONE of these combinations"}; -cvar_t rcon_secure = {CVAR_CLIENT | CVAR_SERVER | CVAR_NQUSERINFOHACK, "rcon_secure", "0", "force secure rcon authentication (1 = time based, 2 = challenge based); NOTE: changing rcon_secure clears rcon_password, so set rcon_secure always before rcon_password"}; +cvar_t rcon_secure = {CVAR_CLIENT | CVAR_SERVER, "rcon_secure", "0", "force secure rcon authentication (1 = time based, 2 = challenge based); NOTE: changing rcon_secure clears rcon_password, so set rcon_secure always before rcon_password"}; cvar_t rcon_secure_challengetimeout = {CVAR_CLIENT, "rcon_secure_challengetimeout", "5", "challenge-based secure rcon: time out requests if no challenge came within this time interval"}; cvar_t rcon_address = {CVAR_CLIENT, "rcon_address", "", "server address to send rcon commands to (when not connected to a server)"}; +cvar_t name = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "name", "player", "change your player name"}; +cvar_t topcolor = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "topcolor", "0", "change the color of your shirt"}; +cvar_t bottomcolor = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "bottomcolor", "0", "change the color of your pants"}; cvar_t team = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "team", "none", "QW team (4 character limit, example: blue)"}; cvar_t skin = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "skin", "", "QW player skin name (example: base)"}; +cvar_t playermodel = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "playermodel", "", "current player model in Nexuiz/Xonotic"}; +cvar_t playerskin = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "playerskin", "", "current player skin in Nexuiz/Xonotic"}; cvar_t noaim = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "noaim", "1", "QW option to disable vertical autoaim"}; +cvar_t pmodel = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "pmodel", "0", "current player model number in nehahra"}; cvar_t r_fixtrans_auto = {CVAR_CLIENT, "r_fixtrans_auto", "0", "automatically fixtrans textures (when set to 2, it also saves the fixed versions to a fixtrans directory)"}; //============================================================================ /* ====================== -CL_Name_f +SV_Name_f ====================== */ -cvar_t cl_name = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_name", "player", "internal storage cvar for current player name (changed by name command)"}; -static void CL_Name_f(cmd_state_t *cmd) +static void SV_Name_f(cmd_state_t *cmd) { prvm_prog_t *prog = SVVM_prog; int i, j; @@ -61,13 +65,7 @@ static void CL_Name_f(cmd_state_t *cmd) char newName[sizeof(host_client->name)]; if (Cmd_Argc (cmd) == 1) - { - if (cmd->source == src_command) - { - Con_Printf("name: %s\n", cl_name.string); - } return; - } if (Cmd_Argc (cmd) == 2) newNameSource = Cmd_Argv(cmd, 1); @@ -77,17 +75,9 @@ static void CL_Name_f(cmd_state_t *cmd) strlcpy(newName, newNameSource, sizeof(newName)); if (cmd->source == src_command) - { - Cvar_Set (&cvars_all, "_cl_name", newName); - if (strlen(newNameSource) >= sizeof(newName)) // overflowed - { - Con_Printf("Your name is longer than %i chars! It has been truncated.\n", (int) (sizeof(newName) - 1)); - Con_Printf("name: %s\n", cl_name.string); - } return; - } - if (host.realtime < host_client->nametime) + if (host.realtime < host_client->nametime && strcmp(newName, host_client->name)) { SV_ClientPrintf("You can't change name more than once every %.1f seconds!\n", max(0.0f, sv_namechangetimer.value)); return; @@ -182,7 +172,6 @@ static void CL_Name_f(cmd_state_t *cmd) CL_Playermodel_f ====================== */ -cvar_t cl_playermodel = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_playermodel", "", "internal storage cvar for current player model in Nexuiz/Xonotic (changed by playermodel command)"}; // the old cl_playermodel in cl_main has been renamed to __cl_playermodel static void CL_Playermodel_f(cmd_state_t *cmd) { @@ -194,7 +183,7 @@ static void CL_Playermodel_f(cmd_state_t *cmd) { if (cmd->source == src_command) { - Con_Printf("\"playermodel\" is \"%s\"\n", cl_playermodel.string); + Con_Printf("\"playermodel\" is \"%s\"\n", playermodel.string); } return; } @@ -243,7 +232,6 @@ static void CL_Playermodel_f(cmd_state_t *cmd) CL_Playerskin_f ====================== */ -cvar_t cl_playerskin = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_playerskin", "", "internal storage cvar for current player skin in Nexuiz/Xonotic (changed by playerskin command)"}; static void CL_Playerskin_f(cmd_state_t *cmd) { prvm_prog_t *prog = SVVM_prog; @@ -254,7 +242,7 @@ static void CL_Playerskin_f(cmd_state_t *cmd) { if (cmd->source == src_command) { - Con_Printf("\"playerskin\" is \"%s\"\n", cl_playerskin.string); + Con_Printf("\"playerskin\" is \"%s\"\n", playerskin.string); } return; } @@ -305,16 +293,24 @@ static void CL_Playerskin_f(cmd_state_t *cmd) CL_Color_f ================== */ -cvar_t cl_color = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_color", "0", "internal storage cvar for current player colors (changed by color command)"}; +cvar_t cl_color = {CVAR_READONLY | CVAR_CLIENT | CVAR_SAVE, "_cl_color", "0", "internal storage cvar for current player colors (changed by color command)"}; static void CL_Color(cmd_state_t *cmd, int changetop, int changebottom) { + /* + * This is just a convenient way to change topcolor and bottomcolor + * We can't change cl_color from here directly because topcolor and + * bottomcolor may be changed separately and do not call this function. + * So it has to be changed when the userinfo strings are updated, which + * happens twice here. Perhaps find a cleaner way? + */ + prvm_prog_t *prog = SVVM_prog; int top, bottom, playercolor; // get top and bottom either from the provided values or the current values // (allows changing only top or bottom, or both at once) - top = changetop >= 0 ? changetop : (cl_color.integer >> 4); - bottom = changebottom >= 0 ? changebottom : cl_color.integer; + top = changetop >= 0 ? changetop : (topcolor.integer); + bottom = changebottom >= 0 ? changebottom : bottomcolor.integer; top &= 15; bottom &= 15; @@ -328,7 +324,8 @@ static void CL_Color(cmd_state_t *cmd, int changetop, int changebottom) if (cmd->source == src_command) { - Cvar_SetValueQuick(&cl_color, playercolor); + Cvar_SetValueQuick(&topcolor, top); + Cvar_SetValueQuick(&bottomcolor, bottom); return; } @@ -362,6 +359,29 @@ static void CL_Color(cmd_state_t *cmd, int changetop, int changebottom) } } +// Ignore the callbacks so this two-to-three way synchronization doesn't cause an infinite loop. +static void CL_Color_c(char *string) +{ + char vabuf[1024]; + + Cvar_Set_NoCallback(&topcolor, va(vabuf, sizeof(vabuf), "%i", ((atoi(string) >> 4) & 15))); + Cvar_Set_NoCallback(&bottomcolor, va(vabuf, sizeof(vabuf), "%i", (atoi(string) & 15))); +} + +static void CL_Topcolor_c(char *string) +{ + char vabuf[1024]; + + Cvar_Set_NoCallback(&cl_color, va(vabuf, sizeof(vabuf), "%i", atoi(string)*16 + bottomcolor.integer)); +} + +static void CL_Bottomcolor_c(char *string) +{ + char vabuf[1024]; + + Cvar_Set_NoCallback(&cl_color, va(vabuf, sizeof(vabuf), "%i", topcolor.integer*16 + atoi(string))); +} + static void CL_Color_f(cmd_state_t *cmd) { int top, bottom; @@ -370,7 +390,7 @@ static void CL_Color_f(cmd_state_t *cmd) { if (cmd->source == src_command) { - Con_Printf("\"color\" is \"%i %i\"\n", cl_color.integer >> 4, cl_color.integer & 15); + Con_Printf("\"color\" is \"%i %i\"\n", topcolor.integer, bottomcolor.integer); Con_Print("color <0-15> [0-15]\n"); } return; @@ -386,82 +406,29 @@ static void CL_Color_f(cmd_state_t *cmd) CL_Color(cmd, top, bottom); } -static void CL_TopColor_f(cmd_state_t *cmd) -{ - if (Cmd_Argc(cmd) == 1) - { - if (cmd->source == src_command) - { - Con_Printf("\"topcolor\" is \"%i\"\n", (cl_color.integer >> 4) & 15); - Con_Print("topcolor <0-15>\n"); - } - return; - } - - CL_Color(cmd, atoi(Cmd_Argv(cmd, 1)), -1); -} - -static void CL_BottomColor_f(cmd_state_t *cmd) -{ - if (Cmd_Argc(cmd) == 1) - { - if (cmd->source == src_command) - { - Con_Printf("\"bottomcolor\" is \"%i\"\n", cl_color.integer & 15); - Con_Print("bottomcolor <0-15>\n"); - } - return; - } - - CL_Color(cmd, -1, atoi(Cmd_Argv(cmd, 1))); -} - -cvar_t cl_rate = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_rate", "20000", "internal storage cvar for current rate (changed by rate command)"}; -cvar_t cl_rate_burstsize = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_rate_burstsize", "1024", "internal storage cvar for current rate control burst size (changed by rate_burstsize command)"}; -static void CL_Rate_f(cmd_state_t *cmd) +cvar_t rate = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "rate", "20000", "change your connection speed"}; +cvar_t rate_burstsize = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "rate_burstsize", "1024", "internal storage cvar for current rate control burst size (changed by rate_burstsize command)"}; +static void SV_Rate_f(cmd_state_t *cmd) { int rate; - if (Cmd_Argc(cmd) != 2) - { - if (cmd->source == src_command) - { - Con_Printf("\"rate\" is \"%i\"\n", cl_rate.integer); - Con_Print("rate \n"); - } - return; - } - rate = atoi(Cmd_Argv(cmd, 1)); if (cmd->source == src_command) - { - Cvar_SetValue (&cvars_all, "_cl_rate", max(NET_MINRATE, rate)); return; - } host_client->rate = rate; } -static void CL_Rate_BurstSize_f(cmd_state_t *cmd) +static void SV_Rate_BurstSize_f(cmd_state_t *cmd) { int rate_burstsize; if (Cmd_Argc(cmd) != 2) - { - Con_Printf("\"rate_burstsize\" is \"%i\"\n", cl_rate_burstsize.integer); - Con_Print("rate_burstsize \n"); return; - } rate_burstsize = atoi(Cmd_Argv(cmd, 1)); - if (cmd->source == src_command) - { - Cvar_SetValue (&cvars_all, "_cl_rate_burstsize", rate_burstsize); - return; - } - host_client->rate_burstsize = rate_burstsize; } @@ -472,7 +439,6 @@ LadyHavoc: only supported for Nehahra, I personally think this is dumb, but Mind LadyHavoc: correction, Mindcrime will be removing pmodel in the future, but it's still stuck here for compatibility. ====================== */ -cvar_t cl_pmodel = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_pmodel", "0", "internal storage cvar for current player model number in nehahra (changed by pmodel command)"}; static void CL_PModel_f(cmd_state_t *cmd) { prvm_prog_t *prog = SVVM_prog; @@ -482,7 +448,7 @@ static void CL_PModel_f(cmd_state_t *cmd) { if (cmd->source == src_command) { - Con_Printf("\"pmodel\" is \"%s\"\n", cl_pmodel.string); + Con_Printf("\"pmodel\" is \"%s\"\n", pmodel.string); } return; } @@ -490,7 +456,7 @@ static void CL_PModel_f(cmd_state_t *cmd) if (cmd->source == src_command) { - if (cl_pmodel.integer == i) + if (pmodel.integer == i) return; Cvar_SetValue (&cvars_all, "_cl_pmodel", i); if (cls.state == ca_connected) @@ -694,6 +660,15 @@ static void CL_Rcon_f(cmd_state_t *cmd) // credit: taken from QuakeWorld } } +static void CL_RCon_ClearPassword_c(char *string) +{ + // whenever rcon_secure is changed to 0, clear rcon_password for + // security reasons (prevents a send-rcon-password-as-plaintext + // attack based on NQ protocol session takeover and svc_stufftext) + if(atoi(string) <= 0) + Cvar_SetQuick(&rcon_password, ""); +} + /* ================== CL_FullServerinfo_f @@ -897,29 +872,42 @@ void Host_InitCommands (void) { dpsnprintf(cls.userinfo, sizeof(cls.userinfo), "\\name\\player\\team\\none\\topcolor\\0\\bottomcolor\\0\\rate\\10000\\msg\\1\\noaim\\1\\*ver\\dp"); - Cvar_RegisterVariable(&cl_name); + Cvar_RegisterVariable(&name); + Cvar_RegisterAlias(&name, "_cl_name"); Cvar_RegisterVariable(&cl_color); - Cvar_RegisterVariable(&cl_rate); - Cvar_RegisterVariable(&cl_rate_burstsize); - Cvar_RegisterVariable(&cl_pmodel); - Cvar_RegisterVariable(&cl_playermodel); - Cvar_RegisterVariable(&cl_playerskin); + Cvar_RegisterCallback(&cl_color, CL_Color_c); + Cvar_RegisterVariable(&topcolor); + Cvar_RegisterCallback(&topcolor, CL_Topcolor_c); + Cvar_RegisterVariable(&bottomcolor); + Cvar_RegisterCallback(&bottomcolor, CL_Bottomcolor_c); + Cvar_RegisterVariable(&rate); + Cvar_RegisterAlias(&rate, "_cl_rate"); + Cvar_RegisterVariable(&rate_burstsize); + Cvar_RegisterAlias(&rate_burstsize, "_cl_rate_burstsize"); + Cvar_RegisterVariable(&pmodel); + Cvar_RegisterAlias(&pmodel, "_cl_pmodel"); + Cvar_RegisterVariable(&playermodel); + Cvar_RegisterAlias(&playermodel, "_cl_playermodel"); + Cvar_RegisterVariable(&playerskin); + Cvar_RegisterAlias(&playerskin, "_cl_playerskin"); Cvar_RegisterVariable(&rcon_password); Cvar_RegisterVariable(&rcon_address); Cvar_RegisterVariable(&rcon_secure); + Cvar_RegisterCallback(&rcon_secure, CL_RCon_ClearPassword_c); Cvar_RegisterVariable(&rcon_secure_challengetimeout); Cvar_RegisterVariable(&r_fixtrans_auto); Cvar_RegisterVariable(&team); Cvar_RegisterVariable(&skin); Cvar_RegisterVariable(&noaim); - Cmd_AddCommand(CMD_CLIENT | CMD_SERVER_FROM_CLIENT, "name", CL_Name_f, "change your player name"); - Cmd_AddCommand(CMD_CLIENT | CMD_SERVER_FROM_CLIENT, "color", CL_Color_f, "change your player shirt and pants colors"); - Cmd_AddCommand(CMD_CLIENT | CMD_SERVER_FROM_CLIENT, "rate", CL_Rate_f, "change your network connection speed"); - Cmd_AddCommand(CMD_CLIENT | CMD_SERVER_FROM_CLIENT, "rate_burstsize", CL_Rate_BurstSize_f, "change your network connection speed"); - Cmd_AddCommand(CMD_CLIENT | CMD_SERVER_FROM_CLIENT, "pmodel", CL_PModel_f, "(Nehahra-only) change your player model choice"); - Cmd_AddCommand(CMD_CLIENT | CMD_SERVER_FROM_CLIENT, "playermodel", CL_Playermodel_f, "change your player model"); - Cmd_AddCommand(CMD_CLIENT | CMD_SERVER_FROM_CLIENT, "playerskin", CL_Playerskin_f, "change your player skin number"); + Cmd_AddCommand(CMD_USERINFO, "name", SV_Name_f, "change your player name"); + Cmd_AddCommand(CMD_CLIENT, "color", CL_Color_f, "change your player shirt and pants colors"); + Cmd_AddCommand(CMD_USERINFO, "color", CL_Color_f, "change your player shirt and pants colors"); + Cmd_AddCommand(CMD_USERINFO, "rate", SV_Rate_f, "change your network connection speed"); + Cmd_AddCommand(CMD_USERINFO, "rate_burstsize", SV_Rate_BurstSize_f, "change your network connection speed"); + Cmd_AddCommand(CMD_USERINFO, "pmodel", CL_PModel_f, "(Nehahra-only) change your player model choice"); + Cmd_AddCommand(CMD_USERINFO, "playermodel", CL_Playermodel_f, "change your player model"); + Cmd_AddCommand(CMD_USERINFO, "playerskin", CL_Playerskin_f, "change your player skin number"); Cmd_AddCommand(CMD_CLIENT, "sendcvar", CL_SendCvar_f, "sends the value of a cvar to the server as a sentcvar command, for use by QuakeC"); Cmd_AddCommand(CMD_CLIENT, "rcon", CL_Rcon_f, "sends a command to the server console (if your rcon_password matches the server's rcon_password), or to the address specified by rcon_address when not connected (again rcon_password must match the server's); note: if rcon_secure is set, client and server clocks must be synced e.g. via NTP"); @@ -927,9 +915,7 @@ void Host_InitCommands (void) Cmd_AddCommand(CMD_CLIENT, "pqrcon", CL_PQRcon_f, "sends a command to a proquake server console (if your rcon_password matches the server's rcon_password), or to the address specified by rcon_address when not connected (again rcon_password must match the server's)"); Cmd_AddCommand(CMD_CLIENT, "fullinfo", CL_FullInfo_f, "allows client to modify their userinfo"); Cmd_AddCommand(CMD_CLIENT, "setinfo", CL_SetInfo_f, "modifies your userinfo"); - Cmd_AddCommand(CMD_CLIENT | CMD_CLIENT_FROM_SERVER, "packet", CL_Packet_f, "send a packet to the specified address:port containing a text string"); - Cmd_AddCommand(CMD_CLIENT | CMD_CLIENT_FROM_SERVER, "topcolor", CL_TopColor_f, "QW command to set top color without changing bottom color"); - Cmd_AddCommand(CMD_CLIENT, "bottomcolor", CL_BottomColor_f, "QW command to set bottom color without changing top color"); + Cmd_AddCommand(CMD_CLIENT, "packet", CL_Packet_f, "send a packet to the specified address:port containing a text string"); Cmd_AddCommand(CMD_CLIENT, "fixtrans", Image_FixTransparentPixels_f, "change alpha-zero pixels in an image file to sensible values, and write out a new TGA (warning: SLOW)"); // commands that are only sent by server to client for execution diff --git a/menu.c b/menu.c index 141d9e20..5cad78b7 100644 --- a/menu.c +++ b/menu.c @@ -1284,15 +1284,18 @@ static int setup_oldrate; #define NUM_SETUP_CMDS 5 +extern cvar_t topcolor; +extern cvar_t bottomcolor; + void M_Menu_Setup_f(cmd_state_t *cmd) { key_dest = key_menu; m_state = m_setup; m_entersound = true; - strlcpy(setup_myname, cl_name.string, sizeof(setup_myname)); - setup_top = setup_oldtop = cl_color.integer >> 4; - setup_bottom = setup_oldbottom = cl_color.integer & 15; - setup_rate = cl_rate.integer; + strlcpy(setup_myname, name.string, sizeof(setup_myname)); + setup_top = setup_oldtop = topcolor.integer; + setup_bottom = setup_oldbottom = bottomcolor.integer; + setup_rate = rate.integer; } static int menuplyr_width, menuplyr_height, menuplyr_top, menuplyr_bottom, menuplyr_load; @@ -1493,7 +1496,7 @@ forward: goto forward; // setup_cursor == 4 (Accept changes) - if (strcmp(cl_name.string, setup_myname) != 0) + if (strcmp(name.string, setup_myname) != 0) Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "name \"%s\"\n", setup_myname) ); if (setup_top != setup_oldtop || setup_bottom != setup_oldbottom) Cbuf_AddText(cmd, va(vabuf, sizeof(vabuf), "color %i %i\n", setup_top, setup_bottom) ); diff --git a/netconn.c b/netconn.c index eb61cfed..e4b34ca2 100755 --- a/netconn.c +++ b/netconn.c @@ -93,7 +93,7 @@ static cvar_t net_slist_queriesperframe = {CVAR_CLIENT, "net_slist_queriesperfra static cvar_t net_slist_timeout = {CVAR_CLIENT, "net_slist_timeout", "4", "how long to listen for a server information response before giving up"}; static cvar_t net_slist_pause = {CVAR_CLIENT, "net_slist_pause", "0", "when set to 1, the server list won't update until it is set back to 0"}; static cvar_t net_slist_maxtries = {CVAR_CLIENT, "net_slist_maxtries", "3", "how many times to ask the same server for information (more times gives better ping reports but takes longer)"}; -static cvar_t net_slist_favorites = {CVAR_CLIENT | CVAR_SAVE | CVAR_NQUSERINFOHACK, "net_slist_favorites", "", "contains a list of IP addresses and ports to always query explicitly"}; +static cvar_t net_slist_favorites = {CVAR_CLIENT | CVAR_SAVE, "net_slist_favorites", "", "contains a list of IP addresses and ports to always query explicitly"}; static cvar_t net_tos_dscp = {CVAR_CLIENT | CVAR_SAVE, "net_tos_dscp", "32", "DiffServ Codepoint for network sockets (may need game restart to apply)"}; static cvar_t gameversion = {CVAR_SERVER, "gameversion", "0", "version of game data (mod-specific) to be sent to querying clients"}; static cvar_t gameversion_min = {CVAR_CLIENT | CVAR_SERVER, "gameversion_min", "-1", "minimum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"}; @@ -166,12 +166,12 @@ static lhnetaddress_t favorites[MAX_FAVORITESERVERS]; static int nFavorites_idfp = 0; static char favorites_idfp[MAX_FAVORITESERVERS][FP64_SIZE+1]; -void NetConn_UpdateFavorites(void) +void NetConn_UpdateFavorites_c(char *string) { const char *p; nFavorites = 0; nFavorites_idfp = 0; - p = net_slist_favorites.string; + p = string; while((size_t) nFavorites < sizeof(favorites) / sizeof(*favorites) && COM_ParseToken_Console(&p)) { if(com_token[0] != '[' && strlen(com_token) == FP64_SIZE && !strchr(com_token, '.')) @@ -1265,7 +1265,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s conn->incoming_netgraph[conn->incoming_packetcounter].unreliablebytes = originallength + 28; conn->incoming_netgraph[conn->incoming_packetcounter].reliablebytes = NETGRAPH_NOPACKET; conn->incoming_netgraph[conn->incoming_packetcounter].ackbytes = NETGRAPH_NOPACKET; - NetConn_UpdateCleartime(&conn->incoming_cleartime, cl_rate.integer, cl_rate_burstsize.integer, originallength + 28); + NetConn_UpdateCleartime(&conn->incoming_cleartime, rate.integer, rate_burstsize.integer, originallength + 28); // limit bursts to one packet in size ("dialup mode" emulating old behaviour) if (net_test.integer) @@ -1361,7 +1361,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s conn->incoming_netgraph[conn->incoming_packetcounter].unreliablebytes = originallength + 28; conn->incoming_netgraph[conn->incoming_packetcounter].reliablebytes = NETGRAPH_NOPACKET; conn->incoming_netgraph[conn->incoming_packetcounter].ackbytes = NETGRAPH_NOPACKET; - NetConn_UpdateCleartime(&conn->incoming_cleartime, cl_rate.integer, cl_rate_burstsize.integer, originallength + 28); + NetConn_UpdateCleartime(&conn->incoming_cleartime, rate.integer, rate_burstsize.integer, originallength + 28); conn->nq.unreliableReceiveSequence = sequence + 1; conn->lastMessageTime = host.realtime; @@ -1391,7 +1391,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s else if (flags & NETFLAG_ACK) { conn->incoming_netgraph[conn->incoming_packetcounter].ackbytes += originallength + 28; - NetConn_UpdateCleartime(&conn->incoming_cleartime, cl_rate.integer, cl_rate_burstsize.integer, originallength + 28); + NetConn_UpdateCleartime(&conn->incoming_cleartime, rate.integer, rate_burstsize.integer, originallength + 28); if (sequence == (conn->nq.sendSequence - 1)) { @@ -1451,7 +1451,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s { unsigned char temppacket[8]; conn->incoming_netgraph[conn->incoming_packetcounter].reliablebytes += originallength + 28; - NetConn_UpdateCleartime(&conn->incoming_cleartime, cl_rate.integer, cl_rate_burstsize.integer, originallength + 28); + NetConn_UpdateCleartime(&conn->incoming_cleartime, rate.integer, rate_burstsize.integer, originallength + 28); conn->outgoing_netgraph[conn->outgoing_packetcounter].ackbytes += 8 + 28; @@ -3889,6 +3889,7 @@ void NetConn_Init(void) Cvar_RegisterVariable(&net_slist_timeout); Cvar_RegisterVariable(&net_slist_maxtries); Cvar_RegisterVariable(&net_slist_favorites); + Cvar_RegisterCallback(&net_slist_favorites, NetConn_UpdateFavorites_c); Cvar_RegisterVariable(&net_slist_pause); if(LHNET_DefaultDSCP(-1) >= 0) // register cvar only if supported Cvar_RegisterVariable(&net_tos_dscp); diff --git a/netconn.h b/netconn.h index 7120c531..9e568af1 100755 --- a/netconn.h +++ b/netconn.h @@ -470,7 +470,7 @@ void ServerList_ResetMasks(void); void ServerList_QueryList(qboolean resetcache, qboolean querydp, qboolean queryqw, qboolean consoleoutput); /// called whenever net_slist_favorites changes -void NetConn_UpdateFavorites(void); +void NetConn_UpdateFavorites_c(char *string); #endif #define MAX_CHALLENGES 128 diff --git a/sv_ccmds.c b/sv_ccmds.c index 84340c97..2ed55405 100644 --- a/sv_ccmds.c +++ b/sv_ccmds.c @@ -988,7 +988,7 @@ static void SV_Kick_f(cmd_state_t *cmd) if (cls.state == ca_dedicated) who = "Console"; else - who = cl_name.string; + who = name.string; } else who = save->name; @@ -1199,7 +1199,7 @@ void SV_InitOperatorCommands(void) Cvar_RegisterVariable(&sv_namechangetimer); Cmd_AddCommand(CMD_SERVER | CMD_SERVER_FROM_CLIENT, "status", SV_Status_f, "print server status information"); - Cmd_AddCommand(CMD_SHARED | CMD_INITWAIT, "map", SV_Map_f, "kick everyone off the server and start a new level"); + Cmd_AddCommand(CMD_SHARED, "map", SV_Map_f, "kick everyone off the server and start a new level"); Cmd_AddCommand(CMD_SHARED, "restart", SV_Restart_f, "restart current level"); Cmd_AddCommand(CMD_SHARED, "changelevel", SV_Changelevel_f, "change to another level, bringing along all connected clients"); Cmd_AddCommand(CMD_SHARED | CMD_SERVER_FROM_CLIENT, "say", SV_Say_f, "send a chat message to everyone on the server"); @@ -1208,7 +1208,7 @@ void SV_InitOperatorCommands(void) Cmd_AddCommand(CMD_SERVER | CMD_SERVER_FROM_CLIENT, "pause", SV_Pause_f, "pause the game (if the server allows pausing)"); Cmd_AddCommand(CMD_SHARED, "kick", SV_Kick_f, "kick a player off the server by number or name"); Cmd_AddCommand(CMD_SHARED | CMD_SERVER_FROM_CLIENT, "ping", SV_Ping_f, "print ping times of all players on the server"); - Cmd_AddCommand(CMD_SHARED | CMD_INITWAIT, "load", SV_Loadgame_f, "load a saved game file"); + Cmd_AddCommand(CMD_SHARED, "load", SV_Loadgame_f, "load a saved game file"); Cmd_AddCommand(CMD_SHARED, "save", SV_Savegame_f, "save the game to a file"); Cmd_AddCommand(CMD_SHARED, "viewmodel", SV_Viewmodel_f, "change model of viewthing entity in current level"); Cmd_AddCommand(CMD_SHARED, "viewframe", SV_Viewframe_f, "change animation frame of viewthing entity in current level");