progress on getting map changing to work with qtv

subsequent map changes are still behaving strangely, but signon buffer
handling is now much better.
This commit is contained in:
Bill Currie 2010-01-13 06:46:26 +00:00 committed by Jeff Teunissen
parent 53cd9be90a
commit 701652b8aa
5 changed files with 87 additions and 31 deletions

View file

@ -44,6 +44,7 @@ extern double realtime;
extern struct cbuf_s *qtv_cbuf;
extern struct cbuf_args_s *qtv_args;
extern struct cvar_s *sv_timeout;
struct client_s;

View file

@ -76,6 +76,8 @@ static plugin_list_t server_plugin_list[] = {
double realtime;
cvar_t *sv_timeout;
cbuf_t *qtv_cbuf;
cbuf_args_t *qtv_args;
@ -238,6 +240,7 @@ qtv_net_init (void)
{
qtv_port = Cvar_Get ("qtv_port", va ("%d", PORT_QTV), 0, 0,
"udp port to use");
sv_timeout = Cvar_Get ("sv_timeout", "60", 0, 0, "server timeout");
NET_Init (qtv_port->int_val);
Connection_Init ();
net_realtime = &realtime;

View file

@ -193,6 +193,22 @@ qtv_parse_updates (server_t *sv, qmsg_t *msg, int reliable)
}
}
static void
save_signon (server_t *sv, qmsg_t *msg, int start)
{
int size = msg->readcount - start;
byte *buf = msg->message->data + start;
if (!size)
return;
Sys_DPrintf ("save_signon: %d\n", sv->num_signon_buffers);
if (sv->num_signon_buffers >= MAX_SIGNON_BUFFERS)
Sys_Error ("too many signon buffers: %d\n", sv->num_signon_buffers);
sv->signon_buffer_size[sv->num_signon_buffers] = size;
memcpy (sv->signon_buffers[sv->num_signon_buffers], buf, size);
sv->num_signon_buffers++;
}
static void
qtv_packet_f (server_t *sv)
{
@ -200,16 +216,32 @@ qtv_packet_f (server_t *sv)
int reliable = 0;
sizebuf_t sub_message_buf;
qmsg_t sub_message;
int start = -1;
len = MSG_ReadShort (net_message);
type = len & 0xf000;
len &= 0x0fff;
setup_sub_message (net_message, &sub_message, &sub_message_buf, len);
//qtv_printf ("qtv_packet: %x %d\n", type, len);
if (0) {
static const char *qtv_types[16] = {
"qtv_p_signon",
"qtv_p_print",
"qtv_p_reliable",
"qtv_p_unreliable",
"[4]", "[5]", "[6]", "[7]",
"[8]", "[9]", "[a]", "[b]",
"[c]", "[d]", "[e]", "[f]",
};
qtv_printf ("qtv_packet: %s %d\n", qtv_types[type >> 12], len);
}
switch (type) {
case qtv_p_signon:
if (sv->signon)
start = sub_message.readcount;
setup_player_list (sv, ~0);
sv_parse (sv, &sub_message, 1);
if (start >= 0)
save_signon (sv, &sub_message, start);
break;
case qtv_p_print:
qtv_printf ("%s\n", MSG_ReadString (net_message));
@ -234,13 +266,23 @@ server_handler (connection_t *con, void *object)
return;
if (!Netchan_Process (&sv->netchan))
return;
if (0) {
int i;
for (i = 0; i < net_message->message->cursize; i++)
qtv_printf ("%c%02x", (i % 16) ? ' ' : '\n',
net_message->message->data[i]);
qtv_printf ("\n");
}
while (1) {
int cmd;
if (net_message->badread) {
qtv_printf ("badread\n");
break;
}
cmd = MSG_ReadByte (net_message);
if (cmd == -1) {
//qtv_printf ("cmd = -1\n");
net_message->readcount++;
break;
}
@ -424,7 +466,7 @@ sv_del_f (void)
}
name = Cmd_Argv (1);
if (!(sv = Hash_Del (server_hash, name))) {
qtv_printf ("sv_new: %s unknown\n", name);
qtv_printf ("sv_del: %s unknown\n", name);
return;
}
Hash_Free (server_hash, sv);
@ -468,6 +510,7 @@ server_run (server_t *sv)
{
static byte delta_msg[2] = {qtv_delta};
static byte nop_msg[1] = {qtv_nop};
if (sv->connected > 1) {
int frame = (sv->netchan.outgoing_sequence) & UPDATE_MASK;
sv->next_run = realtime + 0.03;
@ -500,6 +543,12 @@ Server_Frame (void)
server_t *sv;
for (sv = servers; sv; sv = sv->next) {
if (realtime - sv->netchan.last_received > sv_timeout->value) {
qtv_printf ("Server %s timed out\n", sv->name);
Hash_Del (server_hash, sv->name);
Hash_Free (server_hash, sv);
continue;
}
if (sv->next_run && sv->next_run <= realtime) {
sv->next_run = 0;
server_run (sv);

View file

@ -177,6 +177,7 @@ sv_modellist (server_t *sv, qmsg_t *msg)
MSG_WriteByte (&sv->netchan.message, qtv_stringcmd);
MSG_WriteString (&sv->netchan.message,
va ("prespawn %d 0 0", sv->spawncount));
sv->signon = 1;
}
sv->next_run = realtime;
}
@ -185,9 +186,8 @@ static void
sv_cmd_f (server_t *sv)
{
if (Cmd_Argc () > 1) {
sv->signon = 0;
if (strcmp (Cmd_Argv (1), "prespawn") == 0)
sv->signon = 1;
if (!strcmp (Cmd_Argv(1), "spawn"))
sv->signon = 0;
MSG_WriteByte (&sv->netchan.message, qtv_stringcmd);
SZ_Print (&sv->netchan.message, Cmd_Args (1));
}
@ -213,6 +213,24 @@ sv_skins_f (server_t *sv)
}
}
static void
sv_changing_f (server_t *sv)
{
sv->connected = 1;
sv->num_signon_buffers = 0;
qtv_printf ("Changing map...\n");
}
static void
sv_reconnect_f (server_t *sv)
{
sizebuf_t *msg = &sv->netchan.message;
qtv_printf ("Reconnecting...\n");
MSG_WriteByte (msg, qtv_stringcmd);
MSG_WriteString (msg, "new");
}
typedef struct {
const char *name;
void (*func) (server_t *sv);
@ -221,6 +239,8 @@ typedef struct {
svcmd_t svcmds[] = {
{"cmd", sv_cmd_f},
{"skins", sv_skins_f},
{"changing", sv_changing_f},
{"reconnect", sv_reconnect_f},
{0, 0},
};
@ -333,6 +353,11 @@ sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
int full;
packet_entities_t *oldp, *newp, dummy;
if (sv->connected < 2) {
flush_entity_packet (sv, msg);
return;
}
newpacket = sv->netchan.incoming_sequence & UPDATE_MASK;
newp = &sv->frames[newpacket].entities;
sv->frames[newpacket].invalid = false;
@ -846,28 +871,12 @@ sv_updateentertime (server_t *sv, qmsg_t *msg)
pl->time = time;
}
static void
save_signon (server_t *sv, qmsg_t *msg, int start)
{
int size = msg->readcount - start;
byte *buf = msg->message->data + start;
if (!size)
return;
sv->signon_buffer_size[sv->num_signon_buffers] = size;
memcpy (sv->signon_buffers[sv->num_signon_buffers], buf, size);
sv->num_signon_buffers++;
}
void
sv_parse (server_t *sv, qmsg_t *msg, int reliable)
{
int svc;
vec3_t v;
player_t *pl;
int start = msg->readcount;
int signon_saved = 0;
while (1) {
int bc_len = msg->readcount;
@ -1011,10 +1020,6 @@ sv_parse (server_t *sv, qmsg_t *msg, int reliable)
sv_serverdata (sv, msg);
break;
case svc_stufftext:
if (sv->signon && !signon_saved) {
save_signon (sv, msg, start);
signon_saved = 1;
}
sv_stringcmd (sv, msg);
break;
@ -1048,7 +1053,4 @@ sv_parse (server_t *sv, qmsg_t *msg, int reliable)
Server_Broadcast (sv, reliable, bc_data, bc_len);
}
}
if (sv->signon && !signon_saved) {
save_signon (sv, msg, start);
}
}

View file

@ -121,6 +121,7 @@ qtv_new_f (sv_qtv_t *proxy)
buf = proxy->netchan.message.data + pos;
buf[0] = len & 0xff;
buf[1] |= (len >> 8) & 0x0f;
proxy->begun = 0;
}
static void
@ -163,7 +164,7 @@ qtv_modellist_f (sv_qtv_t *proxy)
}
n = atoi (Cmd_Argv (2));
if (n >= MAX_SOUNDS) {
if (n >= MAX_MODELS) {
qtv_new_f (proxy);
return;
}
@ -198,7 +199,7 @@ qtv_prespawn_f (sv_qtv_t *proxy)
command = va ("cmd spawn %i 0\n", svs.spawncount);
else
command = va ("cmd prespawn %i %i\n", svs.spawncount, buf + 1);
size = (5 + sv.signon_buffer_size[buf]) + (1 + strlen (command) + 1);
size = (3 + sv.signon_buffer_size[buf]) + (1 + strlen (command) + 1);
msg = MSG_ReliableCheckBlock (&proxy->backbuf, size);
@ -247,7 +248,7 @@ qtv_write (void *r, sizebuf_t *msg, int reliable)
if (!msg->cursize)
return;
if (reliable) {
buf = MSG_ReliableCheckBlock (&proxy->backbuf, msg->cursize);
buf = MSG_ReliableCheckBlock (&proxy->backbuf, msg->cursize + 3);
type = qtv_p_reliable;
} else {
buf = &proxy->datagram;