xmpp NAT holepunching (ICE) is now implemented. it doesn't know how to do relays.

xmpp voip support (speex only). just because.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4413 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-06-29 16:01:07 +00:00
parent 601373a1c3
commit 0823eb0968
21 changed files with 2875 additions and 1060 deletions

View File

@ -3698,8 +3698,6 @@ void Host_DoRunFile(hrf_t *f)
VFS_SEEK(f->srcfile, 0);
COM_StripExtension(COM_SkipPath(f->fname), qname, sizeof(qname));
f->dstfile = FS_OpenVFS(qname, "rb", FS_GAME);
if (f->dstfile)
{
@ -3987,6 +3985,7 @@ double Host_Frame (double time)
#ifdef PLUGINS
Plug_Tick();
#endif
NET_Tick();
if (cl.paused)
cl.gametimemark += time;

View File

@ -375,6 +375,8 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
CL_PredictUsercmd (pnum, entnum, &temp, to, &split);
return;
}
if (!cl.worldmodel || cl.worldmodel->needload)
return;
VectorCopy (from->origin, pmove.origin);
VectorCopy (u->angles, pmove.angles);

View File

@ -138,6 +138,8 @@ void Con_Destroy (console_t *con)
console_t *Con_FindConsole(char *name)
{
console_t *con;
if (!strcmp(name, "current") && con_current)
return con_current;
for (con = &con_main; con; con = con->next)
{
if (!strcmp(con->name, name))
@ -149,6 +151,10 @@ console_t *Con_FindConsole(char *name)
console_t *Con_Create(char *name, unsigned int flags)
{
console_t *con;
if (!strcmp(name, "current"))
return NULL;
if (!strcmp(name, "MAIN"))
return NULL;
con = Z_Malloc(sizeof(console_t));
Q_strncpyz(con->name, name, sizeof(con->name));

View File

@ -10,6 +10,7 @@ cvar_t menualias = SCVAR("menualias", "");
void M_Script_Remove (menu_t *menu)
{
menu_script = NULL;
Cbuf_AddText(va("set option cancel\n%s\n", menualias.string), RESTRICT_LOCAL);
Cvar_Set(&menualias, "");
}
qboolean M_Script_Key (int key, menu_t *menu)
@ -29,12 +30,11 @@ qboolean M_Script_Key (int key, menu_t *menu)
void M_MenuS_Clear_f (void)
{
Cvar_Set(&menualias, "");
if (menu_script)
{
M_RemoveMenu(menu_script);
}
// Cvar_Set(menualias.name, "");
}
void M_MenuS_Script_f (void) //create a menu.

View File

@ -617,15 +617,35 @@ static void M_Menu_Prompt_Cancel (struct menu_s *gm)
void M_Menu_Prompt (void (*callback)(void *, int), void *ctx, char *m1, char *m2, char *m3, char *optionyes, char *optionno, char *optioncancel)
{
promptmenu_t *m;
char *t;
key_dest = key_menu;
m_state = m_complex;
m = (promptmenu_t*)M_CreateMenuInfront(sizeof(*m) - sizeof(m->m));
m = (promptmenu_t*)M_CreateMenuInfront(sizeof(*m) - sizeof(m->m) + strlen(m1)+strlen(m2)+strlen(m3)+strlen(optionyes)+strlen(optionyes)+strlen(optioncancel)+6);
m->callback = callback;
m->ctx = ctx;
m->m.remove = M_Menu_Prompt_Cancel;
t = (char*)(m+1);
strcpy(t, m1);
m1 = t;
t += strlen(t)+1;
strcpy(t, m2);
m2 = t;
t += strlen(t)+1;
strcpy(t, m3);
m3 = t;
t += strlen(t)+1;
strcpy(t, optionyes);
optionyes = t;
t += strlen(t)+1;
strcpy(t, optionno);
optionno = t;
t += strlen(t)+1;
strcpy(t, optioncancel);
optioncancel = t;
MC_AddWhiteText(&m->m, 64, 84, m1, false);
MC_AddWhiteText(&m->m, 64, 92, m2, false);
MC_AddWhiteText(&m->m, 64, 100, m3, false);

View File

@ -341,9 +341,6 @@ static void PClassic_DrawParticles(void)
static float oldtime;
RSpeedMark();
//make sure all ents are pushed through first
RQ_RenderBatchClear();
if (!active_particles)
{
oldtime = cl.time;

View File

@ -1534,12 +1534,23 @@ static void P_ParticleEffect_f(void)
if (!settype)
{
if (ptype->looks.type == PT_NORMAL && !*ptype->texname)
ptype->looks.type = PT_SPARK;
if (ptype->looks.type == PT_SPARK)
{
if (ptype->scale)
{
ptype->looks.type = PT_SPARKFAN;
Con_DPrintf("effect %s lacks a texture. assuming type sparkfan.\n", ptype->name);
}
else
{
ptype->looks.type = PT_SPARK;
Con_DPrintf("effect %s lacks a texture. assuming type spark.\n", ptype->name);
}
}
else if (ptype->looks.type == PT_SPARK)
{
if (*ptype->texname)
ptype->looks.type = PT_TEXTUREDSPARK;
if (ptype->scale)
else if (ptype->scale)
ptype->looks.type = PT_SPARKFAN;
}
}
@ -4836,8 +4847,8 @@ static void GL_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type)
continue;
p = b->p;
q->rgba[3] = 1;
p->rgba[3] = 1;
// q->rgba[3] = 1;
// p->rgba[3] = 1;
VectorSubtract(r_refdef.vieworg, q->org, v);
VectorNormalize(v);

View File

@ -225,9 +225,11 @@ void S_SoundInfo_f(void)
enum
{
VOIP_SPEEX = 0, //original supported codec
VOIP_RAW = 1, //support is not recommended.
VOIP_OPUS = 2, //supposed to be better than speex.
VOIP_SPEEX_OLD = 0, //original supported codec (with needless padding and at the wrong rate to keep quake implementations easy)
VOIP_RAW = 1, //support is not recommended.
VOIP_OPUS = 2, //supposed to be better than speex.
VOIP_SPEEX_NARROW = 3, //narrowband speex. packed data.
VOIP_SPEEX_WIDE = 4, //wideband speex. packed data.
VOIP_INVALID = 16 //not currently generating audio.
};
@ -242,7 +244,8 @@ static struct
SpeexBits encbits;
SpeexBits decbits[MAX_CLIENTS];
const SpeexMode *mode;
const SpeexMode *modenb;
const SpeexMode *modewb;
} speex;
struct
@ -280,6 +283,7 @@ static struct
unsigned char capturebuf[32768]; /*pending data*/
unsigned int capturepos;/*amount of pending data*/
unsigned int encsequence;/*the outgoing sequence count*/
unsigned int enctimestamp;/*for rtp streaming*/
unsigned int generation;/*incremented whenever capture is restarted*/
qboolean wantsend; /*set if we're capturing data to send*/
float voiplevel; /*your own voice level*/
@ -439,7 +443,8 @@ static qboolean S_Speex_Init(void)
}
#endif
s_voip.speex.mode = qspeex_lib_get_mode(SPEEX_MODEID_NB);
s_voip.speex.modenb = qspeex_lib_get_mode(SPEEX_MODEID_NB);
s_voip.speex.modewb = qspeex_lib_get_mode(SPEEX_MODEID_WB);
s_voip.speex.loaded = true;
return s_voip.speex.loaded;
@ -498,7 +503,9 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
//make sure old state is closed properly.
switch(s_voip.deccodec[sender])
{
case VOIP_SPEEX:
case VOIP_SPEEX_OLD:
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
qspeex_decoder_destroy(s_voip.decoder[sender]);
break;
case VOIP_OPUS:
@ -513,17 +520,23 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
{
default: //codec not supported.
return;
case VOIP_SPEEX:
case VOIP_SPEEX_OLD:
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
if (!S_Speex_Init())
return; //speex not usable.
s_voip.decsamplerate[sender] = 11025;
if (codec == VOIP_SPEEX_NARROW)
s_voip.decsamplerate[sender] = 8000;
else if (codec == VOIP_SPEEX_WIDE)
s_voip.decsamplerate[sender] = 16000;
else
s_voip.decsamplerate[sender] = 11025;
s_voip.decframesize[sender] = 160;
if (!s_voip.decoder[sender])
{
qspeex_bits_init(&s_voip.speex.decbits[sender]);
qspeex_bits_reset(&s_voip.speex.decbits[sender]);
s_voip.decoder[sender] = qspeex_decoder_init(s_voip.speex.mode);
s_voip.decoder[sender] = qspeex_decoder_init(codec==VOIP_SPEEX_WIDE?s_voip.speex.modewb:s_voip.speex.modenb);
if (!s_voip.decoder[sender])
return;
}
@ -576,7 +589,9 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
}
switch(codec)
{
case VOIP_SPEEX:
case VOIP_SPEEX_OLD:
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
qspeex_decode_int(s_voip.decoder[sender], NULL, decodebuf + decodesamps);
decodesamps += s_voip.decframesize[sender];
break;
@ -601,25 +616,46 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
default:
bytes = 0;
break;
case VOIP_SPEEX:
bytes--;
len = *start++;
if (bytes < len)
break;
case VOIP_SPEEX_OLD:
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
if (codec == VOIP_SPEEX_OLD)
{ //older versions support only this, and require this extra bit.
bytes--;
len = *start++;
if (bytes < len)
break;
}
else
len = bytes;
qspeex_bits_read_from(&s_voip.speex.decbits[sender], start, len);
bytes -= len;
start += len;
qspeex_decode_int(s_voip.decoder[sender], &s_voip.speex.decbits[sender], decodebuf + decodesamps);
decodesamps += s_voip.decframesize[sender];
while (qspeex_decode_int(s_voip.decoder[sender], &s_voip.speex.decbits[sender], decodebuf + decodesamps) == 0)
{
decodesamps += s_voip.decframesize[sender];
s_voip.decseq[sender]++;
seq++;
if (decodesamps + s_voip.decframesize[sender] > sizeof(decodebuf)/sizeof(decodebuf[0]))
{
S_RawAudio(sender, (qbyte*)decodebuf, s_voip.decsamplerate[sender], decodesamps, 1, 2, cl_voip_play.value);
decodesamps = 0;
}
}
break;
case VOIP_OPUS:
//FIXME: we shouldn't need this crap
bytes--;
len = *start++;
if (bytes < len)
break;
r = qopus_decode(s_voip.decoder[sender], start, len, decodebuf + decodesamps, sizeof(decodebuf)/sizeof(decodebuf[0]) - decodesamps, false);
if (r > 0)
{
decodesamps += r;
s_voip.decseq[sender]++;
seq++;
}
else if (r < 0)
Con_Printf("Opus decoding error %i\n", r);
@ -627,8 +663,6 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
start += len;
break;
}
s_voip.decseq[sender]++;
seq++;
}
if (drops)
@ -638,6 +672,22 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
S_RawAudio(sender, (qbyte*)decodebuf, s_voip.decsamplerate[sender], decodesamps, 1, 2, cl_voip_play.value);
}
#ifdef SUPPORT_ICE
void S_Voip_RTP_Parse(unsigned short sequence, char *codec, unsigned char *data, unsigned int datalen)
{
if (!strcmp(codec, "speex@8000"))
S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_NARROW, 0, sequence, datalen, data);
if (!strcmp(codec, "speex@11025"))
S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_OLD, 0, sequence, datalen, data); //very much non-standard rtp
if (!strcmp(codec, "speex@16000"))
S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_WIDE, 0, sequence, datalen, data);
}
qboolean NET_RTP_Transmit(unsigned int sequence, unsigned int timestamp, char *codec, char *cdata, int clength);
qboolean NET_RTP_Active(void);
#else
#define NET_RTP_Active() false
#endif
void S_Voip_Parse(void)
{
unsigned int sender;
@ -674,7 +724,8 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
unsigned int outpos;//in bytes
unsigned int encpos;//in bytes
short *start;
unsigned char initseq;//in frames
unsigned int initseq;//in frames
unsigned int inittimestamp;//in samples
unsigned int i;
unsigned int samps;
float level, f;
@ -682,6 +733,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
float micamp = cl_voip_micamp.value;
qboolean voipsendenable = true;
int voipcodec = cl_voip_codec.ival;
qboolean rtpstream = NET_RTP_Active();
if (buf)
{
@ -693,6 +745,14 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
}
else
voipsendenable = cl_voip_test.ival;
if (rtpstream)
{
voipsendenable = true;
//if rtp streaming is enabled, hack the codec to something better supported
if (voipcodec == VOIP_SPEEX_OLD)
voipcodec = VOIP_SPEEX_NARROW;
}
voicevolumemod = s_voip.lastspoke_any > realtime?cl_voip_ducking.value:1;
@ -714,7 +774,9 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
}
switch(s_voip.enccodec)
{
case VOIP_SPEEX:
case VOIP_SPEEX_OLD:
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
break;
case VOIP_OPUS:
qopus_encoder_destroy(s_voip.encoder);
@ -749,7 +811,9 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
/*see if we can init our encoding codec...*/
switch(voipcodec)
{
case VOIP_SPEEX:
case VOIP_SPEEX_OLD:
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
if (!S_Speex_Init())
{
Con_Printf("Unable to use speex codec - not installed\n");
@ -758,12 +822,17 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
qspeex_bits_init(&s_voip.speex.encbits);
qspeex_bits_reset(&s_voip.speex.encbits);
s_voip.encoder = qspeex_encoder_init(s_voip.speex.mode);
s_voip.encoder = qspeex_encoder_init(voipcodec == VOIP_SPEEX_WIDE?s_voip.speex.modewb:s_voip.speex.modenb);
if (!s_voip.encoder)
return;
qspeex_encoder_ctl(s_voip.encoder, SPEEX_GET_FRAME_SIZE, &s_voip.encframesize);
qspeex_encoder_ctl(s_voip.encoder, SPEEX_GET_SAMPLING_RATE, &s_voip.encsamplerate);
s_voip.encsamplerate = 11025;
if (voipcodec == VOIP_SPEEX_NARROW)
s_voip.encsamplerate = 8000;
else if (voipcodec == VOIP_SPEEX_WIDE)
s_voip.encsamplerate = 16000;
else
s_voip.encsamplerate = 11025;
qspeex_encoder_ctl(s_voip.encoder, SPEEX_SET_SAMPLING_RATE, &s_voip.encsamplerate);
break;
case VOIP_OPUS:
@ -833,7 +902,9 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
//reset codecs so they start with a clean slate when new audio blocks are generated.
switch(s_voip.enccodec)
{
case VOIP_SPEEX:
case VOIP_SPEEX_OLD:
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
qspeex_bits_reset(&s_voip.speex.encbits);
break;
case VOIP_OPUS:
@ -861,10 +932,11 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
}
initseq = s_voip.encsequence;
inittimestamp = s_voip.enctimestamp;
level = 0;
samps=0;
//*2 for 16bit audio input.
for (encpos = 0, outpos = 0; s_voip.capturepos-encpos >= s_voip.encframesize*2 && sizeof(outbuf)-outpos > 64; s_voip.encsequence++)
for (encpos = 0, outpos = 0; s_voip.capturepos-encpos >= s_voip.encframesize*2 && sizeof(outbuf)-outpos > 64; )
{
start = (short*)(s_voip.capturebuf + encpos);
@ -902,7 +974,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
switch(s_voip.enccodec)
{
case VOIP_SPEEX:
case VOIP_SPEEX_OLD:
qspeex_bits_reset(&s_voip.speex.encbits);
qspeex_encode_int(s_voip.encoder, start, &s_voip.speex.encbits);
len = qspeex_bits_write(&s_voip.speex.encbits, outbuf+(outpos+1), sizeof(outbuf) - (outpos+1));
@ -910,6 +982,28 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
len = 0;
outbuf[outpos] = len;
outpos += 1+len;
s_voip.encsequence++;
s_voip.enctimestamp += s_voip.encframesize;
samps+=s_voip.encframesize;
encpos += s_voip.encframesize*2;
break;
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
qspeex_bits_reset(&s_voip.speex.encbits);
for (; s_voip.capturepos-encpos >= s_voip.encframesize*2 && sizeof(outbuf)-outpos > 64; )
{
start = (short*)(s_voip.capturebuf + encpos);
qspeex_encode_int(s_voip.encoder, start, &s_voip.speex.encbits);
s_voip.encsequence++;
samps+=s_voip.encframesize;
s_voip.enctimestamp += s_voip.encframesize;
encpos += s_voip.encframesize*2;
if (rtpstream)
break;
}
len = qspeex_bits_write(&s_voip.speex.encbits, outbuf+outpos, sizeof(outbuf) - outpos);
outpos += len;
break;
case VOIP_OPUS:
len = qopus_encode(s_voip.encoder, start, s_voip.encframesize, outbuf+(outpos+1), max(255, sizeof(outbuf) - (outpos+1)));
@ -925,20 +1019,25 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
//error!
Con_Printf("Opus encoding error: %i\n", len);
}
s_voip.encsequence++;
samps+=s_voip.encframesize;
s_voip.enctimestamp += s_voip.encframesize;
encpos += s_voip.encframesize*2;
break;
default:
outbuf[outpos] = 0;
break;
}
samps+=s_voip.encframesize;
encpos += s_voip.encframesize*2;
if (rtpstream)
break;
}
if (samps)
{
float nl;
nl = (3000*level) / (32767.0f*32767*samps);
s_voip.voiplevel = (s_voip.voiplevel*7 + nl)/8;
if (s_voip.voiplevel < cl_voip_vad_threshhold.ival && !(cl_voip_send.ival & 2))
if (s_voip.voiplevel < cl_voip_vad_threshhold.ival && !(cl_voip_send.ival & 6))
{
/*try and dump it, it was too quiet, and they're not pressing +voip*/
if (s_voip.keeps > samps)
@ -965,7 +1064,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
if (outpos && (!buf || buf->maxsize - buf->cursize >= outpos+4))
{
if (buf)
if (buf && (cl_voip_send.ival & ~4))
{
MSG_WriteByte(buf, clc);
MSG_WriteByte(buf, (s_voip.enccodec<<4) | (s_voip.generation & 0x0f)); /*gonna leave that nibble clear here... in this version, the client will ignore packets with those bits set. can use them for codec or something*/
@ -974,6 +1073,18 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
SZ_Write(buf, outbuf, outpos);
}
switch(s_voip.enccodec)
{
case VOIP_SPEEX_NARROW:
case VOIP_SPEEX_WIDE:
case VOIP_SPEEX_OLD:
NET_RTP_Transmit(initseq, inittimestamp, va("speex@%i", s_voip.encsamplerate), outbuf, outpos);
break;
case VOIP_OPUS:
NET_RTP_Transmit(initseq, inittimestamp, "opus", outbuf, outpos);
break;
}
if (cl_voip_test.ival)
S_Voip_Decode(cl.playerview[0].playernum, s_voip.enccodec, s_voip.generation & 0x0f, initseq, outpos, outbuf);

View File

@ -246,7 +246,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define IRCCONNECT //an ircconnect command, that allows the player to connect to irc-encapsulated qw protocols... yeah, really.
#define PLUGINS //qvm/dll plugins.
#define SUPPORT_ICE //Internet Connection Establishment protocol, for peer-to-peer connections
#define SUPPORT_ICE //Interactive Connectivity Establishment protocol, for peer-to-peer connections
#ifdef _DEBUG
// #define OFFSCREENGECKO //FIXME: move to plugin and remove from engine

View File

@ -510,6 +510,9 @@ qbyte COM_BlockSequenceCheckByte (qbyte *base, int length, int sequence, unsigne
qbyte COM_BlockSequenceCRCByte (qbyte *base, int length, int sequence);
qbyte Q2COM_BlockSequenceCRCByte (qbyte *base, int length, int sequence);
int SHA1(char *digest, int maxdigestsize, char *string, int stringlen);
int SHA1_HMAC(unsigned char *digest, int maxdigestsize, unsigned char *key, int keylen, unsigned char *data, int datalen);
int version_number(void);
char *version_string(void);

View File

@ -106,8 +106,8 @@ typedef struct conline_s {
float time;
} conline_t;
#define CONF_HIDDEN 1
#define CONF_NOTIFY 2
#define CONF_HIDDEN 1 /*do not show in the console list (unless active)*/
#define CONF_NOTIFY 2 /*text printed to console also appears as notify lines*/
#define CONF_NOTIFY_BOTTOM 4 /*align the bottom*/
#define CONF_NOTIMES 8
typedef struct console_s

View File

@ -83,6 +83,7 @@ int TCP_OpenStream (netadr_t *remoteaddr); //makes things easier
struct ftenet_connections_s;
void NET_Init (void);
void NET_Tick (void);
void SVNET_RegisterCvars(void);
void NET_InitClient (void);
void NET_InitServer (void);

File diff suppressed because it is too large Load Diff

View File

@ -130,10 +130,12 @@
#endif
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS WSAEINPROGRESS
#define EMSGSIZE WSAEMSGSIZE
#define ECONNRESET WSAECONNRESET
#define ECONNABORTED WSAECONNABORTED
#define ECONNREFUSED WSAECONNREFUSED
#define ENOTCONN WSAENOTCONN
#define EACCES WSAEACCES
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define EAFNOSUPPORT WSAEAFNOSUPPORT
@ -196,11 +198,10 @@
#endif
#if 1//def SUPPORT_ICE
struct icecandidate_s
struct icecandinfo_s
{
struct icecandidate_s *next;
char *candidateid;
char *addr; //v4/v6/fqdn. fqdn should prefer ipv6
char candidateid[64];
char addr[64]; //v4/v6/fqdn. fqdn should prefer ipv6
int port;
int transport; //0=udp. other values not supported
int foundation; //to figure out...
@ -213,42 +214,41 @@ struct icecandidate_s
ICE_PRFLX=2,
ICE_RELAY=3,
} type; //says what sort of proxy is used.
char *reladdr; //when proxied, this is our local info
char reladdr[64]; //when proxied, this is our local info
int relport;
int generation; //for ice restarts. starts at 0.
int network; //which network device this comes from.
qboolean dirty;
};
struct icestate_s
enum iceproto_e
{
struct icestate_s *next;
void *module;
int netsrc;
enum icemode_e
{
ICE_RAW, //not actually interactive beyond a simple handshake.
ICE_ICE //rfc5245. meant to be able to holepunch, but not implemented properly yet.
} mode;
char *conname; //internal id.
char *friendlyname; //who you're talking to.
char *stunserver;//where to get our public ip from.
int stunport;
struct icecandidate_s *lc;
char *lpwd;
char *lfrag;
struct icecandidate_s *rc;
char *rpwd;
char *rfrag;
ICEP_INVALID, //not allowed..
ICEP_QWSERVER, //we're server side
ICEP_QWCLIENT, //we're client side
ICEP_VOICE //speex. requires client.
};
struct icestate_s *QDECL ICE_Create(void *module, char *conname, char *peername, enum icemode_e mode); //doesn't start pinging anything.
struct icestate_s *QDECL ICE_Find(void *module, char *conname);
void QDECL ICE_Begin(struct icestate_s *con, char *stunip, int stunport); //begins sending stun packets and stuff as required. data flows automagically. caller should poll ICE_GetLCandidateInfo periodically to pick up new candidates that need to be reported to the peer.
struct icecandidate_s *QDECL ICE_GetLCandidateInfo(struct icestate_s *con); //retrieves candidates that need reporting to the peer.
void QDECL ICE_AddRCandidateInfo(struct icestate_s *con, struct icecandidate_s *cand); //stuff that came from the peer.
void QDECL ICE_Close(struct icestate_s *con); //bye then.
void QDECL ICE_CloseModule(void *module); //closes all unclosed connections, with warning.
enum icemode_e
{
ICEM_RAW, //not actually interactive beyond a simple handshake.
ICEM_ICE //rfc5245. meant to be able to holepunch, but not implemented properly yet.
};
enum icestate_e
{
ICE_INACTIVE, //idle.
ICE_FAILED,
ICE_CONNECTING, //exchanging pings.
ICE_CONNECTED //media is flowing, supposedly. sending keepalives.
};
struct icestate_s;
#define ICE_API_CURRENT "Internet Connectivity Establishment 0.0"
typedef struct
{
struct icestate_s *(QDECL *ICE_Create)(void *module, char *conname, char *peername, enum icemode_e mode, enum iceproto_e proto); //doesn't start pinging anything.
qboolean (QDECL *ICE_Set)(struct icestate_s *con, char *prop, char *value);
qboolean (QDECL *ICE_Get)(struct icestate_s *con, char *prop, char *value, int valuesize);
struct icecandinfo_s *(QDECL *ICE_GetLCandidateInfo)(struct icestate_s *con); //retrieves candidates that need reporting to the peer.
void (QDECL *ICE_AddRCandidateInfo)(struct icestate_s *con, struct icecandinfo_s *cand); //stuff that came from the peer.
void (QDECL *ICE_Close)(struct icestate_s *con); //bye then.
void (QDECL *ICE_CloseModule)(void *module); //closes all unclosed connections, with warning.
} icefuncs_t;
extern icefuncs_t iceapi;
#endif

View File

@ -120,18 +120,8 @@ static qintptr_t VARGS Plug_GetNativePointer(void *offset, quintptr_t mask, cons
{
char *p = (char *)VM_POINTER(args[0]);
#ifdef SUPPORT_ICE
if (!strcmp(p, "ICE_Create"))
return (qintptr_t)ICE_Create;
if (!strcmp(p, "ICE_Find"))
return (qintptr_t)ICE_Find;
if (!strcmp(p, "ICE_Begin"))
return (qintptr_t)ICE_Begin;
if (!strcmp(p, "ICE_GetLCandidateInfo"))
return (qintptr_t)ICE_GetLCandidateInfo;
if (!strcmp(p, "ICE_AddRCandidateInfo"))
return (qintptr_t)ICE_AddRCandidateInfo;
if (!strcmp(p, "ICE_Close"))
return (qintptr_t)ICE_Close;
if (!strcmp(p, ICE_API_CURRENT))
return (qintptr_t)&iceapi;
#endif
return (qintptr_t)NULL;

View File

@ -191,3 +191,90 @@ int SHA1(char *digest, int maxdigestsize, char *string, int stringlen)
return DIGEST_SIZE;
}
/* hmac-sha1.c -- hashed message authentication codes
Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Written by Simon Josefsson.
hacked up a bit by someone else...
*/
#define IPAD 0x36
#define OPAD 0x5c
static void memxor(char *dest, char *src, size_t length)
{
size_t i;
for (i = 0; i < length; i++)
{
dest[i] ^= src[i];
}
}
int SHA1_HMAC(unsigned char *digest, int maxdigestsize,
unsigned char *key, int keylen,
unsigned char *data, int datalen)
{
SHA1_CTX inner;
SHA1_CTX outer;
char optkeybuf[20];
char block[64];
char innerhash[20];
if (maxdigestsize < DIGEST_SIZE)
return 0;
/* Reduce the key's size, so that it becomes <= 64 bytes large. */
if (keylen > 64)
{
SHA1_CTX keyhash;
SHA1Init (&keyhash);
SHA1Update (&keyhash, key, keylen);
SHA1Final (optkeybuf, &keyhash);
key = optkeybuf;
keylen = 20;
}
/* Compute INNERHASH from KEY and IN. */
SHA1Init (&inner);
memset (block, IPAD, sizeof (block));
memxor (block, key, keylen);
SHA1Update (&inner, block, 64);
SHA1Update (&inner, data, datalen);
SHA1Final (innerhash, &inner);
/* Compute result from KEY and INNERHASH. */
SHA1Init (&outer);
memset (block, OPAD, sizeof (block));
memxor (block, key, keylen);
SHA1Update (&outer, block, 64);
SHA1Update (&outer, innerhash, 20);
SHA1Final (digest, &outer);
return DIGEST_SIZE;
}

View File

@ -4120,6 +4120,7 @@ void SV_MVDStream_Poll(void);
#ifdef PLUGINS
Plug_Tick();
#endif
NET_Tick();
SV_GetConsoleCommands ();

View File

@ -309,7 +309,7 @@ qboolean Sys_Rename (char *oldfname, char *newfname)
return !rename(oldfname, newfname);
}
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *fname, int fsize, void *parm, void *spath), void *parm, void *spath)
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath)
{
HANDLE r;
WIN32_FIND_DATA fd;

File diff suppressed because it is too large Load Diff

View File

@ -103,11 +103,13 @@ char *XML_Markup(char *s, char *d, int dlen)
d+=xmlchars[i].namelen;
*d++ = ';';
s++;
dlen -= xmlchars[i].namelen+2;
}
else
{
if (!dlen)
break;
dlen--;
*d++ = *s++;
}
}

View File

@ -20,7 +20,7 @@ int Q_vsnprintf(char *buffer, size_t maxlen, const char *format, va_list vargs)
float _float;
int i;
int use0s;
int precision, useprepad;
int precision, useprepad, plus;
if (!maxlen)
return 0;
@ -31,6 +31,7 @@ maxlen--;
switch(*format)
{
case '%':
plus = 0;
precision= 0;
useprepad=0;
use0s=0;
@ -40,6 +41,9 @@ retry:
case '-':
useprepad=true;
goto retry;
case '+':
plus = true;
goto retry;
case '0':
if (!precision)
{
@ -177,6 +181,12 @@ Con_Printf("%i bytes left\n", maxlen);
*buffer++ = '-';
_int *= -1;
}
else if (plus)
{
if (maxlen-- == 0)
{*buffer++='\0';return tokens;}
*buffer++ = '+';
}
i = sizeof(tempbuffer)-2;
tempbuffer[sizeof(tempbuffer)-1] = '\0';
while(_int)