DragonNest/Common/FMODEngine/FMOD_static/src/fmod_net.cpp

359 lines
5.9 KiB
C++
Raw Normal View History

2024-12-19 09:48:26 +08:00
#include "fmod_settings.h"
#include "fmod.h"
#include "fmod_net.h"
#include "fmod_string.h"
#include "fmod_memory.h"
#include <stdlib.h>
enum
{
FMOD_NET_VERSION_HTTP_1_0 = 0,
FMOD_NET_VERSION_HTTP_1_1,
FMOD_NET_VERSION_ICY,
CT_FMOD_NET_VERSION
};
static const char *FMOD_Net_VersionString[CT_FMOD_NET_VERSION] =
{
"HTTP/1.0",
"HTTP/1.1",
"ICY",
};
static const char base64_code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *FMOD_Net_ProxyString = 0;
char *FMOD_Net_ProxyHostname = 0;
int FMOD_Net_ProxyPort = 0;
char *FMOD_Net_ProxyAuth = 0; // Base64 encoded, user:pass pair
int FMOD_Net_Timeout = 5000;
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[SEE_ALSO]
]
*/
FMOD_RESULT FMOD_Net_ParseHTTPStatus(char *buf, int buflen, int *version, int *statuscode)
{
int i, j, k;
for (i=0;(i < buflen) && (buf[i] != 0) && (buf[i] != ' ');i++);
if (i < buflen)
{
buf[i] = 0;
for (j=0;j < CT_FMOD_NET_VERSION;j++)
{
if (!FMOD_strcmp(buf, FMOD_Net_VersionString[j]))
{
*version = j;
break;
}
}
if (j < CT_FMOD_NET_VERSION)
{
i++;
k = i;
for (;(i < buflen) && (buf[i] != 0) && (buf[i] != ' ');i++);
if (i < buflen)
{
buf[i] = 0;
*statuscode = atoi(&buf[k]);
return FMOD_OK;
}
}
}
return FMOD_ERR_INVALID_PARAM;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[SEE_ALSO]
]
*/
#define CHECK_LENGTH if (out_cnt == outbuflen) { return FMOD_ERR_INVALID_PARAM; }
FMOD_RESULT FMOD_Net_EncodeBase64(char *inbuf, char *outbuf, int outbuflen)
{
int bits = 0, char_count = 0, out_cnt = 0, c;
if (!inbuf || !outbuf)
{
return FMOD_ERR_INVALID_PARAM;
}
while ((c = (unsigned char)*inbuf++))
{
bits += c;
char_count++;
if (char_count == 3)
{
CHECK_LENGTH
outbuf[out_cnt++] = base64_code[bits >> 18];
CHECK_LENGTH
outbuf[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
CHECK_LENGTH
outbuf[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
CHECK_LENGTH
outbuf[out_cnt++] = base64_code[bits & 0x3f];
bits = 0;
char_count = 0;
}
else
{
bits <<= 8;
}
}
if (char_count != 0)
{
bits <<= 16 - (8 * char_count);
CHECK_LENGTH
outbuf[out_cnt++] = base64_code[bits >> 18];
CHECK_LENGTH
outbuf[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
if (char_count == 1)
{
CHECK_LENGTH
outbuf[out_cnt++] = '=';
CHECK_LENGTH
outbuf[out_cnt++] = '=';
}
else
{
CHECK_LENGTH
outbuf[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
CHECK_LENGTH
outbuf[out_cnt++] = '=';
}
}
CHECK_LENGTH
outbuf[out_cnt] = 0;
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[SEE_ALSO]
]
*/
FMOD_RESULT FMOD_Net_SetProxy(const char *proxy)
{
char *hostname, *username, *tmp, *p;
FMOD_RESULT result;
int port;
if (FMOD_Net_ProxyString)
{
FMOD_Memory_Free(FMOD_Net_ProxyString);
FMOD_Net_ProxyString = 0;
}
if (FMOD_Net_ProxyHostname)
{
FMOD_Memory_Free(FMOD_Net_ProxyHostname);
FMOD_Net_ProxyHostname = 0;
}
if (FMOD_Net_ProxyAuth)
{
FMOD_Memory_Free(FMOD_Net_ProxyAuth);
FMOD_Net_ProxyAuth = 0;
}
FMOD_Net_ProxyPort = 0;
if (FMOD_strlen(proxy))
{
p = FMOD_strdup(proxy);
if (!p)
{
return FMOD_ERR_MEMORY;
}
}
else
{
/*
Setting proxy server to null here
*/
return FMOD_OK;
}
FMOD_Net_ProxyString = FMOD_strdup(proxy);
if (!FMOD_Net_ProxyString)
{
return FMOD_ERR_MEMORY;
}
hostname = FMOD_strstr(p, "@");
if (hostname)
{
*hostname = 0;
hostname++;
username = p;
}
else
{
hostname = p;
username = 0;
}
if (username)
{
char buf[4096];
result = FMOD_Net_EncodeBase64(username, buf, 4095);
if (result != FMOD_OK)
{
FMOD_Memory_Free(p);
return result;
}
FMOD_Net_ProxyAuth = FMOD_strdup(buf);
if (!FMOD_Net_ProxyAuth)
{
return FMOD_ERR_MEMORY;
}
}
tmp = FMOD_strstr(hostname, ":");
if (tmp)
{
*tmp = 0;
tmp++;
port = atoi(tmp);
}
else
{
port = 80;
}
FMOD_Net_ProxyHostname = FMOD_strdup(hostname);
if (!FMOD_Net_ProxyHostname)
{
return FMOD_ERR_MEMORY;
}
FMOD_Net_ProxyPort = port;
FMOD_Memory_Free(p);
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[SEE_ALSO]
]
*/
FMOD_RESULT FMOD_Net_GetProxy(char *proxy, int proxylen)
{
if (proxy && proxylen)
{
if (FMOD_Net_ProxyString)
{
FMOD_strncpy(proxy, FMOD_Net_ProxyString, proxylen);
proxy[proxylen - 1] = 0;
}
else
{
proxy[0] = 0;
}
}
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[SEE_ALSO]
]
*/
FMOD_RESULT FMOD_Net_SetTimeout(int timeout)
{
FMOD_Net_Timeout = timeout;
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[SEE_ALSO]
]
*/
FMOD_RESULT FMOD_Net_GetTimeout(int *timeout)
{
if (!timeout)
{
return FMOD_ERR_INVALID_PARAM;
}
*timeout = FMOD_Net_Timeout;
return FMOD_OK;
}