mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 14:20:59 +00:00
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:
parent
d16cf69017
commit
4a425a1b1a
6 changed files with 234 additions and 31 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,6 +394,7 @@ main (int argc, const char *argv[])
|
|||
Con_ProcessInput ();
|
||||
|
||||
Server_Frame ();
|
||||
Client_Frame ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue