1
0
Fork 0
forked from fte/fteqw

some bugs have been spotted. one serious one regarding demos and small downloads and reading configs. a couple of minor ones, and a minor cleanup too.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2464 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2007-01-09 05:24:03 +00:00
parent 4262948c3e
commit f321ee32ee
6 changed files with 314 additions and 192 deletions

View file

@ -825,6 +825,7 @@ void SV_GenerateQTVDemoListing(cluster_t *cluster, oproxy_t *dest)
namelen = strlen(oneentry->d_name);
if (namelen > 4 && !strcmp(oneentry->d_name + namelen-4, ".mvd"))
{
numdemos++;
snprintf(link, sizeof(link), "<A HREF=\"watch.qtv?demo=%s\">%s</A><br/>", oneentry->d_name, oneentry->d_name);
Net_ProxySend(cluster, dest, link, strlen(link));
}
@ -1064,6 +1065,42 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
Net_ProxySend(cluster, pend, s, strlen(s));
pend->flushing = true;
}
else if (!strcmp(s, "REVERSE"))
{ //this is actually a server trying to connect to us
//start up a new stream
}
else if (!strcmp(s, "RECEIVE"))
{ //a client connection request without a source
if (cluster->numservers == 1)
{ //only one stream anyway
qtv = cluster->servers;
}
else
{ //try and hunt down an explicit stream (rather than a user-recorded one)
int numfound = 0;
sv_t *suitable;
for (qtv = cluster->servers; qtv; qtv = qtv->next)
{
if (!qtv->disconnectwhennooneiswatching)
{
suitable = qtv;
numfound++;
}
}
if (numfound == 1)
qtv = suitable;
}
if (!qtv)
{
s = "QTVSV 1\n";
Net_ProxySend(cluster, pend, s, strlen(s));
s = "PERROR: Multiple streams are currently playing\n";
Net_ProxySend(cluster, pend, s, strlen(s));
s = "\n";
Net_ProxySend(cluster, pend, s, strlen(s));
pend->flushing = true;
}
}
else if (!strcmp(s, "DEMOLIST"))
{ //lists the demos available on this proxy
s = "QTVSV 1\n";

View file

@ -880,7 +880,12 @@ static void ParsePacketEntities(sv_t *tv, netmsg_t *m, int deltaframe)
{
newframe = &tv->frame[tv->netchan.incoming_sequence & (ENTITY_FRAMES-1)];
if (newframe->oldframe != deltaframe)
if (tv->netchan.outgoing_sequence - tv->netchan.incoming_sequence >= ENTITY_FRAMES - 1)
{
//should drop it
Sys_Printf(tv->cluster, "Outdated frames\n");
}
else if (deltaframe != -1 && newframe->oldframe != deltaframe)
Sys_Printf(tv->cluster, "Mismatching delta frames\n");
}
else

View file

@ -501,7 +501,7 @@ typedef struct {
float angle[3];
} intermission_t;
struct sv_s {
struct sv_s { //details about a server connection (also known as stream)
char connectpassword[64]; //password given to server
netadr_t serveraddress;
netchan_t netchan;
@ -557,7 +557,9 @@ struct sv_s {
unsigned int timeout;
qboolean ispaused;
unsigned int packetratelimiter;
viewer_t *controller;
int controllersquencebias;
qboolean proxyplayer; //a player is actually playing on the proxy.
usercmd_t proxyplayerucmds[3];
@ -572,8 +574,8 @@ struct sv_s {
unsigned int filelength;
SOCKET sourcesock;
SOCKET tcpsocket; //tcp + mvd protocol
int tcplistenportnum;
// SOCKET tcpsocket; //tcp + mvd protocol
// int tcplistenportnum;
oproxy_t *proxies;
@ -654,10 +656,11 @@ struct cluster_s {
oproxy_t *pendingproxies;
};
#define MENU_NONE 0
#define MENU_SERVERS 1
#define MENU_ADMIN 2
#define MENU_ADMINSERVER 3
#define MENU_NONE 0
#define MENU_SERVERS 1
#define MENU_ADMIN 2
#define MENU_ADMINSERVER 3
#define MENU_MAIN MENU_SERVERS

View file

@ -914,7 +914,7 @@ void NewQWClient(cluster_t *cluster, netadr_t *addr, char *connectmessage)
viewer->delta_frame = -1;
initialserver = NULL;
if (cluster->numservers == 1)
if (cluster->nouserconnects && cluster->numservers == 1)
{
initialserver = cluster->servers;
if (!initialserver->modellist[1].name[0])
@ -1817,6 +1817,25 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
}
}
//returns self, or the final commentator
viewer_t *GetCommentator(viewer_t *v)
{
viewer_t *orig = v;
int runaway = 10;
while(runaway-- > 0)
{
if (!v->commentator)
break;
if (v->commentator->thinksitsconnected == false)
break;
if (v->commentator->server != orig->server)
break;
v = v->commentator;
}
return v;
}
void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
{
viewer_t *cv;
@ -1839,14 +1858,6 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
if (tv)
{
if (v->trackplayer >= 0 && !v->backbuffered)
{
if (v->trackplayer != tv->trackplayer && tv->usequkeworldprotocols)
if (!tv->players[v->trackplayer].active && tv->players[tv->trackplayer].active)
{
QW_StuffcmdToViewer (v, "track %i\n", tv->trackplayer);
}
}
if (tv->physicstime != v->settime && tv->cluster->chokeonnotupdated)
{
WriteByte(msg, svc_updatestatlong);
@ -1867,20 +1878,25 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
if (tv->controller == v)
lerp = 1;
track = v->trackplayer;
for (cv = v; cv && runaway-->0; cv = cv->commentator)
{
track = cv->trackplayer;
if (track != MAX_CLIENTS-2)
break;
cv = GetCommentator(v);
track = cv->trackplayer;
if (cv != v && track < 0)
{ //following a commentator
track = MAX_CLIENTS-2;
}
/*
if (v->commentator && track == MAX_CLIENTS-2)
if (v->trackplayer != track)
QW_StuffcmdToViewer (v, "track %i\n", track);
if (!v->commentator && track >= 0 && !v->backbuffered)
{
track = v->commentator->trackplayer;
if (track < 0)
track = MAX_CLIENTS-2;
}*/
if (v->trackplayer != tv->trackplayer && tv->usequkeworldprotocols)
if (!tv->players[v->trackplayer].active && tv->players[tv->trackplayer].active)
{
QW_StuffcmdToViewer (v, "track %i\n", tv->trackplayer);
}
}
for (i = 0; i < MAX_CLIENTS; i++)
{
@ -1890,46 +1906,6 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
continue;
}
if (v->commentator && v->thinksitsconnected)// && track == i)
{
if (i == MAX_CLIENTS-2)
{
flags = PF_COMMAND;
WriteByte(msg, svc_playerinfo);
WriteByte(msg, i);
WriteShort(msg, flags);
interp = v->commentator->origin[0]*8;
WriteShort(msg, interp);
interp = v->commentator->origin[1]*8;
WriteShort(msg, interp);
interp = v->commentator->origin[2]*8;
WriteShort(msg, interp);
WriteByte(msg, 0);
if (flags & PF_MSEC)
{
WriteByte(msg, 0);
}
if (flags & PF_COMMAND)
{
to.angles[0] = v->commentator->ucmds[2].angles[0];
to.angles[1] = v->commentator->ucmds[2].angles[1];
to.angles[2] = v->commentator->ucmds[2].angles[2];
WriteDeltaUsercmd(msg, &nullcmd, &to);
}
if (flags & PF_MODEL)
WriteByte(msg, tv->players[i].current.modelindex);
if (flags & PF_WEAPONFRAME)
WriteByte(msg, tv->players[i].current.weaponframe);
continue;
}
if (track == i)
continue;
}
if (!tv->players[i].active)
continue;
@ -2010,8 +1986,7 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
topacket = &tv->frame[tv->netchan.incoming_sequence&(ENTITY_FRAMES-1)];
if (tv->usequkeworldprotocols)
{
//qw protocols don't interpolate... yet
frompacket = topacket;
frompacket = &tv->frame[(topacket->oldframe)&(ENTITY_FRAMES-1)];
}
else
{
@ -2341,31 +2316,26 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
{
int newp;
int news;
if (qtv)
newp = atoi(message);
if (newp)
{
newp = atoi(message);
news = Net_MVDListen(newp);
if (newp)
if (news != INVALID_SOCKET)
{
news = Net_MVDListen(newp);
if (news != INVALID_SOCKET)
{
if (qtv->tcpsocket != INVALID_SOCKET)
closesocket(qtv->tcpsocket);
qtv->tcpsocket = news;
qtv->tcplistenportnum = newp;
qtv->disconnectwhennooneiswatching = false;
}
}
else if (qtv->tcpsocket != INVALID_SOCKET)
{
closesocket(qtv->tcpsocket);
qtv->tcpsocket = INVALID_SOCKET;
if (cluster->tcpsocket != INVALID_SOCKET)
closesocket(cluster->tcpsocket);
cluster->tcpsocket = news;
cluster->tcplistenportnum = newp;
}
}
else
QW_PrintfToViewer(v, "You were disconnected from that stream\n");
else if (cluster->tcpsocket != INVALID_SOCKET)
{
closesocket(cluster->tcpsocket);
cluster->tcpsocket = INVALID_SOCKET;
}
}
else
{
@ -2678,7 +2648,7 @@ guimenu:
if (ov->server)
{
if (ov->server->controller == ov)
QW_PrintfToViewer(v, "%i: %s: %s\n", ov->userid, ov->name, ov->server->server);
QW_PrintfToViewer(v, "%i: %s: *%s\n", ov->userid, ov->name, ov->server->server);
else
QW_PrintfToViewer(v, "%i: %s: %s\n", ov->userid, ov->name, ov->server->server);
}
@ -2862,7 +2832,7 @@ guimenu:
{
if (cluster->notalking)
return;
SendClientCommand(qtv, "say %s: %s\n", v->name, message);
SendClientCommand(qtv, "say [%s]: %s\n", v->name, message);
}
//FIXME: we ought to broadcast this to everyone not watching that qtv.
@ -3146,8 +3116,11 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
}
if ((v->ucmds[1].buttons&2) != (v->ucmds[2].buttons&2) && (v->ucmds[2].buttons&2))
{
if (!v->server && !v->menunum)
QW_SetMenu(v, MENU_MAIN);
v->trackplayer--;
}
break;
default:
Sys_Printf(cluster, "Bad message type %i\n", mtype);
@ -3376,7 +3349,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
else if (!strncmp(buf, "ptrack", 6))
{
v->trackplayer = -1;
QW_SetCommentator(cluster, v, NULL);
QW_SetCommentator(cluster, v, NULL); //clicking out will stop the client from tracking thier commentator
}
else if (!strncmp(buf, "pings", 5))
{
@ -3490,6 +3463,12 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
ReadDeltaUsercmd(m, &v->ucmds[1], &v->ucmds[2]);
PMove(v, &v->ucmds[2]);
if (v->ucmds[0].buttons & 2)
{
if (!v->server && !v->menunum)
QW_SetMenu(v, MENU_MAIN);
}
break;
case clc_tmove:
v->origin[0] = ((signed short)ReadShort(m))/8.0f;
@ -3528,15 +3507,24 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
i = 0;
sv = viewer->server;
if (i++ == viewer->menuop)
{ //mvd port
QW_StuffcmdToViewer(viewer, "echo Please enter a new tcp port number\nmessagemode\n");
strcpy(viewer->expectcommand, "setmvdport");
{ //auto disconnect
sv->disconnectwhennooneiswatching ^= 1;
}
if (i++ == viewer->menuop)
{ //disconnect
QTV_Shutdown(viewer->server);
}
if (i++ == viewer->menuop)
{
if (sv->controller == viewer)
sv->controller = NULL;
else
{
sv->controller = viewer;
sv->controllersquencebias = viewer->netchan.outgoing_sequence - sv->netchan.outgoing_sequence;
}
}
if (i++ == viewer->menuop)
{ //back
QW_SetMenu(viewer, MENU_ADMIN);
}
@ -3670,7 +3658,7 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
WriteString2(&m, "bad menu");
break;
case 3: //per-connection options
case MENU_ADMINSERVER: //per-connection options
if (viewer->server)
{
sv = viewer->server;
@ -3684,16 +3672,23 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
viewer->menuop = 0;
i = 0;
WriteString2(&m, " port");
WriteString2(&m, " auto disconnect");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
if (sv->tcpsocket == INVALID_SOCKET)
sprintf(str, "!%-19i", sv->tcplistenportnum);
if (viewer->server->disconnectwhennooneiswatching)
sprintf(str, "%-20s", "when inactive");
else
sprintf(str, "%-20i", sv->tcplistenportnum);
sprintf(str, "%-20s", "never");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " disconnect");
WriteString2(&m, "force disconnect");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " take control");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
@ -3708,10 +3703,18 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
if (viewer->menuop >= i)
viewer->menuop = i - 1;
WriteString2(&m, "\n");
WriteString2(&m, " status");
WriteString2(&m, " : ");
sprintf(str, "%-20s", viewer->server->status);
WriteString2(&m, str);
WriteString2(&m, "\n");
break;
}
//fallthrough
case 1: //connections list
case MENU_SERVERS: //connections list
WriteString2(&m, "\n\nServers\n\n");
@ -3749,7 +3752,7 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
}
break;
case 2: //admin menu
case MENU_ADMIN: //admin menu
WriteString2(&m, "\n\nCluster Admin\n\n");
@ -3867,7 +3870,12 @@ void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer)
if (viewer->server)
{
if (viewer->server->controller == viewer)
viewer->server->drop = true;
{
if (viewer->server->disconnectwhennooneiswatching)
viewer->server->drop = true;
else
viewer->server->controller = NULL;
}
viewer->server->numviewers--;
}
@ -3883,6 +3891,78 @@ void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer)
cluster->numviewers--;
}
void SendViewerPackets(cluster_t *cluster, viewer_t *v)
{
char buffer[MAX_MSGLEN*2];
netmsg_t m;
int read;
sv_t *useserver;
v->drop |= v->netchan.drop;
if (v->timeout < cluster->curtime)
{
Sys_Printf(cluster, "Viewer %s timed out\n", v->name);
v->drop = true;
}
if (v->netchan.isnqprotocol)
{
v->maysend = (v->nextpacket < cluster->curtime);
}
if (!Netchan_CanPacket(&v->netchan))
return;
if (v->maysend) //don't send incompleate connection data.
{
v->nextpacket = cluster->curtime + 1000/NQ_PACKETS_PER_SECOND;
useserver = v->server;
if (useserver && useserver->parsingconnectiondata)
useserver = NULL;
v->maysend = false;
InitNetMsg(&m, buffer, MAX_MSGLEN);
m.cursize = 0;
if (v->thinksitsconnected)
{
if (v->netchan.isnqprotocol)
SendNQPlayerStates(cluster, useserver, v, &m);
else
SendPlayerStates(useserver, v, &m);
UpdateStats(useserver, v);
}
if (v->menunum)
Menu_Draw(cluster, v);
else if (v->server && v->server->parsingconnectiondata)
{
WriteByte(&m, svc_centerprint);
WriteString(&m, v->server->status);
}
//printf("in %i, out %i, ", v->netchan.incoming_sequence, v->netchan.outgoing_sequence);
if (v->netchan.incoming_sequence != v->netchan.outgoing_sequence)
printf("%s: in %i, out %i\n", v->name, v->netchan.incoming_sequence, v->netchan.outgoing_sequence);
Netchan_Transmit(cluster, &v->netchan, m.cursize, m.data);
if (!v->netchan.message.cursize && v->backbuffered)
{//shift the backbuffers around
memcpy(v->netchan.message.data, v->backbuf[0].data, v->backbuf[0].cursize);
v->netchan.message.cursize = v->backbuf[0].cursize;
for (read = 0; read < v->backbuffered; read++)
{
if (read == v->backbuffered-1)
{
v->backbuf[read].cursize = 0;
}
else
{
memcpy(v->backbuf[read].data, v->backbuf[read+1].data, v->backbuf[read+1].cursize);
v->backbuf[read].cursize = v->backbuf[read+1].cursize;
}
}
v->backbuffered--;
}
}
}
void QW_UpdateUDPStuff(cluster_t *cluster)
{
char buffer[MAX_MSGLEN*2];
@ -3893,8 +3973,8 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
int qport;
netmsg_t m;
sv_t *useserver;
viewer_t *v, *f;
sv_t *useserver;
if (*cluster->master && (cluster->curtime > cluster->mastersendtime || cluster->mastersendtime > cluster->curtime + 4*1000*60)) //urm... time wrapped?
{
@ -3910,10 +3990,7 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
cluster->mastersendtime = cluster->curtime + 3*1000*60; //3 minuites.
}
m.data = buffer;
m.cursize = 0;
m.maxsize = MAX_MSGLEN;
m.readpos = 0;
InitNetMsg(&m, buffer, MAX_MSGLEN);
for (;;)
{
@ -3926,10 +4003,7 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
continue;
}
m.data = buffer;
m.cursize = read;
m.maxsize = MAX_MSGLEN;
m.readpos = 0;
if (*(int*)buffer == -1)
{ //connectionless message
@ -3979,6 +4053,9 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
{
if (Net_CompareAddress(&v->netchan.remote_address, &from, v->netchan.qport, qport))
{
if (v->server && v->server->controller == v && v->maysend)
SendViewerPackets(cluster, v); //do this before we read the new sequences
if (Netchan_Process(&v->netchan, &m))
{
useserver = v->server;
@ -3991,8 +4068,8 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
if (v->server && v->server->controller == v)
{
// v->maysend = true;
v->server->maysend = true;
// v->server->netchan.outgoing_sequence = v->netchan.incoming_sequence;
v->server->maysend = true;
v->server->netchan.outgoing_sequence = v->netchan.incoming_sequence + v->server->controllersquencebias;
}
else
{
@ -4093,66 +4170,6 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
QW_FreeViewer(cluster, f);
}
v->drop |= v->netchan.drop;
if (v->timeout < cluster->curtime)
{
Sys_Printf(cluster, "Viewer %s timed out\n", v->name);
v->drop = true;
}
if (v->netchan.isnqprotocol)
{
v->maysend = (v->nextpacket < cluster->curtime);
}
if (!Netchan_CanPacket(&v->netchan))
continue;
if (v->maysend) //don't send incompleate connection data.
{
v->nextpacket = cluster->curtime + 1000/NQ_PACKETS_PER_SECOND;
useserver = v->server;
if (useserver && useserver->parsingconnectiondata)
useserver = NULL;
v->maysend = false;
m.cursize = 0;
if (v->thinksitsconnected)
{
if (v->netchan.isnqprotocol)
SendNQPlayerStates(cluster, useserver, v, &m);
else
SendPlayerStates(useserver, v, &m);
UpdateStats(useserver, v);
if (v->menunum)
Menu_Draw(cluster, v);
}
if (!v->menunum && v->server && v->server->parsingconnectiondata)
{
WriteByte(&m, svc_centerprint);
WriteString(&m, v->server->status);
}
Netchan_Transmit(cluster, &v->netchan, m.cursize, m.data);
if (!v->netchan.message.cursize && v->backbuffered)
{//shift the backbuffers around
memcpy(v->netchan.message.data, v->backbuf[0].data, v->backbuf[0].cursize);
v->netchan.message.cursize = v->backbuf[0].cursize;
for (read = 0; read < v->backbuffered; read++)
{
if (read == v->backbuffered-1)
{
v->backbuf[read].cursize = 0;
}
else
{
memcpy(v->backbuf[read].data, v->backbuf[read+1].data, v->backbuf[read+1].cursize);
v->backbuf[read].cursize = v->backbuf[read+1].cursize;
}
}
}
}
SendViewerPackets(cluster, v);
}
}

View file

@ -362,7 +362,8 @@ char *Cmd_Master(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe
strncpy(cluster->master, arg[1], sizeof(cluster->master)-1);
cluster->mastersendtime = cluster->curtime;
NET_SendPacket (cluster, cluster->qwdsocket, 1, "k", addr);
if (cluster->qwdsocket != INVALID_SOCKET)
NET_SendPacket (cluster, cluster->qwdsocket, 1, "k", addr);
return "Master server set.\n";
}
@ -535,6 +536,7 @@ char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe
{
catbuffer(buffer, sizeofbuffer, " udp port %i\n", cluster->qwlistenportnum);
}
catbuffer(buffer, sizeofbuffer, " user connections are %sallowed\n", cluster->nouserconnects?"":"NOT ");
catbuffer(buffer, sizeofbuffer, "\n");
@ -568,10 +570,11 @@ char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe
if (qtv->disconnectwhennooneiswatching)
catbuffer(buffer, sizeofbuffer, "Stream is temporary\n");
if (qtv->tcpsocket != INVALID_SOCKET)
/* if (qtv->tcpsocket != INVALID_SOCKET)
{
catbuffer(buffer, sizeofbuffer, "Listening for proxies (%i)\n", qtv->tcplistenportnum);
}
*/
if (qtv->bsp)
{

View file

@ -281,6 +281,12 @@ void Net_SendQTVConnectionRequest(sv_t *qtv, char *authmethod, char *challenge)
str = "\n"; Net_QueueUpstream(qtv, strlen(str), str);
*at = '@';
}
else
{
*at = '\0';
str = "RECEIVE\n"; Net_QueueUpstream(qtv, strlen(str), str);
*at = '@';
}
if (!qtv->parsingqtvheader)
{
@ -428,6 +434,52 @@ qboolean Net_ConnectToUDPServer(sv_t *qtv, char *ip)
return true;
}
qboolean DemoFilenameIsOkay(char *fname)
{
int len;
if (strchr(fname, '/'))
return false; //unix path seperator
if (strchr(fname, '\\'))
return false; //windows path seperator
if (strchr(fname, ':'))
return false; //mac path seperator
//now make certain that the last four characters are '.mvd' and not something like '.cfg' perhaps
len = strlen(fname);
if (len < 5)
return false;
if (strcmp(fname+len-4, ".mvd"))
return false;
return true;
/*
if (strchr(fname, '\\'))
{
char *s;
Con_Printf("Warning: \\ charactures in filename %s\n", fname);
while((s = strchr(fname, '\\')))
*s = '/';
}
if (strstr(fname, ".."))
{
Con_Printf("Error: '..' charactures in filename %s\n", fname);
}
else if (fname[0] == '/')
{
Con_Printf("Error: absolute path in filename %s\n", fname);
}
else if (strstr(fname, ":")) //win32 drive seperator (or mac path seperator, but / works there and they're used to it)
{
Con_Printf("Error: absolute path in filename %s\n", fname);
}
else
return false;
return true;
*/
}
qboolean Net_ConnectToServer(sv_t *qtv, char *ip)
{
char *at;
@ -442,7 +494,10 @@ qboolean Net_ConnectToServer(sv_t *qtv, char *ip)
if (!strncmp(ip, "file:", 5) || !strncmp(ip, "demo:", 5))
{
qtv->sourcesock = INVALID_SOCKET;
qtv->sourcefile = fopen(ip+5, "rb");
if (DemoFilenameIsOkay(ip+5))
qtv->sourcefile = fopen(ip+5, "rb");
else
qtv->sourcefile = NULL;
if (qtv->sourcefile)
{
fseek(qtv->sourcefile, 0, SEEK_END);
@ -461,7 +516,7 @@ qboolean Net_ConnectToServer(sv_t *qtv, char *ip)
qtv->usequkeworldprotocols = true;
status = Net_ConnectToUDPServer(qtv, ip);
}
else if (!strncmp(ip, "tcp:", 4))
else if (!strncmp(ip, "tcp:", 4) || at!=NULL)
status = Net_ConnectToTCPServer(qtv, ip);
else
{
@ -837,8 +892,8 @@ void QTV_Shutdown(sv_t *qtv)
qtv->downloadfile = NULL;
unlink(qtv->downloadname);
}
if (qtv->tcpsocket != INVALID_SOCKET)
closesocket(qtv->tcpsocket);
// if (qtv->tcpsocket != INVALID_SOCKET)
// closesocket(qtv->tcpsocket);
BSP_Free(qtv->bsp);
qtv->bsp = NULL;
@ -1107,8 +1162,10 @@ void QTV_ParseQWStream(sv_t *qtv)
if (qtv->controller)
{
qtv->controller->maysend = true;
qtv->controller->netchan.outgoing_sequence = qtv->netchan.incoming_sequence;
qtv->controller->netchan.incoming_sequence = qtv->netchan.incoming_acknowledged;
if (qtv->controller->netchan.outgoing_sequence != qtv->controller->netchan.incoming_sequence)
printf("bug is here\n");
qtv->controller->netchan.outgoing_sequence = qtv->controller->netchan.incoming_sequence;
// qtv->controller->netchan.incoming_sequence = qtv->netchan.incoming_acknowledged;
}
}
}
@ -1283,15 +1340,15 @@ void QTV_Run(sv_t *qtv)
if (qtv->controller && !qtv->controller->netchan.isnqprotocol)
{
qtv->netchan.outgoing_sequence = qtv->controller->netchan.incoming_sequence;
qtv->netchan.incoming_sequence = qtv->controller->netchan.incoming_acknowledged;
// qtv->netchan.outgoing_sequence = qtv->controller->netchan.incoming_sequence;
// qtv->netchan.incoming_sequence = qtv->controller->netchan.incoming_acknowledged;
if (qtv->maysend)
{
qtv->maysend = false;
qtv->curtime = qtv->packetratelimiter;
qtv->packetratelimiter = qtv->curtime;
}
else
qtv->curtime = qtv->packetratelimiter - 1;
qtv->packetratelimiter = qtv->curtime + 1;
}
else
{
@ -1407,7 +1464,7 @@ void QTV_Run(sv_t *qtv)
}
SV_FindProxies(qtv->tcpsocket, qtv->cluster, qtv); //look for any other proxies wanting to muscle in on the action.
// SV_FindProxies(qtv->tcpsocket, qtv->cluster, qtv); //look for any other proxies wanting to muscle in on the action.
if (qtv->sourcefile || qtv->sourcesock != INVALID_SOCKET)
{
@ -1716,12 +1773,12 @@ sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, char *password,
memset(qtv, 0, sizeof(*qtv));
//set up a default config
qtv->tcplistenportnum = PROX_DEFAULTLISTENPORT;
// qtv->tcplistenportnum = PROX_DEFAULTLISTENPORT;
strcpy(qtv->server, PROX_DEFAULTSERVER);
memcpy(qtv->connectpassword, password, sizeof(qtv->connectpassword)-1);
qtv->tcpsocket = INVALID_SOCKET;
// qtv->tcpsocket = INVALID_SOCKET;
qtv->sourcesock = INVALID_SOCKET;
qtv->disconnectwhennooneiswatching = autoclose;
qtv->parsingconnectiondata = true;