// sv_main.c -- server main program
#include "quakedef.h"
+#include "libcurl.h"
void SV_VM_Init();
void SV_VM_Setup();
cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1", "fixes a bug in Quake that made setmodel always set the entity box to ('-16 -16 -16', '16 16 16') rather than properly checking the model box, breaks some poorly coded mods"};
cvar_t sv_gameplayfix_blowupfallenzombies = {0, "sv_gameplayfix_blowupfallenzombies", "1", "causes findradius to detect SOLID_NOT entities such as zombies and corpses on the floor, allowing splash damage to apply to them"};
cvar_t sv_gameplayfix_findradiusdistancetobox = {0, "sv_gameplayfix_findradiusdistancetobox", "1", "causes findradius to check the distance to the corner of a box rather than the center of the box, makes findradius detect bmodels such as very large doors that would otherwise be unaffected by splash damage"};
+cvar_t sv_gameplayfix_qwplayerphysics = {0, "sv_gameplayfix_qwplayerphysics", "1", "changes water jumping to make it easier to get out of water, and prevents friction on landing when bunnyhopping"};
+cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag = {0, "sv_gameplayfix_upwardvelocityclearsongroundflag", "1", "prevents monsters, items, and most other objects from being stuck to the floor when pushed around by damage, and other situations in mods"};
cvar_t sv_progs = {0, "sv_progs", "progs.dat", "selects which quakec progs.dat file to run" };
+// TODO: move these cvars here
+extern cvar_t sv_clmovement_enable;
+extern cvar_t sv_clmovement_minping;
+extern cvar_t sv_clmovement_minping_disabletime;
+extern cvar_t sv_clmovement_waitforinput;
+
server_t sv;
server_static_t svs;
*/
void SV_Init (void)
{
+ // init the csqc progs cvars, since they are updated/used by the server code
+ // TODO: fix this since this is a quick hack to make some of [515]'s broken code run ;) [9/13/2006 Black]
+ extern cvar_t csqc_progname; //[515]: csqc crc check and right csprogs name according to progs.dat
+ extern cvar_t csqc_progcrc;
+ Cvar_RegisterVariable (&csqc_progname);
+ Cvar_RegisterVariable (&csqc_progcrc);
+
Cmd_AddCommand("sv_saveentfile", SV_SaveEntFile_f, "save map entities to .ent file (to allow external editing)");
Cvar_RegisterVariable (&sv_maxvelocity);
Cvar_RegisterVariable (&sv_gravity);
Cvar_RegisterVariable (&sv_accelerate);
Cvar_RegisterVariable (&sv_airaccelerate);
Cvar_RegisterVariable (&sv_wateraccelerate);
+ Cvar_RegisterVariable (&sv_clmovement_enable);
+ Cvar_RegisterVariable (&sv_clmovement_minping);
+ Cvar_RegisterVariable (&sv_clmovement_minping_disabletime);
+ Cvar_RegisterVariable (&sv_clmovement_waitforinput);
Cvar_RegisterVariable (&sv_idealpitchscale);
Cvar_RegisterVariable (&sv_aim);
Cvar_RegisterVariable (&sv_nostep);
Cvar_RegisterVariable (&sv_gameplayfix_setmodelrealbox);
Cvar_RegisterVariable (&sv_gameplayfix_blowupfallenzombies);
Cvar_RegisterVariable (&sv_gameplayfix_findradiusdistancetobox);
+ Cvar_RegisterVariable (&sv_gameplayfix_qwplayerphysics);
+ Cvar_RegisterVariable (&sv_gameplayfix_upwardvelocityclearsongroundflag);
Cvar_RegisterVariable (&sv_protocolname);
Cvar_RegisterVariable (&sv_ratelimitlocalplayer);
Cvar_RegisterVariable (&sv_maxrate);
==============================================================================
*/
-static const char *SV_InitCmd; //[515]: svprogs able to send cmd to client on connect
-extern qboolean csqc_loaded;
/*
================
SV_SendServerinfo
dpsnprintf (message, sizeof (message), "\nServer: %s build %s (progs %i crc)", gamename, buildstring, prog->filecrc);
MSG_WriteString (&client->netconnection->message,message);
- // FIXME: LordHavoc: this does not work on dedicated servers, needs fixing.
-//[515]: init csprogs according to version of svprogs, check the crc, etc.
- if(csqc_loaded && (cls.state == ca_dedicated || PRVM_NUM_FOR_EDICT(client->edict) != 1))
+ //[515]: init csprogs according to version of svprogs, check the crc, etc.
+ if (sv.csqc_progcrc >= 0)
{
+ prvm_eval_t *val;
+ Con_DPrintf("sending csqc info to client (\"%s\" with crc %i)\n", sv.csqc_progname, sv.csqc_progcrc);
+ //[515]: init stufftext string (it is sent before svc_serverinfo)
+ val = PRVM_GETGLOBALFIELDVALUE(PRVM_ED_FindGlobalOffset("SV_InitCmd"));
MSG_WriteByte (&client->netconnection->message, svc_stufftext);
- if(SV_InitCmd)
- MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i;%s\n", csqc_progcrc.integer, SV_InitCmd));
- else
- MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i\n", csqc_progcrc.integer));
+ MSG_WriteString (&client->netconnection->message, va("csqc_progname %s\n", sv.csqc_progname));
+ MSG_WriteByte (&client->netconnection->message, svc_stufftext);
+ MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i\n", sv.csqc_progcrc));
+ if (val)
+ {
+ MSG_WriteByte (&client->netconnection->message, svc_stufftext);
+ MSG_WriteString (&client->netconnection->message, va("%s\n", PRVM_GetString(val->string)));
+ }
}
MSG_WriteByte (&client->netconnection->message, svc_serverinfo);
MSG_WriteByte (&client->netconnection->message, svc_signonnum);
MSG_WriteByte (&client->netconnection->message, 1);
+ {
+ client_t *save;
+ save = host_client;
+ host_client = client;
+ Curl_SendRequirements();
+ host_client = save;
+ }
+
client->spawned = false; // need prespawn, spawn, etc
}
Con_DPrintf("Client %s connected\n", client->netconnection ? client->netconnection->address : "botclient");
- strcpy(client->name, "unconnected");
- strcpy(client->old_name, "unconnected");
+ strlcpy(client->name, "unconnected", sizeof(client->name));
+ strlcpy(client->old_name, "unconnected", sizeof(client->old_name));
client->spawned = false;
client->edict = PRVM_EDICT_NUM(clientnum+1);
if (client->netconnection)
else
{
// PROTOCOL_DARKPLACES5 and later support packet size limiting of updates
- maxrate = bound(NET_MINRATE, sv_maxrate.integer, NET_MAXRATE);
+ maxrate = max(NET_MINRATE, sv_maxrate.integer);
if (sv_maxrate.integer != maxrate)
Cvar_SetValueQuick(&sv_maxrate, maxrate);
// this rate limiting does not understand sys_ticrate 0
// (but no one should be running that on a server!)
rate = bound(NET_MINRATE, client->rate, maxrate);
- rate = (int)(client->rate * sys_ticrate.value);
+ rate = (int)(rate * sys_ticrate.value);
maxsize = bound(100, rate, 1400);
maxsize2 = 1400;
}
{
if (host_client->spawned)
SV_BroadcastPrintf("%s changed name to %s\n", host_client->old_name, host_client->name);
- strcpy(host_client->old_name, host_client->name);
+ strlcpy(host_client->old_name, host_client->name, sizeof(host_client->old_name));
// send notification to all clients
MSG_WriteByte (&sv.reliable_datagram, svc_updatename);
MSG_WriteByte (&sv.reliable_datagram, i);
svs.changelevel_issued = false; // now safe to issue another
+ // make the map a required file for clients
+ Curl_ClearRequirements();
+ Curl_RequireFile(modelname);
+
//
// tell all connected clients that we are going to a new level
//
worldmodel->used = true;
strlcpy (sv.name, server, sizeof (sv.name));
- strcpy(sv.modelname, modelname);
+ strlcpy(sv.modelname, modelname, sizeof(sv.modelname));
sv.worldmodel = worldmodel;
sv.models[1] = sv.worldmodel;
int eval_Version;
int eval_customizeentityforclient;
int eval_dphitcontentsmask;
+// DRESK - Support for Entity Contents Transition Event
+int eval_contentstransition;
int gval_trace_dpstartcontents;
int gval_trace_dphitcontents;
//KrimZon - SERVER COMMANDS IN QUAKEC
mfunction_t *SV_ParseClientCommandQC;
-ddef_t *PRVM_ED_FindGlobal(const char *name);
-
void SV_VM_FindEdictFieldOffsets(void)
{
eval_gravity = PRVM_ED_FindFieldOffset("gravity");
eval_Version = PRVM_ED_FindFieldOffset("Version");
eval_customizeentityforclient = PRVM_ED_FindFieldOffset("customizeentityforclient");
eval_dphitcontentsmask = PRVM_ED_FindFieldOffset("dphitcontentsmask");
+ // DRESK - Support for Entity Contents Transition Event
+ eval_contentstransition = PRVM_ED_FindFieldOffset("contentstransition");
// LordHavoc: allowing QuakeC to override the player movement code
SV_PlayerPhysicsQC = PRVM_ED_FindFunction ("SV_PlayerPhysics");
EndFrameQC = PRVM_ED_FindFunction ("EndFrame");
//KrimZon - SERVER COMMANDS IN QUAKEC
SV_ParseClientCommandQC = PRVM_ED_FindFunction ("SV_ParseClientCommand");
-
- //[515]: init stufftext string (it is sent before svc_serverinfo)
- if(PRVM_ED_FindGlobal("SV_InitCmd") && PRVM_ED_FindGlobal("SV_InitCmd")->type & ev_string)
- SV_InitCmd = PRVM_G_STRING(PRVM_ED_FindGlobal("SV_InitCmd")->ofs);
- else
- SV_InitCmd = NULL;
-
gval_trace_dpstartcontents = PRVM_ED_FindGlobalOffset("trace_dpstartcontents");
gval_trace_dphitcontents = PRVM_ED_FindGlobalOffset("trace_dphitcontents");
gval_trace_dphitq3surfaceflags = PRVM_ED_FindGlobalOffset("trace_dphitq3surfaceflags");
{ev_string, "playerskin"},
{ev_function, "SendEntity"},
{ev_function, "customizeentityforclient"},
+ // DRESK - Support for Entity Contents Transition Event
+ {ev_function, "contentstransition"},
};
void SV_VM_Setup(void)
{
+ extern cvar_t csqc_progname; //[515]: csqc crc check and right csprogs name according to progs.dat
+ extern cvar_t csqc_progcrc;
+ unsigned char *csprogsdata;
+ fs_offset_t csprogsdatasize;
PRVM_Begin;
PRVM_InitProg( PRVM_SERVERPROG );
// allocate the mempools
+ // TODO: move the magic numbers/constants into #defines [9/13/2006 Black]
prog->progs_mempool = Mem_AllocPool("Server Progs", 0, NULL);
prog->builtins = vm_sv_builtins;
prog->numbuiltins = vm_sv_numbuiltins;
EntityFrameCSQC_ClearVersions();//[515]: csqc
PRVM_End;
+
+ // see if there is a csprogs.dat installed, and if so, set the csqc_progcrc accordingly, this will be sent to connecting clients to tell them to only load a matching csprogs.dat file
+ sv.csqc_progcrc = -1;
+ sv.csqc_progname[0] = 0;
+ csprogsdata = FS_LoadFile(csqc_progname.string, tempmempool, true, &csprogsdatasize);
+ if (csprogsdata)
+ {
+ strlcpy(sv.csqc_progname, csqc_progname.string, sizeof(sv.csqc_progname));
+ sv.csqc_progcrc = CRC_Block(csprogsdata, csprogsdatasize);
+ Mem_Free(csprogsdata);
+ Con_DPrintf("server detected csqc progs file \"%s\" with crc %i\n", sv.csqc_progname, sv.csqc_progcrc);
+ }
}
void SV_VM_Begin(void)