MSG_WriteByte (&client->netconnection->message, (int)prog->edicts->fields.server->sounds);
// set view
+// store this in clientcamera, too
+ client->clientcamera = PRVM_NUM_FOR_EDICT(client->edict);
MSG_WriteByte (&client->netconnection->message, svc_setview);
- MSG_WriteShort (&client->netconnection->message, PRVM_NUM_FOR_EDICT(client->edict));
-
+ MSG_WriteShort (&client->netconnection->message, client->clientcamera);
+
MSG_WriteByte (&client->netconnection->message, svc_signonnum);
MSG_WriteByte (&client->netconnection->message, 1);
{
int i, numsendstates;
entity_state_t *s;
+ prvm_edict_t *camera;
// if there isn't enough space to accomplish anything, skip it
if (msg->cursize + 25 > msg->maxsize)
// find the client's PVS
// the real place being tested from
- VectorAdd(clent->fields.server->origin, clent->fields.server->view_ofs, sv.writeentitiestoclient_testeye);
+ camera = PRVM_EDICT_NUM( client->clientcamera );
+ VectorAdd(camera->fields.server->origin, clent->fields.server->view_ofs, sv.writeentitiestoclient_testeye);
sv.writeentitiestoclient_pvsbytes = 0;
if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
sv.writeentitiestoclient_pvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, sv.writeentitiestoclient_testeye, 8, sv.writeentitiestoclient_pvs, sizeof(sv.writeentitiestoclient_pvs), false);
if (LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) == LHNETADDRESSTYPE_LOOP && !sv_ratelimitlocalplayer.integer)
{
- // for good singleplayer, send huge packets and never limit frequency
- clientrate = 1000000000;
+ // for good singleplayer, send huge packets
maxsize = sizeof(sv_sendclientdatagram_buf);
maxsize2 = sizeof(sv_sendclientdatagram_buf);
+ // never limit frequency in singleplayer
+ clientrate = 1000000000;
}
- else if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
+ else if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_QUAKEWORLD)
{
- // no packet size limit support on older protocols because DP1-4 kick
- // the client off if they overflow, and quake protocol shows less than
- // the full entity set if rate limited
- clientrate = max(NET_MINRATE, client->rate);
+ // no packet size limit support on Quake protocols because it just
+ // causes missing entities/effects
+ // packets are simply sent less often to obey the rate limit
maxsize = 1024;
maxsize2 = 1024;
}
+ else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
+ {
+ // no packet size limit support on DP1-4 protocols because they kick
+ // the client off if they overflow, and miss effects
+ // packets are simply sent less often to obey the rate limit
+ maxsize = sizeof(sv_sendclientdatagram_buf);
+ maxsize2 = sizeof(sv_sendclientdatagram_buf);
+ }
else
{
// DP5 and later protocols support packet size limiting which is a
// better method than limiting packet frequency as QW does
//
- // this rate limiting does not understand sys_ticrate 0
- // (but no one should be running that on a server!)
+ // at very low rates (or very small sys_ticrate) the packet size is
+ // not reduced below 128, but packets may be sent less often
maxsize = (int)(clientrate * sys_ticrate.value);
- maxsize = bound(100, maxsize, 1400);
+ maxsize = bound(128, maxsize, 1400);
maxsize2 = 1400;
}
+ // obey rate limit by limiting packet frequency if the packet size
+ // limiting fails
+ // (usually this is caused by reliable messages)
+ if (!NetConn_CanSend(client->netconnection))
+ return;
+
// while downloading, limit entity updates to half the packet
// (any leftover space will be used for downloading)
if (host_client->download_file)
msg.maxsize = maxsize;
msg.cursize = 0;
- // obey rate limit by limiting packet frequency if the packet size
- // limiting fails
- // (usually this is caused by reliable messages)
- if (!NetConn_CanSend(client->netconnection))
- {
- // send the datagram
- //NetConn_SendUnreliableMessage (client->netconnection, &msg, sv.protocol, clientrate, true);
- return;
- }
- else if (host_client->spawned)
+ if (host_client->spawned)
{
+ // the player is in the game
MSG_WriteByte (&msg, svc_time);
MSG_WriteFloat (&msg, sv.time);
{
// the player isn't totally in the game yet
// send small keepalive messages if too much time has passed
+ // (may also be sending downloads)
msg.maxsize = maxsize2;
client->keepalivetime = realtime + 5;
MSG_WriteChar (&msg, svc_nop);
PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playerskin)->string = PRVM_SetEngineString(host_client->playerskin);
}
+ // TODO: add an extension name for this [1/17/2008 Black]
+ if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.clientcamera)) && val->edict > 0 ) {
+ int oldclientcamera = host_client->clientcamera;
+ if( val->edict >= prog->max_edicts || PRVM_EDICT_NUM( val->edict )->priv.required->free ) {
+ val->edict = host_client->clientcamera = PRVM_NUM_FOR_EDICT( host_client->edict );
+ } else {
+ host_client->clientcamera = val->edict;
+ }
+
+ if( oldclientcamera != host_client->clientcamera ) {
+ MSG_WriteByte (&sv.reliable_datagram, svc_setview );
+ MSG_WriteShort (&host_client->netconnection->message, host_client->clientcamera);
+ }
+ }
+
// frags
host_client->frags = (int)host_client->edict->fields.server->frags;
if(gamemode == GAME_NEXUIZ)