more progress for qtv

This commit is contained in:
Bill Currie 2004-03-05 23:42:15 +00:00
parent cd1fc18ea4
commit a3934f8841
6 changed files with 154 additions and 32 deletions

View file

@ -96,7 +96,26 @@ server_handler (connection_t *con, void *object)
return;
if (!Netchan_Process (&sv->netchan))
return;
Con_Printf ("hi\n");
while (1) {
int cmd;
if (net_message->badread) {
break;
}
cmd = MSG_ReadByte (net_message);
if (cmd == -1) {
net_message->readcount++;
break;
}
switch (cmd) {
default:
qtv_printf ("Illegible server message: %d\n", cmd);
goto bail;
case svc_disconnect:
qtv_printf ("%s: disconnected\n", sv->name);
break;
}
}
bail:
Netchan_Transmit (&sv->netchan, 1, &d);
}
@ -109,16 +128,16 @@ expect_packet (qmsg_t *msg, int type)
MSG_BeginReading (net_message);
seq = MSG_ReadLong (net_message);
if (seq != -1) {
Con_Printf ("unexpected connected packet\n");
qtv_printf ("unexpected connected packet\n");
return 0;
}
str = MSG_ReadString (net_message);
if (str[0] == A2C_PRINT) {
Con_Printf ("%s", str + 1);
qtv_printf ("%s", str + 1);
return 0;
}
if (str[0] != type) {
Con_Printf ("unexpected connectionless packet type: %s\n", str);
qtv_printf ("unexpected connectionless packet type: %s\n", str);
return 0;
}
return str;
@ -134,7 +153,7 @@ server_connect (connection_t *con, void *object)
if (!(str = expect_packet (net_message, S2C_CONNECTION)))
return;
Con_Printf ("connection from %s\n", sv->name);
qtv_printf ("connection from %s\n", sv->name);
Netchan_Setup (&sv->netchan, con->address, sv->qport, NC_SEND_QPORT);
sv->netchan.outgoing_sequence = 1;
sv->connected = 1;
@ -162,17 +181,17 @@ server_challenge (connection_t *con, void *object)
for (i = 1; i < Cmd_Argc (); i++) {
str = Cmd_Argv (i);
if (!strcmp ("QF", str)) {
Con_Printf ("QuakeForge server detected\n");
qtv_printf ("QuakeForge server detected\n");
} else if (!strcmp ("qtv", str)) {
Con_Printf ("QTV capable server\n");
qtv_printf ("QTV capable server\n");
qtv = str;
} else {
Con_Printf ("%s\n", str);
qtv_printf ("%s\n", str);
}
}
if (!qtv) {
Con_Printf ("%s can't handle qtv.\n", sv->name);
qtv_printf ("%s can't handle qtv.\n", sv->name);
Hash_Del (servers, sv->name);
Hash_Free (servers, sv);
return;
@ -205,17 +224,17 @@ sv_new_f (void)
netadr_t adr;
if (Cmd_Argc () != 3) {
Con_Printf ("Usage: sv_new <name> <address>\n");
qtv_printf ("Usage: sv_new <name> <address>\n");
return;
}
name = Cmd_Argv (1);
if (Hash_Find (servers, name)) {
Con_Printf ("sv_new: %s already exists\n", name);
qtv_printf ("sv_new: %s already exists\n", name);
return;
}
address = Cmd_Argv (2);
if (!NET_StringToAdr (address, &adr)) {
Con_Printf ("Bad server address\n");
qtv_printf ("Bad server address\n");
return;
}
if (!adr.port)
@ -245,12 +264,12 @@ sv_del_f (void)
server_t *sv;
if (Cmd_Argc () != 2) {
Con_Printf ("Usage: sv_del <name>\n");
qtv_printf ("Usage: sv_del <name>\n");
return;
}
name = Cmd_Argv (1);
if (!(sv = Hash_Del (servers, name))) {
Con_Printf ("sv_new: %s unkown\n", name);
qtv_printf ("sv_new: %s unkown\n", name);
return;
}
Hash_Free (servers, sv);
@ -266,13 +285,13 @@ sv_list_f (void)
for (l = list, count = 0; *l; l++)
count++;
if (!count) {
Con_Printf ("no servers\n");
qtv_printf ("no servers\n");
return;
}
qsort (list, count, sizeof (*list), server_compare);
for (l = list; *l; l++) {
sv = *l;
Con_Printf ("%-20s %s(%s)\n", sv->name, sv->address,
qtv_printf ("%-20s %s(%s)\n", sv->name, sv->address,
NET_AdrToString (sv->adr));
}
}

View file

@ -398,6 +398,8 @@ extern struct cvar_s *sv_highchars;
extern struct cvar_s *sv_mintic, *sv_maxtic;
extern struct cvar_s *sv_maxspeed;
extern struct cvar_s *timeout;
extern netadr_t master_adr[MAX_MASTERS]; // address of the master server
extern struct cvar_s *spawn;

View file

@ -32,6 +32,9 @@
#ifndef __sv_qtv_h
#define __sv_qtv_h
void SV_qtvConnect (void);
struct info_s;
void SV_qtvConnect (int qport, struct info_s *info);
int SV_qtvPacket (int qport);
void SV_qtvCheckTimeouts (void);
#endif//__sv_qtv_h

View file

@ -1207,7 +1207,7 @@ CL_ParseServerMessage (void)
cmd = MSG_ReadByte (net_message);
if (cmd == -1) {
net_message->readcount++; // so the EOM showner has the right
net_message->readcount++; // so the EOM SHOWNET has the right
// value
SHOWNET ("END OF MESSAGE");
break;

View file

@ -769,7 +769,7 @@ SVC_DirectConnect (void)
info_t *userinfo = 0;
const char *s;
client_t *cl, *newcl;
int challenge, qport, version, i;
int challenge, qport, version, i, qtv = 0;
netadr_t adr;
qboolean spectator;
@ -778,16 +778,15 @@ SVC_DirectConnect (void)
s = Cmd_Argv (1);
if (!strcmp (s, "qtv")) {
SV_qtvConnect ();
return;
}
version = atoi (s);
if (version != PROTOCOL_VERSION) {
Netchan_OutOfBandPrint (net_from, "%c\nServer is version %s.\n",
A2C_PRINT, QW_VERSION);
SV_Printf ("* rejected connect from version %i\n", version);
return;
qtv = 1;
} else {
version = atoi (s);
if (version != PROTOCOL_VERSION) {
Netchan_OutOfBandPrint (net_from, "%c\nServer is version %s.\n",
A2C_PRINT, QW_VERSION);
SV_Printf ("* rejected connect from version %i\n", version);
return;
}
}
qport = atoi (Cmd_Argv (2));
@ -821,6 +820,11 @@ SVC_DirectConnect (void)
return;
}
if (qtv) {
SV_qtvConnect (qport, userinfo);
return;
}
s = Info_ValueForKey (userinfo, "*qf_version");
if ((!s[0]) || sv_minqfversion->string[0]) { // kick old clients?
if (ver_compare (s, sv_minqfversion->string) < 0) {
@ -1803,6 +1807,9 @@ SV_ReadPackets (void)
if (i != MAX_CLIENTS)
continue;
if (SV_qtvPacket (qport))
continue;
// packet is not from a known client
// SV_Printf ("%s:sequenced packet without connection\n",
// NET_AdrToString (net_from));
@ -1846,6 +1853,7 @@ SV_CheckTimeouts (void)
svs.num_clients--;
}
}
SV_qtvCheckTimeouts ();
if (sv.paused && !nclients) {
// nobody left, unpause the server
SV_TogglePause ("Pause released since no players are left.\n");

View file

@ -35,15 +35,105 @@ static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include "QF/cmd.h"
#include "QF/hash.h"
#include "QF/info.h"
#include "server.h"
#include "sv_qtv.h"
typedef struct {
netchan_t netchan;
backbuf_t backbuf;
info_t *info;
info_key_t *name_key;
} sv_qtv_t;
void
SV_qtvConnect (void)
#define MAX_PROXIES 2
static sv_qtv_t proxies[MAX_PROXIES];
static sv_qtv_t *
alloc_proxy (void)
{
SV_Printf ("QTV proxy connection: %d %s\n", Cmd_Argc (), Cmd_Args (1));
int i;
for (i = 0; i < MAX_PROXIES; i++) {
if (!proxies[i].info)
return proxies;
}
return 0;
}
void
SV_qtvConnect (int qport, info_t *info)
{
sv_qtv_t *proxy;
SV_Printf ("QTV proxy connection: %d %s\n", Cmd_Argc (), Cmd_Args (1));
SV_Printf ("qport: %d\n", qport);
if (!(proxy = alloc_proxy ())) {
SV_Printf ("%s:full proxy connect\n", NET_AdrToString (net_from));
Netchan_OutOfBandPrint (net_from, "%c\nserver is full\n\n", A2C_PRINT);
return;
}
proxy->info = info;
while (!(proxy->name_key = Hash_Find (proxy->info->tab, "name")))
Info_SetValueForKey (proxy->info, "name", "\"unnamed proxy\"", 1);
Netchan_Setup (&proxy->netchan, net_from, qport, NC_READ_QPORT);
proxy->backbuf.netchan = &proxy->netchan;
proxy->backbuf.name = proxy->name_key->value;
Netchan_OutOfBandPrint (net_from, "%c", S2C_CONNECTION);
}
int
SV_qtvPacket (int qport)
{
int i;
for (i = 0; i < MAX_PROXIES; i++) {
if (!proxies[i].info)
continue;
if (!NET_CompareBaseAdr (net_from, proxies[i].netchan.remote_address))
continue;
if (proxies[i].netchan.qport != qport)
continue;
if (proxies[i].netchan.remote_address.port != net_from.port) {
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);
return 1;
}
return 0;
}
void
SV_qtvCheckTimeouts (void)
{
int i;
float droptime;
sv_qtv_t *proxy;
droptime = realtime - timeout->value;
for (i = 0; i < MAX_PROXIES; i++) {
proxy = proxies + i;
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;
}
}
}
}