From 40bbda3135e611673d899661fd4fd29486a60c2f Mon Sep 17 00:00:00 2001 From: cloudwalk Date: Wed, 1 Jul 2020 01:58:39 +0000 Subject: [PATCH] (Round 7) host_cmd.c is no more. Last remaining cmds/cvars moved. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12766 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_cmd.c | 177 +++++++++++++- common.c | 8 + darkplaces-sdl2-vs2017.vcxproj | 1 - darkplaces-sdl2-vs2019.vcxproj | 1 - host.c | 4 +- host_cmd.c | 410 --------------------------------- makefile.inc | 1 - sv_ccmds.c | 146 ++++++++++++ 8 files changed, 330 insertions(+), 418 deletions(-) delete mode 100644 host_cmd.c diff --git a/cl_cmd.c b/cl_cmd.c index 8378e46d..d17c6fda 100644 --- a/cl_cmd.c +++ b/cl_cmd.c @@ -23,15 +23,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // for secure rcon authentication #include "hmac.h" #include "mdfour.h" +#include "image.h" #include +cvar_t cl_name = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "name", "player", "change your player name"}; +cvar_t cl_rate = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "rate", "20000", "change your connection speed"}; +cvar_t cl_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)"}; +cvar_t cl_topcolor = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "topcolor", "0", "change the color of your shirt"}; +cvar_t cl_bottomcolor = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "bottomcolor", "0", "change the color of your pants"}; +cvar_t cl_team = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "team", "none", "QW team (4 character limit, example: blue)"}; +cvar_t cl_skin = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "skin", "", "QW player skin name (example: base)"}; +cvar_t cl_noaim = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "noaim", "1", "QW option to disable vertical autoaim"}; +cvar_t cl_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)"}; 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, "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 cl_name = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "name", "player", "change your player name"}; -cvar_t cl_topcolor = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "topcolor", "0", "change the color of your shirt"}; -cvar_t cl_bottomcolor = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "bottomcolor", "0", "change the color of your pants"}; /* =================== @@ -180,6 +188,28 @@ void CL_ForwardToServer_f (cmd_state_t *cmd) CL_ForwardToServer(s); } +static void CL_SendCvar_f(cmd_state_t *cmd) +{ + cvar_t *c; + const char *cvarname; + char vabuf[1024]; + + if(Cmd_Argc(cmd) != 2) + return; + cvarname = Cmd_Argv(cmd, 1); + if (cls.state == ca_connected) + { + c = Cvar_FindVar(&cvars_all, cvarname, CVAR_CLIENT | CVAR_SERVER); + // LadyHavoc: 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)) + CL_ForwardToServer(va(vabuf, sizeof(vabuf), "sentcvar %s", cvarname)); + else + CL_ForwardToServer(va(vabuf, sizeof(vabuf), "sentcvar %s \"%s\"", c->name, c->string)); + return; + } +} + /* ================== CL_Color_f @@ -489,8 +519,135 @@ static void CL_RCon_ClearPassword_c(cvar_t *var) Cvar_SetQuick(&rcon_password, ""); } +/* +================== +CL_FullServerinfo_f + +Sent by server when serverinfo changes +================== +*/ +// TODO: shouldn't this be a cvar instead? +static void CL_FullServerinfo_f(cmd_state_t *cmd) // credit: taken from QuakeWorld +{ + char temp[512]; + if (Cmd_Argc(cmd) != 2) + { + Con_Printf ("usage: fullserverinfo \n"); + return; + } + + strlcpy (cl.qw_serverinfo, Cmd_Argv(cmd, 1), sizeof(cl.qw_serverinfo)); + InfoString_GetValue(cl.qw_serverinfo, "teamplay", temp, sizeof(temp)); + cl.qw_teamplay = atoi(temp); +} + +/* +================== +CL_FullInfo_f + +Allow clients to change userinfo +================== +Casey was here :) +*/ +static void CL_FullInfo_f(cmd_state_t *cmd) // credit: taken from QuakeWorld +{ + char key[512]; + char value[512]; + const char *s; + + if (Cmd_Argc(cmd) != 2) + { + Con_Printf ("fullinfo \n"); + return; + } + + s = Cmd_Argv(cmd, 1); + if (*s == '\\') + s++; + while (*s) + { + size_t len = strcspn(s, "\\"); + if (len >= sizeof(key)) { + len = sizeof(key) - 1; + } + strlcpy(key, s, len + 1); + s += len; + if (!*s) + { + Con_Printf ("MISSING VALUE\n"); + return; + } + ++s; // Skip over backslash. + + len = strcspn(s, "\\"); + if (len >= sizeof(value)) { + len = sizeof(value) - 1; + } + strlcpy(value, s, len + 1); + + CL_SetInfo(key, value, false, false, false, false); + + s += len; + if (!*s) + { + break; + } + ++s; // Skip over backslash. + } +} + +/* +================== +CL_SetInfo_f + +Allow clients to change userinfo +================== +*/ +static void CL_SetInfo_f(cmd_state_t *cmd) // credit: taken from QuakeWorld +{ + if (Cmd_Argc(cmd) == 1) + { + InfoString_Print(cls.userinfo); + return; + } + if (Cmd_Argc(cmd) != 3) + { + Con_Printf ("usage: setinfo [ ]\n"); + return; + } + CL_SetInfo(Cmd_Argv(cmd, 1), Cmd_Argv(cmd, 2), true, false, false, false); +} + +static void CL_PingPLReport_f(cmd_state_t *cmd) +{ + char *errbyte; + int i; + int l = Cmd_Argc(cmd); + if (l > cl.maxclients) + l = cl.maxclients; + for (i = 0;i < l;i++) + { + cl.scores[i].qw_ping = atoi(Cmd_Argv(cmd, 1+i*2)); + cl.scores[i].qw_packetloss = strtol(Cmd_Argv(cmd, 1+i*2+1), &errbyte, 0); + if(errbyte && *errbyte == ',') + cl.scores[i].qw_movementloss = atoi(errbyte + 1); + else + cl.scores[i].qw_movementloss = 0; + } +} + void CL_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_RegisterAlias(&cl_name, "_cl_name"); + Cvar_RegisterVariable(&cl_rate); + Cvar_RegisterAlias(&cl_rate, "_cl_rate"); + Cvar_RegisterVariable(&cl_rate_burstsize); + Cvar_RegisterAlias(&cl_rate_burstsize, "_cl_rate_burstsize"); + Cvar_RegisterVariable(&cl_pmodel); + Cvar_RegisterAlias(&cl_pmodel, "_cl_pmodel"); Cvar_RegisterVariable(&cl_color); Cvar_RegisterCallback(&cl_color, CL_Color_c); Cvar_RegisterVariable(&cl_topcolor); @@ -501,6 +658,11 @@ void CL_InitCommands(void) Cvar_RegisterVariable(&rcon_secure); Cvar_RegisterCallback(&rcon_secure, CL_RCon_ClearPassword_c); Cvar_RegisterVariable(&rcon_secure_challengetimeout); + Cvar_RegisterVariable(&rcon_password); + Cvar_RegisterVariable(&r_fixtrans_auto); + Cvar_RegisterVariable(&cl_team); + Cvar_RegisterVariable(&cl_skin); + Cvar_RegisterVariable(&cl_noaim); Cmd_AddCommand(CMD_CLIENT | CMD_CLIENT_FROM_SERVER, "cmd", CL_ForwardToServer_f, "send a console commandline to the server (used by some mods)"); Cmd_AddCommand(CMD_CLIENT, "color", CL_Color_f, "change your player shirt and pants colors"); @@ -508,5 +670,12 @@ void CL_InitCommands(void) Cmd_AddCommand(CMD_CLIENT, "srcon", 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); this always works as if rcon_secure is set; note: client and server clocks must be synced e.g. via NTP"); 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, "packet", CL_Packet_f, "send a packet to the specified address:port containing a text string"); - + 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, "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, "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 + Cmd_AddCommand(CMD_CLIENT_FROM_SERVER, "pingplreport", CL_PingPLReport_f, "command sent by server containing client ping and packet loss values for scoreboard, triggered by pings command from client (not used by QW servers)"); + Cmd_AddCommand(CMD_CLIENT_FROM_SERVER, "fullserverinfo", CL_FullServerinfo_f, "internal use only, sent by server to client to update client's local copy of serverinfo string"); } diff --git a/common.c b/common.c index 40713e22..c1bdac48 100644 --- a/common.c +++ b/common.c @@ -31,6 +31,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cvar_t registered = {CVAR_CLIENT | CVAR_SERVER, "registered","0", "indicates if this is running registered quake (whether gfx/pop.lmp was found)"}; cvar_t cmdline = {CVAR_CLIENT | CVAR_SERVER, "cmdline","0", "contains commandline the engine was launched with"}; +// FIXME: Find a better place for these. +cvar_t cl_playermodel = {CVAR_CLIENT | CVAR_SERVER | CVAR_USERINFO | CVAR_SAVE, "playermodel", "", "current player model in Nexuiz/Xonotic"}; +cvar_t cl_playerskin = {CVAR_CLIENT | CVAR_SERVER | CVAR_USERINFO | CVAR_SAVE, "playerskin", "", "current player skin in Nexuiz/Xonotic"}; + char com_token[MAX_INPUTLINE]; gamemode_t gamemode; @@ -1076,6 +1080,10 @@ void COM_Init_Commands (void) Cvar_RegisterVariable (®istered); Cvar_RegisterVariable (&cmdline); + Cvar_RegisterVariable(&cl_playermodel); + Cvar_RegisterAlias(&cl_playermodel, "_cl_playermodel"); + Cvar_RegisterVariable(&cl_playerskin); + Cvar_RegisterAlias(&cl_playerskin, "_cl_playerskin"); // reconstitute the command line for the cmdline externally visible cvar n = 0; diff --git a/darkplaces-sdl2-vs2017.vcxproj b/darkplaces-sdl2-vs2017.vcxproj index b58de8d8..c292a782 100644 --- a/darkplaces-sdl2-vs2017.vcxproj +++ b/darkplaces-sdl2-vs2017.vcxproj @@ -235,7 +235,6 @@ - diff --git a/darkplaces-sdl2-vs2019.vcxproj b/darkplaces-sdl2-vs2019.vcxproj index 97118ba3..3b4ea935 100644 --- a/darkplaces-sdl2-vs2019.vcxproj +++ b/darkplaces-sdl2-vs2019.vcxproj @@ -236,7 +236,6 @@ - diff --git a/host.c b/host.c index bd843943..fc46a229 100644 --- a/host.c +++ b/host.c @@ -999,7 +999,6 @@ static void Host_Init (void) World_Init(); SV_Init(); V_Init(); // some cvars needed by server player physics (cl_rollangle etc) - Host_InitCommands(); Host_InitLocal(); Host_ServerOptions(); @@ -1175,3 +1174,6 @@ void Host_Shutdown(void) Memory_Shutdown(); } +void Host_NoOperation_f(cmd_state_t *cmd) +{ +} diff --git a/host_cmd.c b/host_cmd.c deleted file mode 100644 index 01790dd7..00000000 --- a/host_cmd.c +++ /dev/null @@ -1,410 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "quakedef.h" -#include "sv_demo.h" -#include "image.h" - -#include "prvm_cmds.h" -#include "utf8lib.h" - -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 cl_team = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "team", "none", "QW team (4 character limit, example: blue)"}; -cvar_t cl_skin = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "skin", "", "QW player skin name (example: base)"}; -cvar_t cl_playermodel = {CVAR_CLIENT | CVAR_SERVER | CVAR_USERINFO | CVAR_SAVE, "playermodel", "", "current player model in Nexuiz/Xonotic"}; -cvar_t cl_playerskin = {CVAR_CLIENT | CVAR_SERVER | CVAR_USERINFO | CVAR_SAVE, "playerskin", "", "current player skin in Nexuiz/Xonotic"}; -cvar_t cl_noaim = {CVAR_CLIENT | CVAR_USERINFO | CVAR_SAVE, "noaim", "1", "QW option to disable vertical autoaim"}; -cvar_t cl_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_Playermodel_f -====================== -*/ -// the old cl_playermodel in cl_main has been renamed to __cl_playermodel -static void CL_Playermodel_f(cmd_state_t *cmd) -{ - prvm_prog_t *prog = SVVM_prog; - int i, j; - char newPath[sizeof(host_client->playermodel)]; - - if (Cmd_Argc (cmd) == 1) - { - if (cmd->source == src_command) - { - Con_Printf("\"playermodel\" is \"%s\"\n", cl_playermodel.string); - } - return; - } - - if (Cmd_Argc (cmd) == 2) - strlcpy (newPath, Cmd_Argv(cmd, 1), sizeof (newPath)); - else - strlcpy (newPath, Cmd_Args(cmd), sizeof (newPath)); - - for (i = 0, j = 0;newPath[i];i++) - if (newPath[i] != '\r' && newPath[i] != '\n') - newPath[j++] = newPath[i]; - newPath[j] = 0; - - if (cmd->source == src_command) - { - Cvar_Set (&cvars_all, "_cl_playermodel", newPath); - return; - } - - /* - if (host.realtime < host_client->nametime) - { - SV_ClientPrintf("You can't change playermodel more than once every 5 seconds!\n"); - return; - } - - host_client->nametime = host.realtime + 5; - */ - - // point the string back at updateclient->name to keep it safe - strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel)); - PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(prog, 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)); - /*// send notification to all clients - MSG_WriteByte (&sv.reliable_datagram, svc_updatepmodel); - MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); - MSG_WriteString (&sv.reliable_datagram, host_client->playermodel);*/ - } -} - -/* -====================== -CL_Playerskin_f -====================== -*/ -static void CL_Playerskin_f(cmd_state_t *cmd) -{ - prvm_prog_t *prog = SVVM_prog; - int i, j; - char newPath[sizeof(host_client->playerskin)]; - - if (Cmd_Argc (cmd) == 1) - { - if (cmd->source == src_command) - { - Con_Printf("\"playerskin\" is \"%s\"\n", cl_playerskin.string); - } - return; - } - - if (Cmd_Argc (cmd) == 2) - strlcpy (newPath, Cmd_Argv(cmd, 1), sizeof (newPath)); - else - strlcpy (newPath, Cmd_Args(cmd), sizeof (newPath)); - - for (i = 0, j = 0;newPath[i];i++) - if (newPath[i] != '\r' && newPath[i] != '\n') - newPath[j++] = newPath[i]; - newPath[j] = 0; - - if (cmd->source == src_command) - { - Cvar_Set (&cvars_all, "_cl_playerskin", newPath); - return; - } - - /* - if (host.realtime < host_client->nametime) - { - SV_ClientPrintf("You can't change playermodel more than once every 5 seconds!\n"); - return; - } - - host_client->nametime = host.realtime + 5; - */ - - // point the string back at updateclient->name to keep it safe - strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin)); - PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(prog, host_client->playerskin); - if (strcmp(host_client->old_skin, host_client->playerskin)) - { - //if (host_client->begun) - // SV_BroadcastPrintf("%s changed skin to %s\n", host_client->name, host_client->playerskin); - strlcpy(host_client->old_skin, host_client->playerskin, sizeof(host_client->old_skin)); - /*// send notification to all clients - MSG_WriteByte (&sv.reliable_datagram, svc_updatepskin); - MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); - MSG_WriteString (&sv.reliable_datagram, host_client->playerskin);*/ - } -} - -cvar_t cl_rate = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "rate", "20000", "change your connection speed"}; -cvar_t cl_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)"}; - -/* -====================== -CL_PModel_f -LadyHavoc: only supported for Nehahra, I personally think this is dumb, but Mindcrime won't listen. -LadyHavoc: correction, Mindcrime will be removing pmodel in the future, but it's still stuck here for compatibility. -====================== -*/ -static void CL_PModel_f(cmd_state_t *cmd) -{ - prvm_prog_t *prog = SVVM_prog; - int i; - - if (Cmd_Argc (cmd) == 1) - { - if (cmd->source == src_command) - { - Con_Printf("\"pmodel\" is \"%s\"\n", cl_pmodel.string); - } - return; - } - i = atoi(Cmd_Argv(cmd, 1)); - - if (cmd->source == src_command) - { - if (cl_pmodel.integer == i) - return; - Cvar_SetValue (&cvars_all, "_cl_pmodel", i); - if (cls.state == ca_connected) - CL_ForwardToServer_f(cmd); - return; - } - - PRVM_serveredictfloat(host_client->edict, pmodel) = i; -} - -//=========================================================================== - -//=========================================================================== - -static void CL_SendCvar_f(cmd_state_t *cmd) -{ - int i; - cvar_t *c; - const char *cvarname; - client_t *old; - char vabuf[1024]; - - if(Cmd_Argc(cmd) != 2) - return; - cvarname = Cmd_Argv(cmd, 1); - if (cls.state == ca_connected) - { - c = Cvar_FindVar(&cvars_all, cvarname, CVAR_CLIENT | CVAR_SERVER); - // LadyHavoc: 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)) - CL_ForwardToServer(va(vabuf, sizeof(vabuf), "sentcvar %s", cvarname)); - else - CL_ForwardToServer(va(vabuf, sizeof(vabuf), "sentcvar %s \"%s\"", c->name, c->string)); - return; - } - if(!sv.active)// || !PRVM_serverfunction(SV_ParseClientCommand)) - return; - - old = host_client; - if (cls.state != ca_dedicated) - i = 1; - else - i = 0; - for(;i\n"); - return; - } - - strlcpy (cl.qw_serverinfo, Cmd_Argv(cmd, 1), sizeof(cl.qw_serverinfo)); - InfoString_GetValue(cl.qw_serverinfo, "teamplay", temp, sizeof(temp)); - cl.qw_teamplay = atoi(temp); -} - -/* -================== -CL_FullInfo_f - -Allow clients to change userinfo -================== -Casey was here :) -*/ -static void CL_FullInfo_f(cmd_state_t *cmd) // credit: taken from QuakeWorld -{ - char key[512]; - char value[512]; - const char *s; - - if (Cmd_Argc(cmd) != 2) - { - Con_Printf ("fullinfo \n"); - return; - } - - s = Cmd_Argv(cmd, 1); - if (*s == '\\') - s++; - while (*s) - { - size_t len = strcspn(s, "\\"); - if (len >= sizeof(key)) { - len = sizeof(key) - 1; - } - strlcpy(key, s, len + 1); - s += len; - if (!*s) - { - Con_Printf ("MISSING VALUE\n"); - return; - } - ++s; // Skip over backslash. - - len = strcspn(s, "\\"); - if (len >= sizeof(value)) { - len = sizeof(value) - 1; - } - strlcpy(value, s, len + 1); - - CL_SetInfo(key, value, false, false, false, false); - - s += len; - if (!*s) - { - break; - } - ++s; // Skip over backslash. - } -} - -/* -================== -CL_SetInfo_f - -Allow clients to change userinfo -================== -*/ -static void CL_SetInfo_f(cmd_state_t *cmd) // credit: taken from QuakeWorld -{ - if (Cmd_Argc(cmd) == 1) - { - InfoString_Print(cls.userinfo); - return; - } - if (Cmd_Argc(cmd) != 3) - { - Con_Printf ("usage: setinfo [ ]\n"); - return; - } - CL_SetInfo(Cmd_Argv(cmd, 1), Cmd_Argv(cmd, 2), true, false, false, false); -} - -static void CL_PingPLReport_f(cmd_state_t *cmd) -{ - char *errbyte; - int i; - int l = Cmd_Argc(cmd); - if (l > cl.maxclients) - l = cl.maxclients; - for (i = 0;i < l;i++) - { - cl.scores[i].qw_ping = atoi(Cmd_Argv(cmd, 1+i*2)); - cl.scores[i].qw_packetloss = strtol(Cmd_Argv(cmd, 1+i*2+1), &errbyte, 0); - if(errbyte && *errbyte == ',') - cl.scores[i].qw_movementloss = atoi(errbyte + 1); - else - cl.scores[i].qw_movementloss = 0; - } -} - -//============================================================================= - -/* -================== -Host_InitCommands -================== -*/ -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_RegisterAlias(&cl_name, "_cl_name"); - Cvar_RegisterVariable(&cl_rate); - Cvar_RegisterAlias(&cl_rate, "_cl_rate"); - Cvar_RegisterVariable(&cl_rate_burstsize); - Cvar_RegisterAlias(&cl_rate_burstsize, "_cl_rate_burstsize"); - Cvar_RegisterVariable(&cl_pmodel); - Cvar_RegisterAlias(&cl_pmodel, "_cl_pmodel"); - Cvar_RegisterVariable(&cl_playermodel); - Cvar_RegisterAlias(&cl_playermodel, "_cl_playermodel"); - Cvar_RegisterVariable(&cl_playerskin); - Cvar_RegisterAlias(&cl_playerskin, "_cl_playerskin"); - Cvar_RegisterVariable(&rcon_password); - Cvar_RegisterVariable(&r_fixtrans_auto); - Cvar_RegisterVariable(&cl_team); - Cvar_RegisterVariable(&cl_skin); - Cvar_RegisterVariable(&cl_noaim); - - 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, "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, "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 - Cmd_AddCommand(CMD_CLIENT_FROM_SERVER, "pingplreport", CL_PingPLReport_f, "command sent by server containing client ping and packet loss values for scoreboard, triggered by pings command from client (not used by QW servers)"); - Cmd_AddCommand(CMD_CLIENT_FROM_SERVER, "fullserverinfo", CL_FullServerinfo_f, "internal use only, sent by server to client to update client's local copy of serverinfo string"); -} - -void Host_NoOperation_f(cmd_state_t *cmd) -{ -} diff --git a/makefile.inc b/makefile.inc index 5620fc2b..a69e8fa4 100644 --- a/makefile.inc +++ b/makefile.inc @@ -111,7 +111,6 @@ OBJ_COMMON= \ gl_textures.o \ hmac.o \ host.o \ - host_cmd.o \ image.o \ image_png.o \ jpeg.o \ diff --git a/sv_ccmds.c b/sv_ccmds.c index 0c2674c6..cf70e6dc 100644 --- a/sv_ccmds.c +++ b/sv_ccmds.c @@ -1232,6 +1232,120 @@ static void SV_MaxPlayers_f(cmd_state_t *cmd) Cvar_Set (&cvars_all, "deathmatch", "1"); } +/* +====================== +SV_Playermodel_f +====================== +*/ +// the old playermodel in cl_main has been renamed to __cl_playermodel +static void SV_Playermodel_f(cmd_state_t *cmd) +{ + prvm_prog_t *prog = SVVM_prog; + int i, j; + char newPath[sizeof(host_client->playermodel)]; + + if (Cmd_Argc (cmd) == 1) + return; + + if (Cmd_Argc (cmd) == 2) + strlcpy (newPath, Cmd_Argv(cmd, 1), sizeof (newPath)); + else + strlcpy (newPath, Cmd_Args(cmd), sizeof (newPath)); + + for (i = 0, j = 0;newPath[i];i++) + if (newPath[i] != '\r' && newPath[i] != '\n') + newPath[j++] = newPath[i]; + newPath[j] = 0; + + /* + if (host.realtime < host_client->nametime) + { + SV_ClientPrintf("You can't change playermodel more than once every 5 seconds!\n"); + return; + } + + host_client->nametime = host.realtime + 5; + */ + + // point the string back at updateclient->name to keep it safe + strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel)); + PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(prog, 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)); + /*// send notification to all clients + MSG_WriteByte (&sv.reliable_datagram, svc_updatepmodel); + MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); + MSG_WriteString (&sv.reliable_datagram, host_client->playermodel);*/ + } +} + +/* +====================== +SV_Playerskin_f +====================== +*/ +static void SV_Playerskin_f(cmd_state_t *cmd) +{ + prvm_prog_t *prog = SVVM_prog; + int i, j; + char newPath[sizeof(host_client->playerskin)]; + + if (Cmd_Argc (cmd) == 1) + return; + + if (Cmd_Argc (cmd) == 2) + strlcpy (newPath, Cmd_Argv(cmd, 1), sizeof (newPath)); + else + strlcpy (newPath, Cmd_Args(cmd), sizeof (newPath)); + + for (i = 0, j = 0;newPath[i];i++) + if (newPath[i] != '\r' && newPath[i] != '\n') + newPath[j++] = newPath[i]; + newPath[j] = 0; + + /* + if (host.realtime < host_client->nametime) + { + SV_ClientPrintf("You can't change playermodel more than once every 5 seconds!\n"); + return; + } + + host_client->nametime = host.realtime + 5; + */ + + // point the string back at updateclient->name to keep it safe + strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin)); + PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(prog, host_client->playerskin); + if (strcmp(host_client->old_skin, host_client->playerskin)) + { + //if (host_client->begun) + // SV_BroadcastPrintf("%s changed skin to %s\n", host_client->name, host_client->playerskin); + strlcpy(host_client->old_skin, host_client->playerskin, sizeof(host_client->old_skin)); + /*// send notification to all clients + MSG_WriteByte (&sv.reliable_datagram, svc_updatepskin); + MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); + MSG_WriteString (&sv.reliable_datagram, host_client->playerskin);*/ + } +} + +/* +====================== +SV_PModel_f +LadyHavoc: only supported for Nehahra, I personally think this is dumb, but Mindcrime won't listen. +LadyHavoc: correction, Mindcrime will be removing pmodel in the future, but it's still stuck here for compatibility. +====================== +*/ +static void SV_PModel_f(cmd_state_t *cmd) +{ + prvm_prog_t *prog = SVVM_prog; + + if (Cmd_Argc (cmd) == 1) + return; + + PRVM_serveredictfloat(host_client->edict, pmodel) = atoi(Cmd_Argv(cmd, 1)); +} + /* =============================================================================== @@ -1373,6 +1487,34 @@ static void SV_Viewprev_f(cmd_state_t *cmd) } } +static void SV_SendCvar_f(cmd_state_t *cmd) +{ + int i; + const char *cvarname; + client_t *old; + + if(Cmd_Argc(cmd) != 2) + return; + + if(!sv.active)// || !PRVM_serverfunction(SV_ParseClientCommand)) + return; + + cvarname = Cmd_Argv(cmd, 1); + + old = host_client; + if (cls.state != ca_dedicated) + i = 1; + else + i = 0; + for(;i