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:
parent
601373a1c3
commit
0823eb0968
21 changed files with 2875 additions and 1060 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -4120,6 +4120,7 @@ void SV_MVDStream_Poll(void);
|
|||
#ifdef PLUGINS
|
||||
Plug_Tick();
|
||||
#endif
|
||||
NET_Tick();
|
||||
|
||||
SV_GetConsoleCommands ();
|
||||
|
||||
|
|
|
@ -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
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue