proxy now stays connected :) also gets the server data packet. most changes

due to move of pmove.h
This commit is contained in:
Bill Currie 2005-05-02 04:09:15 +00:00
parent 438073e110
commit cd2f9434fc
25 changed files with 311 additions and 76 deletions

View file

@ -12,7 +12,7 @@ EXTRA_DIST = asm_i386.h alsa_funcs_list.h adivtab.h anorm_dots.h anorms.h \
r_local.h r_screen.h r_shared.h rua_internal.h sbar.h skin_stencil.h \
snd_render.h varrays.h vgamodes.h view.h vregset.h winquake.h world.h \
\
qw/msg_backbuf.h qw/msg_ucmd.h qw/protocol.h \
qw/msg_backbuf.h qw/msg_ucmd.h qw/pmove.h qw/protocol.h \
\
win32/fnmatch.h \
\

View file

@ -131,6 +131,16 @@
#define clc_tmove 6 // teleport request, spectator only
#define clc_upload 7 // teleport request, spectator only
// qtv ========================================================================
#define qtv_bad 0
#define qtv_nop 1
#define qtv_stringcmd 2 // [string] message
#define qtv_delta 3 // [byte] sequence number, requests delta
// compression of message
#define qtv_serverdata 4
#define qtv_disconnect 5
// demo recording
#define dem_cmd 0

View file

@ -523,10 +523,10 @@ Sys_CheckInput (int idle, int net_socket)
}
_timeout.tv_sec = 0;
_timeout.tv_usec = net_socket < 0 ? 0 : 100;
_timeout.tv_usec = net_socket < 0 ? 0 : 20;
#else
_timeout.tv_sec = 0;
_timeout.tv_usec = net_socket < 0 ? 0 : 10000;
_timeout.tv_usec = net_socket < 0 ? 0 : 2000;
#endif
// select on the net socket and stdin
// the only reason we have a timeout at all is so that if the last

View file

@ -33,18 +33,30 @@
#define __server_h
#include "netchan.h"
#include "qw/pmove.h"
typedef struct server_s {
struct server_s *next;
const char *name;
const char *address;
int qport;
int connected;
struct info_s *info;
struct connection_s *con;
netadr_t adr;
netchan_t netchan;
double next_run;
int ver;
int spawncount;
const char *gamedir;
const char *message;
movevars_t movevars;
int cdtrack;
int sounds;
struct info_s *info;
} server_t;
void Server_Init (void);
void Server_Frame (void);
#endif//__server_h

View file

@ -388,6 +388,8 @@ main (int argc, const char *argv[])
qtv_read_packets ();
Con_ProcessInput ();
Server_Frame ();
}
return 0;
}

View file

@ -61,7 +61,8 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "qtv.h"
#include "server.h"
static hashtab_t *servers;
static hashtab_t *server_hash;
static server_t *servers;
static const char *
server_get_key (void *sv, void *unused)
@ -73,11 +74,20 @@ static void
server_free (void *_sv, void *unused)
{
server_t *sv = (server_t *) _sv;
static byte final[] = {clc_stringcmd, 'd', 'r', 'o', 'p', 0};
server_t **s;
static byte final[] = {qtv_stringcmd, 'd', 'r', 'o', 'p', 0};
if (sv->connected)
Netchan_Transmit (&sv->netchan, sizeof (final), final);
Connection_Del (sv->con);
for (s = &servers; *s; s = &(*s)->next) {
if (*s == sv) {
*s = sv->next;
break;
}
}
}
static int
@ -86,11 +96,51 @@ server_compare (const void *a, const void *b)
return strcmp ((*(server_t **) a)->name, (*(server_t **) b)->name);
}
static void
qtv_server_data (server_t *sv)
{
const char *str;
sv->ver = MSG_ReadLong (net_message);
sv->spawncount = MSG_ReadLong (net_message);
sv->gamedir = strdup (MSG_ReadString (net_message));
sv->message = strdup (MSG_ReadString (net_message));
sv->movevars.gravity = MSG_ReadFloat (net_message);
sv->movevars.stopspeed = MSG_ReadFloat (net_message);
sv->movevars.maxspeed = MSG_ReadFloat (net_message);
sv->movevars.spectatormaxspeed = MSG_ReadFloat (net_message);
sv->movevars.accelerate = MSG_ReadFloat (net_message);
sv->movevars.airaccelerate = MSG_ReadFloat (net_message);
sv->movevars.wateraccelerate = MSG_ReadFloat (net_message);
sv->movevars.friction = MSG_ReadFloat (net_message);
sv->movevars.waterfriction = MSG_ReadFloat (net_message);
sv->movevars.entgravity = MSG_ReadFloat (net_message);
sv->cdtrack = MSG_ReadByte (net_message);
sv->sounds = MSG_ReadByte (net_message);
COM_TokenizeString (MSG_ReadString (net_message), qtv_args);
cmd_args = qtv_args;
sv->info = Info_ParseString (Cmd_Argv (1), MAX_SERVERINFO_STRING, 0);
str = Info_ValueForKey (sv->info, "hostname");
if (strcmp (str, "unnamed"))
qtv_printf ("%s: %s\n", sv->name, str);
str = Info_ValueForKey (sv->info, "*version");
qtv_printf ("%s: QW %s\n", sv->name, str);
str = Info_ValueForKey (sv->info, "*qf_version");
if (str[0])
qtv_printf ("%s: QuakeForge %s\n", sv->name, str);
qtv_printf ("%s: gamedir: %s\n", sv->name, sv->gamedir);
str = Info_ValueForKey (sv->info, "map");
qtv_printf ("%s: (%s) %s\n", sv->name, str, sv->message);
}
static void
server_handler (connection_t *con, void *object)
{
server_t *sv = (server_t *) object;
byte d = clc_nop;
if (*(int *) net_message->message->data == -1)
return;
@ -110,13 +160,16 @@ server_handler (connection_t *con, void *object)
default:
qtv_printf ("Illegible server message: %d\n", cmd);
goto bail;
case svc_disconnect:
case qtv_disconnect:
qtv_printf ("%s: disconnected\n", sv->name);
break;
case qtv_serverdata:
qtv_server_data (sv);
break;
}
}
bail:
Netchan_Transmit (&sv->netchan, 1, &d);
return;
}
static inline const char *
@ -157,10 +210,12 @@ server_connect (connection_t *con, void *object)
Netchan_Setup (&sv->netchan, con->address, sv->qport, NC_SEND_QPORT);
sv->netchan.outgoing_sequence = 1;
sv->connected = 1;
MSG_WriteByte (msg, clc_stringcmd);
MSG_WriteByte (msg, qtv_stringcmd);
MSG_WriteString (msg, "new");
Netchan_Transmit (&sv->netchan, 0, 0);
con->handler = server_handler;
sv->next_run = realtime;
}
static void
@ -192,8 +247,8 @@ server_challenge (connection_t *con, void *object)
if (!qtv) {
qtv_printf ("%s can't handle qtv.\n", sv->name);
Hash_Del (servers, sv->name);
Hash_Free (servers, sv);
Hash_Del (server_hash, sv->name);
Hash_Free (server_hash, sv);
return;
}
@ -228,7 +283,7 @@ sv_new_f (void)
return;
}
name = Cmd_Argv (1);
if (Hash_Find (servers, name)) {
if (Hash_Find (server_hash, name)) {
qtv_printf ("sv_new: %s already exists\n", name);
return;
}
@ -241,6 +296,8 @@ sv_new_f (void)
adr.port = BigShort (27500);
sv = calloc (1, sizeof (server_t));
sv->next = servers;
servers = sv;
sv->name = strdup (name);
sv->address = strdup (address);
sv->adr = adr;
@ -250,7 +307,7 @@ sv_new_f (void)
va ("%s QTV %s", QW_VERSION, VERSION), 0);
Info_SetValueForStarKey (sv->info, "*qsg_version", QW_QSG_VERSION, 0);
Info_SetValueForKey (sv->info, "name", "QTV Proxy", 0);
Hash_Add (servers, sv);
Hash_Add (server_hash, sv);
sv->con = Connection_Add (&adr, sv, server_challenge);
@ -268,11 +325,11 @@ sv_del_f (void)
return;
}
name = Cmd_Argv (1);
if (!(sv = Hash_Del (servers, name))) {
if (!(sv = Hash_Del (server_hash, name))) {
qtv_printf ("sv_new: %s unkown\n", name);
return;
}
Hash_Free (servers, sv);
Hash_Free (server_hash, sv);
}
static void
@ -281,33 +338,57 @@ sv_list_f (void)
server_t **list, **l, *sv;
int count;
list = (server_t **) Hash_GetList (servers);
for (l = list, count = 0; *l; l++)
for (l = &servers, count = 0; *l; l = &(*l)->next)
count++;
if (!count) {
qtv_printf ("no servers\n");
return;
}
list = malloc (count * sizeof (server_t **));
for (l = &servers, count = 0; *l; l = &(*l)->next)
list[count] = *l;
qsort (list, count, sizeof (*list), server_compare);
for (l = list; *l; l++) {
sv = *l;
qtv_printf ("%-20s %s(%s)\n", sv->name, sv->address,
NET_AdrToString (sv->adr));
}
free (list);
}
static void
server_shutdown (void)
{
Hash_FlushTable (servers);
Hash_FlushTable (server_hash);
}
static void
server_run (server_t *sv)
{
static byte msg[] = {qtv_nop};
Netchan_Transmit (&sv->netchan, sizeof (msg), msg);
sv->next_run = realtime + 0.03;
}
void
Server_Init (void)
{
Sys_RegisterShutdown (server_shutdown);
servers = Hash_NewTable (61, server_get_key, server_free, 0);
server_hash = Hash_NewTable (61, server_get_key, server_free, 0);
Cmd_AddCommand ("sv_new", sv_new_f, "Add a new server");
Cmd_AddCommand ("sv_del", sv_del_f, "Remove an existing server");
Cmd_AddCommand ("sv_list", sv_list_f, "List available servers");
}
void
Server_Frame (void)
{
server_t *sv;
for (sv = servers; sv; sv = sv->next) {
if (sv->next_run && sv->next_run <= realtime) {
sv->next_run = 0;
server_run (sv);
}
}
}

View file

@ -4,6 +4,5 @@ AUTOMAKE_OPTIONS= foreign
EXTRA_DIST = \
bothdefs.h cl_cam.h cl_chat.h cl_demo.h cl_ents.h cl_input.h \
cl_main.h cl_parse.h cl_pred.h cl_skin.h cl_slist.h cl_tent.h \
client.h crudefile.h game.h host.h pmove.h \
server.h sv_gib.h sv_demo.h sv_pr_cmds.h sv_pr_qwe.h sv_progs.h \
sv_qtv.h
client.h crudefile.h game.h host.h server.h sv_gib.h sv_demo.h \
sv_pr_cmds.h sv_pr_qwe.h sv_progs.h sv_qtv.h

View file

@ -548,6 +548,7 @@ void SV_FindModelNumbers (void);
#define UCMD_NO_REDIRECT 1
#define UCMD_OVERRIDABLE 2
void SV_WriteWorldVars (netchan_t *netchan);
void SV_ExecuteClientMessage (client_t *cl);
void SV_UserInit (void);
void SV_TogglePause (const char *msg);

View file

@ -36,5 +36,6 @@ struct info_s;
void SV_qtvConnect (int qport, struct info_s *info);
int SV_qtvPacket (int qport);
void SV_qtvCheckTimeouts (void);
void SV_qtvSendMessages (void);
#endif//__sv_qtv_h

View file

@ -53,7 +53,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "cl_input.h"
#include "client.h"
#include "compat.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "sbar.h"
#define PM_SPECTATORMAXSPEED 500

View file

@ -60,7 +60,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "client.h"
#include "compat.h"
#include "host.h"
#include "pmove.h"
#include "qw/pmove.h"
typedef struct {
int frames;

View file

@ -57,7 +57,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "compat.h"
#include "d_iface.h"
#include "host.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "r_cvar.h"
#include "r_dynamic.h"
#include "view.h"

View file

@ -103,7 +103,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "game.h"
#include "host.h"
#include "netchan.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "r_cvar.h"
#include "r_dynamic.h"
#include "sbar.h"

View file

@ -73,7 +73,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "client.h"
#include "compat.h"
#include "host.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "qw/protocol.h"
#include "sbar.h"
#include "view.h"

View file

@ -42,7 +42,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "cl_ents.h"
#include "cl_pred.h"
#include "client.h"
#include "pmove.h"
#include "qw/pmove.h"
cvar_t *cl_predict;
cvar_t *cl_pushlatency;

View file

@ -45,7 +45,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "client.h"
#include "compat.h"
#include "host.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "view.h"
/*

View file

@ -39,7 +39,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "client.h"
#include "compat.h"
#include "pmove.h"
#include "qw/pmove.h"
cvar_t *no_pogo_stick;
movevars_t movevars;

View file

@ -44,7 +44,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/sys.h"
#include "compat.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "world.h"
static hull_t box_hull;

View file

@ -48,7 +48,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/va.h"
#include "compat.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "server.h"
#include "sv_demo.h"
#include "sv_progs.h"

View file

@ -48,7 +48,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "compat.h"
#include "crudefile.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "server.h"
#include "sv_progs.h"
#include "sv_gib.h"

View file

@ -85,7 +85,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "crudefile.h"
#include "game.h"
#include "netchan.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "server.h"
#include "sv_demo.h"
#include "sv_progs.h"
@ -1983,6 +1983,8 @@ SV_Frame (float time)
// send messages back to the clients that had packets read this frame
SV_SendClientMessages ();
SV_qtvSendMessages ();
demo_start = Sys_DoubleTime ();
if (sv.recorders)
SV_SendDemoMessage ();

View file

@ -35,7 +35,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/cvar.h"
#include "QF/sys.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "server.h"
#include "sv_progs.h"
#include "world.h"

View file

@ -34,10 +34,21 @@
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/cmd.h"
#include "QF/cbuf.h"
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/idparse.h"
#include "QF/info.h"
#include "compat.h"
#include "server.h"
#include "sv_qtv.h"
@ -46,6 +57,7 @@ typedef struct {
backbuf_t backbuf;
info_t *info;
info_key_t *name_key;
int packet;
} sv_qtv_t;
#define MAX_PROXIES 2
@ -64,6 +76,102 @@ alloc_proxy (void)
return 0;
}
static void
drop_proxy (sv_qtv_t *proxy)
{
SV_Printf ("dropped %s\n", proxy->name_key->value);
MSG_WriteByte (&proxy->netchan.message, qtv_disconnect);
Netchan_Transmit (&proxy->netchan, 0, 0);
proxy->packet = 0;
Info_Destroy (proxy->info);
proxy->info = 0;
}
static void
qtv_new_f (sv_qtv_t *proxy)
{
const char *gamedir;
gamedir = Info_ValueForKey (svs.info, "*gamedir");
if (!gamedir[0])
gamedir = "qw";
MSG_WriteByte (&proxy->netchan.message, qtv_serverdata);
MSG_WriteLong (&proxy->netchan.message, PROTOCOL_VERSION);
MSG_WriteLong (&proxy->netchan.message, svs.spawncount);
MSG_WriteString (&proxy->netchan.message, gamedir);
SV_WriteWorldVars (&proxy->netchan);
}
typedef struct {
const char *name;
void (*func) (sv_qtv_t *proxy);
unsigned no_redirect:1;
} qcmd_t;
qcmd_t qcmds[] = {
{"drop", drop_proxy},
{"new", qtv_new_f},
{0, 0},
};
static void
qtv_command (sv_qtv_t *proxy, const char *s)
{
qcmd_t *c;
const char *name;
COM_TokenizeString (s, sv_args);
cmd_args = sv_args;
name = Cmd_Argv (0);
for (c = qcmds; c->name; c++)
if (strcmp (c->name, name) == 0)
break;
if (!c->name) {
SV_Printf ("Bad QTV command: %s\n", sv_args->argv[0]->str);
return;
}
c->func (proxy);
}
static void
qtv_parse (sv_qtv_t *proxy)
{
int c;
proxy->packet = 1;
while (1) {
if (net_message->badread) {
SV_Printf ("SV_ReadClientMessage: badread\n");
drop_proxy (proxy);
return;
}
c = MSG_ReadByte (net_message);
if (c == -1)
return;
switch (c) {
default:
SV_Printf ("SV_ReadClientMessage: unknown command char\n");
drop_proxy (proxy);
return;
case qtv_nop:
break;
case qtv_stringcmd:
qtv_command (proxy, MSG_ReadString (net_message));
break;
case qtv_delta:
MSG_ReadByte (net_message);
break;
}
}
}
void
SV_qtvConnect (int qport, info_t *info)
{
@ -104,12 +212,11 @@ SV_qtvPacket (int qport)
Con_DPrintf ("SV_ReadPackets: fixing up a translated port\n");
proxies[i].netchan.remote_address.port = net_from.port;
}
Con_Printf ("boo\n");
if (Netchan_Process (&proxies[i].netchan)) {
// this is a valid, sequenced packet, so process it
svs.stats.packets++;
}
Netchan_Transmit (&proxies[i].netchan, 0, 0);
qtv_parse (&proxies[i]);
return 1;
}
return 0;
@ -129,11 +236,25 @@ SV_qtvCheckTimeouts (void)
if (proxy->info) {
if (proxy->netchan.last_received < droptime) {
SV_Printf ("%s timed out\n", proxy->name_key->value);
MSG_WriteByte (&proxy->netchan.message, svc_disconnect);
Netchan_Transmit (&proxy->netchan, 0, 0);
Info_Destroy (proxy->info);
proxy->info = 0;
drop_proxy (proxy);
}
}
}
}
void
SV_qtvSendMessages (void)
{
int i;
sv_qtv_t *proxy;
for (i = 0; i < MAX_PROXIES; i++) {
proxy = proxies + i;
if (!proxy->info)
continue;
if (!proxy->packet)
continue;
proxy->packet = 0;
Netchan_Transmit (&proxy->netchan, 0, 0);
}
}

View file

@ -60,7 +60,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "bothdefs.h"
#include "compat.h"
#include "pmove.h"
#include "qw/pmove.h"
#include "server.h"
#include "sv_gib.h"
#include "sv_progs.h"
@ -108,25 +108,55 @@ static void OutofBandPrintf (netadr_t where, const char *fmt, ...) __attribute__
Sends the first message from the server to a connected client.
This will be sent on the initial connection and upon each server load.
*/
void
SV_WriteWorldVars (netchan_t *netchan)
{
// send full levelname
MSG_WriteString (&netchan->message,
PR_GetString (&sv_pr_state,
SVstring (sv.edicts, message)));
// send the movevars
MSG_WriteFloat (&netchan->message, movevars.gravity);
MSG_WriteFloat (&netchan->message, movevars.stopspeed);
MSG_WriteFloat (&netchan->message, movevars.maxspeed);
MSG_WriteFloat (&netchan->message, movevars.spectatormaxspeed);
MSG_WriteFloat (&netchan->message, movevars.accelerate);
MSG_WriteFloat (&netchan->message, movevars.airaccelerate);
MSG_WriteFloat (&netchan->message, movevars.wateraccelerate);
MSG_WriteFloat (&netchan->message, movevars.friction);
MSG_WriteFloat (&netchan->message, movevars.waterfriction);
MSG_WriteFloat (&netchan->message, movevars.entgravity);
// send music
MSG_WriteByte (&netchan->message, svc_cdtrack);
MSG_WriteByte (&netchan->message, SVfloat (sv.edicts, sounds));
// send server info string
MSG_WriteByte (&netchan->message, svc_stufftext);
MSG_WriteString (&netchan->message,
va ("fullserverinfo \"%s\"\n",
Info_MakeString (svs.info, 0)));
}
static void
SV_New_f (void *unused)
{
const char *gamedir;
int playernum;
const char *gamedir;
if (host_client->state == cs_spawned)
return;
gamedir = Info_ValueForKey (svs.info, "*gamedir");
if (!gamedir[0])
gamedir = "qw";
host_client->state = cs_connected;
host_client->connection_started = realtime;
// send the info about the new client to all connected clients
// SV_FullClientUpdate (host_client, &sv.reliable_datagram);
// host_client->sendinfo = true;
gamedir = Info_ValueForKey (svs.info, "*gamedir");
if (!gamedir[0])
gamedir = "qw";
// NOTE: This doesn't go through MSG_ReliableWrite since it's before the
// user spawns. These functions are written to not overflow
@ -136,6 +166,7 @@ SV_New_f (void *unused)
host_client->backbuf.num_backbuf = 0;
SZ_Clear (&host_client->netchan.message);
}
// send the serverdata
MSG_WriteByte (&host_client->netchan.message, svc_serverdata);
MSG_WriteLong (&host_client->netchan.message, PROTOCOL_VERSION);
@ -147,32 +178,7 @@ SV_New_f (void *unused)
playernum |= 128;
MSG_WriteByte (&host_client->netchan.message, playernum);
// send full levelname
MSG_WriteString (&host_client->netchan.message,
PR_GetString (&sv_pr_state,
SVstring (sv.edicts, message)));
// send the movevars
MSG_WriteFloat (&host_client->netchan.message, movevars.gravity);
MSG_WriteFloat (&host_client->netchan.message, movevars.stopspeed);
MSG_WriteFloat (&host_client->netchan.message, movevars.maxspeed);
MSG_WriteFloat (&host_client->netchan.message, movevars.spectatormaxspeed);
MSG_WriteFloat (&host_client->netchan.message, movevars.accelerate);
MSG_WriteFloat (&host_client->netchan.message, movevars.airaccelerate);
MSG_WriteFloat (&host_client->netchan.message, movevars.wateraccelerate);
MSG_WriteFloat (&host_client->netchan.message, movevars.friction);
MSG_WriteFloat (&host_client->netchan.message, movevars.waterfriction);
MSG_WriteFloat (&host_client->netchan.message, movevars.entgravity);
// send music
MSG_WriteByte (&host_client->netchan.message, svc_cdtrack);
MSG_WriteByte (&host_client->netchan.message, SVfloat (sv.edicts, sounds));
// send server info string
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
MSG_WriteString (&host_client->netchan.message,
va ("fullserverinfo \"%s\"\n",
Info_MakeString (svs.info, 0)));
SV_WriteWorldVars (&host_client->netchan);
// Trigger GIB connection event
if (sv_client_connect_e->func)