mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-29 23:22:01 +00:00
a4942abf52
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5234 fc73d0e0-1445-4013-8a0c-d673dee63da5
223 lines
5 KiB
C
223 lines
5 KiB
C
/*
|
|
This file is intended as a set of exports for an NQ-based engine.
|
|
This is supported _purely_ for clients, and will not work for servers.
|
|
|
|
documentation can be found inside net_qtv.h
|
|
*/
|
|
|
|
|
|
|
|
#include "qtv.h"
|
|
int build_number(void);
|
|
|
|
static cluster_t *cluster;
|
|
|
|
//note that a qsockaddr is only 16 bytes.
|
|
//this is not enough for ipv6 etc.
|
|
struct qsockaddr
|
|
{
|
|
int ipid;
|
|
};
|
|
static char resolvedadrstring[128];
|
|
static int lastadrid;
|
|
|
|
#ifdef _WIN32
|
|
#define EXPORT __declspec(dllexport)
|
|
#endif
|
|
|
|
#include "net_qtv.h"
|
|
|
|
|
|
PUBEXPORT void PUBLIC QTV_Command (char *command, char *results, int resultlen)
|
|
{
|
|
if (!cluster)
|
|
return;
|
|
Rcon_Command(cluster, NULL, command, results, resultlen, true);
|
|
}
|
|
PUBEXPORT void PUBLIC QTV_RunFrame (void)
|
|
{
|
|
if (!cluster)
|
|
return;
|
|
Cluster_Run(cluster, false);
|
|
}
|
|
|
|
|
|
EXPORT int PUBLIC QTV_Init (void)
|
|
{
|
|
if (cluster)
|
|
return 0;
|
|
|
|
cluster = malloc(sizeof(*cluster));
|
|
if (cluster)
|
|
{
|
|
memset(cluster, 0, sizeof(*cluster));
|
|
|
|
cluster->qwdsocket[0] = INVALID_SOCKET;
|
|
cluster->qwdsocket[1] = INVALID_SOCKET;
|
|
cluster->tcpsocket[0] = INVALID_SOCKET;
|
|
cluster->tcpsocket[1] = INVALID_SOCKET;
|
|
cluster->anticheattime = 1*1000;
|
|
cluster->tooslowdelay = 100;
|
|
cluster->qwlistenportnum = 0;
|
|
cluster->allownqclients = true;
|
|
strcpy(cluster->hostname, DEFAULT_HOSTNAME);
|
|
cluster->buildnumber = build_number();
|
|
cluster->maxproxies = -1;
|
|
|
|
strcpy(cluster->demodir, "qw/demos/");
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
EXPORT void PUBLIC QTV_Shutdown (void)
|
|
{
|
|
}
|
|
EXPORT void PUBLIC QTV_Listen (qboolean state)
|
|
{
|
|
}
|
|
EXPORT int PUBLIC QTV_OpenSocket (int port)
|
|
{
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_CloseSocket (int socket)
|
|
{
|
|
//give it a chance to close any server connections from us disconnecting (should have already send disconnect message, but won't have run the server so not noticed the lack of viewers)
|
|
Cluster_Run(cluster, false);
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_Connect (int socket, struct qsockaddr *addr)
|
|
{
|
|
if (addr->ipid == lastadrid)
|
|
{
|
|
strlcpy(cluster->autojoinadr, resolvedadrstring, sizeof(cluster->autojoinadr));
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
cluster->autojoinadr[0] = 0;
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_CheckNewConnections (void)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
static byte pendingbuf[8][1032];
|
|
static int pendinglen[8];
|
|
static unsigned int pendingin, pendingout;
|
|
void QTV_DoReceive(void *data, int length)
|
|
{
|
|
int idx;
|
|
if (length > sizeof(pendingbuf[0]))
|
|
return;
|
|
idx = pendingout++;
|
|
idx &= 7;
|
|
memcpy(pendingbuf[idx], data, length);
|
|
pendinglen[idx] = length;
|
|
}
|
|
EXPORT int PUBLIC QTV_Read (int socket, byte *buf, int len, struct qsockaddr *addr)
|
|
{
|
|
if (pendingout == pendingin)
|
|
{
|
|
Cluster_Run(cluster, false);
|
|
Cluster_Run(cluster, false);
|
|
}
|
|
|
|
while (pendingin != pendingout)
|
|
{
|
|
int idx = pendingin++;
|
|
idx &= 7;
|
|
if (pendinglen[idx] > len)
|
|
continue; //error
|
|
memcpy(buf, pendingbuf[idx], pendinglen[idx]);
|
|
return pendinglen[idx];
|
|
}
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_Write (int socket, byte *buf, int len, struct qsockaddr *addr)
|
|
{
|
|
netmsg_t m;
|
|
netadr_t from;
|
|
from.tcpcon = NULL;
|
|
((struct sockaddr*)from.sockaddr)->sa_family = AF_UNSPEC;
|
|
|
|
m.cursize = len;
|
|
m.data = buf;
|
|
m.readpos = 0;
|
|
|
|
QW_ProcessUDPPacket(cluster, &m, from);
|
|
|
|
if (pendingout == pendingin)
|
|
Cluster_Run(cluster, false);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_Broadcast (int socket, byte *buf, int len)
|
|
{
|
|
netmsg_t m;
|
|
netadr_t from;
|
|
from.tcpcon = NULL;
|
|
((struct sockaddr*)from.sockaddr)->sa_family = AF_UNSPEC;
|
|
|
|
m.cursize = len;
|
|
m.data = buf;
|
|
m.readpos = 0;
|
|
|
|
QW_ProcessUDPPacket(cluster, &m, from);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT char *PUBLIC QTV_AddrToString (struct qsockaddr *addr)
|
|
{
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_StringPortToAddr (char *string, int port, struct qsockaddr *addr)
|
|
{
|
|
if (!strncmp(string, "file:", 5) || !strncmp(string, "demo:", 5))
|
|
{
|
|
snprintf(resolvedadrstring, sizeof(resolvedadrstring), "%s", string);
|
|
addr->ipid = ++lastadrid;
|
|
return 0;
|
|
}
|
|
if (!strncmp(string, "qw:", 3) || !strncmp(string, "udp:", 4) || !strncmp(string, "tcp:", 4))
|
|
{
|
|
if (port)
|
|
snprintf(resolvedadrstring, sizeof(resolvedadrstring), "%s:%i", string, port);
|
|
else
|
|
snprintf(resolvedadrstring, sizeof(resolvedadrstring), "%s", string);
|
|
addr->ipid = ++lastadrid;
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
EXPORT int PUBLIC QTV_StringToAddr (char *string, struct qsockaddr *addr)
|
|
{
|
|
return QTV_StringPortToAddr(string, 0, addr);
|
|
}
|
|
EXPORT int PUBLIC QTV_GetSocketAddr (int socket, struct qsockaddr *addr)
|
|
{
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_GetNameFromAddr (struct qsockaddr *addr, char *name)
|
|
{
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_GetAddrFromName (char *name, struct qsockaddr *addr)
|
|
{
|
|
return QTV_StringToAddr(name, addr);
|
|
}
|
|
EXPORT int PUBLIC QTV_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
|
|
{
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_GetSocketPort (struct qsockaddr *addr)
|
|
{
|
|
return 0;
|
|
}
|
|
EXPORT int PUBLIC QTV_SetSocketPort (struct qsockaddr *addr, int port)
|
|
{
|
|
return 0;
|
|
}
|