though none of the signon info is sent yet, the spectating client now gets

put into the map. can't move yet, though
This commit is contained in:
Bill Currie 2005-05-08 00:48:21 +00:00
parent d16cf69017
commit 4a425a1b1a
6 changed files with 234 additions and 31 deletions

View file

@ -36,8 +36,11 @@
#include "qw/msg_backbuf.h" #include "qw/msg_backbuf.h"
typedef struct client_s { typedef struct client_s {
// list of clients connected to a server
struct client_s *next; struct client_s *next;
struct client_s **prev; struct client_s **prev;
// list of clients in general
struct client_s *clnext;
struct info_s *userinfo; struct info_s *userinfo;
struct connection_s *con; struct connection_s *con;
int drop; int drop;
@ -45,8 +48,11 @@ typedef struct client_s {
backbuf_t backbuf; backbuf_t backbuf;
sizebuf_t datagram; sizebuf_t datagram;
byte datagram_buf[MAX_DATAGRAM]; byte datagram_buf[MAX_DATAGRAM];
qboolean send_message;
struct server_s *server; struct server_s *server;
int connected;
} client_t; } client_t;
typedef struct challenge_s { typedef struct challenge_s {
@ -57,4 +63,7 @@ typedef struct challenge_s {
void Client_Init (void); void Client_Init (void);
void Client_NewConnection (void); void Client_NewConnection (void);
void Client_New (client_t *cl);
void Client_Frame (void);
#endif//__client_h #endif//__client_h

View file

@ -78,6 +78,8 @@ typedef struct server_s {
int cdtrack; int cdtrack;
int sounds; int sounds;
struct info_s *info; struct info_s *info;
char *soundlist[MAX_SOUNDS + 1];
char *modellist[MAX_MODELS + 1];
struct client_s *clients; struct client_s *clients;
@ -98,6 +100,7 @@ void Server_Frame (void);
void Server_List (void); void Server_List (void);
void Server_Connect (const char *name, struct client_s *client); void Server_Connect (const char *name, struct client_s *client);
void Server_Disconnect (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; struct qmsg_s;
void sv_parse (server_t *sv, struct msg_s *msg, int reliable); void sv_parse (server_t *sv, struct msg_s *msg, int reliable);

View file

@ -51,6 +51,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/hash.h" #include "QF/hash.h"
#include "QF/idparse.h" #include "QF/idparse.h"
#include "QF/info.h" #include "QF/info.h"
#include "QF/va.h"
#include "qw/msg_ucmd.h" #include "qw/msg_ucmd.h"
#include "qw/protocol.h" #include "qw/protocol.h"
@ -60,6 +61,8 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "qtv.h" #include "qtv.h"
#include "server.h" #include "server.h"
static client_t *clients;
typedef struct ucmd_s { typedef struct ucmd_s {
const char *name; const char *name;
void (*func) (client_t *cl, void *userdata); void (*func) (client_t *cl, void *userdata);
@ -88,26 +91,118 @@ cl_new_f (client_t *cl, void *unused)
static void static void
cl_modellist_f (client_t *cl, void *unused) 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 static void
cl_soundlist_f (client_t *cl, void *unused) 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 static void
cl_prespawn_f (client_t *cl, void *unused) 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 static void
cl_spawn_f (client_t *cl, void *unused) 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 static void
cl_begin_f (client_t *cl, void *unused) 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 static void
@ -141,6 +236,11 @@ cl_setinfo_f (client_t *cl, void *unused)
static void static void
cl_serverinfo_f (client_t *cl, void *unused) 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 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 static void
client_handler (connection_t *con, void *object) client_handler (connection_t *con, void *object)
{ {
@ -361,14 +485,10 @@ client_handler (connection_t *con, void *object)
if (Netchan_Process (&cl->netchan)) { if (Netchan_Process (&cl->netchan)) {
// this is a valid, sequenced packet, so process it // this is a valid, sequenced packet, so process it
//svs.stats.packets++; //svs.stats.packets++;
//cl->send_message = true; cl->send_message = true;
//if (cl->state != cs_zombie) //if (cl->state != cs_zombie)
client_parse_message (cl); client_parse_message (cl);
if (cl->backbuf.num_backbuf) cl_send_messages (cl);
MSG_Reliable_Send (&cl->backbuf);
Netchan_Transmit (&cl->netchan, cl->datagram.cursize,
cl->datagram.data);
SZ_Clear (&cl->datagram);
if (cl->drop) { if (cl->drop) {
Connection_Del (cl->con); Connection_Del (cl->con);
Info_Destroy (cl->userinfo); Info_Destroy (cl->userinfo);
@ -424,6 +544,8 @@ client_connect (connection_t *con, void *object)
cl = calloc (1, sizeof (client_t)); cl = calloc (1, sizeof (client_t));
Netchan_Setup (&cl->netchan, con->address, qport, NC_READ_QPORT); Netchan_Setup (&cl->netchan, con->address, qport, NC_READ_QPORT);
cl->clnext = clients;
clients = cl;
cl->backbuf.netchan = &cl->netchan; cl->backbuf.netchan = &cl->netchan;
cl->backbuf.name = "FIXME"; cl->backbuf.name = "FIXME";
cl->userinfo = userinfo; cl->userinfo = userinfo;
@ -479,3 +601,44 @@ Client_Init (void)
for (i = 0; i < sizeof (ucmds) / sizeof (ucmds[0]); i++) for (i = 0; i < sizeof (ucmds) / sizeof (ucmds[0]); i++)
Hash_Add (ucmd_table, &ucmds[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);
}
}
}

View file

@ -394,6 +394,7 @@ main (int argc, const char *argv[])
Con_ProcessInput (); Con_ProcessInput ();
Server_Frame (); Server_Frame ();
Client_Frame ();
} }
return 0; return 0;
} }

View file

@ -76,6 +76,8 @@ server_free (void *_sv, void *unused)
{ {
server_t *sv = (server_t *) _sv; server_t *sv = (server_t *) _sv;
server_t **s; server_t **s;
int i;
client_t *cl;
static byte final[] = {qtv_stringcmd, 'd', 'r', 'o', 'p', 0}; static byte final[] = {qtv_stringcmd, 'd', 'r', 'o', 'p', 0};
@ -96,6 +98,16 @@ server_free (void *_sv, void *unused)
break; 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); free (sv);
} }
@ -516,13 +528,36 @@ Server_Connect (const char *name, struct client_s *client)
if (sv->clients) if (sv->clients)
sv->clients->prev = &client->next; sv->clients->prev = &client->next;
sv->clients = client; sv->clients = client;
Client_New (client);
} }
void void
Server_Disconnect (struct client_s *client) Server_Disconnect (struct client_s *client)
{ {
client->server = 0; client->server = 0;
client->connected = 0;
if (client->next) if (client->next)
client->next->prev = client->prev; client->next->prev = client->prev;
*client->prev = client->next; *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);
}
}
}

View file

@ -63,27 +63,6 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "qtv.h" #include "qtv.h"
#include "server.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 static void
sv_serverdata (server_t *sv, qmsg_t *msg) sv_serverdata (server_t *sv, qmsg_t *msg)
{ {
@ -150,7 +129,7 @@ sv_soundlist (server_t *sv, qmsg_t *msg)
MSG_ReadByte (msg); MSG_ReadByte (msg);
return; return;
} }
// save sound name sv->soundlist[numsounds - 1] = strdup (str);
} }
n = MSG_ReadByte (msg); n = MSG_ReadByte (msg);
if (n) { if (n) {
@ -178,13 +157,13 @@ sv_modellist (server_t *sv, qmsg_t *msg)
break; break;
//qtv_printf ("%s\n", str); //qtv_printf ("%s\n", str);
nummodels++; nummodels++;
if (nummodels == MAX_SOUNDS) { if (nummodels == MAX_MODELS) {
while (str[0]) while (str[0])
str = MSG_ReadString (msg); str = MSG_ReadString (msg);
MSG_ReadByte (msg); MSG_ReadByte (msg);
return; return;
} }
// save sound name sv->modellist[nummodels - 1] = strdup (str);
} }
n = MSG_ReadByte (msg); n = MSG_ReadByte (msg);
if (n) { if (n) {
@ -616,7 +595,11 @@ sv_sound (server_t *sv, qmsg_t *msg, int stop)
// XXX // XXX
int c; int c;
vec3_t v; vec3_t v;
byte *data;
int len;
len = msg->readcount - 1;
data = msg->message->data + len;
if (stop) { if (stop) {
MSG_ReadShort (msg); MSG_ReadShort (msg);
} else { } else {
@ -628,6 +611,8 @@ sv_sound (server_t *sv, qmsg_t *msg, int stop)
MSG_ReadByte (msg); MSG_ReadByte (msg);
MSG_ReadCoordV (msg, v); MSG_ReadCoordV (msg, v);
} }
len = msg->readcount - len;
Server_Broadcast (sv, 0, data, len);
} }
static void static void
@ -710,6 +695,11 @@ sv_temp_entity (server_t *sv, qmsg_t *msg)
{ {
vec3_t pos; vec3_t pos;
int type; int type;
byte *data;
int len;
len = msg->readcount - 1;
data = msg->message->data + len;
type = MSG_ReadByte (msg); type = MSG_ReadByte (msg);
switch (type) { switch (type) {
@ -760,6 +750,8 @@ sv_temp_entity (server_t *sv, qmsg_t *msg)
MSG_ReadCoordV (msg, pos); MSG_ReadCoordV (msg, pos);
break; break;
} }
len = msg->readcount - len;
Server_Broadcast (sv, 0, data, len);
} }
static void static void
@ -787,7 +779,7 @@ sv_print (server_t *sv, qmsg_t *msg)
MSG_ReadByte (msg); MSG_ReadByte (msg);
qtv_printf ("%s", MSG_ReadString (msg)); qtv_printf ("%s", MSG_ReadString (msg));
len = msg->readcount - len; len = msg->readcount - len;
sv_broadcast (sv, 1, data, len); Server_Broadcast (sv, 1, data, len);
} }
void void