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:
parent
4262948c3e
commit
f321ee32ee
6 changed files with 314 additions and 192 deletions
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
17
fteqtv/qtv.h
17
fteqtv/qtv.h
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
355
fteqtv/qw.c
355
fteqtv/qw.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue