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:
parent
2d86a6140b
commit
6173ed0ebc
6 changed files with 115 additions and 47 deletions
|
@ -27,6 +27,8 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
#include "qtv.h"
|
||||
|
||||
#include <string.h> /* XoXus: needed for memset call */
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
18
fteqtv/qtv.h
18
fteqtv/qtv.h
|
@ -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);
|
||||
|
||||
|
|
63
fteqtv/qw.c
63
fteqtv/qw.c
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue