mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-26 05:41:52 +00:00
Some tweeks to stop qqshka from moaning. Also added qtvlist and qtvdemolist commands. Tweeked the webpage generation to be more informative.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2472 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
4175b342ea
commit
6210ed87be
6 changed files with 420 additions and 190 deletions
|
@ -435,6 +435,7 @@ int main(int argc, char **argv)
|
||||||
cluster.allownqclients = true;
|
cluster.allownqclients = true;
|
||||||
strcpy(cluster.hostname, DEFAULT_HOSTNAME);
|
strcpy(cluster.hostname, DEFAULT_HOSTNAME);
|
||||||
cluster.buildnumber = build_number();
|
cluster.buildnumber = build_number();
|
||||||
|
cluster.maxproxies = -1;
|
||||||
|
|
||||||
Sys_Printf(&cluster, "QTV Build %i.\n", cluster.buildnumber);
|
Sys_Printf(&cluster, "QTV Build %i.\n", cluster.buildnumber);
|
||||||
|
|
||||||
|
|
253
fteqtv/forward.c
253
fteqtv/forward.c
|
@ -70,7 +70,7 @@ void SV_FindProxies(SOCKET sock, cluster_t *cluster, sv_t *defaultqtv)
|
||||||
if (sock == INVALID_SOCKET)
|
if (sock == INVALID_SOCKET)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cluster->numproxies >= cluster->maxproxies && cluster->maxproxies)
|
if (cluster->maxproxies >= 0 && cluster->numproxies >= cluster->maxproxies)
|
||||||
{
|
{
|
||||||
const char buffer[] = {dem_all, 1, 'P','r','o','x','y',' ','i','s',' ','f','u','l','l','.'};
|
const char buffer[] = {dem_all, 1, 'P','r','o','x','y',' ','i','s',' ','f','u','l','l','.'};
|
||||||
send(sock, buffer, strlen(buffer), 0);
|
send(sock, buffer, strlen(buffer), 0);
|
||||||
|
@ -437,6 +437,100 @@ void SV_ForwardStream(sv_t *qtv, char *buffer, int length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char qfont_table[256] = {
|
||||||
|
'\0', '#', '#', '#', '#', '.', '#', '#',
|
||||||
|
'#', 9, 10, '#', ' ', 13, '.', '.',
|
||||||
|
'[', ']', '0', '1', '2', '3', '4', '5',
|
||||||
|
'6', '7', '8', '9', '.', '<', '=', '>',
|
||||||
|
' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||||
|
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||||
|
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||||
|
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||||
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||||
|
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||||
|
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||||
|
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||||
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||||
|
'x', 'y', 'z', '{', '|', '}', '~', '<',
|
||||||
|
|
||||||
|
'<', '=', '>', '#', '#', '.', '#', '#',
|
||||||
|
'#', '#', ' ', '#', ' ', '>', '.', '.',
|
||||||
|
'[', ']', '0', '1', '2', '3', '4', '5',
|
||||||
|
'6', '7', '8', '9', '.', '<', '=', '>',
|
||||||
|
' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||||
|
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||||
|
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||||
|
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||||
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||||
|
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||||
|
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||||
|
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||||
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||||
|
'x', 'y', 'z', '{', '|', '}', '~', '<'
|
||||||
|
};
|
||||||
|
|
||||||
|
void HTMLprintf(char *outb, int outl, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list val;
|
||||||
|
char qfmt[8192*4];
|
||||||
|
char *inb = qfmt;
|
||||||
|
|
||||||
|
va_start(val, fmt);
|
||||||
|
vsnprintf(qfmt, sizeof(qfmt), fmt, val);
|
||||||
|
va_end(val);
|
||||||
|
qfmt[sizeof(qfmt)-1] = 0;
|
||||||
|
|
||||||
|
outl--;
|
||||||
|
outl -= 5;
|
||||||
|
while (outl > 0 && *inb)
|
||||||
|
{
|
||||||
|
if (*inb == '<')
|
||||||
|
{
|
||||||
|
*outb++ = '&';
|
||||||
|
*outb++ = 'l';
|
||||||
|
*outb++ = 't';
|
||||||
|
*outb++ = ';';
|
||||||
|
outl -= 4;
|
||||||
|
}
|
||||||
|
else if (*inb == '>')
|
||||||
|
{
|
||||||
|
*outb++ = '&';
|
||||||
|
*outb++ = 'g';
|
||||||
|
*outb++ = 't';
|
||||||
|
*outb++ = ';';
|
||||||
|
outl -= 4;
|
||||||
|
}
|
||||||
|
else if (*inb == '\n')
|
||||||
|
{
|
||||||
|
*outb++ = '<';
|
||||||
|
*outb++ = 'b';
|
||||||
|
*outb++ = 'r';
|
||||||
|
*outb++ = '/';
|
||||||
|
*outb++ = '>';
|
||||||
|
outl -= 5;
|
||||||
|
}
|
||||||
|
else if (*inb == '&')
|
||||||
|
{
|
||||||
|
*outb++ = '&';
|
||||||
|
*outb++ = 'a';
|
||||||
|
*outb++ = 'm';
|
||||||
|
*outb++ = 'p';
|
||||||
|
*outb++ = ';';
|
||||||
|
outl -= 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*outb++ = qfont_table[*(unsigned char*)inb];
|
||||||
|
}
|
||||||
|
inb++;
|
||||||
|
}
|
||||||
|
*outb++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void SV_GenerateNowPlayingHTTP(cluster_t *cluster, oproxy_t *dest)
|
void SV_GenerateNowPlayingHTTP(cluster_t *cluster, oproxy_t *dest)
|
||||||
{
|
{
|
||||||
int player;
|
int player;
|
||||||
|
@ -462,28 +556,41 @@ void SV_GenerateNowPlayingHTTP(cluster_t *cluster, oproxy_t *dest)
|
||||||
|
|
||||||
for (streams = cluster->servers; streams; streams = streams->next)
|
for (streams = cluster->servers; streams; streams = streams->next)
|
||||||
{
|
{
|
||||||
sprintf(buffer, "<A HREF=\"watch.qtv?sid=%i\">%s (%s: %s)</A><br/>", streams->streamid, streams->server, streams->gamedir, streams->mapname);
|
sprintf(buffer, "<A HREF=\"watch.qtv?sid=%i\">", streams->streamid);
|
||||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||||
|
HTMLprintf(buffer, sizeof(buffer), "%s (%s: %s)", streams->server, streams->gamedir, streams->mapname);
|
||||||
|
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||||
|
s = "</A><br/>";
|
||||||
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
|
||||||
for (player = 0; player < MAX_CLIENTS; player++)
|
for (player = 0; player < MAX_CLIENTS; player++)
|
||||||
{
|
{
|
||||||
if (*streams->players[player].userinfo)
|
if (*streams->players[player].userinfo)
|
||||||
{
|
{
|
||||||
Info_ValueForKey(streams->players[player].userinfo, "name", plname, sizeof(plname));
|
Info_ValueForKey(streams->players[player].userinfo, "name", plname, sizeof(plname));
|
||||||
sprintf(buffer, " %s<br/>", plname);
|
|
||||||
|
s = " ";
|
||||||
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
HTMLprintf(buffer, sizeof(buffer), "%s", plname);
|
||||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||||
|
s = "<br/>";
|
||||||
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!cluster->servers)
|
if (!cluster->servers)
|
||||||
{
|
{
|
||||||
|
|
||||||
s = "No streams are currently being played<br />";
|
s = "No streams are currently being played<br />";
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
s = "<br /><A href=\"/demos.html\">Available Demos</A>";
|
s = "<br /><A href=\"/demos.html\">Available Demos</A><br />";
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
s = "<A href=\"/admin.html\">Admin</A><br />";
|
||||||
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
|
||||||
|
sprintf(buffer, "<br/>QTV Version: %i <a href=\"http://www.fteqw.com\">www.fteqw.com</a><br />", cluster->buildnumber);
|
||||||
|
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||||
|
|
||||||
sprintf(buffer, "</BODY>");
|
sprintf(buffer, "</BODY>");
|
||||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||||
|
@ -750,13 +857,22 @@ void SV_GenerateAdminHTTP(cluster_t *cluster, oproxy_t *dest, int streamid, char
|
||||||
s = strchr(o, '\n');
|
s = strchr(o, '\n');
|
||||||
if (s)
|
if (s)
|
||||||
*s = 0;
|
*s = 0;
|
||||||
Net_ProxySend(cluster, dest, o, strlen(o));
|
HTMLprintf(cmd, sizeof(cmd), "%s", o);
|
||||||
|
Net_ProxySend(cluster, dest, cmd, strlen(cmd));
|
||||||
Net_ProxySend(cluster, dest, "<BR />", 6);
|
Net_ProxySend(cluster, dest, "<BR />", 6);
|
||||||
if (!s)
|
if (!s)
|
||||||
break;
|
break;
|
||||||
o = s+1;
|
o = s+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s = "<br /><A href=\"/nowplaying.html\">Now Playing</A><br />";
|
||||||
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
s = "<A href=\"/demos.html\">Available Demos</A><br />";
|
||||||
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
|
||||||
|
sprintf(result, "<br/>QTV Version: %i <a href=\"http://www.fteqw.com\">www.fteqw.com</a><br />", cluster->buildnumber);
|
||||||
|
Net_ProxySend(cluster, dest, result, strlen(result));
|
||||||
|
|
||||||
s = "</BODY>"
|
s = "</BODY>"
|
||||||
"</HTML>";
|
"</HTML>";
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
@ -768,7 +884,7 @@ void SV_GenerateAdminHTTP(cluster_t *cluster, oproxy_t *dest, int streamid, char
|
||||||
|
|
||||||
void SV_GenerateQTVDemoListing(cluster_t *cluster, oproxy_t *dest)
|
void SV_GenerateQTVDemoListing(cluster_t *cluster, oproxy_t *dest)
|
||||||
{
|
{
|
||||||
int numdemos = 0;
|
int i;
|
||||||
char link[256];
|
char link[256];
|
||||||
char *s;
|
char *s;
|
||||||
s = "HTTP/1.1 200 OK\n"
|
s = "HTTP/1.1 200 OK\n"
|
||||||
|
@ -781,68 +897,25 @@ void SV_GenerateQTVDemoListing(cluster_t *cluster, oproxy_t *dest)
|
||||||
s = "<H1>QTV Demo listing</H1>";
|
s = "<H1>QTV Demo listing</H1>";
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
|
||||||
#ifdef _WIN32
|
Cluster_BuildAvailableDemoList(cluster);
|
||||||
|
for (i = 0; i < cluster->availdemoscount; i++)
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATA ffd;
|
snprintf(link, sizeof(link), "<A HREF=\"watch.qtv?demo=%s\">%s</A> (%ikb)<br/>", cluster->availdemos[i].name, cluster->availdemos[i].name, cluster->availdemos[i].size/1024);
|
||||||
HANDLE h;
|
Net_ProxySend(cluster, dest, link, strlen(link));
|
||||||
h = FindFirstFile("*.mvd", &ffd);
|
|
||||||
if (h != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
numdemos++;
|
|
||||||
snprintf(link, sizeof(link), "<A HREF=\"watch.qtv?demo=%s\">%s</A><br/>", ffd.cFileName, ffd.cFileName);
|
|
||||||
Net_ProxySend(cluster, dest, link, strlen(link));
|
|
||||||
} while(FindNextFile(h, &ffd));
|
|
||||||
FindClose(h);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
{
|
|
||||||
int namelen;
|
|
||||||
DIR *dir;
|
|
||||||
struct dirent *oneentry;
|
|
||||||
|
|
||||||
dir=opendir(".");
|
sprintf(link, "<P>Total: %i demos</P>", cluster->availdemoscount);
|
||||||
if (!dir)
|
|
||||||
{
|
|
||||||
s = "QTV Proxy is unable to search for available demos.";
|
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
oneentry=readdir(dir);
|
|
||||||
if(!oneentry)
|
|
||||||
break;
|
|
||||||
#ifndef __CYGWIN__
|
|
||||||
if (oneentry->d_type == DT_DIR || oneentry->d_type == DT_LNK)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
s = "QTV Proxy is running on a platform for which file system listing is not coded.<br />Demo listing is not available.";
|
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sprintf(link, "<P>Total: %i demos</P>", numdemos);
|
|
||||||
Net_ProxySend(cluster, dest, link, strlen(link));
|
Net_ProxySend(cluster, dest, link, strlen(link));
|
||||||
|
|
||||||
|
s = "<br /><A href=\"/nowplaying.html\">Now Playing</A><br />";
|
||||||
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
s = "<A href=\"/admin.html\">Admin</A><br />";
|
||||||
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
|
||||||
|
sprintf(link, "<br/>QTV Version: %i <a href=\"http://www.fteqw.com\">www.fteqw.com</a><br />", cluster->buildnumber);
|
||||||
|
Net_ProxySend(cluster, dest, link, strlen(link));
|
||||||
|
|
||||||
|
|
||||||
s = "</BODY>"
|
s = "</BODY>"
|
||||||
"</HTML>";
|
"</HTML>";
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||||
|
@ -1102,11 +1175,28 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp(s, "DEMOLIST"))
|
else if (!strcmp(s, "DEMOLIST"))
|
||||||
{ //lists the demos available on this proxy
|
{ //lists sources that are currently playing
|
||||||
|
int i;
|
||||||
|
|
||||||
|
Cluster_BuildAvailableDemoList(cluster);
|
||||||
|
|
||||||
s = "QTVSV 1\n";
|
s = "QTVSV 1\n";
|
||||||
Net_ProxySend(cluster, pend, s, strlen(s));
|
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||||
s = "PERROR: DEMOLIST command not yet implemented\n";
|
if (!cluster->availdemoscount)
|
||||||
Net_ProxySend(cluster, pend, s, strlen(s));
|
{
|
||||||
|
s = "PERROR: No demos currently available\n";
|
||||||
|
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < cluster->availdemoscount; i++)
|
||||||
|
{
|
||||||
|
sprintf(tempbuf, "ADEMO: %i: %15s\n", cluster->availdemos[i].size, cluster->availdemos[i].name);
|
||||||
|
s = tempbuf;
|
||||||
|
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||||
|
}
|
||||||
|
qtv = NULL;
|
||||||
|
}
|
||||||
s = "\n";
|
s = "\n";
|
||||||
Net_ProxySend(cluster, pend, s, strlen(s));
|
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||||
pend->flushing = true;
|
pend->flushing = true;
|
||||||
|
@ -1154,7 +1244,7 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
||||||
if (*s < '0' || *s > '9')
|
if (*s < '0' || *s > '9')
|
||||||
break;
|
break;
|
||||||
if (*s)
|
if (*s)
|
||||||
qtv = QTV_NewServerConnection(cluster, colon, "", false, true, true);
|
qtv = QTV_NewServerConnection(cluster, colon, "", false, true, true, false);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//numerical source, use a stream id.
|
//numerical source, use a stream id.
|
||||||
|
@ -1162,18 +1252,25 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
||||||
if (qtv->streamid == atoi(colon))
|
if (qtv->streamid == atoi(colon))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// s = "QTVSV 1\n"
|
|
||||||
// "PERROR: SOURCE command not yet implemented\n"
|
|
||||||
// "\n";
|
|
||||||
// Net_ProxySend(cluster, pend, s, strlen(s));
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(s, "DEMO"))
|
else if (!strcmp(s, "DEMO"))
|
||||||
{ //starts a demo off the server... source does the same thing though...
|
{ //starts a demo off the server... source does the same thing though...
|
||||||
s = "QTVSV 1\n"
|
char buf[256];
|
||||||
"PERROR: DEMO command not yet implemented\n"
|
|
||||||
"\n";
|
sprintf(buf, sizeof(buf), "demo:%s", colon);
|
||||||
Net_ProxySend(cluster, pend, s, strlen(s));
|
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, true, false);
|
||||||
pend->flushing = true;
|
if (!qtv)
|
||||||
|
{
|
||||||
|
s = "QTVSV 1\n"
|
||||||
|
"PERROR: couldn't open demo\n"
|
||||||
|
"\n";
|
||||||
|
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||||
|
pend->flushing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strcmp(s, "AUTH"))
|
||||||
|
{ //lists the demos available on this proxy
|
||||||
|
//part of the connection process, can be ignored if there's no password
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
printf("Unrecognised token in QTV connection request (%s)\n", s);
|
printf("Unrecognised token in QTV connection request (%s)\n", s);
|
||||||
|
@ -1217,7 +1314,7 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
||||||
pend->flushing = true;
|
pend->flushing = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cluster->maxproxies && cluster->numproxies >= cluster->maxproxies)
|
if (cluster->maxproxies>=0 && cluster->numproxies >= cluster->maxproxies)
|
||||||
{
|
{
|
||||||
s = "QTVSV 1\n"
|
s = "QTVSV 1\n"
|
||||||
"TERROR: This QTV has reached it's connection limit\n"
|
"TERROR: This QTV has reached it's connection limit\n"
|
||||||
|
|
|
@ -509,6 +509,7 @@ struct sv_s { //details about a server connection (also known as stream)
|
||||||
char connectpassword[64]; //password given to server
|
char connectpassword[64]; //password given to server
|
||||||
netadr_t serveraddress;
|
netadr_t serveraddress;
|
||||||
netchan_t netchan;
|
netchan_t netchan;
|
||||||
|
qboolean serverquery;
|
||||||
|
|
||||||
unsigned char buffer[MAX_PROXY_BUFFER]; //this doesn't cycle.
|
unsigned char buffer[MAX_PROXY_BUFFER]; //this doesn't cycle.
|
||||||
int buffersize; //it memmoves down
|
int buffersize; //it memmoves down
|
||||||
|
@ -924,7 +925,7 @@ void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf);
|
||||||
void Sys_Printf(cluster_t *cluster, char *fmt, ...);
|
void Sys_Printf(cluster_t *cluster, char *fmt, ...);
|
||||||
|
|
||||||
oproxy_t *Net_FileProxy(sv_t *qtv, char *filename);
|
oproxy_t *Net_FileProxy(sv_t *qtv, char *filename);
|
||||||
sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, char *password, qboolean force, qboolean autoclose, qboolean noduplicates);
|
sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, char *password, qboolean force, qboolean autoclose, qboolean noduplicates, qboolean query);
|
||||||
SOCKET Net_MVDListen(int port);
|
SOCKET Net_MVDListen(int port);
|
||||||
qboolean Net_StopFileProxy(sv_t *qtv);
|
qboolean Net_StopFileProxy(sv_t *qtv);
|
||||||
|
|
||||||
|
|
14
fteqtv/qw.c
14
fteqtv/qw.c
|
@ -2300,7 +2300,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
||||||
else if (!strcmp(v->expectcommand, "addserver"))
|
else if (!strcmp(v->expectcommand, "addserver"))
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "tcp:%s", message);
|
snprintf(buf, sizeof(buf), "tcp:%s", message);
|
||||||
qtv = QTV_NewServerConnection(cluster, buf, "", false, false, false);
|
qtv = QTV_NewServerConnection(cluster, buf, "", false, false, false, false);
|
||||||
if (qtv)
|
if (qtv)
|
||||||
{
|
{
|
||||||
QW_SetViewersServer(cluster, v, qtv);
|
QW_SetViewersServer(cluster, v, qtv);
|
||||||
|
@ -2326,7 +2326,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
||||||
else if (!strcmp(v->expectcommand, "insecadddemo"))
|
else if (!strcmp(v->expectcommand, "insecadddemo"))
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "file:%s", message);
|
snprintf(buf, sizeof(buf), "file:%s", message);
|
||||||
qtv = QTV_NewServerConnection(cluster, buf, "", false, false, false);
|
qtv = QTV_NewServerConnection(cluster, buf, "", false, false, false, false);
|
||||||
if (!qtv)
|
if (!qtv)
|
||||||
QW_PrintfToViewer(v, "Failed to play demo \"%s\"\n", message);
|
QW_PrintfToViewer(v, "Failed to play demo \"%s\"\n", message);
|
||||||
else
|
else
|
||||||
|
@ -2339,7 +2339,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
||||||
else if (!strcmp(v->expectcommand, "adddemo"))
|
else if (!strcmp(v->expectcommand, "adddemo"))
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "file:%s", message);
|
snprintf(buf, sizeof(buf), "file:%s", message);
|
||||||
qtv = QTV_NewServerConnection(cluster, buf, "", false, false, false);
|
qtv = QTV_NewServerConnection(cluster, buf, "", false, false, false, false);
|
||||||
if (!qtv)
|
if (!qtv)
|
||||||
QW_PrintfToViewer(v, "Failed to play demo \"%s\"\n", message);
|
QW_PrintfToViewer(v, "Failed to play demo \"%s\"\n", message);
|
||||||
else
|
else
|
||||||
|
@ -2681,7 +2681,7 @@ tuidemos:
|
||||||
else
|
else
|
||||||
message += 9;
|
message += 9;
|
||||||
snprintf(buf, sizeof(buf), "udp:%s", message);
|
snprintf(buf, sizeof(buf), "udp:%s", message);
|
||||||
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, true);
|
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, true, false);
|
||||||
if (qtv)
|
if (qtv)
|
||||||
{
|
{
|
||||||
QW_SetMenu(v, MENU_NONE);
|
QW_SetMenu(v, MENU_NONE);
|
||||||
|
@ -2695,7 +2695,7 @@ tuidemos:
|
||||||
{
|
{
|
||||||
message += 6;
|
message += 6;
|
||||||
snprintf(buf, sizeof(buf), "udp:%s", message);
|
snprintf(buf, sizeof(buf), "udp:%s", message);
|
||||||
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, false);
|
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, false, false);
|
||||||
if (qtv)
|
if (qtv)
|
||||||
{
|
{
|
||||||
QW_SetMenu(v, MENU_NONE);
|
QW_SetMenu(v, MENU_NONE);
|
||||||
|
@ -2710,7 +2710,7 @@ tuidemos:
|
||||||
{
|
{
|
||||||
message += 5;
|
message += 5;
|
||||||
snprintf(buf, sizeof(buf), "tcp:%s", message);
|
snprintf(buf, sizeof(buf), "tcp:%s", message);
|
||||||
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, true);
|
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, true, false);
|
||||||
if (qtv)
|
if (qtv)
|
||||||
{
|
{
|
||||||
QW_SetMenu(v, MENU_NONE);
|
QW_SetMenu(v, MENU_NONE);
|
||||||
|
@ -2747,7 +2747,7 @@ tuidemos:
|
||||||
{
|
{
|
||||||
message += 6;
|
message += 6;
|
||||||
snprintf(buf, sizeof(buf), "file:%s", message);
|
snprintf(buf, sizeof(buf), "file:%s", message);
|
||||||
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, true);
|
qtv = QTV_NewServerConnection(cluster, buf, "", false, true, true, false);
|
||||||
if (qtv)
|
if (qtv)
|
||||||
{
|
{
|
||||||
QW_SetMenu(v, MENU_NONE);
|
QW_SetMenu(v, MENU_NONE);
|
||||||
|
|
|
@ -27,18 +27,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
FTEQTV proxy commands: (build "__DATE__")\n\
|
FTEQTV proxy commands: (build "__DATE__")\n\
|
||||||
----------------------\n\
|
----------------------\n\
|
||||||
connect, qtv, addserver\n\
|
connect, qtv, addserver\n\
|
||||||
- connect to a MVD stream (TCP)\n\
|
connect to a MVD stream (TCP)\n\
|
||||||
|
qtvlist\n\
|
||||||
|
lists available streams on a proxy\n\
|
||||||
qw\n\
|
qw\n\
|
||||||
- connect to a server as a player (UDP)\n\
|
connect to a server as a player (UDP)\n\
|
||||||
adddemo\n\
|
adddemo\n\
|
||||||
- play a demo from a MVD file\n\
|
play a demo from a MVD file\n\
|
||||||
port\n\
|
port\n\
|
||||||
- UDP port for QuakeWorld client connections\n\
|
UDP port for QuakeWorld client connections\n\
|
||||||
mvdport\n\
|
mvdport\n\
|
||||||
- specify TCP port for MVD broadcasting\n\
|
specify TCP port for MVD broadcasting\n\
|
||||||
maxviewers, maxproxies\n\
|
maxviewers, maxproxies\n\
|
||||||
- limit number of connections\n\
|
limit number of connections\n\
|
||||||
status, choke, late, talking, nobsp, reconnect, exec, password, master, hostname, record, stop, quit\n\n"
|
status, choke, late, talking, nobsp, reconnect, exec, password, master, hostname, record, stop, quit\n\
|
||||||
|
other random commands\n\
|
||||||
|
\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -402,6 +406,33 @@ char *Cmd_AdminPassword(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char
|
||||||
strncpy(cluster->adminpassword, arg[1], sizeof(cluster->adminpassword)-1);
|
strncpy(cluster->adminpassword, arg[1], sizeof(cluster->adminpassword)-1);
|
||||||
return "Password changed.\n";
|
return "Password changed.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *Cmd_QTVList(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffer, int sizeofbuffer, qboolean localcommand)
|
||||||
|
{
|
||||||
|
if (!*arg[1])
|
||||||
|
return "connect requires an ip:port parameter\n";
|
||||||
|
|
||||||
|
memmove(arg[1]+4, arg[1], ARG_LEN-5);
|
||||||
|
strncpy(arg[1], "tcp:", 4);
|
||||||
|
|
||||||
|
qtv = QTV_NewServerConnection(cluster, arg[1], arg[2], false, false, false, true);
|
||||||
|
if (!qtv)
|
||||||
|
return "Failed to connect to server, connection aborted\n";
|
||||||
|
return "Querying proxy\n";
|
||||||
|
}
|
||||||
|
char *Cmd_QTVDemoList(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffer, int sizeofbuffer, qboolean localcommand)
|
||||||
|
{
|
||||||
|
if (!*arg[1])
|
||||||
|
return "connect requires an ip:port parameter\n";
|
||||||
|
|
||||||
|
memmove(arg[1]+4, arg[1], ARG_LEN-5);
|
||||||
|
strncpy(arg[1], "tcp:", 4);
|
||||||
|
|
||||||
|
qtv = QTV_NewServerConnection(cluster, arg[1], arg[2], false, false, false, 2);
|
||||||
|
if (!qtv)
|
||||||
|
return "Failed to connect to server, connection aborted\n";
|
||||||
|
return "Querying proxy\n";
|
||||||
|
}
|
||||||
char *Cmd_QTVConnect(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffer, int sizeofbuffer, qboolean localcommand)
|
char *Cmd_QTVConnect(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffer, int sizeofbuffer, qboolean localcommand)
|
||||||
{
|
{
|
||||||
if (!*arg[1])
|
if (!*arg[1])
|
||||||
|
@ -410,7 +441,7 @@ char *Cmd_QTVConnect(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *b
|
||||||
memmove(arg[1]+4, arg[1], ARG_LEN-5);
|
memmove(arg[1]+4, arg[1], ARG_LEN-5);
|
||||||
strncpy(arg[1], "tcp:", 4);
|
strncpy(arg[1], "tcp:", 4);
|
||||||
|
|
||||||
if (!QTV_NewServerConnection(cluster, arg[1], arg[2], false, false, false))
|
if (!QTV_NewServerConnection(cluster, arg[1], arg[2], false, false, false, false))
|
||||||
return "Failed to connect to server, connection aborted\n";
|
return "Failed to connect to server, connection aborted\n";
|
||||||
return "Source registered\n";
|
return "Source registered\n";
|
||||||
}
|
}
|
||||||
|
@ -422,7 +453,7 @@ char *Cmd_QWConnect(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *bu
|
||||||
memmove(arg[1]+4, arg[1], ARG_LEN-5);
|
memmove(arg[1]+4, arg[1], ARG_LEN-5);
|
||||||
strncpy(arg[1], "udp:", 4);
|
strncpy(arg[1], "udp:", 4);
|
||||||
|
|
||||||
if (!QTV_NewServerConnection(cluster, arg[1], arg[2], false, false, false))
|
if (!QTV_NewServerConnection(cluster, arg[1], arg[2], false, false, false, false))
|
||||||
return "Failed to connect to server, connection aborted\n";
|
return "Failed to connect to server, connection aborted\n";
|
||||||
return "Source registered\n";
|
return "Source registered\n";
|
||||||
}
|
}
|
||||||
|
@ -438,7 +469,7 @@ char *Cmd_MVDConnect(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *b
|
||||||
memmove(arg[1]+5, arg[1], ARG_LEN-6);
|
memmove(arg[1]+5, arg[1], ARG_LEN-6);
|
||||||
strncpy(arg[1], "file:", 5);
|
strncpy(arg[1], "file:", 5);
|
||||||
|
|
||||||
if (!QTV_NewServerConnection(cluster, arg[1], arg[2], false, false, false))
|
if (!QTV_NewServerConnection(cluster, arg[1], arg[2], false, false, false, false))
|
||||||
return "Failed to connect to server, connection aborted\n";
|
return "Failed to connect to server, connection aborted\n";
|
||||||
return "Source registered\n";
|
return "Source registered\n";
|
||||||
}
|
}
|
||||||
|
@ -847,6 +878,8 @@ const rconcommands_t rconcommands[] =
|
||||||
{"port", 0, 1, Cmd_UDPPort},
|
{"port", 0, 1, Cmd_UDPPort},
|
||||||
{"adminpassword",0, 1, Cmd_AdminPassword},
|
{"adminpassword",0, 1, Cmd_AdminPassword},
|
||||||
{"rconpassword",0, 1, Cmd_AdminPassword},
|
{"rconpassword",0, 1, Cmd_AdminPassword},
|
||||||
|
{"qtvlist", 0, 1, Cmd_QTVList},
|
||||||
|
{"qtvdemolist", 0, 1, Cmd_QTVDemoList},
|
||||||
{"qtv", 0, 1, Cmd_QTVConnect},
|
{"qtv", 0, 1, Cmd_QTVConnect},
|
||||||
{"addserver", 0, 1, Cmd_QTVConnect},
|
{"addserver", 0, 1, Cmd_QTVConnect},
|
||||||
{"connect", 0, 1, Cmd_QTVConnect},
|
{"connect", 0, 1, Cmd_QTVConnect},
|
||||||
|
|
286
fteqtv/source.c
286
fteqtv/source.c
|
@ -272,80 +272,110 @@ void Net_SendQTVConnectionRequest(sv_t *qtv, char *authmethod, char *challenge)
|
||||||
str = "QTV\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
str = "QTV\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
str = "VERSION: 1\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
str = "VERSION: 1\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
|
||||||
at = strchrrev(qtv->server, '@');
|
if (qtv->serverquery)
|
||||||
if (at)
|
|
||||||
{
|
{
|
||||||
*at = '\0';
|
if (qtv->serverquery == 2)
|
||||||
str = "SOURCE: "; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = qtv->server; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = "\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
*at = '@';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
str = "RECEIVE\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!qtv->parsingqtvheader)
|
|
||||||
{
|
|
||||||
str = "RAW: 1\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (authmethod)
|
|
||||||
{
|
{
|
||||||
if (!strcmp(authmethod, "PLAIN"))
|
str = "DEMOLIST\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
{
|
|
||||||
str = "AUTH: PLAIN\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = "PASSWORD: \""; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = qtv->connectpassword; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = "\"\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
}
|
|
||||||
else if (challenge && strlen(challenge)>=32 && !strcmp(authmethod, "CCITT"))
|
|
||||||
{
|
|
||||||
unsigned short crcvalue;
|
|
||||||
str = "AUTH: CCITT\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = "PASSWORD: \""; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
|
|
||||||
snprintf(hash, sizeof(hash), "%s%s", challenge, qtv->connectpassword);
|
|
||||||
crcvalue = QCRC_Block(hash, strlen(hash));
|
|
||||||
sprintf(hash, "0x%X", (unsigned int)QCRC_Value(crcvalue));
|
|
||||||
|
|
||||||
str = hash; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = "\"\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
}
|
|
||||||
else if (challenge && strlen(challenge)>=8 && !strcmp(authmethod, "MD4"))
|
|
||||||
{
|
|
||||||
unsigned int md4sum[4];
|
|
||||||
str = "AUTH: MD4\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = "PASSWORD: \""; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
|
|
||||||
snprintf(hash, sizeof(hash), "%s%s", challenge, qtv->connectpassword);
|
|
||||||
Com_BlockFullChecksum (hash, strlen(hash), (unsigned char*)md4sum);
|
|
||||||
sprintf(hash, "%X%X%X%X", md4sum[0], md4sum[1], md4sum[2], md4sum[3]);
|
|
||||||
|
|
||||||
str = hash; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = "\"\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
}
|
|
||||||
else if (!strcmp(authmethod, "NONE"))
|
|
||||||
{
|
|
||||||
str = "AUTH: NONE\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
str = "PASSWORD: \n"; Net_QueueUpstream(qtv, strlen(str), str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qtv->drop = true;
|
|
||||||
qtv->upstreambuffersize = 0;
|
|
||||||
Sys_Printf(qtv->cluster, "Auth method %s was not usable\n", authmethod);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
str = "AUTH: MD4\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
str = "SOURCELIST\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
str = "AUTH: CCITT\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
}
|
||||||
str = "AUTH: PLAIN\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
}
|
||||||
str = "AUTH: NONE\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
at = strchrrev(qtv->server, '@');
|
||||||
|
if (at)
|
||||||
|
{
|
||||||
|
*at = '\0';
|
||||||
|
str = "SOURCE: "; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
|
||||||
|
if (strncmp(qtv->server, "tcp:", 4))
|
||||||
|
{
|
||||||
|
str = qtv->server;
|
||||||
|
Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = strchr(qtv->server, ':');
|
||||||
|
if (str)
|
||||||
|
{
|
||||||
|
str++;
|
||||||
|
Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str = "\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
*at = '@';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = "RECEIVE\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qtv->parsingqtvheader)
|
||||||
|
{
|
||||||
|
str = "RAW: 1\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (authmethod)
|
||||||
|
{
|
||||||
|
if (!strcmp(authmethod, "PLAIN"))
|
||||||
|
{
|
||||||
|
str = "AUTH: PLAIN\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "PASSWORD: \""; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = qtv->connectpassword; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "\"\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
|
else if (challenge && strlen(challenge)>=32 && !strcmp(authmethod, "CCITT"))
|
||||||
|
{
|
||||||
|
unsigned short crcvalue;
|
||||||
|
str = "AUTH: CCITT\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "PASSWORD: \""; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
|
||||||
|
snprintf(hash, sizeof(hash), "%s%s", challenge, qtv->connectpassword);
|
||||||
|
crcvalue = QCRC_Block(hash, strlen(hash));
|
||||||
|
sprintf(hash, "0x%X", (unsigned int)QCRC_Value(crcvalue));
|
||||||
|
|
||||||
|
str = hash; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "\"\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
|
else if (challenge && strlen(challenge)>=8 && !strcmp(authmethod, "MD4"))
|
||||||
|
{
|
||||||
|
unsigned int md4sum[4];
|
||||||
|
str = "AUTH: MD4\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "PASSWORD: \""; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
|
||||||
|
snprintf(hash, sizeof(hash), "%s%s", challenge, qtv->connectpassword);
|
||||||
|
Com_BlockFullChecksum (hash, strlen(hash), (unsigned char*)md4sum);
|
||||||
|
sprintf(hash, "%X%X%X%X", md4sum[0], md4sum[1], md4sum[2], md4sum[3]);
|
||||||
|
|
||||||
|
str = hash; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "\"\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
|
else if (!strcmp(authmethod, "NONE"))
|
||||||
|
{
|
||||||
|
str = "AUTH: NONE\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "PASSWORD: \n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qtv->drop = true;
|
||||||
|
qtv->upstreambuffersize = 0;
|
||||||
|
Sys_Printf(qtv->cluster, "Auth method %s was not usable\n", authmethod);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = "AUTH: MD4\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "AUTH: CCITT\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "AUTH: PLAIN\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
str = "AUTH: NONE\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str = "\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
str = "\n"; Net_QueueUpstream(qtv, strlen(str), str);
|
||||||
|
@ -357,7 +387,7 @@ qboolean Net_ConnectToTCPServer(sv_t *qtv, char *ip)
|
||||||
netadr_t from;
|
netadr_t from;
|
||||||
unsigned long nonblocking = true;
|
unsigned long nonblocking = true;
|
||||||
|
|
||||||
if (!NET_StringToAddr(ip+4, &qtv->serveraddress, 27500))
|
if (!NET_StringToAddr(ip, &qtv->serveraddress, 27500))
|
||||||
{
|
{
|
||||||
Sys_Printf(qtv->cluster, "Unable to resolve %s\n", ip);
|
Sys_Printf(qtv->cluster, "Unable to resolve %s\n", ip);
|
||||||
return false;
|
return false;
|
||||||
|
@ -402,7 +432,7 @@ qboolean Net_ConnectToUDPServer(sv_t *qtv, char *ip)
|
||||||
netadr_t from;
|
netadr_t from;
|
||||||
unsigned long nonblocking = true;
|
unsigned long nonblocking = true;
|
||||||
|
|
||||||
if (!NET_StringToAddr(ip+4, &qtv->serveraddress, 27500))
|
if (!NET_StringToAddr(ip, &qtv->serveraddress, 27500))
|
||||||
{
|
{
|
||||||
Sys_Printf(qtv->cluster, "Unable to resolve %s\n", ip);
|
Sys_Printf(qtv->cluster, "Unable to resolve %s\n", ip);
|
||||||
return false;
|
return false;
|
||||||
|
@ -478,22 +508,56 @@ qboolean DemoFilenameIsOkay(char *fname)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean Net_ConnectToServer(sv_t *qtv, char *ip)
|
qboolean Net_ConnectToServer(sv_t *qtv)
|
||||||
{
|
{
|
||||||
char *at;
|
char *at;
|
||||||
qboolean status;
|
enum {
|
||||||
|
SRC_BAD,
|
||||||
|
SRC_DEMO,
|
||||||
|
SRC_UDP,
|
||||||
|
SRC_TCP
|
||||||
|
} type = SRC_BAD;
|
||||||
|
char *ip = qtv->server;
|
||||||
|
|
||||||
|
if (!strncmp(ip, "udp:", 4))
|
||||||
|
{
|
||||||
|
type = SRC_UDP;
|
||||||
|
ip += 4;
|
||||||
|
}
|
||||||
|
else if (!strncmp(ip, "tcp:", 4))
|
||||||
|
{
|
||||||
|
type = SRC_TCP;
|
||||||
|
ip += 4;
|
||||||
|
}
|
||||||
|
else if (!strncmp(ip, "demo:", 5))
|
||||||
|
{
|
||||||
|
type = SRC_DEMO;
|
||||||
|
ip += 5;
|
||||||
|
}
|
||||||
|
else if (!strncmp(ip, "file:", 5))
|
||||||
|
{
|
||||||
|
type = SRC_DEMO;
|
||||||
|
ip += 5;
|
||||||
|
}
|
||||||
|
|
||||||
at = strchrrev(ip, '@');
|
at = strchrrev(ip, '@');
|
||||||
if (at)
|
if (at && (type == SRC_DEMO || type == SRC_TCP))
|
||||||
|
{
|
||||||
|
if (type == SRC_DEMO)
|
||||||
|
type = SRC_TCP;
|
||||||
ip = at+1;
|
ip = at+1;
|
||||||
|
}
|
||||||
|
|
||||||
qtv->usequkeworldprotocols = false;
|
qtv->usequkeworldprotocols = false;
|
||||||
|
|
||||||
if (!strncmp(ip, "file:", 5) || !strncmp(ip, "demo:", 5))
|
qtv->nextconnectattempt = qtv->curtime + RECONNECT_TIME; //wait half a minuite before trying to reconnect
|
||||||
|
|
||||||
|
switch(type)
|
||||||
{
|
{
|
||||||
|
case SRC_DEMO:
|
||||||
qtv->sourcesock = INVALID_SOCKET;
|
qtv->sourcesock = INVALID_SOCKET;
|
||||||
if (DemoFilenameIsOkay(ip+5))
|
if (DemoFilenameIsOkay(ip))
|
||||||
qtv->sourcefile = fopen(ip+5, "rb");
|
qtv->sourcefile = fopen(ip, "rb");
|
||||||
else
|
else
|
||||||
qtv->sourcefile = NULL;
|
qtv->sourcefile = NULL;
|
||||||
if (qtv->sourcefile)
|
if (qtv->sourcefile)
|
||||||
|
@ -505,23 +569,19 @@ qboolean Net_ConnectToServer(sv_t *qtv, char *ip)
|
||||||
}
|
}
|
||||||
Sys_Printf(qtv->cluster, "Unable to open file %s\n", ip+5);
|
Sys_Printf(qtv->cluster, "Unable to open file %s\n", ip+5);
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
qtv->nextconnectattempt = qtv->curtime + RECONNECT_TIME; //wait half a minuite before trying to reconnect
|
|
||||||
|
|
||||||
if (!strncmp(ip, "udp:", 4))
|
case SRC_UDP:
|
||||||
{
|
|
||||||
qtv->usequkeworldprotocols = true;
|
qtv->usequkeworldprotocols = true;
|
||||||
status = Net_ConnectToUDPServer(qtv, ip);
|
return Net_ConnectToUDPServer(qtv, ip);
|
||||||
}
|
|
||||||
else if (!strncmp(ip, "tcp:", 4) || at!=NULL)
|
case SRC_TCP:
|
||||||
status = Net_ConnectToTCPServer(qtv, ip);
|
return Net_ConnectToTCPServer(qtv, ip);
|
||||||
else
|
|
||||||
{
|
default:
|
||||||
Sys_Printf(qtv->cluster, "Unknown source type %s\n", ip);
|
Sys_Printf(qtv->cluster, "Unknown source type %s\n", ip);
|
||||||
status = false;
|
return false;
|
||||||
}
|
}
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net_QueueUpstream(sv_t *qtv, int size, char *buffer)
|
void Net_QueueUpstream(sv_t *qtv, int size, char *buffer)
|
||||||
|
@ -847,7 +907,7 @@ qboolean QTV_Connect(sv_t *qtv, char *serverurl)
|
||||||
|
|
||||||
memcpy(qtv->server, serverurl, sizeof(qtv->server)-1);
|
memcpy(qtv->server, serverurl, sizeof(qtv->server)-1);
|
||||||
|
|
||||||
if (!Net_ConnectToServer(qtv, qtv->server))
|
if (!Net_ConnectToServer(qtv))
|
||||||
{
|
{
|
||||||
Sys_Printf(qtv->cluster, "Couldn't connect (%s)\n", qtv->server);
|
Sys_Printf(qtv->cluster, "Couldn't connect (%s)\n", qtv->server);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1566,13 +1626,43 @@ void QTV_Run(sv_t *qtv)
|
||||||
qtv->buffersize = 0;
|
qtv->buffersize = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!strcmp(start, "TERROR"))
|
else if (!strcmp(start, "TERROR") || !strcmp(start, "ERROR"))
|
||||||
{ //we don't support compression, we didn't ask for it.
|
{ //we don't support compression, we didn't ask for it.
|
||||||
Sys_Printf(qtv->cluster, "\nQTV server error: %s\n\n", colon);
|
Sys_Printf(qtv->cluster, "\nQTV server error: %s\n\n", colon);
|
||||||
qtv->drop = true;
|
|
||||||
qtv->buffersize = 0;
|
qtv->buffersize = 0;
|
||||||
|
|
||||||
|
if (qtv->disconnectwhennooneiswatching)
|
||||||
|
qtv->drop = true; //if its a user registered stream, drop it immediatly
|
||||||
|
else
|
||||||
|
{ //otherwise close the socket (this will result in a timeout and reconnect)
|
||||||
|
if (qtv->sourcesock != INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
closesocket(qtv->sourcesock);
|
||||||
|
qtv->sourcesock = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(start, "ASOURCE"))
|
||||||
|
{
|
||||||
|
Sys_Printf(qtv->cluster, "SRC: %s\n", colon);
|
||||||
|
}
|
||||||
|
else if (!strcmp(start, "ADEMO"))
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
size = atoi(colon);
|
||||||
|
colon = strchr(colon, ':');
|
||||||
|
if (!colon)
|
||||||
|
colon = "";
|
||||||
|
else
|
||||||
|
colon = colon+1;
|
||||||
|
while(*colon == ' ')
|
||||||
|
colon++;
|
||||||
|
if (size > 1024*1024)
|
||||||
|
Sys_Printf(qtv->cluster, "DEMO: (%3imb) %s\n", size/(1024*1024), colon);
|
||||||
|
else
|
||||||
|
Sys_Printf(qtv->cluster, "DEMO: (%3ikb) %s\n", size/1024, colon);
|
||||||
|
}
|
||||||
else if (!strcmp(start, "PRINT"))
|
else if (!strcmp(start, "PRINT"))
|
||||||
{
|
{
|
||||||
Sys_Printf(qtv->cluster, "QTV server: %s\n", colon);
|
Sys_Printf(qtv->cluster, "QTV server: %s\n", colon);
|
||||||
|
@ -1592,7 +1682,14 @@ void QTV_Run(sv_t *qtv)
|
||||||
qtv->buffersize -= length;
|
qtv->buffersize -= length;
|
||||||
memmove(qtv->buffer, qtv->buffer + length, qtv->buffersize);
|
memmove(qtv->buffer, qtv->buffer + length, qtv->buffersize);
|
||||||
|
|
||||||
if (*authmethod)
|
if (qtv->serverquery)
|
||||||
|
{
|
||||||
|
Sys_Printf(qtv->cluster, "End of sources\n", colon);
|
||||||
|
qtv->drop = true;
|
||||||
|
qtv->buffersize = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (*authmethod)
|
||||||
{ //we need to send a challenge response now.
|
{ //we need to send a challenge response now.
|
||||||
Net_SendQTVConnectionRequest(qtv, authmethod, challenge);
|
Net_SendQTVConnectionRequest(qtv, authmethod, challenge);
|
||||||
return;
|
return;
|
||||||
|
@ -1750,7 +1847,7 @@ void QTV_Run(sv_t *qtv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, char *password, qboolean force, qboolean autoclose, qboolean noduplicates)
|
sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, char *password, qboolean force, qboolean autoclose, qboolean noduplicates, qboolean query)
|
||||||
{
|
{
|
||||||
sv_t *qtv;
|
sv_t *qtv;
|
||||||
|
|
||||||
|
@ -1781,6 +1878,7 @@ sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, char *password,
|
||||||
qtv->sourcesock = INVALID_SOCKET;
|
qtv->sourcesock = INVALID_SOCKET;
|
||||||
qtv->disconnectwhennooneiswatching = autoclose;
|
qtv->disconnectwhennooneiswatching = autoclose;
|
||||||
qtv->parsingconnectiondata = true;
|
qtv->parsingconnectiondata = true;
|
||||||
|
qtv->serverquery = query;
|
||||||
|
|
||||||
qtv->streamid = ++cluster->nextstreamid;
|
qtv->streamid = ++cluster->nextstreamid;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue