mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
svc_[delta]packetentities now getting parsed
This commit is contained in:
parent
080e619675
commit
be93162837
3 changed files with 490 additions and 125 deletions
|
@ -35,13 +35,27 @@
|
||||||
#include "netchan.h"
|
#include "netchan.h"
|
||||||
#include "qw/pmove.h"
|
#include "qw/pmove.h"
|
||||||
|
|
||||||
typedef struct sv_client_s {
|
typedef struct player_s {
|
||||||
struct sv_client_s *next; // for multicast messages
|
struct player_s *next; // for multicast messages
|
||||||
struct info_s *info;
|
struct info_s *info;
|
||||||
int stats[MAX_CL_STATS];
|
int stats[MAX_CL_STATS];
|
||||||
} sv_client_t;
|
int uid;
|
||||||
|
int ping;
|
||||||
|
int pl;
|
||||||
|
int frags;
|
||||||
|
|
||||||
#define MAX_SV_CLIENTS 32
|
plent_state_t ent;
|
||||||
|
} player_t;
|
||||||
|
|
||||||
|
typedef struct frame_s {
|
||||||
|
int delta_sequence;
|
||||||
|
qboolean invalid;
|
||||||
|
packet_players_t players;
|
||||||
|
packet_entities_t entities;
|
||||||
|
} frame_t;
|
||||||
|
|
||||||
|
#define MAX_SV_PLAYERS 32
|
||||||
|
#define MAX_SV_ENTITIES 512
|
||||||
|
|
||||||
typedef struct server_s {
|
typedef struct server_s {
|
||||||
struct server_s *next;
|
struct server_s *next;
|
||||||
|
@ -65,8 +79,14 @@ typedef struct server_s {
|
||||||
|
|
||||||
int delta;
|
int delta;
|
||||||
|
|
||||||
sv_client_t clients[MAX_SV_CLIENTS];
|
frame_t frames[UPDATE_BACKUP];
|
||||||
sv_client_t *client_list; // list of clients for multicast
|
entity_state_t entities[MAX_SV_ENTITIES];
|
||||||
|
entity_state_t baselines[MAX_SV_ENTITIES];
|
||||||
|
player_t players[MAX_SV_PLAYERS];
|
||||||
|
player_t *player_list; // list of players for multicast
|
||||||
|
unsigned player_mask; // which players are in the list
|
||||||
|
plent_state_t player_states[UPDATE_BACKUP][MAX_SV_PLAYERS];
|
||||||
|
entity_state_t entity_states[UPDATE_BACKUP][MAX_DEMO_PACKET_ENTITIES];
|
||||||
} server_t;
|
} server_t;
|
||||||
|
|
||||||
void Server_Init (void);
|
void Server_Init (void);
|
||||||
|
|
|
@ -121,14 +121,17 @@ setup_sub_message (qmsg_t *msg, qmsg_t *sub, sizebuf_t *buf, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_client_list (server_t *sv, unsigned mask)
|
setup_player_list (server_t *sv, unsigned mask)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
sv_client_t **p, *cl;
|
player_t **p, *cl;
|
||||||
|
|
||||||
p = &sv->client_list;
|
if (sv->player_mask == mask)
|
||||||
|
return;
|
||||||
|
sv->player_mask = mask;
|
||||||
|
p = &sv->player_list;
|
||||||
*p = 0;
|
*p = 0;
|
||||||
for (i = 0, cl = sv->clients; i < MAX_SV_CLIENTS; i++, cl++) {
|
for (i = 0, cl = sv->players; i < MAX_SV_PLAYERS; i++, cl++) {
|
||||||
if (mask & (1 << i)) {
|
if (mask & (1 << i)) {
|
||||||
*p = cl;
|
*p = cl;
|
||||||
p = &(*p)->next;
|
p = &(*p)->next;
|
||||||
|
@ -146,10 +149,11 @@ qtv_parse_updates (server_t *sv, qmsg_t *msg, int reliable)
|
||||||
qmsg_t sub_message;
|
qmsg_t sub_message;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
msec = MSG_ReadByte (net_message);
|
msec = MSG_ReadByte (msg);
|
||||||
|
//qtv_printf ("msec = %d\n", msec);
|
||||||
if (msec == -1)
|
if (msec == -1)
|
||||||
break;
|
break;
|
||||||
type = MSG_ReadByte (net_message);
|
type = MSG_ReadByte (msg);
|
||||||
switch (type & 7) {
|
switch (type & 7) {
|
||||||
case dem_cmd:
|
case dem_cmd:
|
||||||
case dem_set:
|
case dem_set:
|
||||||
|
@ -159,14 +163,14 @@ qtv_parse_updates (server_t *sv, qmsg_t *msg, int reliable)
|
||||||
case dem_read:
|
case dem_read:
|
||||||
break;
|
break;
|
||||||
case dem_multiple:
|
case dem_multiple:
|
||||||
setup_client_list (sv, MSG_ReadLong (net_message));
|
setup_player_list (sv, MSG_ReadLong (msg));
|
||||||
break;
|
break;
|
||||||
case dem_stats:
|
case dem_stats:
|
||||||
case dem_single:
|
case dem_single:
|
||||||
setup_client_list (sv, 1 << (type >> 3));
|
setup_player_list (sv, 1 << (type >> 3));
|
||||||
break;
|
break;
|
||||||
case dem_all:
|
case dem_all:
|
||||||
setup_client_list (sv, ~0);
|
setup_player_list (sv, ~0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +192,10 @@ qtv_packet_f (server_t *sv)
|
||||||
type = len & 0xf000;
|
type = len & 0xf000;
|
||||||
len &= 0x0fff;
|
len &= 0x0fff;
|
||||||
setup_sub_message (net_message, &sub_message, &sub_message_buf, len);
|
setup_sub_message (net_message, &sub_message, &sub_message_buf, len);
|
||||||
qtv_printf ("qtv_packet: %x %d\n", type, len);
|
//qtv_printf ("qtv_packet: %x %d\n", type, len);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case qtv_p_signon:
|
case qtv_p_signon:
|
||||||
|
setup_player_list (sv, ~0);
|
||||||
sv_parse (sv, &sub_message, 1);
|
sv_parse (sv, &sub_message, 1);
|
||||||
break;
|
break;
|
||||||
case qtv_p_print:
|
case qtv_p_print:
|
||||||
|
@ -448,7 +453,9 @@ server_run (server_t *sv)
|
||||||
static byte delta_msg[2] = {qtv_delta};
|
static byte delta_msg[2] = {qtv_delta};
|
||||||
static byte nop_msg[1] = {qtv_nop};
|
static byte nop_msg[1] = {qtv_nop};
|
||||||
if (sv->connected > 1) {
|
if (sv->connected > 1) {
|
||||||
|
int frame = (sv->netchan.outgoing_sequence) & UPDATE_MASK;
|
||||||
sv->next_run = realtime + 0.03;
|
sv->next_run = realtime + 0.03;
|
||||||
|
sv->frames[frame].delta_sequence = sv->delta;
|
||||||
if (sv->delta != -1) {
|
if (sv->delta != -1) {
|
||||||
delta_msg[1] = sv->delta;
|
delta_msg[1] = sv->delta;
|
||||||
Netchan_Transmit (&sv->netchan, sizeof (delta_msg), delta_msg);
|
Netchan_Transmit (&sv->netchan, sizeof (delta_msg), delta_msg);
|
||||||
|
|
|
@ -55,6 +55,7 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
#include "QF/va.h"
|
#include "QF/va.h"
|
||||||
|
|
||||||
|
#include "qw/msg_ucmd.h"
|
||||||
#include "qw/protocol.h"
|
#include "qw/protocol.h"
|
||||||
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
@ -62,7 +63,7 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtv_serverdata (server_t *sv, qmsg_t *msg)
|
sv_serverdata (server_t *sv, qmsg_t *msg)
|
||||||
{
|
{
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ qtv_serverdata (server_t *sv, qmsg_t *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtv_soundlist (server_t *sv, qmsg_t *msg)
|
sv_soundlist (server_t *sv, qmsg_t *msg)
|
||||||
{
|
{
|
||||||
int numsounds = MSG_ReadByte (msg);
|
int numsounds = MSG_ReadByte (msg);
|
||||||
int n;
|
int n;
|
||||||
|
@ -143,7 +144,7 @@ qtv_soundlist (server_t *sv, qmsg_t *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtv_modellist (server_t *sv, qmsg_t *msg)
|
sv_modellist (server_t *sv, qmsg_t *msg)
|
||||||
{
|
{
|
||||||
int nummodels = MSG_ReadByte (msg);
|
int nummodels = MSG_ReadByte (msg);
|
||||||
int n;
|
int n;
|
||||||
|
@ -177,7 +178,7 @@ qtv_modellist (server_t *sv, qmsg_t *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtv_cmd_f (server_t *sv)
|
sv_cmd_f (server_t *sv)
|
||||||
{
|
{
|
||||||
if (Cmd_Argc () > 1) {
|
if (Cmd_Argc () > 1) {
|
||||||
MSG_WriteByte (&sv->netchan.message, qtv_stringcmd);
|
MSG_WriteByte (&sv->netchan.message, qtv_stringcmd);
|
||||||
|
@ -187,8 +188,9 @@ qtv_cmd_f (server_t *sv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtv_skins_f (server_t *sv)
|
sv_skins_f (server_t *sv)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
// we don't actually bother checking skins here, but this is a good way
|
// we don't actually bother checking skins here, but this is a good way
|
||||||
// to get everything ready at the last miniute before we start getting
|
// to get everything ready at the last miniute before we start getting
|
||||||
// actual in-game update messages
|
// actual in-game update messages
|
||||||
|
@ -197,6 +199,11 @@ qtv_skins_f (server_t *sv)
|
||||||
sv->next_run = realtime;
|
sv->next_run = realtime;
|
||||||
sv->connected = 2;
|
sv->connected = 2;
|
||||||
sv->delta = -1;
|
sv->delta = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < UPDATE_BACKUP; i++) {
|
||||||
|
sv->frames[i].entities.entities = sv->entity_states[i];
|
||||||
|
sv->frames[i].players.players = sv->player_states[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -205,8 +212,8 @@ typedef struct {
|
||||||
} svcmd_t;
|
} svcmd_t;
|
||||||
|
|
||||||
svcmd_t svcmds[] = {
|
svcmd_t svcmds[] = {
|
||||||
{"cmd", qtv_cmd_f},
|
{"cmd", sv_cmd_f},
|
||||||
{"skins", qtv_skins_f},
|
{"skins", sv_skins_f},
|
||||||
|
|
||||||
{0, 0},
|
{0, 0},
|
||||||
};
|
};
|
||||||
|
@ -232,8 +239,9 @@ sv_stringcmd (server_t *sv, qmsg_t *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtv_parse_delta (server_t *sv, qmsg_t *msg, int bits)
|
sv_parse_delta (qmsg_t *msg, int bits, entity_state_t *ent)
|
||||||
{
|
{
|
||||||
|
ent->number = bits & 511;
|
||||||
bits &= ~511;
|
bits &= ~511;
|
||||||
|
|
||||||
if (bits & U_MOREBITS)
|
if (bits & U_MOREBITS)
|
||||||
|
@ -244,137 +252,463 @@ qtv_parse_delta (server_t *sv, qmsg_t *msg, int bits)
|
||||||
bits |= MSG_ReadByte (msg) << 24;
|
bits |= MSG_ReadByte (msg) << 24;
|
||||||
}
|
}
|
||||||
if (bits & U_MODEL)
|
if (bits & U_MODEL)
|
||||||
MSG_ReadByte (msg);
|
ent->modelindex = MSG_ReadByte (msg);
|
||||||
if (bits & U_FRAME)
|
if (bits & U_FRAME)
|
||||||
MSG_ReadByte (msg);
|
ent->frame = (ent->frame & 0xff00) | MSG_ReadByte (msg);
|
||||||
if (bits & U_COLORMAP)
|
if (bits & U_COLORMAP)
|
||||||
MSG_ReadByte (msg);
|
ent->colormap = MSG_ReadByte (msg);
|
||||||
if (bits & U_SKIN)
|
if (bits & U_SKIN)
|
||||||
MSG_ReadByte (msg);
|
ent->skinnum = MSG_ReadByte (msg);
|
||||||
if (bits & U_EFFECTS)
|
if (bits & U_EFFECTS)
|
||||||
MSG_ReadByte (msg);
|
ent->effects = (ent->effects & 0xff00) | MSG_ReadByte (msg);
|
||||||
if (bits & U_ORIGIN1)
|
if (bits & U_ORIGIN1)
|
||||||
MSG_ReadCoord (msg);
|
ent->origin[0] = MSG_ReadCoord (msg);
|
||||||
if (bits & U_ANGLE1)
|
if (bits & U_ANGLE1)
|
||||||
MSG_ReadAngle (msg);
|
ent->angles[0] = MSG_ReadAngle (msg);
|
||||||
if (bits & U_ORIGIN2)
|
if (bits & U_ORIGIN2)
|
||||||
MSG_ReadCoord (msg);
|
ent->origin[1] = MSG_ReadCoord (msg);
|
||||||
if (bits & U_ANGLE2)
|
if (bits & U_ANGLE2)
|
||||||
MSG_ReadAngle (msg);
|
ent->angles[1] = MSG_ReadAngle (msg);
|
||||||
if (bits & U_ORIGIN3)
|
if (bits & U_ORIGIN3)
|
||||||
MSG_ReadCoord (msg);
|
ent->origin[2] = MSG_ReadCoord (msg);
|
||||||
if (bits & U_ANGLE3)
|
if (bits & U_ANGLE3)
|
||||||
MSG_ReadAngle (msg);
|
ent->angles[2] = MSG_ReadAngle (msg);
|
||||||
if (bits & U_SOLID) {
|
if (bits & U_SOLID) {
|
||||||
// FIXME
|
// FIXME
|
||||||
}
|
}
|
||||||
if (!(bits & U_EXTEND1))
|
if (!(bits & U_EXTEND1))
|
||||||
return;
|
return;
|
||||||
if (bits & U_ALPHA)
|
if (bits & U_ALPHA)
|
||||||
MSG_ReadByte (msg);
|
ent->alpha = MSG_ReadByte (msg);
|
||||||
if (bits & U_SCALE)
|
if (bits & U_SCALE)
|
||||||
MSG_ReadByte (msg);
|
ent->scale = MSG_ReadByte (msg);
|
||||||
if (bits & U_EFFECTS2)
|
if (bits & U_EFFECTS2)
|
||||||
MSG_ReadByte (msg);
|
ent->effects = (ent->effects & 0x00ff) | (MSG_ReadByte (msg) << 8);
|
||||||
if (bits & U_GLOWSIZE)
|
if (bits & U_GLOWSIZE)
|
||||||
MSG_ReadByte (msg);
|
ent->glow_size = MSG_ReadByte (msg);
|
||||||
if (bits & U_GLOWCOLOR)
|
if (bits & U_GLOWCOLOR)
|
||||||
MSG_ReadByte (msg);
|
ent->glow_color = MSG_ReadByte (msg);
|
||||||
if (bits & U_COLORMOD)
|
if (bits & U_COLORMOD)
|
||||||
MSG_ReadByte (msg);
|
ent->colormod = MSG_ReadByte (msg);
|
||||||
if (!(bits & U_EXTEND1))
|
if (!(bits & U_EXTEND1))
|
||||||
return;
|
return;
|
||||||
if (bits & U_FRAME2)
|
if (bits & U_FRAME2)
|
||||||
MSG_ReadByte (msg);
|
ent->frame = (ent->frame & 0x00ff) | (MSG_ReadByte (msg) << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtv_packetentities (server_t *sv, qmsg_t *msg, int delta)
|
sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
|
||||||
{
|
{
|
||||||
unsigned short word;
|
unsigned short word;
|
||||||
int newnum, oldnum;
|
int newnum, oldnum, from;
|
||||||
|
int newindex, oldindex;
|
||||||
|
int newpacket, oldpacket;
|
||||||
|
int full;
|
||||||
|
packet_entities_t *oldp, *newp, dummy;
|
||||||
|
|
||||||
|
newpacket = sv->netchan.incoming_sequence & UPDATE_MASK;
|
||||||
|
newp = &sv->frames[newpacket].entities;
|
||||||
|
sv->frames[newpacket].invalid = false;
|
||||||
|
|
||||||
newnum = oldnum = 0;
|
|
||||||
if (delta) {
|
if (delta) {
|
||||||
/*from =*/ MSG_ReadByte (msg);
|
from = MSG_ReadByte (msg);
|
||||||
|
oldpacket = sv->frames[newpacket].delta_sequence;
|
||||||
|
if ((from & UPDATE_MASK) != (oldpacket & UPDATE_MASK))
|
||||||
|
qtv_printf ("WARNING: from mismatch\n");
|
||||||
} else {
|
} else {
|
||||||
|
oldpacket = -1;
|
||||||
}
|
}
|
||||||
|
full = 0;
|
||||||
|
if (oldpacket != -1) {
|
||||||
|
if (sv->netchan.outgoing_sequence - oldpacket > UPDATE_BACKUP) {
|
||||||
|
//XXX flush_entity_packet ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
oldp = &sv->frames[oldpacket & UPDATE_MASK].entities;
|
||||||
|
} else {
|
||||||
|
oldp = &dummy;
|
||||||
|
dummy.num_entities = 0;
|
||||||
|
full = 1;
|
||||||
|
}
|
||||||
|
//qtv_printf ("newp = %-5d oldp = %d\n", newpacket, oldpacket & UPDATE_MASK);
|
||||||
sv->delta = sv->netchan.incoming_sequence;
|
sv->delta = sv->netchan.incoming_sequence;
|
||||||
|
newindex = oldindex = 0;
|
||||||
|
newp->num_entities = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
word = (unsigned short) MSG_ReadShort (msg);
|
word = MSG_ReadShort (msg);
|
||||||
if (msg->badread) { // something didn't parse right...
|
if (msg->badread) { // something didn't parse right...
|
||||||
qtv_printf ("msg_badread in packetentities\n");
|
qtv_printf ("msg_badread in packetentities\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//qtv_printf ("word = %04x new = %-3d old = %-3d\n", word, newindex, oldindex);
|
||||||
if (!word) {
|
if (!word) {
|
||||||
// copy rest of ents from old packet
|
// copy rest of ents from old packet
|
||||||
|
while (oldindex < oldp->num_entities) {
|
||||||
|
if (newindex >= MAX_DEMO_PACKET_ENTITIES) {
|
||||||
|
qtv_printf ("A too many packet entities\n");
|
||||||
|
Sys_Quit ();
|
||||||
|
//XXX flush_entitiy_packet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newp->entities[newindex] = oldp->entities[oldindex];
|
||||||
|
newnum = newp->entities[newindex].number;
|
||||||
|
sv->entities[newnum] = newp->entities[newindex];
|
||||||
|
newindex++;
|
||||||
|
oldindex++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
newnum = word & 511;
|
||||||
|
oldnum = 9999;
|
||||||
|
if (oldindex < oldp->num_entities)
|
||||||
|
oldnum = oldp->entities[oldindex].number;
|
||||||
|
//qtv_printf (" %-3d %-4d %3d\n", newnum, oldnum, oldp->num_entities);
|
||||||
|
|
||||||
|
while (newnum > oldnum) {
|
||||||
|
if (full) {
|
||||||
|
qtv_printf ("WARNING: oldcopy on full update\n");
|
||||||
|
//XXX flush_entitiy_packet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (newindex >= MAX_DEMO_PACKET_ENTITIES) {
|
||||||
|
qtv_printf ("B too many packet entities\n");
|
||||||
|
Sys_Quit ();
|
||||||
|
//XXX flush_entitiy_packet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newp->entities[newindex] = oldp->entities[oldindex];
|
||||||
|
sv->entities[newnum] = newp->entities[newindex];
|
||||||
|
newindex++;
|
||||||
|
oldindex++;
|
||||||
|
oldnum = 9999;
|
||||||
|
if (oldindex < oldp->num_entities)
|
||||||
|
oldnum = oldp->entities[oldindex].number;
|
||||||
|
//qtv_printf (" %-3d %-4d %3d\n", newnum, oldnum, oldp->num_entities);
|
||||||
|
}
|
||||||
|
|
||||||
if (newnum < oldnum) {
|
if (newnum < oldnum) {
|
||||||
if (word & U_REMOVE) {
|
if (word & U_REMOVE) {
|
||||||
|
if (full) {
|
||||||
|
sv->delta = 0; //XXX -1?
|
||||||
|
qtv_printf ("WARNING: U_REMOVE on full update\n");
|
||||||
|
//XXX flush_entitiy_packet
|
||||||
|
return;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
qtv_parse_delta (sv, msg, word);
|
if (newindex >= MAX_DEMO_PACKET_ENTITIES) {
|
||||||
|
qtv_printf ("C too many packet entities\n");
|
||||||
|
Sys_Quit ();
|
||||||
|
//XXX flush_entitiy_packet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newp->entities[newindex] = sv->baselines[newnum];
|
||||||
|
sv_parse_delta (msg, word, &newp->entities[newindex]);
|
||||||
|
sv->entities[newnum] = newp->entities[newindex];
|
||||||
|
newindex++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (newnum == oldnum) {
|
if (newnum == oldnum) {
|
||||||
|
if (full) {
|
||||||
|
sv->delta = 0; //XXX -1?
|
||||||
|
qtv_printf ("WARNING: delta on full update\n");
|
||||||
|
}
|
||||||
if (word & U_REMOVE) {
|
if (word & U_REMOVE) {
|
||||||
|
memset (&sv->entities[newnum], 0, sizeof (entity_state_t));
|
||||||
|
oldindex++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
qtv_parse_delta (sv, msg, word);
|
newp->entities[newindex] = oldp->entities[oldindex];
|
||||||
continue;
|
sv_parse_delta (msg, word, &sv->entities[newindex]);
|
||||||
|
sv->entities[newnum] = newp->entities[newindex];
|
||||||
|
newindex++;
|
||||||
|
oldindex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
newp->num_entities = newindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_playerinfo (server_t *sv, qmsg_t *msg)
|
||||||
|
{
|
||||||
|
player_t *pl;
|
||||||
|
plent_state_t dummy; // for bad player indices
|
||||||
|
plent_state_t *ent;
|
||||||
|
int num, flags;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
num = MSG_ReadByte (msg);
|
||||||
|
if (num > MAX_SV_PLAYERS) {
|
||||||
|
qtv_printf ("bogus player: %d\n", num);
|
||||||
|
ent = &dummy;
|
||||||
|
} else {
|
||||||
|
pl = &sv->players[num];
|
||||||
|
ent = &pl->ent;
|
||||||
|
}
|
||||||
|
flags = ent->flags = MSG_ReadShort (msg);
|
||||||
|
MSG_ReadCoordV (msg, ent->origin);
|
||||||
|
ent->frame = (ent->frame & 0xff00) | MSG_ReadByte (msg);
|
||||||
|
if (flags & PF_MSEC)
|
||||||
|
ent->msec = MSG_ReadByte (msg);
|
||||||
|
if (flags & PF_COMMAND)
|
||||||
|
MSG_ReadDeltaUsercmd (msg, &nullcmd, &ent->cmd);
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
if (flags & (PF_VELOCITY1 << i))
|
||||||
|
ent->velocity[i] = MSG_ReadShort (msg);
|
||||||
|
}
|
||||||
|
if (flags & PF_MODEL)
|
||||||
|
ent->modelindex = MSG_ReadByte (msg);
|
||||||
|
if (flags & PF_SKINNUM)
|
||||||
|
ent->skinnum = MSG_ReadByte (net_message);
|
||||||
|
if (flags & PF_EFFECTS)
|
||||||
|
ent->effects = (ent->effects & 0xff00) | MSG_ReadByte (net_message);;
|
||||||
|
if (flags & PF_WEAPONFRAME)
|
||||||
|
ent->weaponframe = MSG_ReadByte (net_message);
|
||||||
|
if (flags & PF_QF) {
|
||||||
|
int bits;
|
||||||
|
|
||||||
|
bits = MSG_ReadByte (msg);
|
||||||
|
if (bits & PF_ALPHA)
|
||||||
|
ent->alpha = MSG_ReadByte (net_message);
|
||||||
|
if (bits & PF_SCALE)
|
||||||
|
ent->scale = MSG_ReadByte (net_message);
|
||||||
|
if (bits & PF_EFFECTS2)
|
||||||
|
ent->effects = (ent->effects & 0x00ff)
|
||||||
|
| (MSG_ReadByte (net_message) << 8);
|
||||||
|
if (bits & PF_GLOWSIZE)
|
||||||
|
ent->glow_size = MSG_ReadByte (net_message);
|
||||||
|
if (bits & PF_GLOWCOLOR)
|
||||||
|
ent->glow_color = MSG_ReadByte (net_message);
|
||||||
|
if (bits & PF_COLORMOD)
|
||||||
|
ent->colormod = MSG_ReadByte (net_message);
|
||||||
|
if (bits & PF_FRAME2)
|
||||||
|
ent->frame = (ent->frame & 0xff)
|
||||||
|
| (MSG_ReadByte (net_message) << 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_serverinfo (server_t *sv, qmsg_t *msg)
|
||||||
|
{
|
||||||
|
dstring_t *key = dstring_newstr ();
|
||||||
|
dstring_t *value = dstring_newstr ();
|
||||||
|
|
||||||
|
dstring_copystr (key, MSG_ReadString (msg));
|
||||||
|
dstring_copystr (value, MSG_ReadString (msg));
|
||||||
|
|
||||||
|
Info_SetValueForKey (sv->info, key->str, value->str, 0);
|
||||||
|
|
||||||
|
dstring_delete (key);
|
||||||
|
dstring_delete (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_setinfo (server_t *sv, qmsg_t *msg)
|
||||||
|
{
|
||||||
|
int slot;
|
||||||
|
dstring_t *key = dstring_newstr ();
|
||||||
|
dstring_t *value = dstring_newstr ();
|
||||||
|
player_t *pl;
|
||||||
|
|
||||||
|
slot = MSG_ReadByte (msg);
|
||||||
|
dstring_copystr (key, MSG_ReadString (msg));
|
||||||
|
dstring_copystr (value, MSG_ReadString (msg));
|
||||||
|
if (slot >= MAX_SV_PLAYERS) {
|
||||||
|
qtv_printf ("bogus player: %d\n", slot);
|
||||||
|
} else {
|
||||||
|
pl = sv->players + slot;
|
||||||
|
if (!pl->info)
|
||||||
|
pl->info = Info_ParseString ("", MAX_INFO_STRING,
|
||||||
|
0);
|
||||||
|
Info_SetValueForKey (pl->info, key->str, value->str,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
dstring_delete (key);
|
||||||
|
dstring_delete (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_updateuserinfo (server_t *sv, qmsg_t *msg)
|
||||||
|
{
|
||||||
|
int slot, uid;
|
||||||
|
const char *info;
|
||||||
|
player_t *pl;
|
||||||
|
|
||||||
|
slot = MSG_ReadByte (msg);
|
||||||
|
uid = MSG_ReadLong (msg);
|
||||||
|
info = MSG_ReadString (msg);
|
||||||
|
if (slot >= MAX_SV_PLAYERS) {
|
||||||
|
qtv_printf ("bogus player: %d\n", slot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pl = sv->players + slot;
|
||||||
|
if (pl->info)
|
||||||
|
Info_Destroy (pl->info);
|
||||||
|
if (info) {
|
||||||
|
pl->info = Info_ParseString (info, MAX_INFO_STRING, 0);
|
||||||
|
pl->uid = uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_updatestat (server_t *sv, qmsg_t *msg, int islong)
|
||||||
|
{
|
||||||
|
int stat, val;
|
||||||
|
player_t *pl;
|
||||||
|
|
||||||
|
stat = MSG_ReadByte (msg);
|
||||||
|
if (!islong)
|
||||||
|
val = MSG_ReadByte (msg);
|
||||||
|
else
|
||||||
|
val = MSG_ReadLong (msg);
|
||||||
|
for (pl = sv->players; pl; pl = pl->next)
|
||||||
|
pl->stats[stat] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_update_net (server_t *sv, qmsg_t *msg, int ping)
|
||||||
|
{
|
||||||
|
int slot, val;
|
||||||
|
player_t *pl;
|
||||||
|
|
||||||
|
slot = MSG_ReadByte (msg);
|
||||||
|
val = MSG_ReadShort (msg);
|
||||||
|
if (slot >= MAX_SV_PLAYERS) {
|
||||||
|
qtv_printf ("bogus player: %d\n", slot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pl = sv->players + slot;
|
||||||
|
if (ping)
|
||||||
|
pl->ping = val;
|
||||||
|
else
|
||||||
|
pl->pl = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_sound (server_t *sv, qmsg_t *msg, int stop)
|
||||||
|
{
|
||||||
|
// XXX
|
||||||
|
int c;
|
||||||
|
vec3_t v;
|
||||||
|
|
||||||
|
if (stop) {
|
||||||
|
MSG_ReadShort (msg);
|
||||||
|
} else {
|
||||||
|
c = MSG_ReadShort (msg);
|
||||||
|
if (c & SND_VOLUME)
|
||||||
|
MSG_ReadByte (msg);
|
||||||
|
if (c & SND_ATTENUATION)
|
||||||
|
MSG_ReadByte (msg);
|
||||||
|
MSG_ReadByte (msg);
|
||||||
|
MSG_ReadCoordV (msg, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_setangle (server_t *sv, qmsg_t *msg)
|
||||||
|
{
|
||||||
|
int slot;
|
||||||
|
player_t *pl;
|
||||||
|
vec3_t ang;
|
||||||
|
|
||||||
|
slot = MSG_ReadByte (msg);
|
||||||
|
MSG_ReadAngleV (msg, ang);
|
||||||
|
if (slot >= MAX_SV_PLAYERS) {
|
||||||
|
qtv_printf ("bogus player: %d\n", slot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pl = sv->players + slot;
|
||||||
|
VectorCopy (ang, pl->ent.cmd.angles);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_updatefrags (server_t *sv, qmsg_t *msg)
|
||||||
|
{
|
||||||
|
int slot, frags;
|
||||||
|
player_t *pl;
|
||||||
|
|
||||||
|
slot = MSG_ReadByte (msg);
|
||||||
|
frags = MSG_ReadShort (msg);
|
||||||
|
if (slot >= MAX_SV_PLAYERS) {
|
||||||
|
qtv_printf ("bogus player: %d\n", slot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pl = sv->players + slot;
|
||||||
|
pl->frags = frags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_baseline (qmsg_t *msg, entity_state_t *ent)
|
||||||
|
{
|
||||||
|
ent->modelindex = MSG_ReadByte (msg);
|
||||||
|
ent->frame = MSG_ReadByte (msg);
|
||||||
|
ent->colormap = MSG_ReadByte (msg);
|
||||||
|
ent->skinnum = MSG_ReadByte (msg);
|
||||||
|
MSG_ReadCoordAngleV (msg, ent->origin, ent->angles);
|
||||||
|
ent->colormod = 255;
|
||||||
|
ent->alpha = 255;
|
||||||
|
ent->scale = 16;
|
||||||
|
ent->glow_size = 254;
|
||||||
|
ent->glow_color = 254;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_spawnbaseline (server_t *sv, qmsg_t *msg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = MSG_ReadShort (msg) % MAX_SV_ENTITIES;
|
||||||
|
sv->baselines[i].number = i;
|
||||||
|
parse_baseline (msg, &sv->baselines[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sv_spawnstatic (server_t *sv, qmsg_t *msg)
|
||||||
|
{
|
||||||
|
entity_state_t ent;
|
||||||
|
parse_baseline (msg, &ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sv_parse (server_t *sv, qmsg_t *msg, int reliable)
|
sv_parse (server_t *sv, qmsg_t *msg, int reliable)
|
||||||
{
|
{
|
||||||
int c;
|
int svc;
|
||||||
vec3_t v, a;
|
vec3_t v;
|
||||||
|
player_t *pl;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
c = MSG_ReadByte (msg);
|
svc = MSG_ReadByte (msg);
|
||||||
if (c == -1)
|
if (svc == -1)
|
||||||
break;
|
break;
|
||||||
//qtv_printf ("sv_parse: svc: %d\n", c);
|
//qtv_printf ("sv_parse: svc: %d\n", svc);
|
||||||
switch (c) {
|
switch (svc) {
|
||||||
default:
|
default:
|
||||||
qtv_printf ("sv_parse: unknown svc: %d\n", c);
|
qtv_printf ("sv_parse: unknown svc: %d\n", svc);
|
||||||
|
Sys_Quit ();
|
||||||
return;
|
return;
|
||||||
case svc_nop:
|
case svc_nop:
|
||||||
break;
|
break;
|
||||||
case svc_updatestat:
|
//case svc_setview:
|
||||||
MSG_ReadByte (msg);
|
// break;
|
||||||
MSG_ReadByte (msg);
|
|
||||||
break;
|
|
||||||
case svc_setview:
|
|
||||||
break;
|
|
||||||
case svc_sound:
|
case svc_sound:
|
||||||
c = MSG_ReadShort (msg);
|
sv_sound (sv, msg, 0);
|
||||||
if (c & SND_VOLUME)
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
if (c & SND_ATTENUATION)
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
MSG_ReadCoordV (msg, v);
|
|
||||||
break;
|
break;
|
||||||
case svc_print:
|
case svc_print:
|
||||||
|
//XXX
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
MSG_ReadString (msg);
|
MSG_ReadString (msg);
|
||||||
break;
|
break;
|
||||||
case svc_setangle:
|
case svc_setangle:
|
||||||
MSG_ReadByte (msg);
|
sv_setangle (sv, msg);
|
||||||
MSG_ReadAngleV(msg, v);
|
|
||||||
break;
|
break;
|
||||||
case svc_updatefrags:
|
case svc_updatefrags:
|
||||||
MSG_ReadByte (msg);
|
sv_updatefrags (sv, msg);
|
||||||
MSG_ReadShort (msg);
|
|
||||||
break;
|
break;
|
||||||
case svc_stopsound:
|
case svc_stopsound:
|
||||||
MSG_ReadShort (msg);
|
sv_sound (sv, msg, 1);
|
||||||
break;
|
break;
|
||||||
case svc_damage:
|
case svc_damage:
|
||||||
|
//XXX
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
MSG_ReadCoordV (msg, v);
|
MSG_ReadCoordV (msg, v);
|
||||||
|
@ -383,29 +717,36 @@ sv_parse (server_t *sv, qmsg_t *msg, int reliable)
|
||||||
//XXX
|
//XXX
|
||||||
break;
|
break;
|
||||||
case svc_setpause:
|
case svc_setpause:
|
||||||
|
//XXX
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
break;
|
break;
|
||||||
case svc_centerprint:
|
case svc_centerprint:
|
||||||
|
//XXX
|
||||||
MSG_ReadString (msg);
|
MSG_ReadString (msg);
|
||||||
break;
|
break;
|
||||||
case svc_killedmonster:
|
case svc_killedmonster:
|
||||||
//XXX
|
for (pl = sv->players; pl; pl = pl->next)
|
||||||
|
pl->stats[14]++; //FIXME STAT_MONSTERS
|
||||||
break;
|
break;
|
||||||
case svc_foundsecret:
|
case svc_foundsecret:
|
||||||
//XXX
|
for (pl = sv->players; pl; pl = pl->next)
|
||||||
|
pl->stats[13]++; //FIXME STAT_SECRETS
|
||||||
break;
|
break;
|
||||||
case svc_intermission:
|
case svc_intermission:
|
||||||
|
//XXX
|
||||||
MSG_ReadCoordV (msg, v);
|
MSG_ReadCoordV (msg, v);
|
||||||
MSG_ReadAngleV (msg, v);
|
MSG_ReadAngleV (msg, v);
|
||||||
break;
|
break;
|
||||||
case svc_finale:
|
case svc_finale:
|
||||||
|
//XXX
|
||||||
MSG_ReadString (msg);
|
MSG_ReadString (msg);
|
||||||
break;
|
break;
|
||||||
case svc_cdtrack:
|
case svc_cdtrack:
|
||||||
|
//XXX
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
break;
|
break;
|
||||||
case svc_sellscreen:
|
case svc_sellscreen:
|
||||||
//XXX
|
//ignore
|
||||||
break;
|
break;
|
||||||
case svc_smallkick:
|
case svc_smallkick:
|
||||||
//XXX
|
//XXX
|
||||||
|
@ -413,88 +754,85 @@ sv_parse (server_t *sv, qmsg_t *msg, int reliable)
|
||||||
case svc_bigkick:
|
case svc_bigkick:
|
||||||
//XXX
|
//XXX
|
||||||
break;
|
break;
|
||||||
case svc_updateping:
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
MSG_ReadShort (msg);
|
|
||||||
break;
|
|
||||||
case svc_updateentertime:
|
case svc_updateentertime:
|
||||||
|
//XXX
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
MSG_ReadFloat (msg);
|
MSG_ReadFloat (msg);
|
||||||
break;
|
break;
|
||||||
|
case svc_updatestat:
|
||||||
case svc_updatestatlong:
|
case svc_updatestatlong:
|
||||||
MSG_ReadByte (msg);
|
sv_updatestat (sv, msg, svc == svc_updatestatlong);
|
||||||
MSG_ReadLong (msg);
|
|
||||||
break;
|
break;
|
||||||
case svc_muzzleflash:
|
case svc_muzzleflash:
|
||||||
|
//XXX
|
||||||
MSG_ReadShort (msg);
|
MSG_ReadShort (msg);
|
||||||
break;
|
break;
|
||||||
case svc_updateuserinfo:
|
case svc_updateuserinfo:
|
||||||
MSG_ReadByte (msg);
|
sv_updateuserinfo (sv, msg);
|
||||||
MSG_ReadLong (msg);
|
|
||||||
MSG_ReadString (msg);
|
|
||||||
break;
|
break;
|
||||||
case svc_playerinfo:
|
case svc_playerinfo:
|
||||||
//XXX
|
sv_playerinfo (sv, msg);
|
||||||
break;
|
break;
|
||||||
case svc_nails:
|
case svc_nails:
|
||||||
//XXX
|
|
||||||
break;
|
|
||||||
case svc_packetentities:
|
|
||||||
qtv_packetentities (sv, msg, 0);
|
|
||||||
break;
|
|
||||||
case svc_deltapacketentities:
|
|
||||||
qtv_packetentities (sv, msg, 1);
|
|
||||||
break;
|
|
||||||
case svc_maxspeed:
|
|
||||||
MSG_ReadFloat (msg);
|
|
||||||
break;
|
|
||||||
case svc_entgravity:
|
|
||||||
MSG_ReadFloat (msg);
|
|
||||||
break;
|
|
||||||
case svc_setinfo:
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
MSG_ReadString (msg);
|
|
||||||
MSG_ReadString (msg);
|
|
||||||
break;
|
|
||||||
case svc_serverinfo:
|
|
||||||
MSG_ReadString (msg);
|
|
||||||
MSG_ReadString (msg);
|
|
||||||
break;
|
|
||||||
case svc_updatepl:
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
break;
|
|
||||||
case svc_nails2:
|
case svc_nails2:
|
||||||
//XXX
|
//XXX
|
||||||
break;
|
break;
|
||||||
|
case svc_packetentities:
|
||||||
|
sv_packetentities (sv, msg, 0);
|
||||||
|
break;
|
||||||
|
case svc_deltapacketentities:
|
||||||
|
sv_packetentities (sv, msg, 1);
|
||||||
|
break;
|
||||||
|
case svc_maxspeed:
|
||||||
|
//XXX
|
||||||
|
MSG_ReadFloat (msg);
|
||||||
|
break;
|
||||||
|
case svc_entgravity:
|
||||||
|
//XXX
|
||||||
|
MSG_ReadFloat (msg);
|
||||||
|
break;
|
||||||
|
case svc_setinfo:
|
||||||
|
sv_setinfo (sv, msg);
|
||||||
|
break;
|
||||||
|
case svc_serverinfo:
|
||||||
|
sv_serverinfo (sv, msg);
|
||||||
|
break;
|
||||||
|
case svc_updatepl:
|
||||||
|
sv_update_net (sv, msg, 0);
|
||||||
|
break;
|
||||||
|
case svc_updateping:
|
||||||
|
sv_update_net (sv, msg, 1);
|
||||||
|
break;
|
||||||
case svc_serverdata:
|
case svc_serverdata:
|
||||||
qtv_serverdata (sv, msg);
|
sv_serverdata (sv, msg);
|
||||||
break;
|
break;
|
||||||
case svc_stufftext:
|
case svc_stufftext:
|
||||||
sv_stringcmd (sv, msg);
|
sv_stringcmd (sv, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case svc_soundlist:
|
case svc_soundlist:
|
||||||
qtv_soundlist (sv, msg);
|
sv_soundlist (sv, msg);
|
||||||
break;
|
break;
|
||||||
case svc_modellist:
|
case svc_modellist:
|
||||||
qtv_modellist (sv, msg);
|
sv_modellist (sv, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case svc_spawnstaticsound:
|
case svc_spawnstaticsound:
|
||||||
|
//XXX
|
||||||
MSG_ReadCoordV (msg, v);
|
MSG_ReadCoordV (msg, v);
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case svc_spawnbaseline:
|
case svc_spawnbaseline:
|
||||||
MSG_ReadShort (msg);
|
sv_spawnbaseline (sv, msg);
|
||||||
|
break;
|
||||||
case svc_spawnstatic:
|
case svc_spawnstatic:
|
||||||
MSG_ReadByte (msg);
|
sv_spawnstatic (sv, msg);
|
||||||
MSG_ReadByte (msg);
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
MSG_ReadByte (msg);
|
|
||||||
MSG_ReadCoordAngleV (msg, v, a);
|
|
||||||
break;
|
break;
|
||||||
case svc_lightstyle:
|
case svc_lightstyle:
|
||||||
|
//XXX
|
||||||
MSG_ReadByte (msg);
|
MSG_ReadByte (msg);
|
||||||
MSG_ReadString (msg);
|
MSG_ReadString (msg);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue