mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
A few user interface changes.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2402 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
dc4ca9b290
commit
300f84b8c1
8 changed files with 654 additions and 475 deletions
|
@ -6,6 +6,49 @@ Contains the control routines that handle both incoming and outgoing stuff
|
|||
|
||||
|
||||
|
||||
// char *date = "Oct 24 1996";
|
||||
static char *date = __DATE__ ;
|
||||
static char *mon[12] =
|
||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
static char mond[12] =
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
// returns days since Oct 24 1996
|
||||
int build_number( void )
|
||||
{
|
||||
int m = 0;
|
||||
int d = 0;
|
||||
int y = 0;
|
||||
static int b = 0;
|
||||
|
||||
if (b != 0)
|
||||
return b;
|
||||
|
||||
for (m = 0; m < 11; m++)
|
||||
{
|
||||
if (strncmp( &date[0], mon[m], 3 ) == 0)
|
||||
break;
|
||||
d += mond[m];
|
||||
}
|
||||
|
||||
d += atoi( &date[4] ) - 1;
|
||||
|
||||
y = atoi( &date[7] ) - 1900;
|
||||
|
||||
b = d + (int)((y - 1) * 365.25);
|
||||
|
||||
if (((y % 4) == 0) && m > 1)
|
||||
{
|
||||
b += 1;
|
||||
}
|
||||
|
||||
b -= 35778; // Dec 16 1998
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
char name[56];
|
||||
int offset;
|
||||
|
@ -285,6 +328,9 @@ void DoCommandLine(cluster_t *cluster, int argc, char **argv)
|
|||
char *start, *end, *result;
|
||||
char buffer[8192];
|
||||
|
||||
result = Rcon_Command(cluster, NULL, "exec qtv.cfg", buffer, sizeof(buffer), true);
|
||||
Sys_Printf(cluster, "%s", result);
|
||||
|
||||
commandline[0] = '\0';
|
||||
|
||||
//build a block of strings.
|
||||
|
@ -333,8 +379,11 @@ int main(int argc, char **argv)
|
|||
cluster.qwdsocket = INVALID_SOCKET;
|
||||
cluster.tcpsocket = INVALID_SOCKET;
|
||||
cluster.qwlistenportnum = 0;
|
||||
cluster.allownqclients = true;
|
||||
strcpy(cluster.hostname, DEFAULT_HOSTNAME);
|
||||
cluster.buildnumber = build_number();
|
||||
|
||||
Sys_Printf(&cluster, "QTV Build %i.\n", cluster.buildnumber);
|
||||
|
||||
if (argc >= 2 && (!strcmp(argv[1], "-view") || !strcmp(argv[1], "-play")))
|
||||
{
|
||||
|
|
238
fteqtv/forward.c
238
fteqtv/forward.c
|
@ -267,7 +267,7 @@ void Net_SendConnectionMVD(sv_t *qtv, oproxy_t *prox)
|
|||
|
||||
prox->flushing = false;
|
||||
|
||||
BuildServerData(qtv, &msg, true, 0);
|
||||
BuildServerData(qtv, &msg, true, 0, true);
|
||||
Prox_SendMessage(qtv->cluster, prox, msg.data, msg.cursize, dem_read, (unsigned)-1);
|
||||
msg.cursize = 0;
|
||||
|
||||
|
@ -451,6 +451,9 @@ void SV_GenerateNowPlayingHTTP(cluster_t *cluster, oproxy_t *dest)
|
|||
"<BODY>");
|
||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "<H1>Now Playing on %s</H1>", cluster->hostname);
|
||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||
|
||||
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);
|
||||
|
@ -466,6 +469,13 @@ void SV_GenerateNowPlayingHTTP(cluster_t *cluster, oproxy_t *dest)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!cluster->servers)
|
||||
{
|
||||
|
||||
s = "No streams are currently being played";
|
||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||
}
|
||||
|
||||
sprintf(buffer, "</BODY>");
|
||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||
}
|
||||
|
@ -542,7 +552,8 @@ void SV_GenerateQTVStub(cluster_t *cluster, oproxy_t *dest, int streamid)
|
|||
"<TITLE>QuakeTV: Now Playing</TITLE>"
|
||||
"</HEAD>"
|
||||
"<BODY>"
|
||||
"Your client did not send a Host field\n"
|
||||
"Your client did not send a Host field, which is required in HTTP/1.1\n<BR />"
|
||||
"Please try a different browser.\n"
|
||||
"</BODY>"
|
||||
"</HTML>";
|
||||
|
||||
|
@ -550,7 +561,7 @@ void SV_GenerateQTVStub(cluster_t *cluster, oproxy_t *dest, int streamid)
|
|||
return;
|
||||
}
|
||||
|
||||
s = "HTTP/1.1 200 OK\n"
|
||||
s = "HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/x-quaketvident\n"
|
||||
"Connection: close\n"
|
||||
"\n";
|
||||
|
@ -566,6 +577,166 @@ void SV_GenerateQTVStub(cluster_t *cluster, oproxy_t *dest, int streamid)
|
|||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||
}
|
||||
|
||||
char *SV_ParsePOST(char *post, char *buffer, int buffersize)
|
||||
{
|
||||
while(*post && *post != '&')
|
||||
{
|
||||
if (--buffersize>0)
|
||||
{
|
||||
if (*post == '+')
|
||||
*buffer++ = ' ';
|
||||
else if (*post == '%')
|
||||
{
|
||||
*buffer = 0;
|
||||
post++;
|
||||
if (*post == '\0' || *post == '&')
|
||||
break;
|
||||
else if (*post >= 'a' && *post <= 'f')
|
||||
*buffer += 10 + *post-'a';
|
||||
else if (*post >= 'A' && *post <= 'F')
|
||||
*buffer += 10 + *post-'A';
|
||||
else if (*post >= '0' && *post <= '9')
|
||||
*buffer += *post-'0';
|
||||
|
||||
*buffer <<= 4;
|
||||
|
||||
post++;
|
||||
if (*post == '\0' || *post == '&')
|
||||
break;
|
||||
else if (*post >= 'a' && *post <= 'f')
|
||||
*buffer += 10 + *post-'a';
|
||||
else if (*post >= 'A' && *post <= 'F')
|
||||
*buffer += 10 + *post-'A';
|
||||
else if (*post >= '0' && *post <= '9')
|
||||
*buffer += *post-'0';
|
||||
|
||||
buffer++;
|
||||
}
|
||||
else
|
||||
*buffer++ = *post;
|
||||
}
|
||||
post++;
|
||||
}
|
||||
*buffer = 0;
|
||||
|
||||
return post;
|
||||
}
|
||||
void SV_GenerateAdminHTTP(cluster_t *cluster, oproxy_t *dest, int streamid, char *postbody)
|
||||
{
|
||||
char pwd[64];
|
||||
char cmd[256];
|
||||
char result[8192];
|
||||
char *s;
|
||||
char *o;
|
||||
|
||||
if (!*cluster->adminpassword)
|
||||
{
|
||||
s = "HTTP/1.1 403 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
"<HEAD><TITLE>QuakeTV</TITLE></HEAD><BODY>The admin password is disabled. You may not log in remotely.</BODY>\n";
|
||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
pwd[0] = 0;
|
||||
cmd[0] = 0;
|
||||
if (postbody)
|
||||
while (*postbody)
|
||||
{
|
||||
if (!strncmp(postbody, "pwd=", 4))
|
||||
{
|
||||
postbody = SV_ParsePOST(postbody+4, pwd, sizeof(pwd));
|
||||
}
|
||||
else if (!strncmp(postbody, "cmd=", 4))
|
||||
{
|
||||
postbody = SV_ParsePOST(postbody+4, cmd, sizeof(cmd));
|
||||
}
|
||||
else
|
||||
{
|
||||
while(*postbody && *postbody != '&')
|
||||
{
|
||||
postbody++;
|
||||
}
|
||||
if (*postbody == '&')
|
||||
postbody++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*pwd)
|
||||
o = "";
|
||||
else if (!strcmp(pwd, cluster->adminpassword))
|
||||
{
|
||||
o = Rcon_Command(cluster, NULL, cmd, result, sizeof(result), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
o = "Bad Password";
|
||||
}
|
||||
if (o != result)
|
||||
{
|
||||
strcpy(result, o);
|
||||
o = result;
|
||||
}
|
||||
|
||||
s = "HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
|
||||
"<HTML>"
|
||||
"<HEAD>"
|
||||
"<TITLE>QuakeTV: Admin</TITLE>\n"
|
||||
"<script type=\"text/javascript\">\n"
|
||||
//"<!--"
|
||||
"function sf(){document.f.cmd.focus();}\n"
|
||||
//"// -->"
|
||||
"</script>\n"
|
||||
"</HEAD>\n"
|
||||
"<BODY onload=sf()>";
|
||||
|
||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||
|
||||
s =
|
||||
"<FORM action=\"admin.html\" method=\"post\" name=f>"
|
||||
"<CENTER>"
|
||||
"Password <input name=pwd value=\"";
|
||||
|
||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||
if (*o)
|
||||
Net_ProxySend(cluster, dest, pwd, strlen(pwd));
|
||||
|
||||
|
||||
s = "\">"
|
||||
"<BR />"
|
||||
"Command <input name=cmd maxsize=255 size=40 value=\"\">"
|
||||
"<input type=submit value=\"Submit\" name=btn>"
|
||||
"</CENTER>"
|
||||
"</FORM>";
|
||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||
|
||||
while(*o)
|
||||
{
|
||||
s = strchr(o, '\n');
|
||||
if (s)
|
||||
*s = 0;
|
||||
Net_ProxySend(cluster, dest, o, strlen(o));
|
||||
Net_ProxySend(cluster, dest, "<BR />", 6);
|
||||
if (!s)
|
||||
break;
|
||||
o = s+1;
|
||||
}
|
||||
|
||||
s = "</BODY>"
|
||||
"</HTML>";
|
||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//returns true if the pending proxy should be unlinked
|
||||
//truth does not imply that it should be freed/released, just unlinked.
|
||||
qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
||||
|
@ -583,6 +754,7 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
|||
{
|
||||
closesocket(pend->sock);
|
||||
free(pend);
|
||||
cluster->numproxies--;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -610,7 +782,7 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
|||
|
||||
if (pend->inbuffersize >= 4)
|
||||
{
|
||||
if (strncmp(pend->inbuffer, "QTV\n", 4) && strncmp(pend->inbuffer, "GET ", 4))
|
||||
if (strncmp(pend->inbuffer, "QTV\n", 4) && strncmp(pend->inbuffer, "GET ", 4) && strncmp(pend->inbuffer, "POST ", 5))
|
||||
{ //I have no idea what the smeg you are.
|
||||
pend->drop = true;
|
||||
return false;
|
||||
|
@ -626,8 +798,52 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
|||
}
|
||||
if (!*s)
|
||||
return false; //don't have enough yet
|
||||
s+=3;
|
||||
|
||||
if (!strncmp(pend->inbuffer, "GET ", 4))
|
||||
if (!strncmp(pend->inbuffer, "POST ", 5))
|
||||
{
|
||||
if (!SV_GetHTTPHeaderField(pend->inbuffer, "Content-Length", tempbuf, sizeof(tempbuf)))
|
||||
{
|
||||
s = "HTTP/1.1 411 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
"<HEAD><TITLE>QuakeTV</TITLE></HEAD><BODY>No Content-Length was provided.</BODY>\n";
|
||||
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||
pend->flushing = true;
|
||||
return false;
|
||||
}
|
||||
len = atoi(tempbuf);
|
||||
if (pend->inbuffersize + len >= sizeof(pend->inbuffer)-20)
|
||||
{ //too much data
|
||||
pend->flushing = true;
|
||||
return false;
|
||||
}
|
||||
len = s - pend->inbuffer + len;
|
||||
if (len > pend->inbuffersize)
|
||||
return false; //still need the body
|
||||
|
||||
// if (len >= pend->inbuffersize)
|
||||
{
|
||||
if (!strncmp(pend->inbuffer+5, "/admin", 6))
|
||||
{
|
||||
SV_GenerateAdminHTTP(cluster, pend, 0, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
s = "HTTP/1.1 404 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
"<HEAD><TITLE>QuakeTV</TITLE></HEAD><BODY>That HTTP method is not supported for that URL.</BODY>\n";
|
||||
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||
|
||||
}
|
||||
pend->flushing = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!strncmp(pend->inbuffer, "GET ", 4))
|
||||
{
|
||||
if (!strncmp(pend->inbuffer+4, "/nowplaying", 11))
|
||||
{
|
||||
|
@ -638,12 +854,16 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
|||
SV_GenerateQTVStub(cluster, pend, atoi(pend->inbuffer+19));
|
||||
}
|
||||
else if (!strncmp(pend->inbuffer+4, "/about", 6))
|
||||
{
|
||||
{ //redirect them to our funky website
|
||||
s = "HTTP/1.0 302 Found\n"
|
||||
"Location: http://www.fteqw.com/\n"
|
||||
"\n";
|
||||
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||
}
|
||||
else if (!strncmp(pend->inbuffer+4, "/admin", 6))
|
||||
{
|
||||
SV_GenerateAdminHTTP(cluster, pend, 0, NULL);
|
||||
}
|
||||
else if (!strncmp(pend->inbuffer+4, "/ ", 2))
|
||||
{
|
||||
s = "HTTP/1.0 302 Found\n"
|
||||
|
@ -695,7 +915,11 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend)
|
|||
if (*s)
|
||||
if (!colon)
|
||||
{
|
||||
if (!strcmp(s, "SOURCELIST"))
|
||||
if (!strcmp(s, "QTV"))
|
||||
{
|
||||
//just a qtv request
|
||||
}
|
||||
else if (!strcmp(s, "SOURCELIST"))
|
||||
{ //lists sources that are currently playing
|
||||
s = "QTVSV 1\n";
|
||||
Net_ProxySend(cluster, pend, s, strlen(s));
|
||||
|
|
|
@ -375,6 +375,8 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
|||
Info_SetValueForStarKey(tv->serverinfo, "*qtv", VERSION, sizeof(tv->serverinfo));
|
||||
Info_SetValueForStarKey(tv->serverinfo, "*z_ext", Z_EXT_STRING, sizeof(tv->serverinfo));
|
||||
|
||||
Info_ValueForKey(tv->serverinfo, "hostname", tv->hostname, sizeof(tv->hostname));
|
||||
|
||||
//change the hostname (the qtv's hostname with the server's hostname in brackets)
|
||||
Info_ValueForKey(tv->serverinfo, "hostname", value, sizeof(value));
|
||||
if (fromproxy && strchr(value, '(') && value[strlen(value)-1] == ')') //already has brackets
|
||||
|
|
48
fteqtv/qtv.h
48
fteqtv/qtv.h
|
@ -25,6 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define LittleShort(x) (x)
|
||||
#endif
|
||||
|
||||
//this is for a future version
|
||||
//#define COMMENTARY
|
||||
|
||||
//each server that we are connected to has it's own state.
|
||||
//it should be easy enough to use one thread per server.
|
||||
|
||||
|
@ -128,6 +131,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//linux and other systems have strlcat / strlcpy
|
||||
//we support windows and can't use those
|
||||
#define Q_strncatz(dest, src, sizeofdest) \
|
||||
do { \
|
||||
strncat(dest, src, sizeofdest - strlen(dest) - 1); \
|
||||
dest[sizeofdest - 1] = 0; \
|
||||
} while (0)
|
||||
#define Q_strncpyz(dest, src, sizeofdest) \
|
||||
do { \
|
||||
strncpy(dest, src, sizeofdest - 1); \
|
||||
dest[sizeofdest - 1] = 0; \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define VERSION "0.01" //this will be added to the serverinfo
|
||||
|
||||
#define PROX_DEFAULTLISTENPORT 27501
|
||||
|
@ -191,7 +212,7 @@ extern "C" {
|
|||
|
||||
typedef unsigned char netadr_t[64];
|
||||
|
||||
#define NQ_PACKETS_PER_SECOND 100
|
||||
#define NQ_PACKETS_PER_SECOND 20
|
||||
#define MAX_NQMSGLEN 8000
|
||||
#define MAX_MSGLEN 1400
|
||||
#define MAX_NQDATAGRAM 1024
|
||||
|
@ -217,11 +238,12 @@ typedef unsigned char netadr_t[64];
|
|||
#define NET_GAMENAME_NQ "QUAKE"
|
||||
#define NET_PROTOCOL_VERSION 3
|
||||
|
||||
|
||||
#ifdef COMMENTARY
|
||||
typedef struct soundcapt_s {
|
||||
int (*update)(struct soundcapt_s *ghnd, int samplechunks, char *buffer);
|
||||
void (*close)(struct soundcapt_s *ptr);
|
||||
} soundcapt_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned int readpos;
|
||||
|
@ -339,6 +361,7 @@ typedef struct viewer_s {
|
|||
qboolean maysend;
|
||||
qboolean chokeme;
|
||||
qboolean thinksitsconnected;
|
||||
qboolean conmenussupported;
|
||||
int delta_frame;
|
||||
|
||||
int servercount;
|
||||
|
@ -416,6 +439,13 @@ typedef struct {
|
|||
unsigned short leafs[MAX_ENTITY_LEAFS];
|
||||
} entity_t;
|
||||
|
||||
#define MAX_ENTITY_FRAMES 64
|
||||
typedef struct {
|
||||
int numents;
|
||||
int maxents;
|
||||
entity_state_t *ents; //dynamically allocated
|
||||
} frame_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char number;
|
||||
char bits[6];
|
||||
|
@ -452,6 +482,7 @@ struct sv_s {
|
|||
} movevars;
|
||||
int cdtrack;
|
||||
entity_t entity[MAX_ENTITIES];
|
||||
frame_t frame[MAX_ENTITY_FRAMES];
|
||||
int maxents;
|
||||
staticsound_t staticsound[MAX_STATICSOUNDS];
|
||||
int staticsound_count;
|
||||
|
@ -528,8 +559,10 @@ struct sv_s {
|
|||
bsp_t *bsp;
|
||||
int numinlines;
|
||||
|
||||
#ifdef COMMENTARY
|
||||
//audio stuff
|
||||
soundcapt_t *comentrycapture;
|
||||
#endif
|
||||
|
||||
//options:
|
||||
char server[MAX_QPATH];
|
||||
|
@ -564,9 +597,13 @@ struct cluster_s {
|
|||
qboolean lateforward;
|
||||
qboolean notalking;
|
||||
qboolean nobsp;
|
||||
qboolean allownqclients; //nq clients require no challenge
|
||||
qboolean nouserconnects; //prohibit users from connecting to new streams.
|
||||
|
||||
int maxviewers;
|
||||
|
||||
int buildnumber;
|
||||
|
||||
int numproxies;
|
||||
int maxproxies;
|
||||
|
||||
|
@ -575,7 +612,10 @@ struct cluster_s {
|
|||
oproxy_t *pendingproxies;
|
||||
};
|
||||
|
||||
|
||||
#define MENU_NONE 0
|
||||
#define MENU_SERVERS 1
|
||||
#define MENU_ADMIN 2
|
||||
#define MENU_ADMINSERVER 3
|
||||
|
||||
|
||||
|
||||
|
@ -765,7 +805,7 @@ void WriteData(netmsg_t *b, const char *data, int length);
|
|||
void Multicast(sv_t *tv, char *buffer, int length, int to, unsigned int playermask,int suitablefor);
|
||||
void Broadcast(cluster_t *cluster, char *buffer, int length, int suitablefor);
|
||||
void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask);
|
||||
void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount);
|
||||
void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount, qboolean spectatorflag);
|
||||
void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount);
|
||||
SOCKET QW_InitUDPSocket(int port);
|
||||
void QW_UpdateUDPStuff(cluster_t *qtv);
|
||||
|
|
|
@ -67,7 +67,7 @@ LINK32=link.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"qtv.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "speex-1.2beta1\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"qtv.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
|
222
fteqtv/qw.c
222
fteqtv/qw.c
|
@ -24,10 +24,6 @@ static const filename_t ConnectionlessModelList[] = {{""}, {"maps/start.bsp"}, {
|
|||
static const filename_t ConnectionlessSoundList[] = {{""}, {""}};
|
||||
|
||||
|
||||
#define MENU_NONE 0
|
||||
#define MENU_SERVERS 1
|
||||
#define MENU_ADMIN 2
|
||||
#define MENU_ADMINSERVER 3
|
||||
|
||||
void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum);
|
||||
void QW_SetMenu(viewer_t *v, int menunum);
|
||||
|
@ -197,7 +193,7 @@ SOCKET QW_InitUDPSocket(int port)
|
|||
return sock;
|
||||
}
|
||||
|
||||
void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount)
|
||||
void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount, qboolean spectatorflag)
|
||||
{
|
||||
WriteByte(msg, svc_serverdata);
|
||||
WriteLong(msg, PROTOCOL_VERSION);
|
||||
|
@ -211,7 +207,7 @@ void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount)
|
|||
if (mvd)
|
||||
WriteFloat(msg, 0);
|
||||
else
|
||||
WriteByte(msg, MAX_CLIENTS-1);
|
||||
WriteByte(msg, MAX_CLIENTS-1 | (spectatorflag?128:0));
|
||||
WriteString(msg, "FTEQTV Proxy");
|
||||
|
||||
|
||||
|
@ -242,7 +238,7 @@ void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount)
|
|||
if (mvd)
|
||||
WriteFloat(msg, 0);
|
||||
else
|
||||
WriteByte(msg, tv->thisplayer);
|
||||
WriteByte(msg, tv->thisplayer | (spectatorflag?128:0));
|
||||
WriteString(msg, tv->mapname);
|
||||
|
||||
|
||||
|
@ -330,7 +326,7 @@ void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int playernum)
|
|||
WriteByte(msg, tv->cdtrack);
|
||||
|
||||
WriteByte(msg, svc_nqsetview);
|
||||
WriteShort(msg, tv->trackplayer);
|
||||
WriteShort(msg, 15);
|
||||
|
||||
WriteByte(msg, svc_nqsignonnum);
|
||||
WriteByte(msg, 1);
|
||||
|
@ -350,11 +346,11 @@ void SendServerData(sv_t *tv, viewer_t *viewer)
|
|||
if (tv && (tv->controller == viewer || !tv->controller))
|
||||
viewer->thisplayer = tv->thisplayer;
|
||||
else
|
||||
viewer->thisplayer = 15;
|
||||
viewer->thisplayer = viewer->netchan.isnqprotocol?15:MAX_CLIENTS-1;
|
||||
if (viewer->netchan.isnqprotocol)
|
||||
BuildNQServerData(tv, &msg, false, viewer->thisplayer);
|
||||
else
|
||||
BuildServerData(tv, &msg, false, viewer->servercount);
|
||||
BuildServerData(tv, &msg, false, viewer->servercount, !tv || tv->controller != viewer);
|
||||
|
||||
SendBufferToViewer(viewer, msg.data, msg.cursize, true);
|
||||
|
||||
|
@ -650,7 +646,7 @@ void NewClient(cluster_t *cluster, viewer_t *viewer)
|
|||
}
|
||||
|
||||
|
||||
QW_PrintfToViewer(viewer, "Welcome to FTEQTV\n");
|
||||
QW_PrintfToViewer(viewer, "Welcome to FTEQTV build %i\n", cluster->buildnumber);
|
||||
QW_StuffcmdToViewer(viewer, "alias admin \"cmd admin\"\n");
|
||||
|
||||
QW_StuffcmdToViewer(viewer, "alias \"proxy:up\" \"say proxy:menu up\"\n");
|
||||
|
@ -835,6 +831,10 @@ void QW_SetMenu(viewer_t *v, int menunum)
|
|||
QW_StuffcmdToViewer(v, "alias \"-proxleft\" \"-moveleft\"\n");
|
||||
QW_StuffcmdToViewer(v, "alias \"-proxright\" \"-moveright\"\n");
|
||||
}
|
||||
QW_StuffcmdToViewer(v, "-forward\n");
|
||||
QW_StuffcmdToViewer(v, "-back\n");
|
||||
QW_StuffcmdToViewer(v, "-moveleft\n");
|
||||
QW_StuffcmdToViewer(v, "-moveright\n");
|
||||
}
|
||||
|
||||
v->menunum = menunum;
|
||||
|
@ -880,6 +880,10 @@ void QTV_Status(cluster_t *cluster, netadr_t *from)
|
|||
WriteLong(&msg, -1);
|
||||
WriteByte(&msg, 'n');
|
||||
|
||||
WriteString2(&msg, "\\*QTV\\");
|
||||
sprintf(elem, "%i", cluster->buildnumber);
|
||||
WriteString2(&msg, elem);
|
||||
|
||||
if (cluster->numservers==1)
|
||||
{ //show this server's info
|
||||
sv = cluster->servers;
|
||||
|
@ -946,11 +950,11 @@ void QTV_Status(cluster_t *cluster, netadr_t *from)
|
|||
|
||||
for (sv = cluster->servers, i = 0; sv; sv = sv->next, i++)
|
||||
{
|
||||
sprintf(elem, "\\%i\\", i);
|
||||
sprintf(elem, "\\%i\\", sv->streamid);
|
||||
WriteString2(&msg, elem);
|
||||
WriteString2(&msg, sv->serveraddress);
|
||||
sprintf(elem, " (%s)", sv->serveraddress);
|
||||
WriteString2(&msg, sv->serveraddress);
|
||||
WriteString2(&msg, elem);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2038,7 +2042,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
{
|
||||
QW_PrintfToViewer(v, "Website: http://www.fteqw.com/\n"
|
||||
"Commands:\n"
|
||||
".qw qwserver:port\n"
|
||||
".observe qwserver:port\n"
|
||||
".qtv tcpserver:port\n"
|
||||
".demo gamedir/demoname.mvd\n"
|
||||
".disconnect\n"
|
||||
|
@ -2046,6 +2050,129 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
".bind\n"
|
||||
);
|
||||
}
|
||||
else if (!strncmp(message, ".guimenu", 8))
|
||||
{
|
||||
sv_t *sv;
|
||||
int y;
|
||||
qboolean shownheader = false;
|
||||
QW_StuffcmdToViewer(v,
|
||||
|
||||
"alias menucallback\n"
|
||||
"{\n"
|
||||
"menuclear\n"
|
||||
"if (option == \"OBSERVE\")\n"
|
||||
"{\necho Spectating server $_server\nsay .observe $_server\n}\n"
|
||||
"if (option == \"QTV\")\n"
|
||||
"{\necho Streaming from qtv at $_server\nsay .qtv $_server\n}\n"
|
||||
"if (option == \"JOIN\")\n"
|
||||
"{\necho Joining game at $_server\nsay .join $_server\n}\n"
|
||||
"if (option == \"ADMIN\")\n"
|
||||
"{\nsay .guiadmin\n}\n"
|
||||
"if (\"stream \" isin option)\n"
|
||||
"{\necho Changing stream\nsay .$option\n}\n"
|
||||
"}\n"
|
||||
/*
|
||||
"conmenu menucallback\n"
|
||||
"menupic 16 4 gfx/qplaque.lmp\n"
|
||||
"menupic - 4 gfx/p_option.lmp\n"
|
||||
|
||||
"menuedit 16 32 \" Server\" \"_server\"\n"
|
||||
|
||||
"menutext 72 48 \"Observe\" OBSERVE\n"
|
||||
"menutext 136 48 \"QTV\" QTV\n"
|
||||
"menutext 168 48 \"Cancel\" cancel\n"
|
||||
"menutext 224 48 \"Join\" JOIN\n"
|
||||
"menutext 264 48 \"Admin\" ADMIN\n"
|
||||
*/
|
||||
"conmenu menucallback\n"
|
||||
"menupic 0 4 gfx/qplaque.lmp\n"
|
||||
"menupic 96 4 gfx/p_option.lmp\n"
|
||||
|
||||
"menuedit 48 36 \"Óåòöåòº\" \"_server\"\n"
|
||||
|
||||
"menutext 104 52 \"Join\" JOIN\n"
|
||||
|
||||
"menutext 152 52 \"Observe\" OBSERVE\n"
|
||||
|
||||
"menutext 224 52 \"QTV\" QTV\n"
|
||||
|
||||
|
||||
|
||||
"menutext 48 84 \"Admin\" ADMIN\n"
|
||||
|
||||
"menutext 48 92 \"Close Menu\" cancel\n"
|
||||
|
||||
|
||||
|
||||
"menutext 48 116 \"Type in a server address and\"\n"
|
||||
"menutext 48 124 \"click join to play in the game,\"\n"
|
||||
"menutext 48 132 \"observe(udp) to watch, or qtv(tcp)\"\n"
|
||||
"menutext 48 140 \"to connect to a stream or proxy.\"\n"
|
||||
);
|
||||
|
||||
y = 140+16;
|
||||
for (sv = cluster->servers; sv; sv = sv->next)
|
||||
{
|
||||
if (!shownheader)
|
||||
{
|
||||
shownheader = true;
|
||||
QW_StuffcmdToViewer(v, "menutext 72 %i \"Áãôéöå Çáíåóº\"\n", y);
|
||||
y+=8;
|
||||
}
|
||||
QW_StuffcmdToViewer(v, "menutext 32 %i \"%30s\" \"stream %i\"\n", y, *sv->hostname?sv->hostname:sv->server, sv->streamid);
|
||||
y+=8;
|
||||
}
|
||||
if (!shownheader)
|
||||
QW_StuffcmdToViewer(v, "menutext 72 %i \"There are no active games\"\n", y);
|
||||
|
||||
}
|
||||
else if (!strncmp(message, ".guiadmin", 6))
|
||||
{
|
||||
if (!*cluster->adminpassword)
|
||||
{
|
||||
QW_StuffcmdToViewer(v,
|
||||
|
||||
"alias menucallback\n"
|
||||
"{\n"
|
||||
"menuclear\n"
|
||||
"}\n"
|
||||
|
||||
"conmenu menucallback\n"
|
||||
"menupic 16 4 gfx/qplaque.lmp\n"
|
||||
"menupic - 4 gfx/p_option.lmp\n"
|
||||
|
||||
"menutext 72 48 \"No admin password is set\"\n"
|
||||
"menutext 72 56 \"Admin access is prohibited\"\n"
|
||||
);
|
||||
}
|
||||
else if (v->isadmin)
|
||||
//already an admin, so don't show admin login screen
|
||||
QW_SetMenu(v, MENU_ADMIN);
|
||||
else
|
||||
{
|
||||
QW_StuffcmdToViewer(v,
|
||||
|
||||
"alias menucallback\n"
|
||||
"{\n"
|
||||
"menuclear\n"
|
||||
"if (option == \"log\")\n"
|
||||
"{\nsay $_password\n}\n"
|
||||
"set _password \"\"\n"
|
||||
"}\n"
|
||||
|
||||
"conmenu menucallback\n"
|
||||
"menupic 16 4 gfx/qplaque.lmp\n"
|
||||
"menupic - 4 gfx/p_option.lmp\n"
|
||||
|
||||
"menuedit 16 32 \" Password\" \"_password\"\n"
|
||||
|
||||
"menutext 72 48 \"Log in QW\" log\n"
|
||||
"menutext 192 48 \"Cancel\" cancel\n"
|
||||
);
|
||||
|
||||
strcpy(v->expectcommand, "admin");
|
||||
}
|
||||
}
|
||||
else if (!strncmp(message, ".reset", 6))
|
||||
{
|
||||
QW_SetViewersServer(v, NULL);
|
||||
|
@ -2072,7 +2199,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
QW_StuffcmdToViewer(v, "echo Please enter the rcon password\nmessagemode\n");
|
||||
}
|
||||
}
|
||||
else if (!strncmp(message, ".connect ", 9) || !strncmp(message, ".qw ", 4))
|
||||
else if (!strncmp(message, ".connect ", 9) || !strncmp(message, ".qw ", 4) || !strncmp(message, ".observe ", 9))
|
||||
{
|
||||
if (!strncmp(message, ".qw ", 4))
|
||||
message += 4;
|
||||
|
@ -2118,6 +2245,29 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
else
|
||||
QW_PrintfToViewer(v, "Failed to connect to server \"%s\", connection aborted\n", message);
|
||||
}
|
||||
else if (!strncmp(message, ".stream ", 7))
|
||||
{
|
||||
int id;
|
||||
message += 7;
|
||||
id = atoi(message);
|
||||
for (qtv = cluster->servers; qtv; qtv = qtv->next)
|
||||
{
|
||||
if (qtv->streamid == id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (qtv)
|
||||
{
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QW_SetViewersServer(v, qtv);
|
||||
QW_PrintfToViewer(v, "Connected\n", message);
|
||||
}
|
||||
else
|
||||
{
|
||||
QW_PrintfToViewer(v, "Stream not recognised. Stream id is invalid or terminated.\n", message);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(message, ".demo ", 6))
|
||||
{
|
||||
message += 6;
|
||||
|
@ -2201,26 +2351,38 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
QW_StuffcmdToViewer(v, "bind pause \"proxy:menu\"\n");
|
||||
QW_StuffcmdToViewer(v, "bind backspace \"proxy:menu back\"\n");
|
||||
}
|
||||
else if (!strncmp(message, ".", 1))
|
||||
else if (!strncmp(message, ".", 1) && strncmp(message, "..", 2))
|
||||
{
|
||||
QW_PrintfToViewer(v, "Proxy command not recognised\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strncmp(message, ".", 1))
|
||||
message++;
|
||||
*v->expectcommand = '\0';
|
||||
|
||||
if (cluster->notalking)
|
||||
return;
|
||||
|
||||
if (qtv && qtv->usequkeworldprotocols && !noupwards)
|
||||
{
|
||||
if (qtv->controller == v || !*v->name)
|
||||
{
|
||||
SendClientCommand(qtv, "say %s\n", message);
|
||||
|
||||
if (cluster->notalking)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cluster->notalking)
|
||||
return;
|
||||
SendClientCommand(qtv, "say %s: %s\n", v->name, message);
|
||||
}
|
||||
|
||||
//FIXME: we ought to broadcast this to everyone not watching that qtv.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cluster->notalking)
|
||||
return;
|
||||
|
||||
InitNetMsg(&msg, buf, sizeof(buf));
|
||||
|
||||
|
@ -2334,9 +2496,7 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
}
|
||||
else if (!strncmp(buf, "name ", 5))
|
||||
{
|
||||
/*
|
||||
fixme
|
||||
*/
|
||||
Q_strncpyz(v->name, buf+5, sizeof(v->name));
|
||||
}
|
||||
else if (!strncmp(buf, "color ", 6))
|
||||
{
|
||||
|
@ -2344,7 +2504,7 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
fixme
|
||||
*/
|
||||
}
|
||||
else if (!strncmp(buf, "spawn ", 6))
|
||||
else if (!strncmp(buf, "spawn", 5))
|
||||
{
|
||||
msg.data = buf;
|
||||
msg.maxsize = sizeof(buf);
|
||||
|
@ -2442,6 +2602,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
QW_StuffcmdToViewer(v, "cmd new\n");
|
||||
else
|
||||
{
|
||||
QW_StuffcmdToViewer(v, "//querycmd conmenu\n");
|
||||
SendServerData(qtv, v);
|
||||
}
|
||||
}
|
||||
|
@ -2648,7 +2809,13 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
if (v->server && v->server->controller == v)
|
||||
SendClientCommand(v->server, "%s", buf);
|
||||
}
|
||||
|
||||
else if (!strncmp(buf, "cmdsupported ", 13))
|
||||
{
|
||||
if (!strcmp(buf+13, "conmenu"))
|
||||
v->conmenussupported = true;
|
||||
else if (v->server && v->server->controller == v)
|
||||
SendClientCommand(v->server, "%s", buf);
|
||||
}
|
||||
else if (!qtv)
|
||||
{
|
||||
//all the other things need an active server.
|
||||
|
@ -2809,7 +2976,7 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
|
|||
if (i++ == viewer->menuop)
|
||||
{ //qw port
|
||||
QW_StuffcmdToViewer(viewer, "echo You will need to reconnect\n");
|
||||
cluster->qwlistenportnum += buttonnum?-1:1;
|
||||
cluster->qwlistenportnum += (buttonnum<0)?-1:1;
|
||||
}
|
||||
if (i++ == viewer->menuop)
|
||||
{ //hostname
|
||||
|
@ -2875,7 +3042,8 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
|
|||
|
||||
WriteByte(&m, svc_centerprint);
|
||||
|
||||
WriteString2(&m, "FTEQTV\n");
|
||||
sprintf(str, "FTEQTV build %i\n", cluster->buildnumber);
|
||||
WriteString2(&m, str);
|
||||
if (strcmp(cluster->hostname, DEFAULT_HOSTNAME))
|
||||
WriteString2(&m, cluster->hostname);
|
||||
|
||||
|
@ -3216,7 +3384,7 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!v)
|
||||
if (!v && cluster->allownqclients)
|
||||
{
|
||||
//NQ connectionless packet?
|
||||
m.readpos = 0;
|
||||
|
|
493
fteqtv/rcon.c
493
fteqtv/rcon.c
|
@ -433,66 +433,69 @@ char *Cmd_Exec(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffer,
|
|||
return "Execed\n";
|
||||
}
|
||||
}
|
||||
|
||||
void catbuffer(char *buffer, int bufsize, char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
va_start (argptr, format);
|
||||
vsnprintf (string,sizeof(string)-1, format,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
Q_strncatz(buffer, string, bufsize);
|
||||
}
|
||||
char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffer, int sizeofbuffer, qboolean localcommand)
|
||||
{
|
||||
|
||||
buffer[0] = '\0';
|
||||
|
||||
sprintf(buffer, "%i connections\n", cluster->numservers);
|
||||
catbuffer(buffer, sizeofbuffer, "%i sources\n", cluster->numservers);
|
||||
catbuffer(buffer, sizeofbuffer, "%i viewers\n", cluster->numviewers);
|
||||
catbuffer(buffer, sizeofbuffer, "%i proxies\n", cluster->numproxies);
|
||||
|
||||
strcat(buffer, "Options:\n");
|
||||
strcat(buffer, " Hostname ");
|
||||
strcat(buffer, cluster->hostname);
|
||||
strcat(buffer, "\n");
|
||||
catbuffer(buffer, sizeofbuffer, "Options:\n");
|
||||
catbuffer(buffer, sizeofbuffer, " Hostname %s\n", cluster->hostname);
|
||||
|
||||
if (cluster->chokeonnotupdated)
|
||||
strcat(buffer, " Choke\n");
|
||||
catbuffer(buffer, sizeofbuffer, " Choke\n");
|
||||
if (cluster->lateforward)
|
||||
strcat(buffer, " Late forwarding\n");
|
||||
catbuffer(buffer, sizeofbuffer, " Late forwarding\n");
|
||||
if (!cluster->notalking)
|
||||
strcat(buffer, " Talking allowed\n");
|
||||
catbuffer(buffer, sizeofbuffer, " Talking allowed\n");
|
||||
if (cluster->nobsp)
|
||||
strcat(buffer, " No BSP loading\n");
|
||||
strcat(buffer, "\n");
|
||||
catbuffer(buffer, sizeofbuffer, " No BSP loading\n");
|
||||
catbuffer(buffer, sizeofbuffer, "\n");
|
||||
|
||||
|
||||
if (qtv)
|
||||
{
|
||||
strcat(buffer, "Selected server: ");
|
||||
strcat(buffer, qtv->server);
|
||||
strcat(buffer, "\n");
|
||||
catbuffer(buffer, sizeofbuffer, "Selected server: %s\n", qtv->server);
|
||||
if (qtv->file)
|
||||
strcat(buffer, "Playing from file\n");
|
||||
catbuffer(buffer, sizeofbuffer, "Playing from file\n");
|
||||
if (qtv->sourcesock != INVALID_SOCKET)
|
||||
strcat(buffer, "Connected\n");
|
||||
catbuffer(buffer, sizeofbuffer, "Connected\n");
|
||||
if (qtv->parsingqtvheader || qtv->parsingconnectiondata)
|
||||
strcat(buffer, "Waiting for gamestate\n");
|
||||
catbuffer(buffer, sizeofbuffer, "Waiting for gamestate\n");
|
||||
if (qtv->controller)
|
||||
{
|
||||
strcat(buffer, "Spectating through ");
|
||||
strcat(buffer, qtv->controller->name);
|
||||
strcat(buffer, "\n");
|
||||
catbuffer(buffer, sizeofbuffer, "Spectating through %s\n");
|
||||
}
|
||||
if (*qtv->modellist[1].name)
|
||||
{
|
||||
strcat(buffer, "Map name ");
|
||||
strcat(buffer, qtv->modellist[1].name);
|
||||
strcat(buffer, "\n");
|
||||
catbuffer(buffer, sizeofbuffer, "Map name %s\n", qtv->modellist[1].name);
|
||||
}
|
||||
if (qtv->connectpassword)
|
||||
strcat(buffer, "Using a password\n");
|
||||
if (*qtv->connectpassword)
|
||||
catbuffer(buffer, sizeofbuffer, "Using a password\n");
|
||||
|
||||
if (qtv->tcpsocket != INVALID_SOCKET)
|
||||
{
|
||||
strcat(buffer, "Listening for proxies (");
|
||||
sprintf(arg[0], "%i", qtv->tcplistenportnum);
|
||||
strcat(buffer, arg[0]);
|
||||
strcat(buffer, ")\n");
|
||||
catbuffer(buffer, sizeofbuffer, "Listening for proxies (%i)\n", qtv->tcplistenportnum);
|
||||
}
|
||||
|
||||
if (qtv->bsp)
|
||||
{
|
||||
strcat(buffer, "BSP (");
|
||||
strcat(buffer, qtv->mapname);
|
||||
strcat(buffer, ") is loaded\n");
|
||||
catbuffer(buffer, sizeofbuffer, "BSP (%s) is loaded\n", qtv->mapname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -576,6 +579,17 @@ char *Cmd_Quit(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffer,
|
|||
|
||||
|
||||
|
||||
char *Cmd_Streams(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffer, int sizeofbuffer, qboolean localcommand)
|
||||
{
|
||||
catbuffer(buffer, sizeofbuffer, "Streams:\n");
|
||||
|
||||
for (qtv = cluster->servers; qtv; qtv = qtv->next)
|
||||
{
|
||||
catbuffer(buffer, sizeofbuffer, "%i: %s\n", qtv->streamid, qtv->server);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -679,6 +693,7 @@ const rconcommands_t rconcommands[] =
|
|||
{"addserver", 0, 1, Cmd_QTVConnect},
|
||||
{"connect", 0, 1, Cmd_QTVConnect},
|
||||
{"qw", 0, 1, Cmd_QWConnect},
|
||||
{"observe", 0, 1, Cmd_QWConnect},
|
||||
{"demo", 0, 1, Cmd_MVDConnect},
|
||||
{"playdemo", 0, 1, Cmd_MVDConnect},
|
||||
{"choke", 0, 1, Cmd_Choke},
|
||||
|
@ -691,6 +706,7 @@ const rconcommands_t rconcommands[] =
|
|||
{"reconnect", 0, 1, Cmd_Reconnect},
|
||||
{"echo", 0, 1, Cmd_Echo},
|
||||
{"quit", 0, 1, Cmd_Quit},
|
||||
{"streams", 0, 1, Cmd_Streams},
|
||||
|
||||
|
||||
|
||||
|
@ -704,401 +720,6 @@ const rconcommands_t rconcommands[] =
|
|||
{NULL}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
static char *Cluster_Rcon_Dispatch(cluster_t *cluster, char *arg[MAX_ARGS], char *buffer, int sizeofbuffer, qboolean localcommand)
|
||||
{
|
||||
if (!strcmp(arg[0], "hostname"))
|
||||
{
|
||||
strncpy(cluster->hostname, arg[1], sizeof(cluster->hostname)-1);
|
||||
return "hostname will change at start of next map\n"; //I'm too lazy to alter the serverinfo here.
|
||||
}
|
||||
else if (!strcmp(arg[0], "master"))
|
||||
{
|
||||
netadr_t addr;
|
||||
|
||||
strncpy(cluster->master, arg[1], sizeof(cluster->master)-1);
|
||||
cluster->mastersendtime = cluster->curtime;
|
||||
|
||||
if (NET_StringToAddr(arg[1], &addr, 27000)) //send a ping like a qw server does. this is kinda pointless of course.
|
||||
NET_SendPacket (cluster, cluster->qwdsocket, 1, "k", addr);
|
||||
|
||||
return "Master server set.\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "port"))
|
||||
{
|
||||
int news;
|
||||
int newp = atoi(arg[1]);
|
||||
news = QW_InitUDPSocket(newp);
|
||||
|
||||
if (news != INVALID_SOCKET)
|
||||
{
|
||||
cluster->mastersendtime = cluster->curtime;
|
||||
closesocket(cluster->qwdsocket);
|
||||
cluster->qwdsocket = news;
|
||||
cluster->qwlistenportnum = newp;
|
||||
return "Opened udp port (all connected qw clients will time out)\n";
|
||||
}
|
||||
else
|
||||
return "Failed to open udp port\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "password"))
|
||||
{
|
||||
if (!localcommand)
|
||||
return "Rejecting rcon password change.\n";
|
||||
|
||||
strncpy(cluster->password, arg[1], sizeof(cluster->password)-1);
|
||||
return "Password changed.\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "qtv") || !strcmp(arg[0], "connect") || !strcmp(arg[0], "addserver"))
|
||||
{
|
||||
if (!*arg[1])
|
||||
return "connect requires an ip:port parameter\n";
|
||||
|
||||
memmove(arg[1]+4, arg[1], ARG_LEN-5);
|
||||
strncpy(arg[1], "tcp:", 4);
|
||||
|
||||
if (!QTV_NewServerConnection(cluster, arg[1], false, false, false))
|
||||
return "Failed to connect to server, connection aborted\n";
|
||||
return "Source registered\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "qw"))
|
||||
{
|
||||
if (!*arg[1])
|
||||
return "connect requires an ip:port parameter\n";
|
||||
|
||||
memmove(arg[1]+4, arg[1], ARG_LEN-5);
|
||||
strncpy(arg[1], "udp:", 4);
|
||||
|
||||
if (!QTV_NewServerConnection(cluster, arg[1], false, false, false))
|
||||
return "Failed to connect to server, connection aborted\n";
|
||||
return "Source registered\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "demo") || !strcmp(arg[0], "adddemo") || !strcmp(arg[0], "addfile"))
|
||||
{
|
||||
if (!*arg[1])
|
||||
return "adddemo requires an filename parameter\n";
|
||||
|
||||
if (!localcommand)
|
||||
if (*arg[1] == '\\' || *arg[1] == '/' || strstr(arg[1], "..") || arg[1][1] == ':')
|
||||
return "Absolute paths are prohibited.\n";
|
||||
|
||||
memmove(arg[1]+5, arg[1], ARG_LEN-6);
|
||||
strncpy(arg[1], "file:", 5);
|
||||
|
||||
if (!QTV_NewServerConnection(cluster, arg[1], false, false, false))
|
||||
return "Failed to connect to server, connection aborted\n";
|
||||
return "Source registered\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "exec"))
|
||||
{
|
||||
FILE *f;
|
||||
char line[512], *res;
|
||||
|
||||
if (!localcommand)
|
||||
if (*arg[1] == '\\' || *arg[1] == '/' || strstr(arg[1], "..") || arg[1][1] == ':')
|
||||
return "Absolute paths are prohibited.\n";
|
||||
|
||||
f = fopen(arg[1], "rt");
|
||||
if (!f)
|
||||
{
|
||||
snprintf(buffer, sizeofbuffer, "Couldn't exec \"%s\"\n", arg[1]);
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(fgets(line, sizeof(line)-1, f))
|
||||
{
|
||||
res = Rcon_Command(cluster, NULL, line, buffer, sizeofbuffer, localcommand);
|
||||
Sys_Printf(cluster, "%s", res);
|
||||
}
|
||||
fclose(f);
|
||||
return "Execed\n";
|
||||
}
|
||||
}
|
||||
else if (!strcmp(arg[0], "status"))
|
||||
{
|
||||
buffer[0] = '\0';
|
||||
|
||||
sprintf(buffer, "%i connections\n", cluster->numservers);
|
||||
|
||||
strcat(buffer, "Options:\n");
|
||||
if (cluster->chokeonnotupdated)
|
||||
strcat(buffer, " Choke\n");
|
||||
if (cluster->lateforward)
|
||||
strcat(buffer, " Late forwarding\n");
|
||||
if (!cluster->notalking)
|
||||
strcat(buffer, " Talking allowed\n");
|
||||
if (cluster->nobsp)
|
||||
strcat(buffer, " No BSP loading\n");
|
||||
strcat(buffer, "\n");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
else if (!strcmp(arg[0], "choke"))
|
||||
{
|
||||
cluster->chokeonnotupdated = !!atoi(arg[1]);
|
||||
return "choke-until-update set\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "late"))
|
||||
{
|
||||
cluster->lateforward = !!atoi(arg[1]);
|
||||
return "late forwarding set\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "talking"))
|
||||
{
|
||||
cluster->notalking = !atoi(arg[1]);
|
||||
return "talking permissions set\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "nobsp"))
|
||||
{
|
||||
cluster->nobsp = !!atoi(arg[1]);
|
||||
return "nobsp will change at start of next map\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[1], "maxviewers"))
|
||||
{
|
||||
cluster->maxviewers = atoi(arg[2]);
|
||||
return "maxviewers set\n";
|
||||
}
|
||||
else if (!strcmp(arg[1], "maxproxies"))
|
||||
{
|
||||
cluster->maxproxies = atoi(arg[2]);
|
||||
return "maxproxies set\n";
|
||||
}
|
||||
|
||||
|
||||
else if (!strcmp(arg[0], "ping"))
|
||||
{
|
||||
netadr_t addr;
|
||||
if (NET_StringToAddr(arg[1], &addr, 27500))
|
||||
{
|
||||
NET_SendPacket (cluster, cluster->qwdsocket, 1, "k", addr);
|
||||
return "pinged\n";
|
||||
}
|
||||
return "couldn't resolve\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "help"))
|
||||
{
|
||||
return HELPSTRING;
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "mvdport"))
|
||||
{
|
||||
return "mvdport requires a targeted server. Connect first.\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "record"))
|
||||
{
|
||||
return "record requires a targeted server\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "reconnect"))
|
||||
{
|
||||
return "reconnect requires a targeted server\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "stop"))
|
||||
{ //fixme
|
||||
return "stop requires a targeted server\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "echo"))
|
||||
{
|
||||
return "Poly wants a cracker.\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "quit"))
|
||||
{
|
||||
cluster->wanttoexit = true;
|
||||
return "Shutting down.\n";
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *Server_Rcon_Dispatch(sv_t *qtv, char *arg[MAX_ARGS], char *buffer, int sizeofbuffer, qboolean localcommand)
|
||||
{
|
||||
#define TOKENIZE_PUNCTUATION ""
|
||||
|
||||
|
||||
buffer[0] = '\0';
|
||||
if (!strcmp(arg[0], "status"))
|
||||
{
|
||||
sprintf(buffer, "%i connections\n", qtv->cluster->numservers);
|
||||
|
||||
strcat(buffer, "\n");
|
||||
strcat(buffer, "Selected server: ");
|
||||
strcat(buffer, qtv->server);
|
||||
strcat(buffer, "\n");
|
||||
if (qtv->file)
|
||||
strcat(buffer, "Playing from file\n");
|
||||
if (qtv->sourcesock != INVALID_SOCKET)
|
||||
strcat(buffer, "Connected\n");
|
||||
if (qtv->parsingconnectiondata)
|
||||
strcat(buffer, "Waiting for gamestate\n");
|
||||
|
||||
if (qtv->listenmvd != INVALID_SOCKET)
|
||||
{
|
||||
strcat(buffer, "Listening for proxies (");
|
||||
sprintf(arg[0], "%i", qtv->tcplistenportnum);
|
||||
strcat(buffer, arg[0]);
|
||||
strcat(buffer, ")\n");
|
||||
}
|
||||
|
||||
if (qtv->bsp)
|
||||
{
|
||||
strcat(buffer, "BSP (");
|
||||
strcat(buffer, qtv->mapname);
|
||||
strcat(buffer, ") is loaded\n");
|
||||
}
|
||||
|
||||
strcat(buffer, "Options:\n");
|
||||
if (qtv->cluster->chokeonnotupdated)
|
||||
strcat(buffer, " Choke\n");
|
||||
if (qtv->cluster->lateforward)
|
||||
strcat(buffer, " Late forwarding\n");
|
||||
if (!qtv->cluster->notalking)
|
||||
strcat(buffer, " Talking allowed\n");
|
||||
if (qtv->cluster->nobsp)
|
||||
strcat(buffer, " No BSP loading\n");
|
||||
strcat(buffer, "\n");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "connect"))
|
||||
{
|
||||
if (!*arg[1])
|
||||
return "connect requires an ip:port parameter\n";
|
||||
|
||||
if (QTV_Connect(qtv, arg[1]))
|
||||
return "Connected, waiting for data\n";
|
||||
else
|
||||
return "Failed (will keep trying)\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "disconnect"))
|
||||
{
|
||||
QTV_Shutdown(qtv);
|
||||
return "Disconnected\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "file") || !strcmp(arg[0], "play") || !strcmp(arg[0], "playdemo"))
|
||||
{
|
||||
if (!*arg[1])
|
||||
return "file requires a filename on the proxy's machine\n";
|
||||
|
||||
if (!localcommand)
|
||||
if (*arg[1] == '\\' || *arg[1] == '/' || strstr(arg[1], "..") || arg[1][1] == ':')
|
||||
return "Absolute paths are prohibited.\n";
|
||||
|
||||
memmove(arg[1]+5, arg[1], ARG_LEN-6);
|
||||
strncpy(arg[1], "file:", 5);
|
||||
if (QTV_Connect(qtv, arg[1]))
|
||||
return "File opened successfully\n";
|
||||
else
|
||||
return "Failed (will keep trying)\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "record"))
|
||||
{
|
||||
if (!*arg[1])
|
||||
return "record requires a filename on the proxy's machine\n";
|
||||
|
||||
if (!localcommand)
|
||||
if (*arg[1] == '\\' || *arg[1] == '/' || strstr(arg[1], "..") || arg[1][1] == ':')
|
||||
return "Absolute paths are prohibited.\n";
|
||||
|
||||
if (Net_FileProxy(qtv, arg[1]))
|
||||
return "Recording to disk\n";
|
||||
else
|
||||
return "Failed to open file\n";
|
||||
}
|
||||
else if (!strcmp(arg[0], "stop"))
|
||||
{
|
||||
if (Net_StopFileProxy(qtv))
|
||||
return "stopped\n";
|
||||
else
|
||||
return "not recording to disk\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "reconnect"))
|
||||
{
|
||||
if (QTV_Connect(qtv, qtv->server))
|
||||
return "Reconnected\n";
|
||||
else
|
||||
return "Failed to reconnect (will keep trying)\n";
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "mvdport"))
|
||||
{
|
||||
int news;
|
||||
int newp = atoi(arg[1]);
|
||||
|
||||
if (!newp)
|
||||
{
|
||||
if (qtv->listenmvd != INVALID_SOCKET)
|
||||
{
|
||||
closesocket(qtv->listenmvd);
|
||||
qtv->listenmvd = INVALID_SOCKET;
|
||||
qtv->tcplistenportnum = 0;
|
||||
|
||||
return "mvd port is now closed\n";
|
||||
}
|
||||
return "Already closed\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
news = Net_MVDListen(newp);
|
||||
|
||||
if (news != INVALID_SOCKET)
|
||||
{
|
||||
if (qtv->listenmvd != INVALID_SOCKET)
|
||||
closesocket(qtv->listenmvd);
|
||||
qtv->listenmvd = news;
|
||||
qtv->disconnectwhennooneiswatching = false;
|
||||
qtv->tcplistenportnum = newp;
|
||||
return "Opened tcp port\n";
|
||||
}
|
||||
else
|
||||
return "Failed to open tcp port\n";
|
||||
}
|
||||
}
|
||||
|
||||
else if (!strcmp(arg[0], "exec"))
|
||||
{
|
||||
FILE *f;
|
||||
char line[512], *res;
|
||||
|
||||
if (!localcommand)
|
||||
if (*arg[1] == '\\' || *arg[1] == '/' || strstr(arg[1], "..") || arg[1][1] == ':')
|
||||
return "Absolute paths are prohibited.\n";
|
||||
|
||||
f = fopen(arg[1], "rt");
|
||||
if (!f)
|
||||
{
|
||||
snprintf(buffer, sizeofbuffer, "Couldn't exec \"%s\"\n", arg[1]);
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(fgets(line, sizeof(line)-1, f))
|
||||
{
|
||||
res = Rcon_Command(qtv->cluster, qtv, line, buffer, sizeofbuffer, localcommand);
|
||||
Sys_Printf(qtv->cluster, "%s", res);
|
||||
}
|
||||
fclose(f);
|
||||
return "Execed\n";
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*/
|
||||
char *Rcon_Command(cluster_t *cluster, sv_t *qtv, char *command, char *buffer, int sizeofbuffer, qboolean localcommand)
|
||||
{
|
||||
#define TOKENIZE_PUNCTUATION ""
|
||||
|
@ -1106,6 +727,26 @@ char *Rcon_Command(cluster_t *cluster, sv_t *qtv, char *command, char *buffer, i
|
|||
int i;
|
||||
char arg[MAX_ARGS][ARG_LEN];
|
||||
char *argptrs[MAX_ARGS];
|
||||
char *sid;
|
||||
|
||||
for (sid = command; *sid; sid = sid++)
|
||||
{
|
||||
if (*sid == ':')
|
||||
break;
|
||||
if (*sid < '0' || *sid > '9')
|
||||
break;
|
||||
}
|
||||
if (*sid == ':')
|
||||
{
|
||||
i = atoi(command);
|
||||
command = sid+1;
|
||||
|
||||
for (qtv = cluster->servers; qtv; qtv = qtv->next)
|
||||
if (qtv->streamid == i)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < MAX_ARGS; i++)
|
||||
{
|
||||
|
|
|
@ -821,7 +821,8 @@ void QTV_Shutdown(sv_t *qtv)
|
|||
if (v->server == qtv)
|
||||
{
|
||||
QW_SetViewersServer(v, NULL);
|
||||
v->menunum = 1;
|
||||
QW_SetMenu(v, MENU_SERVERS);
|
||||
QW_PrintfToViewer(v, "Stream %s is closing\n", qtv->server);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -834,6 +835,7 @@ void QTV_Shutdown(sv_t *qtv)
|
|||
old = prox;
|
||||
prox = prox->next;
|
||||
free(old);
|
||||
cluster->numproxies--;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1060,8 +1062,13 @@ void QTV_ParseQWStream(sv_t *qtv)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef COMMENTARY
|
||||
#include <speex/speex.h>
|
||||
#endif
|
||||
|
||||
void QTV_CollectCommentry(sv_t *qtv)
|
||||
{
|
||||
#ifdef COMMENTARY
|
||||
int samps;
|
||||
unsigned char buffer[8192+6];
|
||||
unsigned char *uchar;
|
||||
|
@ -1070,12 +1077,18 @@ void QTV_CollectCommentry(sv_t *qtv)
|
|||
if (!qtv->comentrycapture)
|
||||
{
|
||||
if (0)
|
||||
qtv->comentrycapture = SND_InitCapture(11025, 8);
|
||||
{
|
||||
if (usespeex)
|
||||
qtv->comentrycapture = SND_InitCapture(11025, 16);
|
||||
else
|
||||
qtv->comentrycapture = SND_InitCapture(11025, 8);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
//the protocol WILL be different. Don't add compatability for this code.
|
||||
buffer[0] = 0;
|
||||
buffer[1] = dem_audio;
|
||||
buffer[2] = 255;
|
||||
|
@ -1083,14 +1096,50 @@ void QTV_CollectCommentry(sv_t *qtv)
|
|||
buffer[4] = 8;
|
||||
buffer[5] = 11*5;
|
||||
|
||||
samps=qtv->comentrycapture->update(qtv->comentrycapture, 2048, buffer+6);
|
||||
|
||||
bytesleft = samps;
|
||||
schar = buffer+6;
|
||||
uchar = buffer+6;
|
||||
while(bytesleft-->0)
|
||||
if (usespeex)
|
||||
{
|
||||
*schar++ = *uchar++ - 128;
|
||||
|
||||
SpeexBits bits;
|
||||
void *enc_state;
|
||||
|
||||
int frame_size;
|
||||
|
||||
spx_int16_t pcmdata[8192/2];
|
||||
|
||||
samps=qtv->comentrycapture->update(qtv->comentrycapture, 2048, (char*)pcmdata);
|
||||
|
||||
|
||||
speex_bits_init(&bits);
|
||||
|
||||
enc_state = speex_encoder_init(&speex_nb_mode);
|
||||
|
||||
|
||||
speex_encoder_ctl(enc_state,SPEEX_GET_FRAME_SIZE,&frame_size);
|
||||
|
||||
|
||||
speex_bits_reset(&bits);
|
||||
|
||||
speex_encode_int(enc_state, (spx_int16_t*)pcmdata, &bits);
|
||||
|
||||
samps = speex_bits_write(&bits, buffer+6, sizeof(buffer)-6);
|
||||
|
||||
|
||||
speex_bits_destroy(&bits);
|
||||
|
||||
speex_encoder_destroy(enc_state);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
samps=qtv->comentrycapture->update(qtv->comentrycapture, 2048, buffer+6);
|
||||
|
||||
bytesleft = samps;
|
||||
schar = buffer+6;
|
||||
uchar = buffer+6;
|
||||
while(bytesleft-->0)
|
||||
{
|
||||
*schar++ = *uchar++ - 128;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[2] = samps&255;
|
||||
|
@ -1102,6 +1151,7 @@ void QTV_CollectCommentry(sv_t *qtv)
|
|||
if (samps < 64)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void QTV_Run(sv_t *qtv)
|
||||
|
@ -1114,11 +1164,13 @@ void QTV_Run(sv_t *qtv)
|
|||
|
||||
if (qtv->drop || (qtv->disconnectwhennooneiswatching && qtv->numviewers == 0 && qtv->proxies == NULL))
|
||||
{
|
||||
if (!qtv->drop)
|
||||
Sys_Printf(qtv->cluster, "Stream %s became inactive\n", qtv->server);
|
||||
QTV_Shutdown(qtv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//we will read out as many packets as we can until we're up to date
|
||||
//note: this can cause real issues when we're overloaded for any length of time
|
||||
//each new packet comes with a leading msec byte (msecs from last packet)
|
||||
|
@ -1568,6 +1620,9 @@ sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, char *password,
|
|||
return qtv;
|
||||
}
|
||||
}
|
||||
if (autoclose)
|
||||
if (cluster->nouserconnects)
|
||||
return NULL;
|
||||
|
||||
qtv = malloc(sizeof(sv_t));
|
||||
if (!qtv)
|
||||
|
|
Loading…
Reference in a new issue