mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-16 17:01:53 +00:00
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:
parent
53cd9be90a
commit
701652b8aa
5 changed files with 87 additions and 31 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue