mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-26 22:01:50 +00:00
Support for reverse qtv connections. (server can now connect to qtv to stream the game, rather than the qtv having to know about the server)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2511 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
a696882cb4
commit
e7f6c231e7
1 changed files with 115 additions and 6 deletions
|
@ -40,7 +40,8 @@ typedef struct mvdpendingdest_s {
|
||||||
char outbuffer[2048];
|
char outbuffer[2048];
|
||||||
|
|
||||||
char challenge[64];
|
char challenge[64];
|
||||||
int hasauthed;
|
qboolean hasauthed;
|
||||||
|
qboolean isreverse;
|
||||||
|
|
||||||
int insize;
|
int insize;
|
||||||
int outsize;
|
int outsize;
|
||||||
|
@ -50,6 +51,7 @@ typedef struct mvdpendingdest_s {
|
||||||
|
|
||||||
typedef struct mvddest_s {
|
typedef struct mvddest_s {
|
||||||
qboolean error; //disables writers, quit ASAP.
|
qboolean error; //disables writers, quit ASAP.
|
||||||
|
qboolean droponmapchange;
|
||||||
|
|
||||||
enum {DEST_NONE, DEST_FILE, DEST_BUFFEREDFILE, DEST_STREAM} desttype;
|
enum {DEST_NONE, DEST_FILE, DEST_BUFFEREDFILE, DEST_STREAM} desttype;
|
||||||
|
|
||||||
|
@ -254,6 +256,7 @@ void SV_MVD_RunPendingConnections(void)
|
||||||
}
|
}
|
||||||
if (end)
|
if (end)
|
||||||
{ //we found the end of the header
|
{ //we found the end of the header
|
||||||
|
qboolean server = false, reverse = false;
|
||||||
char *start, *lineend;
|
char *start, *lineend;
|
||||||
int versiontouse = 0;
|
int versiontouse = 0;
|
||||||
int raw = 0;
|
int raw = 0;
|
||||||
|
@ -283,10 +286,21 @@ void SV_MVD_RunPendingConnections(void)
|
||||||
start = lineend+1;
|
start = lineend+1;
|
||||||
if (strcmp(com_token, "QTV"))
|
if (strcmp(com_token, "QTV"))
|
||||||
{ //it's an error if it's not qtv.
|
{ //it's an error if it's not qtv.
|
||||||
|
if (!strcmp(com_token, "QTVSV"))
|
||||||
|
server = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
p->error = true;
|
p->error = true;
|
||||||
lineend = strchr(start, '\n');
|
lineend = strchr(start, '\n');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server != p->isreverse)
|
||||||
|
{ //just a small check
|
||||||
|
p->error = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
@ -375,6 +389,8 @@ void SV_MVD_RunPendingConnections(void)
|
||||||
if (p->hasauthed)
|
if (p->hasauthed)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
else if (p->isreverse)
|
||||||
|
p->hasauthed = true; //reverse connections do not need to auth.
|
||||||
else if (!*qtv_password.string)
|
else if (!*qtv_password.string)
|
||||||
p->hasauthed = true; //no password, no need to auth.
|
p->hasauthed = true; //no password, no need to auth.
|
||||||
else if (*password)
|
else if (*password)
|
||||||
|
@ -496,12 +512,15 @@ void SV_MVD_RunPendingConnections(void)
|
||||||
{
|
{
|
||||||
if (p->hasauthed == true)
|
if (p->hasauthed == true)
|
||||||
{
|
{
|
||||||
|
mvddest_t *dst;
|
||||||
e = ("QTVSV 1\n"
|
e = ("QTVSV 1\n"
|
||||||
"BEGIN\n"
|
"BEGIN\n"
|
||||||
"\n");
|
"\n");
|
||||||
send(p->socket, e, strlen(e), 0);
|
send(p->socket, e, strlen(e), 0);
|
||||||
e = NULL;
|
e = NULL;
|
||||||
SV_MVD_Record(SV_InitStream(p->socket));
|
dst = SV_InitStream(p->socket);
|
||||||
|
dst->droponmapchange = p->isreverse;
|
||||||
|
SV_MVD_Record(dst);
|
||||||
p->socket = -1; //so it's not cleared wrongly.
|
p->socket = -1; //so it's not cleared wrongly.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -543,7 +562,7 @@ int DestCloseAllFlush(qboolean destroyfiles, qboolean mvdonly)
|
||||||
while(d)
|
while(d)
|
||||||
{
|
{
|
||||||
next = d->nextdest;
|
next = d->nextdest;
|
||||||
if (!mvdonly || d->desttype != DEST_STREAM)
|
if (!mvdonly || d->droponmapchange)
|
||||||
{
|
{
|
||||||
*prev = d->nextdest;
|
*prev = d->nextdest;
|
||||||
DestClose(d, destroyfiles);
|
DestClose(d, destroyfiles);
|
||||||
|
@ -1437,6 +1456,7 @@ mvddest_t *SV_InitRecordFile (char *name)
|
||||||
dst->maxcachesize = 0x81000;
|
dst->maxcachesize = 0x81000;
|
||||||
dst->cache = BZ_Malloc(dst->maxcachesize);
|
dst->cache = BZ_Malloc(dst->maxcachesize);
|
||||||
}
|
}
|
||||||
|
dst->droponmapchange = true;
|
||||||
|
|
||||||
Check_DemoDir();
|
Check_DemoDir();
|
||||||
|
|
||||||
|
@ -1489,13 +1509,14 @@ mvddest_t *SV_InitStream(int socket)
|
||||||
dst->socket = socket;
|
dst->socket = socket;
|
||||||
dst->maxcachesize = 0x8000; //is this too small?
|
dst->maxcachesize = 0x8000; //is this too small?
|
||||||
dst->cache = BZ_Malloc(dst->maxcachesize);
|
dst->cache = BZ_Malloc(dst->maxcachesize);
|
||||||
|
dst->droponmapchange = false;
|
||||||
|
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Smile, you're on QTV!\n");
|
SV_BroadcastPrintf (PRINT_CHAT, "Smile, you're on QTV!\n");
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SV_MVD_InitPendingStream(int socket, char *ip)
|
mvdpendingdest_t *SV_MVD_InitPendingStream(int socket, char *ip)
|
||||||
{
|
{
|
||||||
mvdpendingdest_t *dst;
|
mvdpendingdest_t *dst;
|
||||||
int i;
|
int i;
|
||||||
|
@ -1508,6 +1529,8 @@ void SV_MVD_InitPendingStream(int socket, char *ip)
|
||||||
|
|
||||||
dst->nextdest = demo.pendingdest;
|
dst->nextdest = demo.pendingdest;
|
||||||
demo.pendingdest = dst;
|
demo.pendingdest = dst;
|
||||||
|
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2058,6 +2081,91 @@ void SV_MVD_Record_f (void)
|
||||||
SV_MVD_Record (SV_InitRecordFile(name));
|
SV_MVD_Record (SV_InitRecordFile(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SV_MVD_QTVReverse_f (void)
|
||||||
|
{
|
||||||
|
char *ip;
|
||||||
|
if (sv.state != ss_active)
|
||||||
|
{
|
||||||
|
Con_Printf ("Server is not running\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Cmd_Argc() != 2)
|
||||||
|
{
|
||||||
|
Con_Printf ("%s ip:port\n", Cmd_Argv(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = Cmd_Argv(1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
char *data;
|
||||||
|
int sock;
|
||||||
|
|
||||||
|
struct sockaddr_in local;
|
||||||
|
struct sockaddr_qstorage remote;
|
||||||
|
// int fromlen;
|
||||||
|
|
||||||
|
unsigned int nonblocking = true;
|
||||||
|
|
||||||
|
|
||||||
|
if (!NET_StringToSockaddr(ip, &remote))
|
||||||
|
{
|
||||||
|
Con_Printf ("qtvreverse: failed to resolve address\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
local.sin_family = AF_INET;
|
||||||
|
local.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
local.sin_port = 0;
|
||||||
|
|
||||||
|
if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
||||||
|
{
|
||||||
|
Con_Printf ("qtvreverse: socket: %s\n", strerror(qerrno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bind (sock, (void *)&local, sizeof(local)) == -1)
|
||||||
|
{
|
||||||
|
closesocket(sock);
|
||||||
|
Con_Printf ("qtvreverse: bind: %s\n", strerror(qerrno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(sock, (void*)&remote, sizeof(remote)) == -1)
|
||||||
|
{
|
||||||
|
closesocket(sock);
|
||||||
|
Con_Printf ("qtvreverse: connect: %s\n", strerror(qerrno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctlsocket (sock, FIONBIO, &nonblocking) == -1)
|
||||||
|
{
|
||||||
|
closesocket(sock);
|
||||||
|
Con_Printf ("qtvreverse: ioctl FIONBIO: %s\n", strerror(qerrno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = "QTV\n"
|
||||||
|
"REVERSE\n"
|
||||||
|
"\n";
|
||||||
|
if (send(sock, data, strlen(data), 0) == -1)
|
||||||
|
{
|
||||||
|
closesocket(sock);
|
||||||
|
Con_Printf ("qtvreverse: send: %s\n", strerror(qerrno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SV_MVD_InitPendingStream(sock, ip)->isreverse = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//SV_MVD_Record (dest);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
====================
|
====================
|
||||||
SV_EasyRecord_f
|
SV_EasyRecord_f
|
||||||
|
@ -2786,6 +2894,7 @@ void SV_MVDInit(void)
|
||||||
Cmd_AddCommand ("stop", SV_MVDStop_f);
|
Cmd_AddCommand ("stop", SV_MVDStop_f);
|
||||||
Cmd_AddCommand ("cancel", SV_MVD_Cancel_f);
|
Cmd_AddCommand ("cancel", SV_MVD_Cancel_f);
|
||||||
#endif
|
#endif
|
||||||
|
Cmd_AddCommand ("qtvreverse", SV_MVD_QTVReverse_f);
|
||||||
Cmd_AddCommand ("mvdrecord", SV_MVD_Record_f);
|
Cmd_AddCommand ("mvdrecord", SV_MVD_Record_f);
|
||||||
Cmd_AddCommand ("easyrecord", SV_MVDEasyRecord_f);
|
Cmd_AddCommand ("easyrecord", SV_MVDEasyRecord_f);
|
||||||
Cmd_AddCommand ("mvdstop", SV_MVDStop_f);
|
Cmd_AddCommand ("mvdstop", SV_MVDStop_f);
|
||||||
|
|
Loading…
Reference in a new issue