client->unreliablemsg.maxsize = sizeof(client->unreliablemsg_data);
// updated by receiving "rate" command from client, this is also the default if not using a DP client
client->rate = 1000000000;
- // no limits for local player
- if (client->netconnection && LHNETADDRESS_GetAddressType(&client->netconnection->peeraddress) == LHNETADDRESSTYPE_LOOP)
- client->rate = 1000000000;
client->connecttime = realtime;
if (!sv.loadgame)
MSG_WriteByte (msg, stats[STAT_NAILS]);
MSG_WriteByte (msg, stats[STAT_ROCKETS]);
MSG_WriteByte (msg, stats[STAT_CELLS]);
- if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE || gamemode == GAME_QUOTH || gamemode == GAME_NEXUIZ)
+ if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE || gamemode == GAME_QUOTH || IS_OLDNEXUIZ_DERIVED(gamemode))
{
for (i = 0;i < 32;i++)
if (stats[STAT_ACTIVEWEAPON] & (1<<i))
sizebuf_t msg;
int stats[MAX_CL_STATS];
static unsigned char sv_sendclientdatagram_buf[NET_MAXMESSAGE];
+ double timedelta;
// obey rate limit by limiting packet frequency if the packet size
// limiting fails
//
// 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);
+
+ // how long are bursts?
+ timedelta = host_client->rate_burstsize / (double)client->rate;
+
+ // how much of the burst do we keep reserved?
+ timedelta *= 1 - net_burstreserve.value;
+
+ // only try to use excess time
+ timedelta = bound(0, realtime - host_client->netconnection->cleartime, timedelta);
+
+ // but we know next packet will be in sys_ticrate, so we can use up THAT bandwidth
+ timedelta += sys_ticrate.value;
+
+ // note: packet overhead (not counted in maxsize) is 28 bytes
+ maxsize = (int)(clientrate * timedelta) - 28;
+
+ // put it in sound bounds
maxsize = bound(128, maxsize, 1400);
maxsize2 = 1400;
+
// csqc entities can easily exceed 128 bytes, so disable throttling in
// mods that use csqc (they are likely to use less bandwidth anyway)
- if (sv.csqc_progsize > 0)
+ if((net_usesizelimit.integer == 1) ? (sv.csqc_progsize > 0) : (net_usesizelimit.integer < 1))
maxsize = maxsize2;
+
break;
}
SV_WriteDemoMessage(client, &msg, false);
// send the datagram
- NetConn_SendUnreliableMessage (client->netconnection, &msg, sv.protocol, clientrate, client->sendsignon == 2);
+ NetConn_SendUnreliableMessage (client->netconnection, &msg, sv.protocol, clientrate, client->rate_burstsize, client->sendsignon == 2);
if (client->sendsignon == 1 && !client->netconnection->message.cursize)
client->sendsignon = 2; // prevent reliable until client sends prespawn (this is the keepalive phase)
}
// frags
host_client->frags = (int)PRVM_serveredictfloat(host_client->edict, frags);
- if(gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
+ if(IS_OLDNEXUIZ_DERIVED(gamemode))
if(!host_client->begun && host_client->netconnection)
host_client->frags = -666;
if (host_client->old_frags != host_client->frags)
int i, entnum, large;
prvm_edict_t *svent;
- // LordHavoc: clear *all* states (note just active ones)
+ // LordHavoc: clear *all* baselines (not just active ones)
for (entnum = 0;entnum < prog->max_edicts;entnum++)
{
// get the current server version