Now connects nicly to regular qw servers.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1982 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-02-21 23:25:54 +00:00
parent 2d86a6140b
commit 6173ed0ebc
6 changed files with 115 additions and 47 deletions

View file

@ -27,6 +27,8 @@
$Id$
*/
#include "qtv.h"
#include <string.h> /* XoXus: needed for memset call */

View file

@ -347,6 +347,12 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
SendClientCommand(tv, "%s", text+4);
return; //commands the game server asked for are pointless.
}
else if (!strncmp(text, "reconnect", 9))
{
if (tv->usequkeworldprotocols)
SendClientCommand(tv, "new\n");
return;
}
Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, to, mask);
}
@ -1036,7 +1042,7 @@ void ParseLightstyle(sv_t *tv, netmsg_t *m)
Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, dem_read, (unsigned)-1);
}
void ParseNails2(sv_t *tv, netmsg_t *m)
void ParseNails(sv_t *tv, netmsg_t *m, qboolean nails2)
{
int count;
int nailnum;
@ -1045,7 +1051,10 @@ void ParseNails2(sv_t *tv, netmsg_t *m)
count = (unsigned char)ReadByte(m);
while(count-- > 0)
{
nailnum = ReadByte(m);
if (nails2)
nailnum = ReadByte(m);
else
nailnum = count;
for (i = 0; i < 6; i++)
bits[i] = ReadByte(m);
}
@ -1148,7 +1157,11 @@ void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask)
ParseTempEntity(tv, &buf, to, mask);
break;
//#define svc_setpause 24 // [qbyte] on / off
case svc_setpause: // [qbyte] on / off
tv->ispaused = ReadByte(&buf);
Multicast(tv, buf.data+buf.startpos, buf.readpos - buf.startpos, dem_read, (unsigned)-1);
break;
//#define svc_signonnum 25 // [qbyte] used for the signon sequence
case svc_centerprint:
@ -1206,7 +1219,9 @@ void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask)
ParsePlayerInfo(tv, &buf, clearoldplayers);
clearoldplayers = false;
break;
//#define svc_nails 43 // [qbyte] num [48 bits] xyzpy 12 12 12 4 8
case svc_nails:
ParseNails(tv, &buf, false);
break;
case svc_chokecount:
ReadByte(&buf);
break;
@ -1271,7 +1286,7 @@ break;
ParsePacketloss(tv, &buf, to, mask);
break;
case svc_nails2:
ParseNails2(tv, &buf);
ParseNails(tv, &buf, true);
break;
default:
buf.readpos = buf.startpos;

View file

@ -48,9 +48,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#pragma warning(disable: 4018) //signed/unsigned mismatch
#endif
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#elif defined(__CYGWIN__)
#include <sys/time.h>
@ -359,7 +356,9 @@ struct sv_s {
unsigned int nextsendpings;
unsigned int trackplayer;
int thisplayer;
unsigned timeout;
unsigned int timeout;
qboolean ispaused;
unsigned int packetratelimiter;
FILE *file;
unsigned int filelength;
@ -374,6 +373,7 @@ struct sv_s {
qboolean parsingconnectiondata; //so reject any new connects for now
unsigned int physicstime; //the last time all the ents moved.
unsigned int simtime;
unsigned int curtime;
unsigned int oldpackettime;
unsigned int nextpackettime;
@ -485,7 +485,7 @@ void ReadString(netmsg_t *b, char *string, int maxlen);
#define svc_spawnbaseline 22
#define svc_temp_entity 23 // variable
//#define svc_setpause 24 // [qbyte] on / off
#define svc_setpause 24 // [qbyte] on / off
//#define svc_signonnum 25 // [qbyte] used for the signon sequence
#define svc_centerprint 26 // [string] to put in center of the screen
@ -518,7 +518,7 @@ void ReadString(netmsg_t *b, char *string, int maxlen);
#define svc_download 41 // [short] size [size bytes]
#define svc_playerinfo 42 // variable
//#define svc_nails 43 // [qbyte] num [48 bits] xyzpy 12 12 12 4 8
#define svc_nails 43 // [qbyte] num [48 bits] xyzpy 12 12 12 4 8
#define svc_chokecount 44 // [qbyte] packets choked
#define svc_modellist 45 // [strings]
#define svc_soundlist 46 // [strings]
@ -635,6 +635,7 @@ int Prespawn(sv_t *qtv, int curmsgsize, netmsg_t *msg, int bufnum);
bsp_t *BSP_LoadModel(cluster_t *cluster, char *gamedir, char *bspname);
void BSP_Free(bsp_t *bsp);
int BSP_LeafNum(bsp_t *bsp, float x, float y, float z);
unsigned int BSP_Checksum(bsp_t *bsp);
int BSP_SphereLeafNums(bsp_t *bsp, int maxleafs, unsigned short *list, float x, float y, float z, float radius);
qboolean BSP_Visible(bsp_t *bsp, int leafcount, unsigned short *list);
void BSP_SetupForPosition(bsp_t *bsp, float x, float y, float z);
@ -645,8 +646,13 @@ char *Info_ValueForKey (char *s, const char *key, char *buffer, int buffersize);
void Info_SetValueForStarKey (char *s, const char *key, const char *value, int maxsize);
void Sys_Printf(cluster_t *cluster, char *fmt, ...);
#ifdef _WIN32
int snprintf(char *buffer, int buffersize, char *format, ...);
int vsnprintf(char *buffer, int buffersize, char *format, va_list argptr);
#endif
qboolean Net_FileProxy(sv_t *qtv, char *filename);
sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, qboolean force, qboolean autoclose);
SOCKET Net_MVDListen(int port);
qboolean Net_StopFileProxy(sv_t *qtv);

View file

@ -26,12 +26,20 @@ int snprintf(char *buffer, int buffersize, char *format, ...)
va_list argptr;
int ret;
va_start (argptr, format);
ret = _vsnprintf (buf, buffersize, format, argptr);
buf[buffersize - 1] = '\0';
ret = _vsnprintf (buffer, buffersize, format, argptr);
buffer[buffersize - 1] = '\0';
va_end (argptr);
return ret;
}
int vsnprintf(char *buffer, int buffersize, char *format, va_list argptr)
{
int ret;
ret = _vsnprintf (buffer, buffersize, format, argptr);
buffer[buffersize - 1] = '\0';
return ret;
}
#endif
const usercmd_t nullcmd;
@ -430,7 +438,7 @@ void QW_SetViewersServer(viewer_t *viewer, sv_t *sv)
viewer->server = sv;
if (viewer->server)
viewer->server->numviewers++;
QW_StuffcmdToViewer(viewer, "cmd new\n");
QW_StuffcmdToViewer(viewer, "reconnect\n");
viewer->servercount++;
viewer->origin[0] = 0;
viewer->origin[1] = 0;
@ -865,7 +873,7 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
BSP_SetupForPosition(tv->bsp, v->origin[0], v->origin[1], v->origin[2]);
lerp = ((tv->curtime - tv->oldpackettime)/1000.0f) / ((tv->nextpackettime - tv->oldpackettime)/1000.0f);
lerp = ((tv->simtime - tv->oldpackettime)/1000.0f) / ((tv->nextpackettime - tv->oldpackettime)/1000.0f);
if (lerp < 0)
lerp = 0;
if (lerp > 1)
@ -1183,9 +1191,21 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message)
*v->expectcommand = '\0';
return;
}
if (!strncmp(message, ".qw ", 4))
if (!strncmp(message, ".help", 5))
{
message += 4;
QW_PrintfToViewer(v, "Website: http://www.fteqw.com/\n"
"Commands:\n"
".qw qwserver:port\n"
".qtv tcpserver:port\n"
".demo gamedir/demoname.mvd\n"
".disconnect\n");
}
else if (!strncmp(message, ".connect ", 9) || !strncmp(message, ".qw ", 4))
{
if (!strncmp(message, ".qw ", 4))
message += 4;
else
message += 9;
snprintf(buf, sizeof(buf), "udp:%s", message);
qtv = QTV_NewServerConnection(cluster, buf, false, false);
if (qtv)
@ -1196,9 +1216,9 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message)
else
QW_PrintfToViewer(v, "Failed to connect to server \"%s\", connection aborted\n", message);
}
else if (!strncmp(message, ".connect ", 9))
else if (!strncmp(message, ".qtv ", 5))
{
message += 9;
message += 5;
snprintf(buf, sizeof(buf), "tcp:%s", message);
qtv = QTV_NewServerConnection(cluster, buf, false, true);
if (qtv)
@ -1227,6 +1247,10 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message)
QW_SetViewersServer(v, NULL);
QW_PrintfToViewer(v, "Connected\n", message);
}
else if (!strncmp(message, ".admin", 11))
{
QW_StuffcmdToViewer(v, "cmd admin\n");
}
else
{
if (cluster->notalking)
@ -1261,16 +1285,9 @@ void QW_PrintfToViewer(viewer_t *v, char *format, ...)
{
va_list argptr;
char buf[1024];
netmsg_t msg;
InitNetMsg(&msg, buf, sizeof(buf));
va_start (argptr, format);
#ifdef _WIN32
_vsnprintf (buf+2, sizeof(buf) - 3, format, argptr);
buf[sizeof(buf) - 3] = '\0';
#else
vsnprintf (buf+2, sizeof(buf)-2, format, argptr);
#endif // _WIN32
va_end (argptr);
buf[0] = svc_print;
@ -1284,20 +1301,13 @@ void QW_StuffcmdToViewer(viewer_t *v, char *format, ...)
{
va_list argptr;
char buf[1024];
netmsg_t msg;
InitNetMsg(&msg, buf, sizeof(buf));
va_start (argptr, format);
#ifdef _WIN32
_vsnprintf (buf+1, sizeof(buf) - 2, format, argptr);
buf[sizeof(buf) - 2] = '\0';
#else
vsnprintf (buf+1, sizeof(buf)-1, format, argptr);
#endif // _WIN32
va_end (argptr);
buf[0] = svc_stufftext;
printf("\"%s\"", buf);
SendBufferToViewer(v, buf, strlen(buf)+1, true);
}
@ -1428,7 +1438,14 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
if (atoi(buf+6) != v->servercount)
SendServerData(qtv, v); //this is unfortunate!
else
{
v->thinksitsconnected = true;
if (v->server && v->server->ispaused)
{
char msgb[] = {svc_setpause, 1};
SendBufferToViewer(v, msgb, sizeof(msgb), true);
}
}
}
else if (!strncmp(buf, "download", 8))
{

View file

@ -173,7 +173,6 @@ void Info_SetValueForStarKey (char *s, const char *key, const char *value, int m
return;
snprintf (newv, sizeof(newv)-1, "\\%s\\%s", key, value);
newv[sizeof(newv)-1] = '\0';
if ((int)(strlen(newv) + strlen(s) + 1) > maxsize)
{
@ -339,7 +338,7 @@ char *Cluster_Rcon_Dispatch(cluster_t *cluster, char *arg[MAX_ARGS], char *buffe
strncpy(cluster->password, arg[1], sizeof(cluster->password)-1);
return "Password changed.\n";
}
else if (!strcmp(arg[0], "connect") || !strcmp(arg[0], "addserver"))
else if (!strcmp(arg[0], "qtv") || !strcmp(arg[0], "connect") || !strcmp(arg[0], "addserver"))
{
if (!*arg[1])
return "connect requires an ip:port parameter\n";

View file

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define UDPRECONNECT_TIME (1000)
#define PINGSINTERVAL_TIME (1000*5)
#define UDPTIMEOUT_LENGTH (1000*20)
#define UDPPACKETINTERVAL (1000/72)
qboolean NET_StringToAddr (char *s, netadr_t *sadr)
@ -1309,7 +1310,7 @@ void QTV_ParseQWStream(sv_t *qtv)
if (buffer[4] == 'c')
{ //got a challenge
qtv->challenge = atoi(buffer+5);
sprintf(buffer, "connect %i %i %i \"%s\"", 28, qtv->qport, qtv->challenge, "\\*ver\\fteqtv\\name\\fteqtv\\spectator\\1");
sprintf(buffer, "connect %i %i %i \"%s\"", 28, qtv->qport, qtv->challenge, "\\*ver\\fteqtv\\name\\fteqtv\\spectator\\1\\rate\\10000");
Netchan_OutOfBand(qtv->cluster, qtv->sourcesock, qtv->serveraddress, strlen(buffer), buffer);
continue;
}
@ -1341,6 +1342,13 @@ void QTV_ParseQWStream(sv_t *qtv)
if (!Netchan_Process(&qtv->netchan, &msg))
continue;
ParseMessage(qtv, msg.data + msg.readpos, msg.cursize - msg.readpos, dem_all, -1);
qtv->oldpackettime = qtv->nextpackettime;
qtv->nextpackettime = qtv->parsetime;
qtv->parsetime = qtv->curtime;
if (qtv->simtime < qtv->oldpackettime)
qtv->simtime = qtv->oldpackettime; //too old
}
}
@ -1386,6 +1394,11 @@ void QTV_Run(sv_t *qtv)
if (qtv->usequkeworldprotocols)
{
qtv->simtime += qtv->curtime - oldcurtime;
if (qtv->simtime > qtv->nextpackettime)
qtv->simtime = qtv->nextpackettime; //too old
if (!qtv->isconnected && (qtv->curtime >= qtv->nextconnectattempt || qtv->curtime < qtv->nextconnectattempt - UDPRECONNECT_TIME*2))
{
Netchan_OutOfBand(qtv->cluster, qtv->sourcesock, qtv->serveraddress, 12, "getchallenge");
@ -1408,17 +1421,24 @@ void QTV_Run(sv_t *qtv)
return;
}
if (qtv->curtime >= qtv->nextsendpings || qtv->curtime < qtv->nextsendpings - PINGSINTERVAL_TIME*2)
if (qtv->curtime < qtv->packetratelimiter - UDPPACKETINTERVAL*2)
qtv->packetratelimiter = qtv->curtime;
if (qtv->curtime >= qtv->packetratelimiter)
{
qtv->nextsendpings = qtv->curtime + PINGSINTERVAL_TIME;
SendClientCommand(qtv, "pings\n");
}
WriteByte(&msg, clc_tmove);
WriteShort(&msg, qtv->players[qtv->trackplayer].current.origin[0]);
WriteShort(&msg, qtv->players[qtv->trackplayer].current.origin[1]);
WriteShort(&msg, qtv->players[qtv->trackplayer].current.origin[2]);
qtv->packetratelimiter += UDPPACKETINTERVAL;
Netchan_Transmit(qtv->cluster, &qtv->netchan, msg.cursize, msg.data);
if (qtv->curtime >= qtv->nextsendpings || qtv->curtime < qtv->nextsendpings - PINGSINTERVAL_TIME*2)
{
qtv->nextsendpings = qtv->curtime + PINGSINTERVAL_TIME;
SendClientCommand(qtv, "pings\n");
}
WriteByte(&msg, clc_tmove);
WriteShort(&msg, qtv->players[qtv->trackplayer].current.origin[0]);
WriteShort(&msg, qtv->players[qtv->trackplayer].current.origin[1]);
WriteShort(&msg, qtv->players[qtv->trackplayer].current.origin[2]);
Netchan_Transmit(qtv->cluster, &qtv->netchan, msg.cursize, msg.data);
}
}
return;
}
@ -1782,7 +1802,16 @@ int main(int argc, char **argv)
Sys_Printf(&cluster, "opened port %i\n", cluster.qwlistenportnum);
}
Sys_Printf(&cluster, "\nWelcome to FTEQTV\nPlease type \nconnect server:ip\nto connect to a server.\n\n");
Sys_Printf(&cluster, "\n"
"Welcome to FTEQTV\n"
"Please type\n"
"qtv server:port\n"
" to connect to a tcp server.\n"
"qw server:port\n"
" to connect to a regular qw server.\n"
"demo qw/example.mvd\n"
" to play a demo from an mvd.\n"
"\n");
}
while (!cluster.wanttoexit)