From 4a425a1b1a734dcd528829fc526aa806a9270ea4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 8 May 2005 00:48:21 +0000 Subject: [PATCH] though none of the signon info is sent yet, the spectating client now gets put into the map. can't move yet, though --- qtv/include/client.h | 9 +++ qtv/include/server.h | 3 + qtv/source/client.c | 175 ++++++++++++++++++++++++++++++++++++++++-- qtv/source/qtv.c | 1 + qtv/source/server.c | 35 +++++++++ qtv/source/sv_parse.c | 42 ++++------ 6 files changed, 234 insertions(+), 31 deletions(-) diff --git a/qtv/include/client.h b/qtv/include/client.h index 8f8e5aedd..7d2855acb 100644 --- a/qtv/include/client.h +++ b/qtv/include/client.h @@ -36,8 +36,11 @@ #include "qw/msg_backbuf.h" typedef struct client_s { + // list of clients connected to a server struct client_s *next; struct client_s **prev; + // list of clients in general + struct client_s *clnext; struct info_s *userinfo; struct connection_s *con; int drop; @@ -45,8 +48,11 @@ typedef struct client_s { backbuf_t backbuf; sizebuf_t datagram; byte datagram_buf[MAX_DATAGRAM]; + qboolean send_message; struct server_s *server; + + int connected; } client_t; typedef struct challenge_s { @@ -57,4 +63,7 @@ typedef struct challenge_s { void Client_Init (void); void Client_NewConnection (void); +void Client_New (client_t *cl); +void Client_Frame (void); + #endif//__client_h diff --git a/qtv/include/server.h b/qtv/include/server.h index bbe3bdb04..802a1d3f3 100644 --- a/qtv/include/server.h +++ b/qtv/include/server.h @@ -78,6 +78,8 @@ typedef struct server_s { int cdtrack; int sounds; struct info_s *info; + char *soundlist[MAX_SOUNDS + 1]; + char *modellist[MAX_MODELS + 1]; struct client_s *clients; @@ -98,6 +100,7 @@ void Server_Frame (void); void Server_List (void); void Server_Connect (const char *name, struct client_s *client); void Server_Disconnect (struct client_s *client); +void Server_Broadcast (server_t *sv, int reliable, byte *msg, int len); struct qmsg_s; void sv_parse (server_t *sv, struct msg_s *msg, int reliable); diff --git a/qtv/source/client.c b/qtv/source/client.c index 20a25fae0..5b47ec311 100644 --- a/qtv/source/client.c +++ b/qtv/source/client.c @@ -51,6 +51,7 @@ static __attribute__ ((unused)) const char rcsid[] = #include "QF/hash.h" #include "QF/idparse.h" #include "QF/info.h" +#include "QF/va.h" #include "qw/msg_ucmd.h" #include "qw/protocol.h" @@ -60,6 +61,8 @@ static __attribute__ ((unused)) const char rcsid[] = #include "qtv.h" #include "server.h" +static client_t *clients; + typedef struct ucmd_s { const char *name; void (*func) (client_t *cl, void *userdata); @@ -88,26 +91,118 @@ cl_new_f (client_t *cl, void *unused) static void cl_modellist_f (client_t *cl, void *unused) { + server_t *sv = cl->server; + unsigned n; + char **s; + + if (atoi (Cmd_Argv (1)) != sv->spawncount) { + qtv_printf ("modellist from different level\n"); + Client_New (cl); + return; + } + n = atoi (Cmd_Argv (2)); + if (n >= MAX_MODELS) { + qtv_printf ("invalid modellist index\n"); + Client_New (cl); + return; + } + + MSG_WriteByte (&cl->netchan.message, svc_modellist); + MSG_WriteByte (&cl->netchan.message, n); + for (s = sv->modellist + n; + *s && cl->netchan.message.cursize < (MAX_MSGLEN /2); + s++, n++) + MSG_WriteString (&cl->netchan.message, *s); + MSG_WriteByte (&cl->netchan.message, 0); + if (*s) + MSG_WriteByte (&cl->netchan.message, n); + else + MSG_WriteByte (&cl->netchan.message, 0); } static void cl_soundlist_f (client_t *cl, void *unused) { + server_t *sv = cl->server; + unsigned n; + char **s; + + if (!cl->server) + return; + if (atoi (Cmd_Argv (1)) != sv->spawncount) { + qtv_printf ("soundlist from different level\n"); + Client_New (cl); + return; + } + n = atoi (Cmd_Argv (2)); + if (n >= MAX_SOUNDS) { + qtv_printf ("invalid soundlist index\n"); + Client_New (cl); + return; + } + + MSG_WriteByte (&cl->netchan.message, svc_soundlist); + MSG_WriteByte (&cl->netchan.message, n); + for (s = sv->soundlist + n; + *s && cl->netchan.message.cursize < (MAX_MSGLEN /2); + s++, n++) + MSG_WriteString (&cl->netchan.message, *s); + MSG_WriteByte (&cl->netchan.message, 0); + if (*s) + MSG_WriteByte (&cl->netchan.message, n); + else + MSG_WriteByte (&cl->netchan.message, 0); } static void cl_prespawn_f (client_t *cl, void *unused) { + const char *cmd; + server_t *sv = cl->server; + + if (!cl->server) + return; + if (atoi (Cmd_Argv (1)) != sv->spawncount) { + qtv_printf ("prespawn from different level\n"); + Client_New (cl); + return; + } + cmd = va ("cmd spawn %i 0\n", cl->server->spawncount); + MSG_ReliableWrite_Begin (&cl->backbuf, svc_stufftext, strlen (cmd) + 2); + MSG_ReliableWrite_String (&cl->backbuf, cmd); } static void cl_spawn_f (client_t *cl, void *unused) { + const char *cmd; + server_t *sv = cl->server; + + if (!cl->server) + return; + if (atoi (Cmd_Argv (1)) != sv->spawncount) { + qtv_printf ("spawn from different level\n"); + Client_New (cl); + return; + } + cmd = "skins\n"; + MSG_ReliableWrite_Begin (&cl->backbuf, svc_stufftext, strlen (cmd) + 2); + MSG_ReliableWrite_String (&cl->backbuf, cmd); } static void cl_begin_f (client_t *cl, void *unused) { + server_t *sv = cl->server; + + if (!cl->server) + return; + if (atoi (Cmd_Argv (1)) != sv->spawncount) { + qtv_printf ("spawn from different level\n"); + Client_New (cl); + return; + } + cl->connected = 1; } static void @@ -141,6 +236,11 @@ cl_setinfo_f (client_t *cl, void *unused) static void cl_serverinfo_f (client_t *cl, void *unused) { + if (cl->server) { + Info_Print (cl->server->info); + return; + } + qtv_printf ("not connected to a server"); } static void @@ -349,6 +449,30 @@ client_parse_message (client_t *cl) } } +static void +cl_send_messages (client_t *cl) +{ + byte buf[MAX_DATAGRAM]; + sizebuf_t msg; + + memset (&msg, 0, sizeof (msg)); + msg.allowoverflow = true; + msg.maxsize = sizeof (buf); + msg.data = buf; + + if (cl->backbuf.num_backbuf) + MSG_Reliable_Send (&cl->backbuf); + if (cl->connected) { + MSG_WriteByte (&msg, svc_packetentities); + MSG_WriteShort (&msg, 0); + } + if (cl->datagram.cursize) { + SZ_Write (&msg, cl->datagram.data, cl->datagram.cursize); + SZ_Clear (&cl->datagram); + } + Netchan_Transmit (&cl->netchan, msg.cursize, msg.data); +} + static void client_handler (connection_t *con, void *object) { @@ -361,14 +485,10 @@ client_handler (connection_t *con, void *object) if (Netchan_Process (&cl->netchan)) { // this is a valid, sequenced packet, so process it //svs.stats.packets++; - //cl->send_message = true; + cl->send_message = true; //if (cl->state != cs_zombie) client_parse_message (cl); - if (cl->backbuf.num_backbuf) - MSG_Reliable_Send (&cl->backbuf); - Netchan_Transmit (&cl->netchan, cl->datagram.cursize, - cl->datagram.data); - SZ_Clear (&cl->datagram); + cl_send_messages (cl); if (cl->drop) { Connection_Del (cl->con); Info_Destroy (cl->userinfo); @@ -424,6 +544,8 @@ client_connect (connection_t *con, void *object) cl = calloc (1, sizeof (client_t)); Netchan_Setup (&cl->netchan, con->address, qport, NC_READ_QPORT); + cl->clnext = clients; + clients = cl; cl->backbuf.netchan = &cl->netchan; cl->backbuf.name = "FIXME"; cl->userinfo = userinfo; @@ -479,3 +601,44 @@ Client_Init (void) for (i = 0; i < sizeof (ucmds) / sizeof (ucmds[0]); i++) Hash_Add (ucmd_table, &ucmds[i]); } + +void +Client_New (client_t *cl) +{ + server_t *sv = cl->server; + + MSG_WriteByte (&cl->netchan.message, svc_serverdata); + MSG_WriteLong (&cl->netchan.message, PROTOCOL_VERSION); + MSG_WriteLong (&cl->netchan.message, sv->spawncount); + MSG_WriteString (&cl->netchan.message, sv->gamedir); + MSG_WriteByte (&cl->netchan.message, 0x80 | 31); + MSG_WriteString (&cl->netchan.message, sv->message); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.gravity); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.stopspeed); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.maxspeed); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.spectatormaxspeed); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.accelerate); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.airaccelerate); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.wateraccelerate); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.friction); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.waterfriction); + MSG_WriteFloat (&cl->netchan.message, sv->movevars.entgravity); + MSG_WriteByte (&cl->netchan.message, svc_cdtrack); + MSG_WriteByte (&cl->netchan.message, sv->cdtrack); + MSG_WriteByte (&cl->netchan.message, svc_stufftext); + MSG_WriteString (&cl->netchan.message, + va ("fullserverinfo \"%s\"\n", + Info_MakeString (sv->info, 0))); +} + +void +Client_Frame (void) +{ + client_t *cl; + + for (cl = clients; cl; cl = cl->next) { + if (cl->send_message) { + cl_send_messages (cl); + } + } +} diff --git a/qtv/source/qtv.c b/qtv/source/qtv.c index fcd0ad299..41740a415 100644 --- a/qtv/source/qtv.c +++ b/qtv/source/qtv.c @@ -394,6 +394,7 @@ main (int argc, const char *argv[]) Con_ProcessInput (); Server_Frame (); + Client_Frame (); } return 0; } diff --git a/qtv/source/server.c b/qtv/source/server.c index b144244ae..94ecf4ee3 100644 --- a/qtv/source/server.c +++ b/qtv/source/server.c @@ -76,6 +76,8 @@ server_free (void *_sv, void *unused) { server_t *sv = (server_t *) _sv; server_t **s; + int i; + client_t *cl; static byte final[] = {qtv_stringcmd, 'd', 'r', 'o', 'p', 0}; @@ -96,6 +98,16 @@ server_free (void *_sv, void *unused) break; } } + for (i = 0; i < 256; i++) { + if (sv->soundlist[i]) + free (sv->soundlist[i]); + if (sv->modellist[i]) + free (sv->modellist[i]); + } + for (cl = sv->clients; cl; cl = cl->next) { + cl->server = 0; + cl->connected = 0; + } free (sv); } @@ -516,13 +528,36 @@ Server_Connect (const char *name, struct client_s *client) if (sv->clients) sv->clients->prev = &client->next; sv->clients = client; + + Client_New (client); } void Server_Disconnect (struct client_s *client) { client->server = 0; + client->connected = 0; if (client->next) client->next->prev = client->prev; *client->prev = client->next; } + +void +Server_Broadcast (server_t *sv, int reliable, byte *msg, int len) +{ + client_t *cl; + byte svc; + + if (len < 1) + return; + svc = *msg++; + len--; + for (cl = sv->clients; cl; cl = cl->next) { + if (reliable) { + MSG_ReliableWrite_Begin (&cl->backbuf, svc, len + 1); + MSG_ReliableWrite_SZ (&cl->backbuf, msg, len); + } else { + SZ_Write (&cl->datagram, msg - 1, len + 1); + } + } +} diff --git a/qtv/source/sv_parse.c b/qtv/source/sv_parse.c index 75c92e300..fa51bf5e4 100644 --- a/qtv/source/sv_parse.c +++ b/qtv/source/sv_parse.c @@ -63,27 +63,6 @@ static __attribute__ ((unused)) const char rcsid[] = #include "qtv.h" #include "server.h" -static void -sv_broadcast (server_t *sv, int reliable, byte *msg, int len) -{ - client_t *cl; - byte svc; - - if (len < 1) - return; - svc = *msg++; - len--; - for (cl = sv->clients; cl; cl = cl->next) { - if (reliable) { - MSG_ReliableWrite_Begin (&cl->backbuf, svc, len + 1); - MSG_ReliableWrite_SZ (&cl->backbuf, msg, len); - } else { - MSG_WriteByte (&cl->datagram, svc); - SZ_Write (&cl->datagram, msg, len); - } - } -} - static void sv_serverdata (server_t *sv, qmsg_t *msg) { @@ -150,7 +129,7 @@ sv_soundlist (server_t *sv, qmsg_t *msg) MSG_ReadByte (msg); return; } - // save sound name + sv->soundlist[numsounds - 1] = strdup (str); } n = MSG_ReadByte (msg); if (n) { @@ -178,13 +157,13 @@ sv_modellist (server_t *sv, qmsg_t *msg) break; //qtv_printf ("%s\n", str); nummodels++; - if (nummodels == MAX_SOUNDS) { + if (nummodels == MAX_MODELS) { while (str[0]) str = MSG_ReadString (msg); MSG_ReadByte (msg); return; } - // save sound name + sv->modellist[nummodels - 1] = strdup (str); } n = MSG_ReadByte (msg); if (n) { @@ -616,7 +595,11 @@ sv_sound (server_t *sv, qmsg_t *msg, int stop) // XXX int c; vec3_t v; + byte *data; + int len; + len = msg->readcount - 1; + data = msg->message->data + len; if (stop) { MSG_ReadShort (msg); } else { @@ -628,6 +611,8 @@ sv_sound (server_t *sv, qmsg_t *msg, int stop) MSG_ReadByte (msg); MSG_ReadCoordV (msg, v); } + len = msg->readcount - len; + Server_Broadcast (sv, 0, data, len); } static void @@ -710,6 +695,11 @@ sv_temp_entity (server_t *sv, qmsg_t *msg) { vec3_t pos; int type; + byte *data; + int len; + + len = msg->readcount - 1; + data = msg->message->data + len; type = MSG_ReadByte (msg); switch (type) { @@ -760,6 +750,8 @@ sv_temp_entity (server_t *sv, qmsg_t *msg) MSG_ReadCoordV (msg, pos); break; } + len = msg->readcount - len; + Server_Broadcast (sv, 0, data, len); } static void @@ -787,7 +779,7 @@ sv_print (server_t *sv, qmsg_t *msg) MSG_ReadByte (msg); qtv_printf ("%s", MSG_ReadString (msg)); len = msg->readcount - len; - sv_broadcast (sv, 1, data, len); + Server_Broadcast (sv, 1, data, len); } void