X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=host_cmd.c;h=b8ac161b373e91de131094e08969e571d8ef20ed;hb=e24277377e64376fe6a8bbbdfad73f614f3909bf;hp=635882da9a053ba1339fa79de81999355e01ce30;hpb=782901070b01c04dcafcab9b8d27e8c231bccede;p=xonotic%2Fdarkplaces.git diff --git a/host_cmd.c b/host_cmd.c index 635882da..b8ac161b 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sv_demo.h" #include "image.h" +#include "utf8lib.h" + // for secure rcon authentication #include "hmac.h" #include "mdfour.h" @@ -70,7 +72,7 @@ void Host_Status_f (void) client_t *client; int seconds = 0, minutes = 0, hours = 0, i, j, k, in, players, ping = 0, packetloss = 0; void (*print) (const char *fmt, ...); - char ip[22]; + char ip[48]; // can contain a full length v6 address with [] and a port int frags; if (cmd_source == src_command) @@ -112,9 +114,9 @@ void Host_Status_f (void) print ("players: %i active (%i max)\n\n", players, svs.maxclients); if (in == 1) - print ("^2IP %%pl ping time frags no name\n"); + print ("^2IP %%pl ping time frags no name\n"); else if (in == 2) - print ("^5IP no name\n"); + print ("^5IP no name\n"); for (i = 0, k = 0, client = svs.clients;i < svs.maxclients;i++, client++) { @@ -147,15 +149,16 @@ void Host_Status_f (void) } if(sv_status_privacy.integer && cmd_source != src_command) - strlcpy(ip, client->netconnection ? "hidden" : "botclient" , 22); + strlcpy(ip, client->netconnection ? "hidden" : "botclient", 48); else - strlcpy(ip, (client->netconnection && client->netconnection->address) ? client->netconnection->address : "botclient", 22); + strlcpy(ip, (client->netconnection && client->netconnection->address) ? client->netconnection->address : "botclient", 48); frags = client->frags; - if(sv_status_show_qcstatus.integer && prog->fieldoffsets.clientstatus >= 0) + if(sv_status_show_qcstatus.integer) { - const char *str = PRVM_E_STRING(PRVM_EDICT_NUM(i + 1), prog->fieldoffsets.clientstatus); + prvm_edict_t *ed = PRVM_EDICT_NUM(i + 1); + const char *str = PRVM_GetString(PRVM_serveredictstring(ed, clientstatus)); if(str && *str) { char *p; @@ -172,16 +175,26 @@ void Host_Status_f (void) if (in == 0) // default layout { - print ("#%-3u %-16.16s %3i %2i:%02i:%02i\n", i+1, client->name, frags, hours, minutes, seconds); - print (" %s\n", ip); + if (sv.protocol == PROTOCOL_QUAKE && svs.maxclients <= 99) + { + // LordHavoc: this is very touchy because we must maintain ProQuake compatible status output + print ("#%-2u %-16.16s %3i %2i:%02i:%02i\n", i+1, client->name, frags, hours, minutes, seconds); + print (" %s\n", ip); + } + else + { + // LordHavoc: no real restrictions here, not a ProQuake-compatible protocol anyway... + print ("#%-3u %-16.16s %4i %2i:%02i:%02i\n", i+1, client->name, frags, hours, minutes, seconds); + print (" %s\n", ip); + } } else if (in == 1) // extended layout { - print ("%s%-21s %2i %4i %2i:%02i:%02i %4i #%-3u ^7%s\n", k%2 ? "^3" : "^7", ip, packetloss, ping, hours, minutes, seconds, frags, i+1, client->name); + print ("%s%-47s %2i %4i %2i:%02i:%02i %4i #%-3u ^7%s\n", k%2 ? "^3" : "^7", ip, packetloss, ping, hours, minutes, seconds, frags, i+1, client->name); } else if (in == 2) // reduced layout { - print ("%s%-21s #%-3u ^7%s\n", k%2 ? "^3" : "^7", ip, i+1, client->name); + print ("%s%-47s #%-3u ^7%s\n", k%2 ? "^3" : "^7", ip, i+1, client->name); } } @@ -205,8 +218,8 @@ void Host_God_f (void) return; } - host_client->edict->fields.server->flags = (int)host_client->edict->fields.server->flags ^ FL_GODMODE; - if (!((int)host_client->edict->fields.server->flags & FL_GODMODE) ) + PRVM_serveredictfloat(host_client->edict, flags) = (int)PRVM_serveredictfloat(host_client->edict, flags) ^ FL_GODMODE; + if (!((int)PRVM_serveredictfloat(host_client->edict, flags) & FL_GODMODE) ) SV_ClientPrint("godmode OFF\n"); else SV_ClientPrint("godmode ON\n"); @@ -220,8 +233,8 @@ void Host_Notarget_f (void) return; } - host_client->edict->fields.server->flags = (int)host_client->edict->fields.server->flags ^ FL_NOTARGET; - if (!((int)host_client->edict->fields.server->flags & FL_NOTARGET) ) + PRVM_serveredictfloat(host_client->edict, flags) = (int)PRVM_serveredictfloat(host_client->edict, flags) ^ FL_NOTARGET; + if (!((int)PRVM_serveredictfloat(host_client->edict, flags) & FL_NOTARGET) ) SV_ClientPrint("notarget OFF\n"); else SV_ClientPrint("notarget ON\n"); @@ -237,16 +250,16 @@ void Host_Noclip_f (void) return; } - if (host_client->edict->fields.server->movetype != MOVETYPE_NOCLIP) + if (PRVM_serveredictfloat(host_client->edict, movetype) != MOVETYPE_NOCLIP) { noclip_anglehack = true; - host_client->edict->fields.server->movetype = MOVETYPE_NOCLIP; + PRVM_serveredictfloat(host_client->edict, movetype) = MOVETYPE_NOCLIP; SV_ClientPrint("noclip ON\n"); } else { noclip_anglehack = false; - host_client->edict->fields.server->movetype = MOVETYPE_WALK; + PRVM_serveredictfloat(host_client->edict, movetype) = MOVETYPE_WALK; SV_ClientPrint("noclip OFF\n"); } } @@ -266,14 +279,14 @@ void Host_Fly_f (void) return; } - if (host_client->edict->fields.server->movetype != MOVETYPE_FLY) + if (PRVM_serveredictfloat(host_client->edict, movetype) != MOVETYPE_FLY) { - host_client->edict->fields.server->movetype = MOVETYPE_FLY; + PRVM_serveredictfloat(host_client->edict, movetype) = MOVETYPE_FLY; SV_ClientPrint("flymode ON\n"); } else { - host_client->edict->fields.server->movetype = MOVETYPE_WALK; + PRVM_serveredictfloat(host_client->edict, movetype) = MOVETYPE_WALK; SV_ClientPrint("flymode OFF\n"); } } @@ -366,6 +379,8 @@ void Host_Map_f (void) } // remove menu + if (key_dest == key_menu || key_dest == key_menu_grabbed) + MR_ToggleMenu(0); key_dest = key_game; svs.serverflags = 0; // haven't completed an episode yet @@ -373,7 +388,7 @@ void Host_Map_f (void) strlcpy(level, Cmd_Argv(1), sizeof(level)); SV_SpawnServer(level); if (sv.active && cls.state == ca_disconnected) - CL_EstablishConnection("local:1"); + CL_EstablishConnection("local:1", -2); } /* @@ -399,6 +414,8 @@ void Host_Changelevel_f (void) } // remove menu + if (key_dest == key_menu || key_dest == key_menu_grabbed) + MR_ToggleMenu(0); key_dest = key_game; SV_VM_Begin(); @@ -408,7 +425,7 @@ void Host_Changelevel_f (void) strlcpy(level, Cmd_Argv(1), sizeof(level)); SV_SpawnServer(level); if (sv.active && cls.state == ca_disconnected) - CL_EstablishConnection("local:1"); + CL_EstablishConnection("local:1", -2); } /* @@ -434,13 +451,15 @@ void Host_Restart_f (void) } // remove menu + if (key_dest == key_menu || key_dest == key_menu_grabbed) + MR_ToggleMenu(0); key_dest = key_game; allowcheats = sv_cheats.integer != 0; strlcpy(mapname, sv.name, sizeof(mapname)); SV_SpawnServer(mapname); if (sv.active && cls.state == ca_disconnected) - CL_EstablishConnection("local:1"); + CL_EstablishConnection("local:1", -2); } /* @@ -461,7 +480,7 @@ void Host_Reconnect_f (void) // will still contain its IP address, so get the address... InfoString_GetValue(cls.userinfo, "*ip", temp, sizeof(temp)); if (temp[0]) - CL_EstablishConnection(temp); + CL_EstablishConnection(temp, -1); else Con_Printf("Reconnect to what server? (you have not connected to a server yet)\n"); return; @@ -508,15 +527,15 @@ User command to connect to server */ void Host_Connect_f (void) { - if (Cmd_Argc() != 2) + if (Cmd_Argc() < 2) { - Con_Print("connect : connect to a multiplayer game\n"); + Con_Print("connect [ ...]: connect to a multiplayer game\n"); return; } // clear the rcon password, to prevent vulnerability by stuffcmd-ing a connect command if(rcon_secure.integer <= 0) Cvar_SetQuick(&rcon_password, ""); - CL_EstablishConnection(Cmd_Argv(1)); + CL_EstablishConnection(Cmd_Argv(1), 2); } @@ -533,9 +552,11 @@ LOAD / SAVE GAME void Host_Savegame_to (const char *name) { qfile_t *f; - int i, lightstyles = 64; + int i, k, l, lightstyles = 64; char comment[SAVEGAME_COMMENT_LENGTH+1]; + char line[MAX_INPUTLINE]; qboolean isserver; + char *s; // first we have to figure out if this can be saved in 64 lightstyles // (for Quake compatibility) @@ -557,7 +578,7 @@ void Host_Savegame_to (const char *name) memset(comment, 0, sizeof(comment)); if(isserver) - dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(prog->edicts->fields.server->message), (int)prog->globals.server->killed_monsters, (int)prog->globals.server->total_monsters); + dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(PRVM_serveredictstring(prog->edicts, message)), (int)PRVM_serverglobalfloat(killed_monsters), (int)PRVM_serverglobalfloat(total_monsters)); else dpsnprintf(comment, sizeof(comment), "(crash dump of %s progs)", PRVM_NAME); // convert space to _ to make stdio happy @@ -619,6 +640,51 @@ void Host_Savegame_to (const char *name) for (i=1 ; istringbuffersarray); i++) + { + prvm_stringbuffer_t *stringbuffer = (prvm_stringbuffer_t*) Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i); + if(stringbuffer && (stringbuffer->flags & STRINGBUFFER_SAVED)) + { + for(k = 0; k < stringbuffer->num_strings; k++) + { + if (!stringbuffer->strings[k]) + continue; + // Parse the string a bit to turn special characters + // (like newline, specifically) into escape codes + s = stringbuffer->strings[k]; + for (l = 0;l < (int)sizeof(line) - 2 && *s;) + { + if (*s == '\n') + { + line[l++] = '\\'; + line[l++] = 'n'; + } + else if (*s == '\r') + { + line[l++] = '\\'; + line[l++] = 'r'; + } + else if (*s == '\\') + { + line[l++] = '\\'; + line[l++] = '\\'; + } + else if (*s == '"') + { + line[l++] = '\\'; + line[l++] = '"'; + } + else + line[l++] = *s; + s++; + } + line[l] = '\0'; + FS_Printf(f,"sv.bufstr %i %i \"%s\"\n", i, k, line); + } + } + } FS_Printf(f,"*/\n"); #endif @@ -634,6 +700,7 @@ Host_Savegame_f void Host_Savegame_f (void) { char name[MAX_QPATH]; + qboolean deadflag = false; if (!sv.active) { @@ -641,6 +708,10 @@ void Host_Savegame_f (void) return; } + SV_VM_Begin(); + deadflag = cl.islocalgame && svs.clients[0].active && PRVM_serveredictfloat(svs.clients[0].edict, deadflag); + SV_VM_End(); + if (cl.islocalgame) { // singleplayer checks @@ -650,7 +721,7 @@ void Host_Savegame_f (void) return; } - if (svs.clients[0].active && svs.clients[0].edict->fields.server->deadflag) + if (deadflag) { Con_Print("Can't savegame with a dead player\n"); return; @@ -685,6 +756,7 @@ void Host_Savegame_f (void) Host_Loadgame_f =============== */ + void Host_Loadgame_f (void) { char filename[MAX_QPATH]; @@ -695,10 +767,12 @@ void Host_Loadgame_f (void) const char *t; char *text; prvm_edict_t *ent; - int i; + int i, k; int entnum; int version; float spawn_parms[NUM_SPAWN_PARMS]; + prvm_stringbuffer_t *stringbuffer; + size_t alloclen; if (Cmd_Argc() != 2) { @@ -716,6 +790,8 @@ void Host_Loadgame_f (void) CL_Disconnect (); // remove menu + if (key_dest == key_menu || key_dest == key_menu_grabbed) + MR_ToggleMenu(0); key_dest = key_game; cls.demonum = -1; // stop demo loop in case this fails @@ -829,6 +905,9 @@ void Host_Loadgame_f (void) } } + // unlink all entities + World_UnlinkAll(&sv.world); + // load the edicts out of the savegame file end = t; for (;;) @@ -855,6 +934,9 @@ void Host_Loadgame_f (void) // parse the global vars PRVM_ED_ParseGlobals (start); + + // restore the autocvar globals + Cvar_UpdateAllAutoCvars(); } else { @@ -867,7 +949,7 @@ void Host_Loadgame_f (void) while (entnum >= prog->max_edicts) PRVM_MEM_IncreaseEdicts(); ent = PRVM_EDICT_NUM(entnum); - memset (ent->fields.server, 0, prog->progs->entityfields * 4); + memset(ent->fields.vp, 0, prog->entityfields * 4); ent->priv.server->free = false; if(developer_entityparsing.integer) @@ -930,7 +1012,7 @@ void Host_Loadgame_f (void) if (i >= 0 && i < MAX_MODELS) { strlcpy(sv.model_precache[i], com_token, sizeof(sv.model_precache[i])); - sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, sv.model_precache[i][0] == '*' ? sv.modelname : NULL); + sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, sv.model_precache[i][0] == '*' ? sv.worldname : NULL); } else Con_Printf("unsupported model %i \"%s\"\n", i, com_token); @@ -945,6 +1027,46 @@ void Host_Loadgame_f (void) else Con_Printf("unsupported sound %i \"%s\"\n", i, com_token); } + else if (!strcmp(com_token, "sv.bufstr")) + { + COM_ParseToken_Simple(&t, false, false); + i = atoi(com_token); + COM_ParseToken_Simple(&t, false, false); + k = atoi(com_token); + COM_ParseToken_Simple(&t, false, false); + stringbuffer = (prvm_stringbuffer_t*) Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i); + // VorteX: nasty code, cleanup required + // create buffer at this index + if(!stringbuffer) + stringbuffer = (prvm_stringbuffer_t *) Mem_ExpandableArray_AllocRecordAtIndex(&prog->stringbuffersarray, i); + if (!stringbuffer) + Con_Printf("cant write string %i into buffer %i\n", k, i); + else + { + // code copied from VM_bufstr_set + // expand buffer + if (stringbuffer->max_strings <= i) + { + char **oldstrings = stringbuffer->strings; + stringbuffer->max_strings = max(stringbuffer->max_strings * 2, 128); + while (stringbuffer->max_strings <= i) + stringbuffer->max_strings *= 2; + stringbuffer->strings = (char **) Mem_Alloc(prog->progs_mempool, stringbuffer->max_strings * sizeof(stringbuffer->strings[0])); + if (stringbuffer->num_strings > 0) + memcpy(stringbuffer->strings, oldstrings, stringbuffer->num_strings * sizeof(stringbuffer->strings[0])); + if (oldstrings) + Mem_Free(oldstrings); + } + // allocate string + stringbuffer->num_strings = max(stringbuffer->num_strings, k + 1); + if(stringbuffer->strings[k]) + Mem_Free(stringbuffer->strings[k]); + stringbuffer->strings[k] = NULL; + alloclen = strlen(com_token) + 1; + stringbuffer->strings[k] = (char *)Mem_Alloc(prog->progs_mempool, alloclen); + memcpy(stringbuffer->strings[k], com_token, alloclen); + } + } // skip any trailing text or unrecognized commands while (COM_ParseToken_Simple(&t, true, false) && strcmp(com_token, "\n")) ; @@ -960,7 +1082,7 @@ void Host_Loadgame_f (void) // make sure we're connected to loopback if (sv.active && cls.state == ca_disconnected) - CL_EstablishConnection("local:1"); + CL_EstablishConnection("local:1", -2); } //============================================================================ @@ -1027,7 +1149,7 @@ void Host_Name_f (void) host_client->name[1] = '0' + STRING_COLOR_DEFAULT; } - COM_StringLengthNoColors(host_client->name, 0, &valid_colors); + u8_COM_StringLengthNoColors(host_client->name, 0, &valid_colors); if(!valid_colors) // NOTE: this also proves the string is not empty, as "" is a valid colored string { size_t l; @@ -1078,7 +1200,7 @@ void Host_Name_f (void) if (j >= 0 && strlen(host_client->name) < sizeof(host_client->name) - 2) memcpy(host_client->name + strlen(host_client->name), STRING_COLOR_DEFAULT_STR, strlen(STRING_COLOR_DEFAULT_STR) + 1); - host_client->edict->fields.server->netname = PRVM_SetEngineString(host_client->name); + PRVM_serveredictstring(host_client->edict, netname) = PRVM_SetEngineString(host_client->name); if (strcmp(host_client->old_name, host_client->name)) { if (host_client->spawned) @@ -1097,7 +1219,7 @@ void Host_Name_f (void) Host_Playermodel_f ====================== */ -cvar_t cl_playermodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_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/Xonotic (changed by playermodel command)"}; // the old cl_playermodel in cl_main has been renamed to __cl_playermodel void Host_Playermodel_f (void) { @@ -1138,8 +1260,7 @@ 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( prog->fieldoffsets.playermodel >= 0 ) - PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playermodel)->string = PRVM_SetEngineString(host_client->playermodel); + PRVM_serveredictstring(host_client->edict, playermodel) = 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)); @@ -1155,7 +1276,7 @@ void Host_Playermodel_f (void) Host_Playerskin_f ====================== */ -cvar_t cl_playerskin = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_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/Xonotic (changed by playerskin command)"}; void Host_Playerskin_f (void) { int i, j; @@ -1195,8 +1316,7 @@ 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( prog->fieldoffsets.playerskin >= 0 ) - PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playerskin)->string = PRVM_SetEngineString(host_client->playerskin); + PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(host_client->playerskin); if (strcmp(host_client->old_skin, host_client->playerskin)) { //if (host_client->spawned) @@ -1273,7 +1393,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->active && (!teamonly || host_client->edict->fields.server->team == save->edict->fields.server->team)) + if (host_client->active && (!teamonly || PRVM_serveredictfloat(host_client->edict, team) == PRVM_serveredictfloat(save->edict, team))) SV_ClientPrint(text); host_client = save; @@ -1457,22 +1577,20 @@ void Host_Color(int changetop, int changebottom) if (cls.protocol == PROTOCOL_QUAKEWORLD) return; - if (host_client->edict && prog->funcoffsets.SV_ChangeTeam) + if (host_client->edict && PRVM_clientfunction(SV_ChangeTeam)) { Con_DPrint("Calling SV_ChangeTeam\n"); - prog->globals.server->time = sv.time; + PRVM_serverglobalfloat(time) = sv.time; prog->globals.generic[OFS_PARM0] = playercolor; - prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict); - PRVM_ExecuteProgram(prog->funcoffsets.SV_ChangeTeam, "QC function SV_ChangeTeam is missing"); + PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); + PRVM_ExecuteProgram(PRVM_clientfunction(SV_ChangeTeam), "QC function SV_ChangeTeam is missing"); } else { - prvm_eval_t *val; if (host_client->edict) { - if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.clientcolors))) - val->_float = playercolor; - host_client->edict->fields.server->team = bottom + 1; + PRVM_serveredictfloat(host_client->edict, clientcolors) = playercolor; + PRVM_serveredictfloat(host_client->edict, team) = bottom + 1; } host_client->colors = playercolor; if (host_client->old_colors != host_client->colors) @@ -1561,15 +1679,15 @@ Host_Kill_f */ void Host_Kill_f (void) { - if (host_client->edict->fields.server->health <= 0) + if (PRVM_serveredictfloat(host_client->edict, health) <= 0) { SV_ClientPrint("Can't suicide -- already dead!\n"); return; } - prog->globals.server->time = sv.time; - prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict); - PRVM_ExecuteProgram (prog->globals.server->ClientKill, "QC function ClientKill is missing"); + PRVM_serverglobalfloat(time) = sv.time; + PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); + PRVM_ExecuteProgram (PRVM_serverfunction(ClientKill), "QC function ClientKill is missing"); } @@ -1603,7 +1721,6 @@ cvar_t cl_pmodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_pmodel", "0", "interna static void Host_PModel_f (void) { int i; - prvm_eval_t *val; if (Cmd_Argc () == 1) { @@ -1622,8 +1739,7 @@ static void Host_PModel_f (void) return; } - if (host_client->edict && (val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.pmodel))) - val->_float = i; + PRVM_serveredictfloat(host_client->edict, pmodel) = i; } //=========================================================================== @@ -1684,32 +1800,32 @@ void Host_Spawn_f (void) if (sv.loadgame) { // loaded games are fully initialized already - if (prog->funcoffsets.RestoreGame) + if (PRVM_serverfunction(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(prog->funcoffsets.RestoreGame, "QC function RestoreGame is missing"); + PRVM_serverglobalfloat(time) = sv.time; + PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); + PRVM_ExecuteProgram(PRVM_serverfunction(RestoreGame), "QC function RestoreGame is missing"); } } else { - //Con_Printf("Host_Spawn_f: host_client->edict->netname = %s, host_client->edict->netname = %s, host_client->name = %s\n", PRVM_GetString(host_client->edict->fields.server->netname), PRVM_GetString(host_client->edict->fields.server->netname), host_client->name); + //Con_Printf("Host_Spawn_f: host_client->edict->netname = %s, host_client->edict->netname = %s, host_client->name = %s\n", PRVM_GetString(PRVM_serveredictstring(host_client->edict, netname)), PRVM_GetString(PRVM_serveredictstring(host_client->edict, netname)), host_client->name); // copy spawn parms out of the client_t for (i=0 ; i< NUM_SPAWN_PARMS ; i++) - (&prog->globals.server->parm1)[i] = host_client->spawn_parms[i]; + (&PRVM_serverglobalfloat(parm1))[i] = host_client->spawn_parms[i]; // call the spawn function host_client->clientconnectcalled = true; - prog->globals.server->time = sv.time; - prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict); - PRVM_ExecuteProgram (prog->globals.server->ClientConnect, "QC function ClientConnect is missing"); + PRVM_serverglobalfloat(time) = sv.time; + PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); + PRVM_ExecuteProgram (PRVM_serverfunction(ClientConnect), "QC function ClientConnect is missing"); if (cls.state == ca_dedicated) Con_Printf("%s connected\n", host_client->name); - PRVM_ExecuteProgram (prog->globals.server->PutClientInServer, "QC function PutClientInServer is missing"); + PRVM_ExecuteProgram (PRVM_serverfunction(PutClientInServer), "QC function PutClientInServer is missing"); } if (!host_client->netconnection) @@ -1749,19 +1865,19 @@ void Host_Spawn_f (void) // send some stats MSG_WriteByte (&host_client->netconnection->message, svc_updatestat); MSG_WriteByte (&host_client->netconnection->message, STAT_TOTALSECRETS); - MSG_WriteLong (&host_client->netconnection->message, (int)prog->globals.server->total_secrets); + MSG_WriteLong (&host_client->netconnection->message, (int)PRVM_serverglobalfloat(total_secrets)); MSG_WriteByte (&host_client->netconnection->message, svc_updatestat); MSG_WriteByte (&host_client->netconnection->message, STAT_TOTALMONSTERS); - MSG_WriteLong (&host_client->netconnection->message, (int)prog->globals.server->total_monsters); + MSG_WriteLong (&host_client->netconnection->message, (int)PRVM_serverglobalfloat(total_monsters)); MSG_WriteByte (&host_client->netconnection->message, svc_updatestat); MSG_WriteByte (&host_client->netconnection->message, STAT_SECRETS); - MSG_WriteLong (&host_client->netconnection->message, (int)prog->globals.server->found_secrets); + MSG_WriteLong (&host_client->netconnection->message, (int)PRVM_serverglobalfloat(found_secrets)); MSG_WriteByte (&host_client->netconnection->message, svc_updatestat); MSG_WriteByte (&host_client->netconnection->message, STAT_MONSTERS); - MSG_WriteLong (&host_client->netconnection->message, (int)prog->globals.server->killed_monsters); + MSG_WriteLong (&host_client->netconnection->message, (int)PRVM_serverglobalfloat(killed_monsters)); // send a fixangle // Never send a roll angle, because savegames can catch the server @@ -1771,15 +1887,15 @@ void Host_Spawn_f (void) if (sv.loadgame) { MSG_WriteByte (&host_client->netconnection->message, svc_setangle); - MSG_WriteAngle (&host_client->netconnection->message, host_client->edict->fields.server->v_angle[0], sv.protocol); - MSG_WriteAngle (&host_client->netconnection->message, host_client->edict->fields.server->v_angle[1], sv.protocol); + MSG_WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, v_angle)[0], sv.protocol); + MSG_WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, v_angle)[1], sv.protocol); MSG_WriteAngle (&host_client->netconnection->message, 0, sv.protocol); } else { MSG_WriteByte (&host_client->netconnection->message, svc_setangle); - MSG_WriteAngle (&host_client->netconnection->message, host_client->edict->fields.server->angles[0], sv.protocol); - MSG_WriteAngle (&host_client->netconnection->message, host_client->edict->fields.server->angles[1], sv.protocol); + MSG_WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, angles)[0], sv.protocol); + MSG_WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, angles)[1], sv.protocol); MSG_WriteAngle (&host_client->netconnection->message, 0, sv.protocol); } @@ -1825,7 +1941,7 @@ Kicks a user off of the server */ void Host_Kick_f (void) { - char *who; + const char *who; const char *message = NULL; client_t *save; int i; @@ -1913,7 +2029,6 @@ void Host_Give_f (void) { const char *t; int v; - prvm_eval_t *val; if (!allowcheats) { @@ -1942,114 +2057,91 @@ void Host_Give_f (void) if (t[0] == '6') { if (t[1] == 'a') - host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | HIT_PROXIMITY_GUN; + PRVM_serveredictfloat(host_client->edict, items) = (int)PRVM_serveredictfloat(host_client->edict, items) | HIT_PROXIMITY_GUN; else - host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | IT_GRENADE_LAUNCHER; + PRVM_serveredictfloat(host_client->edict, items) = (int)PRVM_serveredictfloat(host_client->edict, items) | IT_GRENADE_LAUNCHER; } else if (t[0] == '9') - host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | HIT_LASER_CANNON; + PRVM_serveredictfloat(host_client->edict, items) = (int)PRVM_serveredictfloat(host_client->edict, items) | HIT_LASER_CANNON; else if (t[0] == '0') - host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | HIT_MJOLNIR; + PRVM_serveredictfloat(host_client->edict, items) = (int)PRVM_serveredictfloat(host_client->edict, items) | HIT_MJOLNIR; else if (t[0] >= '2') - host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | (IT_SHOTGUN << (t[0] - '2')); + PRVM_serveredictfloat(host_client->edict, items) = (int)PRVM_serveredictfloat(host_client->edict, items) | (IT_SHOTGUN << (t[0] - '2')); } else { if (t[0] >= '2') - host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | (IT_SHOTGUN << (t[0] - '2')); + PRVM_serveredictfloat(host_client->edict, items) = (int)PRVM_serveredictfloat(host_client->edict, items) | (IT_SHOTGUN << (t[0] - '2')); } break; case 's': - if (gamemode == GAME_ROGUE && (val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_shells1))) - val->_float = v; + if (gamemode == GAME_ROGUE) + PRVM_serveredictfloat(host_client->edict, ammo_shells1) = v; - host_client->edict->fields.server->ammo_shells = v; + PRVM_serveredictfloat(host_client->edict, ammo_shells) = v; break; case 'n': if (gamemode == GAME_ROGUE) { - if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_nails1))) - { - val->_float = v; - if (host_client->edict->fields.server->weapon <= IT_LIGHTNING) - host_client->edict->fields.server->ammo_nails = v; - } + PRVM_serveredictfloat(host_client->edict, ammo_nails1) = v; + if (PRVM_serveredictfloat(host_client->edict, weapon) <= IT_LIGHTNING) + PRVM_serveredictfloat(host_client->edict, ammo_nails) = v; } else { - host_client->edict->fields.server->ammo_nails = v; + PRVM_serveredictfloat(host_client->edict, ammo_nails) = v; } break; case 'l': if (gamemode == GAME_ROGUE) { - val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_lava_nails); - if (val) - { - val->_float = v; - if (host_client->edict->fields.server->weapon > IT_LIGHTNING) - host_client->edict->fields.server->ammo_nails = v; - } + PRVM_serveredictfloat(host_client->edict, ammo_lava_nails) = v; + if (PRVM_serveredictfloat(host_client->edict, weapon) > IT_LIGHTNING) + PRVM_serveredictfloat(host_client->edict, ammo_nails) = v; } break; case 'r': if (gamemode == GAME_ROGUE) { - val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_rockets1); - if (val) - { - val->_float = v; - if (host_client->edict->fields.server->weapon <= IT_LIGHTNING) - host_client->edict->fields.server->ammo_rockets = v; - } + PRVM_serveredictfloat(host_client->edict, ammo_rockets1) = v; + if (PRVM_serveredictfloat(host_client->edict, weapon) <= IT_LIGHTNING) + PRVM_serveredictfloat(host_client->edict, ammo_rockets) = v; } else { - host_client->edict->fields.server->ammo_rockets = v; + PRVM_serveredictfloat(host_client->edict, ammo_rockets) = v; } break; case 'm': if (gamemode == GAME_ROGUE) { - val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_multi_rockets); - if (val) - { - val->_float = v; - if (host_client->edict->fields.server->weapon > IT_LIGHTNING) - host_client->edict->fields.server->ammo_rockets = v; - } + PRVM_serveredictfloat(host_client->edict, ammo_multi_rockets) = v; + if (PRVM_serveredictfloat(host_client->edict, weapon) > IT_LIGHTNING) + PRVM_serveredictfloat(host_client->edict, ammo_rockets) = v; } break; case 'h': - host_client->edict->fields.server->health = v; + PRVM_serveredictfloat(host_client->edict, health) = v; break; case 'c': if (gamemode == GAME_ROGUE) { - val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_cells1); - if (val) - { - val->_float = v; - if (host_client->edict->fields.server->weapon <= IT_LIGHTNING) - host_client->edict->fields.server->ammo_cells = v; - } + PRVM_serveredictfloat(host_client->edict, ammo_cells1) = v; + if (PRVM_serveredictfloat(host_client->edict, weapon) <= IT_LIGHTNING) + PRVM_serveredictfloat(host_client->edict, ammo_cells) = v; } else { - host_client->edict->fields.server->ammo_cells = v; + PRVM_serveredictfloat(host_client->edict, ammo_cells) = v; } break; case 'p': if (gamemode == GAME_ROGUE) { - val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_plasma); - if (val) - { - val->_float = v; - if (host_client->edict->fields.server->weapon > IT_LIGHTNING) - host_client->edict->fields.server->ammo_cells = v; - } + PRVM_serveredictfloat(host_client->edict, ammo_plasma) = v; + if (PRVM_serveredictfloat(host_client->edict, weapon) > IT_LIGHTNING) + PRVM_serveredictfloat(host_client->edict, ammo_cells) = v; } break; } @@ -2063,7 +2155,7 @@ prvm_edict_t *FindViewthing (void) for (i=0 ; inum_edicts ; i++) { e = PRVM_EDICT_NUM(i); - if (!strcmp (PRVM_GetString(e->fields.server->classname), "viewthing")) + if (!strcmp (PRVM_GetString(PRVM_serveredictstring(e, classname)), "viewthing")) return e; } Con_Print("No viewthing on map\n"); @@ -2096,8 +2188,8 @@ void Host_Viewmodel_f (void) return; } - e->fields.server->frame = 0; - cl.model_precache[(int)e->fields.server->modelindex] = m; + PRVM_serveredictfloat(e, frame) = 0; + cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)] = m; } /* @@ -2119,13 +2211,13 @@ void Host_Viewframe_f (void) SV_VM_End(); if (!e) return; - m = cl.model_precache[(int)e->fields.server->modelindex]; + m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; f = atoi(Cmd_Argv(1)); if (f >= m->numframes) f = m->numframes-1; - e->fields.server->frame = f; + PRVM_serveredictfloat(e, frame) = f; } @@ -2155,13 +2247,13 @@ void Host_Viewnext_f (void) SV_VM_End(); if (!e) return; - m = cl.model_precache[(int)e->fields.server->modelindex]; + m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; - e->fields.server->frame = e->fields.server->frame + 1; - if (e->fields.server->frame >= m->numframes) - e->fields.server->frame = m->numframes - 1; + PRVM_serveredictfloat(e, frame) = PRVM_serveredictfloat(e, frame) + 1; + if (PRVM_serveredictfloat(e, frame) >= m->numframes) + PRVM_serveredictfloat(e, frame) = m->numframes - 1; - PrintFrameName (m, (int)e->fields.server->frame); + PrintFrameName (m, (int)PRVM_serveredictfloat(e, frame)); } /* @@ -2183,13 +2275,13 @@ void Host_Viewprev_f (void) if (!e) return; - m = cl.model_precache[(int)e->fields.server->modelindex]; + m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; - e->fields.server->frame = e->fields.server->frame - 1; - if (e->fields.server->frame < 0) - e->fields.server->frame = 0; + PRVM_serveredictfloat(e, frame) = PRVM_serveredictfloat(e, frame) - 1; + if (PRVM_serveredictfloat(e, frame) < 0) + PRVM_serveredictfloat(e, frame) = 0; - PrintFrameName (m, (int)e->fields.server->frame); + PrintFrameName (m, (int)PRVM_serveredictfloat(e, frame)); } /* @@ -2291,7 +2383,7 @@ void Host_SendCvar_f (void) Cmd_ForwardStringToServer(va("sentcvar %s \"%s\"", c->name, c->string)); return; } - if(!sv.active)// || !prog->funcoffsets.SV_ParseClientCommand) + if(!sv.active)// || !PRVM_serverfunction(SV_ParseClientCommand)) return; old = host_client; @@ -2379,7 +2471,8 @@ void Host_PQRcon_f (void) SZ_Clear(&net_message); MSG_WriteLong (&net_message, 0); MSG_WriteByte (&net_message, CCREQ_RCON); - SZ_Write(&net_message, (void*)rcon_password.string, n); + SZ_Write(&net_message, (const unsigned char*)rcon_password.string, n); + MSG_WriteByte (&net_message, 0); // terminate the (possibly partial) string MSG_WriteString (&net_message, Cmd_Args()); StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); NetConn_Write(mysocket, net_message.data, net_message.cursize, &to); @@ -2764,7 +2857,7 @@ void Host_Pings_f (void) void Host_PingPLReport_f(void) { - char **errbyte; + char *errbyte; int i; int l = Cmd_Argc(); if (l > cl.maxclients) @@ -2793,22 +2886,11 @@ void Host_InitCommands (void) Cmd_AddCommand_WithClientCommand ("status", Host_Status_f, Host_Status_f, "print server status information"); Cmd_AddCommand ("quit", Host_Quit_f, "quit the game"); - if (gamemode == GAME_NEHAHRA) - { - Cmd_AddCommand_WithClientCommand ("max", NULL, Host_God_f, "god mode (invulnerability)"); - Cmd_AddCommand_WithClientCommand ("monster", NULL, Host_Notarget_f, "notarget mode (monsters do not see you)"); - Cmd_AddCommand_WithClientCommand ("scrag", NULL, Host_Fly_f, "fly mode (flight)"); - Cmd_AddCommand_WithClientCommand ("wraith", NULL, Host_Noclip_f, "noclip mode (flight without collisions, move through walls)"); - Cmd_AddCommand_WithClientCommand ("gimme", NULL, Host_Give_f, "alter inventory"); - } - else - { - Cmd_AddCommand_WithClientCommand ("god", NULL, Host_God_f, "god mode (invulnerability)"); - Cmd_AddCommand_WithClientCommand ("notarget", NULL, Host_Notarget_f, "notarget mode (monsters do not see you)"); - Cmd_AddCommand_WithClientCommand ("fly", NULL, Host_Fly_f, "fly mode (flight)"); - Cmd_AddCommand_WithClientCommand ("noclip", NULL, Host_Noclip_f, "noclip mode (flight without collisions, move through walls)"); - Cmd_AddCommand_WithClientCommand ("give", NULL, Host_Give_f, "alter inventory"); - } + Cmd_AddCommand_WithClientCommand ("god", NULL, Host_God_f, "god mode (invulnerability)"); + Cmd_AddCommand_WithClientCommand ("notarget", NULL, Host_Notarget_f, "notarget mode (monsters do not see you)"); + Cmd_AddCommand_WithClientCommand ("fly", NULL, Host_Fly_f, "fly mode (flight)"); + Cmd_AddCommand_WithClientCommand ("noclip", NULL, Host_Noclip_f, "noclip mode (flight without collisions, move through walls)"); + Cmd_AddCommand_WithClientCommand ("give", NULL, Host_Give_f, "alter inventory"); Cmd_AddCommand ("map", Host_Map_f, "kick everyone off the server and start a new level"); Cmd_AddCommand ("restart", Host_Restart_f, "restart current level"); Cmd_AddCommand ("changelevel", Host_Changelevel_f, "change to another level, bringing along all connected clients"); @@ -2840,11 +2922,8 @@ void Host_InitCommands (void) Cmd_AddCommand_WithClientCommand ("color", Host_Color_f, Host_Color_f, "change your player shirt and pants colors"); Cvar_RegisterVariable (&cl_rate); Cmd_AddCommand_WithClientCommand ("rate", Host_Rate_f, Host_Rate_f, "change your network connection speed"); - if (gamemode == GAME_NEHAHRA) - { - Cvar_RegisterVariable (&cl_pmodel); - Cmd_AddCommand_WithClientCommand ("pmodel", Host_PModel_f, Host_PModel_f, "change your player model choice (Nehahra specific)"); - } + Cvar_RegisterVariable (&cl_pmodel); + Cmd_AddCommand_WithClientCommand ("pmodel", Host_PModel_f, Host_PModel_f, "(Nehahra-only) change your player model choice"); // BLACK: This isnt game specific anymore (it was GAME_NEXUIZ at first) Cvar_RegisterVariable (&cl_playermodel);