removed userinfobasic, things should be kept in sync more easily now.
xmpp got some major tweaks. more sasl methods etc. multiple accounts. misc other tweaks. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4418 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
00a6409804
commit
b2f5ae8f1c
28 changed files with 2625 additions and 602 deletions
|
@ -495,7 +495,7 @@ static void UnignoreteamAll_f (void)
|
|||
char Ignore_Check_Flood(char *s, int flags, int offset)
|
||||
{
|
||||
int i, p, q, len;
|
||||
char name[MAX_INFO_STRING];
|
||||
char name[MAX_INFO_KEY];
|
||||
|
||||
if ( !(
|
||||
( (ignore_flood.value == 1 && (flags & TPM_NORMAL || flags & TPM_SPECTATOR)) ||
|
||||
|
@ -523,7 +523,7 @@ char Ignore_Check_Flood(char *s, int flags, int offset)
|
|||
else
|
||||
return NO_IGNORE_NO_ADD;
|
||||
|
||||
len = bound (0, q - p + 1, MAX_INFO_STRING - 1);
|
||||
len = bound (0, q - p + 1, sizeof(name) - 1);
|
||||
|
||||
Q_strncpyz(name, s + p, len + 1);
|
||||
if (!cls.demoplayback && !strcmp(name, Player_MyName()))
|
||||
|
|
|
@ -47,7 +47,7 @@ cvar_t cl_timeout = SCVAR("cl_timeout", "60");
|
|||
|
||||
cvar_t cl_shownet = CVARD("cl_shownet","0", "Debugging var. 0 shows nothing. 1 shows incoming packet sizes. 2 shows individual messages. 3 shows entities too."); // can be 0, 1, or 2
|
||||
|
||||
cvar_t cl_pure = CVARD("cl_pure", "0", "If enabled, the filesystem will be restricted to allow only the content of the current server.");
|
||||
cvar_t cl_pure = CVARD("cl_pure", "0", "0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 is only reliable with total conversions.\nIf sv_pure is set, the client will prefer the highest value set.");
|
||||
cvar_t cl_sbar = CVARFC("cl_sbar", "0", CVAR_ARCHIVE, CL_Sbar_Callback);
|
||||
cvar_t cl_hudswap = CVARF("cl_hudswap", "0", CVAR_ARCHIVE);
|
||||
cvar_t cl_maxfps = CVARF("cl_maxfps", "500", CVAR_ARCHIVE);
|
||||
|
@ -1530,7 +1530,7 @@ void CL_PakDownloads(int mode)
|
|||
void CL_CheckServerPacks(void)
|
||||
{
|
||||
static int oldpure;
|
||||
int pure = atof(Info_ValueForKey(cl.serverinfo, "sv_pure"))*2;
|
||||
int pure = atof(Info_ValueForKey(cl.serverinfo, "sv_pure"));
|
||||
if (pure < cl_pure.ival)
|
||||
pure = cl_pure.ival;
|
||||
pure = bound(0, pure, 2);
|
||||
|
@ -4044,6 +4044,9 @@ double Host_Frame (double time)
|
|||
maxfps = 4;
|
||||
}
|
||||
|
||||
if (vid.isminimized && maxfps <= 0 || maxfps > 10)
|
||||
maxfps = 10;
|
||||
|
||||
if (maxfps > 0
|
||||
#if !defined(NOMEDIA)
|
||||
&& Media_Capturing() != 2
|
||||
|
@ -4053,7 +4056,7 @@ double Host_Frame (double time)
|
|||
realtime += spare/1000; //don't use it all!
|
||||
spare = CL_FilterTime((realtime - oldrealtime)*1000, maxfps, maxfpsignoreserver);
|
||||
if (!spare)
|
||||
return cl_yieldcpu.ival ? (1.0 / maxfps - (realtime - oldrealtime)) : 0;
|
||||
return (cl_yieldcpu.ival || vid.isminimized)? (1.0 / maxfps - (realtime - oldrealtime)) : 0;
|
||||
if (spare < 0 || cls.state < ca_onserver)
|
||||
spare = 0; //uncapped.
|
||||
if (spare > cl_sparemsec.ival)
|
||||
|
@ -4150,7 +4153,7 @@ double Host_Frame (double time)
|
|||
if (host_speeds.ival)
|
||||
time1 = Sys_DoubleTime ();
|
||||
|
||||
if (SCR_UpdateScreen)
|
||||
if (SCR_UpdateScreen && !vid.isminimized)
|
||||
{
|
||||
extern mleaf_t *r_viewleaf;
|
||||
extern cvar_t scr_chatmodecvar;
|
||||
|
|
|
@ -3351,9 +3351,9 @@ void CLQ2_ParseClientinfo(int i, char *s)
|
|||
Info_SetValueForKey(player->userinfo, "model", model, MAX_INFO_STRING);
|
||||
Info_SetValueForKey(player->userinfo, "skin", skin, MAX_INFO_STRING);
|
||||
#else
|
||||
Info_SetValueForKey(player->userinfo, "skin", model, MAX_INFO_STRING);
|
||||
Info_SetValueForKey(player->userinfo, "skin", model, sizeof(player->userinfo));
|
||||
#endif
|
||||
Info_SetValueForKey(player->userinfo, "name", name, MAX_INFO_STRING);
|
||||
Info_SetValueForKey(player->userinfo, "name", name, sizeof(player->userinfo));
|
||||
|
||||
cl.players[i].userid = i;
|
||||
cl.players[i].rbottomcolor = 1;
|
||||
|
|
|
@ -403,7 +403,14 @@ qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t
|
|||
name = "";
|
||||
|
||||
if (qrenderer == QR_NONE)
|
||||
{
|
||||
if (!*name)
|
||||
{
|
||||
Con_Printf("%s", text);
|
||||
return 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
con = Con_FindConsole(name);
|
||||
if (!con)
|
||||
|
|
|
@ -661,6 +661,12 @@ void Key_DefaultLinkClicked(char *text, char *info)
|
|||
Cbuf_AddText(va("\njoin %s\n", c), RESTRICT_LOCAL);
|
||||
return;
|
||||
}
|
||||
/*c = Info_ValueForKey(info, "url");
|
||||
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
|
||||
{
|
||||
Cbuf_AddText(va("\nplayfilm %s\n", c), RESTRICT_LOCAL);
|
||||
return;
|
||||
}*/
|
||||
c = Info_ValueForKey(info, "observe");
|
||||
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
|
||||
{
|
||||
|
|
|
@ -2193,7 +2193,7 @@ struct pendingfilms_s
|
|||
qboolean Media_BeginNextFilm(void)
|
||||
{
|
||||
cin_t *cin;
|
||||
static char sname[MAX_QPATH];
|
||||
char sname[MAX_QPATH];
|
||||
struct pendingfilms_s *p;
|
||||
|
||||
if (!pendingfilms)
|
||||
|
@ -2201,12 +2201,15 @@ qboolean Media_BeginNextFilm(void)
|
|||
p = pendingfilms;
|
||||
pendingfilms = p->next;
|
||||
snprintf(sname, sizeof(sname), "cinematic/%s", p->name);
|
||||
Z_Free(p);
|
||||
|
||||
if (!qrenderer)
|
||||
{
|
||||
Z_Free(p);
|
||||
return false;
|
||||
}
|
||||
|
||||
videoshader = R_RegisterCustom(sname, Shader_DefaultCinematic, sname+10);
|
||||
videoshader = R_RegisterCustom(sname, Shader_DefaultCinematic, p->name);
|
||||
Z_Free(p);
|
||||
|
||||
cin = R_ShaderGetCinematic(videoshader);
|
||||
if (cin)
|
||||
|
|
|
@ -445,6 +445,7 @@ extern cvar_t r_editlights_import_specular;
|
|||
extern cvar_t r_mirroralpha;
|
||||
extern cvar_t r_wateralpha;
|
||||
extern cvar_t r_waterstyle;
|
||||
extern cvar_t r_slimestyle;
|
||||
extern cvar_t r_lavastyle;
|
||||
extern cvar_t r_dynamic;
|
||||
extern cvar_t r_novis;
|
||||
|
|
|
@ -364,8 +364,9 @@ cvar_t r_editlights_import_specular = SCVAR ("r_editlights_import_specular", "
|
|||
cvar_t r_shadow_shadowmapping = SCVARF ("debug_r_shadow_shadowmapping", "0", 0);
|
||||
cvar_t r_sun_dir = SCVAR ("r_sun_dir", "0.2 0.5 0.8");
|
||||
cvar_t r_sun_colour = SCVARF ("r_sun_colour", "0 0 0", CVAR_ARCHIVE);
|
||||
cvar_t r_waterstyle = CVARFD ("r_waterstyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes how water, slime, and teleporters are drawn. Possible values are:\n0: fastturb-style block colour.\n1: regular q1-style water.\n2: refraction(ripply and transparent)\n3: refraction with reflection at an angle\n4: ripplemapped without reflections (requires particle effects)\n5: ripples+reflections");
|
||||
cvar_t r_lavastyle = CVARFD ("r_lavastyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only lava.");
|
||||
cvar_t r_waterstyle = CVARFD ("r_waterstyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes how water, and teleporters are drawn. Possible values are:\n0: fastturb-style block colour.\n1: regular q1-style water.\n2: refraction(ripply and transparent)\n3: refraction with reflection at an angle\n4: ripplemapped without reflections (requires particle effects)\n5: ripples+reflections");
|
||||
cvar_t r_slimestyle = CVARFD ("r_slimestyle", "", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only slime. If empty, defers to r_waterstyle.");
|
||||
cvar_t r_lavastyle = CVARFD ("r_lavastyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only lava. If empty, defers to r_waterstyle.");
|
||||
|
||||
cvar_t r_vertexdlights = SCVAR ("r_vertexdlights", "0");
|
||||
|
||||
|
@ -1058,7 +1059,7 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
|
|||
|
||||
if (qrenderer == QR_NONE)
|
||||
{
|
||||
if (newr->renderer->rtype == qrenderer)
|
||||
if (newr->renderer->rtype == qrenderer && currentrendererstate.renderer)
|
||||
return true; //no point
|
||||
|
||||
Sys_CloseTerminal ();
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef struct vrect_s
|
|||
|
||||
typedef struct
|
||||
{
|
||||
qboolean isminimized; //can omit rendering as it won't be seen anyway.
|
||||
int fullbright; // index of first fullbright color
|
||||
|
||||
unsigned width; /*virtual 2d width*/
|
||||
|
|
|
@ -2906,6 +2906,48 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
|||
}
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
else if ((str[0] == 'h' && str[1] == 't' && str[2] == 't' && str[3] == 'p' && str[4] == ':' && !linkstart && !(flags & (PFS_NOMARKUP|PFS_KEEPMARKUP))) ||
|
||||
(str[0] == 'h' && str[1] == 't' && str[2] == 't' && str[3] == 'p' && str[4] == 's' && str[5] == ':' && !linkstart && !(flags & (PFS_NOMARKUP|PFS_KEEPMARKUP))))
|
||||
{
|
||||
//this code can just recurse. saves affecting the rest of the code with weird encodings.
|
||||
int l;
|
||||
char temp[1024];
|
||||
conchar_t *ls, *le;
|
||||
l = 0;
|
||||
while (*str && l < sizeof(temp)-32 && (
|
||||
(*str >= 'a' && *str <= 'z') ||
|
||||
(*str >= 'A' && *str <= 'Z') ||
|
||||
(*str >= '0' && *str <= '9') ||
|
||||
*str == '.' || *str == '/' || *str == '&' || *str == '=' || *str == '_' || *str == '%' || *str == '?' || *str == ':'))
|
||||
l += utf8_encode(temp+l, *str++, sizeof(temp)-1);
|
||||
//recurse
|
||||
temp[l] = 0;
|
||||
|
||||
if (!--outsize)
|
||||
break;
|
||||
*out++ = CON_LINKSTART;
|
||||
ls = out;
|
||||
l = COM_ParseFunString(COLOR_BLUE << CON_FGSHIFT, temp, out, outsize, PFS_FORCEUTF8|PFS_NOMARKUP) - out;
|
||||
outsize -= l;
|
||||
out += l;
|
||||
le = out;
|
||||
|
||||
*out++ = '\\' | CON_HIDDEN;
|
||||
*out++ = 'u' | CON_HIDDEN;
|
||||
*out++ = 'r' | CON_HIDDEN;
|
||||
*out++ = 'l' | CON_HIDDEN;
|
||||
*out++ = '\\' | CON_HIDDEN;
|
||||
while (ls < le)
|
||||
*out++ = (*ls++ & CON_CHARMASK) | CON_HIDDEN;
|
||||
*out++ = CON_LINKEND;
|
||||
|
||||
if (!--outsize)
|
||||
break;
|
||||
*out++ = CON_LINKEND;
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
messedup:
|
||||
if (!--outsize)
|
||||
break;
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef enum {false, true} qboolean;
|
|||
#define STRINGIFY2(s) #s
|
||||
#define STRINGIFY(s) STRINGIFY2(s)
|
||||
|
||||
#define MAX_INFO_STRING 196 //regular quakeworld. Sickening isn't it.
|
||||
#define BASIC_INFO_STRING 196 //regular quakeworld. Sickening isn't it.
|
||||
#define EXTENDED_INFO_STRING 1024
|
||||
#define MAX_SERVERINFO_STRING 1024 //standard quake has 512 here.
|
||||
#define MAX_LOCALINFO_STRING 32768
|
||||
|
@ -511,7 +511,7 @@ 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 SHA1_HMAC(unsigned char *digest, int maxdigestsize, unsigned char *data, int datalen, unsigned char *key, int keylen);
|
||||
|
||||
int version_number(void);
|
||||
char *version_string(void);
|
||||
|
|
|
@ -27,6 +27,7 @@ static struct
|
|||
BOOL (WINAPI *pCertGetCertificateChain) (HCERTCHAINENGINE,PCCERT_CONTEXT,LPFILETIME,HCERTSTORE,PCERT_CHAIN_PARA,DWORD,LPVOID,PCCERT_CHAIN_CONTEXT*);
|
||||
BOOL (WINAPI *pCertVerifyCertificateChainPolicy) (LPCSTR,PCCERT_CHAIN_CONTEXT,PCERT_CHAIN_POLICY_PARA,PCERT_CHAIN_POLICY_STATUS);
|
||||
void (WINAPI *pCertFreeCertificateChain) (PCCERT_CHAIN_CONTEXT);
|
||||
DWORD (WINAPI *pCertNameToStrA) (DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, DWORD dwStrType, LPTSTR psz, DWORD csz);
|
||||
} crypt;
|
||||
static qboolean SSL_Init(void)
|
||||
{
|
||||
|
@ -48,6 +49,7 @@ static qboolean SSL_Init(void)
|
|||
{(void**)&crypt.pCertGetCertificateChain, "CertGetCertificateChain"},
|
||||
{(void**)&crypt.pCertVerifyCertificateChainPolicy, "CertVerifyCertificateChainPolicy"},
|
||||
{(void**)&crypt.pCertFreeCertificateChain, "CertFreeCertificateChain"},
|
||||
{(void**)&crypt.pCertNameToStrA, "CertNameToStrA"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -337,6 +339,7 @@ static DWORD VerifyServerCertificate(PCCERT_CONTEXT pServerCert, PWSTR pwszServe
|
|||
{
|
||||
if (PolicyStatus.dwError)
|
||||
{
|
||||
char fmsg[512];
|
||||
char *err;
|
||||
Status = PolicyStatus.dwError;
|
||||
switch (Status)
|
||||
|
@ -355,7 +358,11 @@ static DWORD VerifyServerCertificate(PCCERT_CONTEXT pServerCert, PWSTR pwszServe
|
|||
case CERT_E_REVOKED: err = "CERT_E_REVOKED"; break;
|
||||
case CERT_E_UNTRUSTEDTESTROOT: err = "CERT_E_UNTRUSTEDTESTROOT"; break;
|
||||
case CERT_E_REVOCATION_FAILURE: err = "CERT_E_REVOCATION_FAILURE"; break;
|
||||
case CERT_E_CN_NO_MATCH: err = "CERT_E_CN_NO_MATCH"; break;
|
||||
case CERT_E_CN_NO_MATCH:
|
||||
err = fmsg;
|
||||
Q_strncpyz(fmsg, "Certificate is for ", sizeof(fmsg));
|
||||
crypt.pCertNameToStrA(X509_ASN_ENCODING, &pServerCert->pCertInfo->Subject, 0, fmsg+strlen(fmsg), sizeof(fmsg)-strlen(fmsg));
|
||||
break;
|
||||
case CERT_E_WRONG_USAGE: err = "CERT_E_WRONG_USAGE"; break;
|
||||
default: err = "(unknown)"; break;
|
||||
}
|
||||
|
|
|
@ -4817,7 +4817,10 @@ qboolean NET_Sleep(int msec, qboolean stdinissocket)
|
|||
|
||||
timeout.tv_sec = msec/1000;
|
||||
timeout.tv_usec = (msec%1000)*1000;
|
||||
select(maxfd+1, &fdset, NULL, NULL, &timeout);
|
||||
if (!maxfd)
|
||||
Sys_Sleep(msec/1000.0);
|
||||
else
|
||||
select(maxfd+1, &fdset, NULL, NULL, &timeout);
|
||||
|
||||
if (stdinissocket)
|
||||
return FD_ISSET(0, &fdset);
|
||||
|
@ -5303,7 +5306,7 @@ static qboolean ICE_SendSpam(struct icestate_s *con)
|
|||
data[2] = ((buf.cursize+4+sizeof(integ)-20)>>8)&0xff; //hashed header length is up to the end of the hmac attribute
|
||||
data[3] = ((buf.cursize+4+sizeof(integ)-20)>>0)&0xff;
|
||||
//but the hash is to the start of the attribute's header
|
||||
SHA1_HMAC(integ, sizeof(integ), con->rpwd, strlen(con->rpwd), data, buf.cursize);
|
||||
SHA1_HMAC(integ, sizeof(integ), data, buf.cursize, con->rpwd, strlen(con->rpwd));
|
||||
MSG_WriteShort(&buf, BigShort(0x8)); //MESSAGE-INTEGRITY
|
||||
MSG_WriteShort(&buf, BigShort(20)); //sha1 key length
|
||||
SZ_Write(&buf, integ, sizeof(integ)); //integrity data
|
||||
|
@ -5521,6 +5524,13 @@ void QDECL ICE_AddRCandidateInfo(struct icestate_s *con, struct icecandinfo_s *n
|
|||
if (!NET_StringToAdr(n->addr, n->port, &peer))
|
||||
return;
|
||||
|
||||
if (peer.type == NA_IP)
|
||||
{
|
||||
//ignore invalid addresses
|
||||
if (!peer.address.ip[0] && !peer.address.ip[1] && !peer.address.ip[2] && !peer.address.ip[3])
|
||||
return;
|
||||
}
|
||||
|
||||
for (o = con->rc; o; o = o->next)
|
||||
{
|
||||
//not sure that updating candidates is particuarly useful tbh, but hey.
|
||||
|
@ -5909,7 +5919,7 @@ static qboolean NET_WasStun(netsrc_t netsrc)
|
|||
char key[20];
|
||||
//the hmac is a bit weird. the header length includes the integrity attribute's length, but the checksum doesn't even consider the attribute header.
|
||||
stun->msglen = BigShort(integritypos+sizeof(integrity) - (char*)stun - sizeof(*stun));
|
||||
SHA1_HMAC(key, sizeof(key), con->lpwd, strlen(con->lpwd), (qbyte*)stun, integritypos-4 - (char*)stun);
|
||||
SHA1_HMAC(key, sizeof(key), (qbyte*)stun, integritypos-4 - (char*)stun, con->lpwd, strlen(con->lpwd));
|
||||
if (memcmp(key, integrity, sizeof(integrity)))
|
||||
{
|
||||
Con_DPrintf("Integrity is bad! needed %x got %x\n", *(int*)key, *(int*)integrity);
|
||||
|
|
|
@ -1613,13 +1613,18 @@ void Plug_Close(plugin_t *plug)
|
|||
}
|
||||
|
||||
Con_Printf("Closing plugin %s\n", plug->name);
|
||||
if (plug->shutdown)
|
||||
{
|
||||
plugin_t *cp = currentplug;
|
||||
currentplug = plug;
|
||||
VM_Call(plug->vm, plug->shutdown);
|
||||
currentplug = cp;
|
||||
}
|
||||
#if defined(PLUGINS) && !defined(NOMEDIA) && !defined(SERVERONLY)
|
||||
Media_UnregisterDecoder(plug, NULL);
|
||||
Media_UnregisterEncoder(plug, NULL);
|
||||
#endif
|
||||
FS_UnRegisterFileSystemModule(plug);
|
||||
if (plug->shutdown)
|
||||
VM_Call(plug->vm, plug->shutdown);
|
||||
VM_Destroy(plug->vm);
|
||||
|
||||
for (i = 0; i < pluginstreamarraylen; i++)
|
||||
|
|
|
@ -15,7 +15,7 @@ This file came to FTE via EzQuake.
|
|||
*/
|
||||
|
||||
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||
|
||||
#define SHA1HANDSOFF
|
||||
//#include "quakedef.h"
|
||||
#include <string.h>
|
||||
|
||||
|
@ -226,19 +226,19 @@ static void memxor(char *dest, char *src, size_t length)
|
|||
}
|
||||
|
||||
int SHA1_HMAC(unsigned char *digest, int maxdigestsize,
|
||||
unsigned char *key, int keylen,
|
||||
unsigned char *data, int datalen)
|
||||
unsigned char *data, int datalen,
|
||||
unsigned char *key, int keylen)
|
||||
{
|
||||
SHA1_CTX inner;
|
||||
SHA1_CTX outer;
|
||||
char optkeybuf[20];
|
||||
char optkeybuf[DIGEST_SIZE];
|
||||
char block[64];
|
||||
char innerhash[20];
|
||||
char innerhash[DIGEST_SIZE];
|
||||
|
||||
if (maxdigestsize < DIGEST_SIZE)
|
||||
return 0;
|
||||
|
||||
/* Reduce the key's size, so that it becomes <= 64 bytes large. */
|
||||
/* Reduce the key's size, so that it is never larger than a block. */
|
||||
|
||||
if (keylen > 64)
|
||||
{
|
||||
|
@ -249,7 +249,7 @@ int SHA1_HMAC(unsigned char *digest, int maxdigestsize,
|
|||
SHA1Final (optkeybuf, &keyhash);
|
||||
|
||||
key = optkeybuf;
|
||||
keylen = 20;
|
||||
keylen = sizeof(optkeybuf);
|
||||
}
|
||||
|
||||
/* Compute INNERHASH from KEY and IN. */
|
||||
|
|
|
@ -4259,8 +4259,10 @@ char *Shader_DefaultBSPWater(char *shortname)
|
|||
else if (r_fastturb.ival)
|
||||
wstyle = 0;
|
||||
#ifdef GLQUAKE
|
||||
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && !strncmp(shortname, "*lava", 5))
|
||||
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && !strncmp(shortname, "*lava", 5) && *r_lavastyle.string)
|
||||
wstyle = r_lavastyle.ival;
|
||||
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && !strncmp(shortname, "*slime", 5) && *r_lavastyle.string)
|
||||
wstyle = r_slimestyle.ival;
|
||||
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && strncmp(shortname, "*lava", 5))
|
||||
wstyle = r_waterstyle.ival<1?1:r_waterstyle.ival;
|
||||
#endif
|
||||
|
|
|
@ -1796,7 +1796,8 @@ qboolean GLAppActivate(BOOL fActive, BOOL minimize)
|
|||
{
|
||||
if (modestate != MS_WINDOWED)
|
||||
{
|
||||
if (vid_canalttab) {
|
||||
if (vid_canalttab)
|
||||
{
|
||||
ChangeDisplaySettings (NULL, 0);
|
||||
vid_wassuspended = true;
|
||||
}
|
||||
|
@ -1969,6 +1970,7 @@ LONG WINAPI GLMainWndProc (
|
|||
}
|
||||
return 0;
|
||||
case WM_SIZE:
|
||||
vid.isminimized = (wParam==SIZE_MINIMIZED);
|
||||
if (!vid_initializing)
|
||||
{
|
||||
VID_UpdateWindowStatus (hWnd);
|
||||
|
|
|
@ -8360,9 +8360,6 @@ void QCBUILTIN PF_ForceInfoKey(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
|
||||
SV_ExtractFromUserinfo (&svs.clients[e1-1], false);
|
||||
|
||||
if (SV_UserInfoIsBasic(key))
|
||||
Info_SetValueForKey (svs.clients[e1-1].userinfobasic, key, value, sizeof(svs.clients[e1-1].userinfobasic));
|
||||
|
||||
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
|
||||
MSG_WriteByte (&sv.reliable_datagram, e1-1);
|
||||
MSG_WriteString (&sv.reliable_datagram, key);
|
||||
|
|
|
@ -369,7 +369,6 @@ typedef struct client_s
|
|||
|
||||
int challenge;
|
||||
int userid; // identifying number
|
||||
char userinfobasic[MAX_INFO_STRING];
|
||||
char userinfo[EXTENDED_INFO_STRING]; // infostring
|
||||
|
||||
usercmd_t lastcmd; // for filling in big drops and partial predictions
|
||||
|
@ -944,6 +943,7 @@ void SV_ExecInitialConfigs(char *defaultexec);
|
|||
|
||||
int SV_CalcPing (client_t *cl, qboolean forcecalc);
|
||||
void SV_FullClientUpdate (client_t *client, client_t *to);
|
||||
void SV_GeneratePublicUserInfo(int pext, client_t *cl, char *info, int infolength);
|
||||
|
||||
int SV_ModelIndex (char *name);
|
||||
|
||||
|
|
|
@ -1130,7 +1130,7 @@ void SV_ForceName_f (void)
|
|||
|
||||
while((cl = SV_GetClientForString(Cmd_Argv(1), &clnum)))
|
||||
{
|
||||
Info_SetValueForKey(cl->userinfo, "name", Cmd_Argv(2), MAX_INFO_STRING);
|
||||
Info_SetValueForKey(cl->userinfo, "name", Cmd_Argv(2), EXTENDED_INFO_STRING);
|
||||
SV_LogPlayer(cl, "name forced");
|
||||
SV_ExtractFromUserinfo(cl, true);
|
||||
Q_strncpyz(cl->name, Cmd_Argv(2), sizeof(cl->namebuf));
|
||||
|
|
|
@ -599,7 +599,6 @@ void SV_DropClient (client_t *drop)
|
|||
drop->namebuf[0] = 0;
|
||||
drop->name = drop->namebuf;
|
||||
memset (drop->userinfo, 0, sizeof(drop->userinfo));
|
||||
memset (drop->userinfobasic, 0, sizeof(drop->userinfobasic));
|
||||
|
||||
while ((lp = drop->laggedpacket))
|
||||
{
|
||||
|
@ -876,20 +875,36 @@ int SV_CalcPing (client_t *cl, qboolean forcecalc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void SV_GenerateBasicUserInfo(client_t *cl)
|
||||
//generate whatever public userinfo is supported by the client.
|
||||
//private keys like _ prefixes and the password key are stripped out here.
|
||||
//password needs to be stripped in case the password key doesn't actually relate to this server.
|
||||
void SV_GeneratePublicUserInfo(int pext, client_t *cl, char *info, int infolength)
|
||||
{
|
||||
char *key, *s;
|
||||
int i;
|
||||
for (i= 1; (key = Info_KeyForNumber(cl->userinfo, i)); i++)
|
||||
|
||||
//FIXME: we should probably use some sort of priority system instead if I'm honest about it
|
||||
if (pext & PEXT_BIGUSERINFOS)
|
||||
Q_strncpyz (info, cl->userinfo, sizeof(info));
|
||||
else
|
||||
{
|
||||
if (!*key)
|
||||
break;
|
||||
if (!SV_UserInfoIsBasic(key))
|
||||
continue;
|
||||
if (infolength >= BASIC_INFO_STRING)
|
||||
infolength = BASIC_INFO_STRING;
|
||||
for (i = 0; (key = Info_KeyForNumber(cl->userinfo, i)); i++)
|
||||
{
|
||||
if (!*key)
|
||||
break;
|
||||
if (!SV_UserInfoIsBasic(key))
|
||||
continue;
|
||||
|
||||
s = Info_ValueForKey(cl->userinfo, key);
|
||||
Info_SetValueForStarKey (cl->userinfobasic, key, s, sizeof(cl->userinfobasic));
|
||||
s = Info_ValueForKey(cl->userinfo, key);
|
||||
Info_SetValueForStarKey (info, key, s, infolength);
|
||||
}
|
||||
}
|
||||
|
||||
Info_RemovePrefixedKeys (info, '_'); // server passwords, etc
|
||||
Info_RemoveKey(info, "password");
|
||||
Info_RemoveKey(info, "*ip");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -902,7 +917,7 @@ Writes all update values to client. use to=NULL to broadcast.
|
|||
void SV_FullClientUpdate (client_t *client, client_t *to)
|
||||
{
|
||||
int i;
|
||||
char info[MAX_INFO_STRING];
|
||||
char info[EXTENDED_INFO_STRING];
|
||||
|
||||
if (!to)
|
||||
{
|
||||
|
@ -910,6 +925,8 @@ void SV_FullClientUpdate (client_t *client, client_t *to)
|
|||
{
|
||||
SV_FullClientUpdate(client, &svs.clients[i]);
|
||||
}
|
||||
if (sv.mvdrecording)
|
||||
SV_FullClientUpdate(client, &demo.recorder);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -941,12 +958,7 @@ void SV_FullClientUpdate (client_t *client, client_t *to)
|
|||
ClientReliableWrite_Byte (to, i);
|
||||
ClientReliableWrite_Float (to, realtime - client->connection_started);
|
||||
|
||||
if ((to->fteprotocolextensions) & PEXT_BIGUSERINFOS)
|
||||
Q_strncpyz (info, client->userinfo, sizeof(info));
|
||||
else
|
||||
Q_strncpyz (info, client->userinfobasic, sizeof(info));
|
||||
Info_RemoveKey(info, "password"); //main password key
|
||||
Info_RemovePrefixedKeys (info, '_'); // server passwords, etc
|
||||
SV_GeneratePublicUserInfo(to->fteprotocolextensions, client, info, sizeof(info));
|
||||
|
||||
ClientReliableWrite_Begin(to, svc_updateuserinfo, 7 + strlen(info));
|
||||
ClientReliableWrite_Byte (to, i);
|
||||
|
@ -2464,7 +2476,6 @@ client_t *SVC_DirectConnect(void)
|
|||
|
||||
// parse some info from the info strings
|
||||
SV_ExtractFromUserinfo (newcl, true);
|
||||
SV_GenerateBasicUserInfo (newcl);
|
||||
|
||||
// JACK: Init the floodprot stuff.
|
||||
newcl->floodprotmessage = 0.0;
|
||||
|
@ -4030,6 +4041,11 @@ void SV_MVDStream_Poll(void);
|
|||
SV_MVDStream_Poll();
|
||||
}
|
||||
|
||||
#ifdef PLUGINS
|
||||
if (isDedicated)
|
||||
Plug_Tick();
|
||||
#endif
|
||||
|
||||
if (sv.state < ss_active || !sv.world.worldmodel)
|
||||
{
|
||||
#ifndef SERVERONLY
|
||||
|
@ -4117,9 +4133,6 @@ void SV_MVDStream_Poll(void);
|
|||
if (isDedicated)
|
||||
#endif
|
||||
{
|
||||
#ifdef PLUGINS
|
||||
Plug_Tick();
|
||||
#endif
|
||||
NET_Tick();
|
||||
|
||||
SV_GetConsoleCommands ();
|
||||
|
|
|
@ -773,7 +773,7 @@ void SV_MVDPings (void)
|
|||
}
|
||||
void SV_MVD_FullClientUpdate(sizebuf_t *msg, client_t *player)
|
||||
{
|
||||
char info[MAX_INFO_STRING];
|
||||
char info[EXTENDED_INFO_STRING];
|
||||
qboolean dosizes;
|
||||
|
||||
if (!sv.mvdrecording)
|
||||
|
@ -805,10 +805,7 @@ void SV_MVD_FullClientUpdate(sizebuf_t *msg, client_t *player)
|
|||
MSG_WriteByte (msg, player - svs.clients);
|
||||
MSG_WriteFloat (msg, realtime - player->connection_started);
|
||||
|
||||
Q_strncpyz (info, player->userinfo, MAX_INFO_STRING);
|
||||
Info_RemovePrefixedKeys (info, '_'); // server passwords, etc
|
||||
Info_RemoveKey(info, "password");
|
||||
Info_RemoveKey(info, "*ip");
|
||||
SV_GeneratePublicUserInfo(demo.recorder.fteprotocolextensions, player, info, sizeof(info));
|
||||
|
||||
if (dosizes)
|
||||
msg = MVDWrite_Begin (dem_all, 0, 7 + strlen(info));
|
||||
|
|
|
@ -57,7 +57,7 @@ cvar_t sv_cmdlikercon = SCVAR("sv_cmdlikercon", "0"); //set to 1 to allow a pass
|
|||
cvar_t cmd_allowaccess = SCVAR("cmd_allowaccess", "0"); //set to 1 to allow cmd to execute console commands on the server.
|
||||
cvar_t cmd_gamecodelevel = SCVAR("cmd_gamecodelevel", "50"); //execution level which gamecode is told about (for unrecognised commands)
|
||||
|
||||
cvar_t sv_pure = CVARFD("sv_pure", "", CVAR_SERVERINFO, "The most evil cvar in the world.");
|
||||
cvar_t sv_pure = CVARFD("sv_pure", "", CVAR_SERVERINFO, "The most evil cvar in the world, many clients will ignore this.\n0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 only works in total conversions.");
|
||||
cvar_t sv_nqplayerphysics = CVARAD("sv_nqplayerphysics", "0", "sv_nomsec", "Disregard player prediction and run NQ-style player physics instead. This can be used for compatibility with mods that expect exact behaviour.");
|
||||
cvar_t sv_edgefriction = CVARAF("sv_edgefriction", "2",
|
||||
"edgefriction", 0);
|
||||
|
@ -3598,7 +3598,7 @@ Allow clients to change userinfo
|
|||
void SV_SetInfo_f (void)
|
||||
{
|
||||
int i, j;
|
||||
char oldval[MAX_INFO_STRING];
|
||||
char oldval[MAX_INFO_KEY];
|
||||
char *key, *val;
|
||||
qboolean basic; //infos that we send to any old qw client.
|
||||
client_t *client;
|
||||
|
@ -3623,7 +3623,7 @@ void SV_SetInfo_f (void)
|
|||
if (strstr(Cmd_Argv(1), "\\") || strstr(Cmd_Argv(2), "\\"))
|
||||
return; // illegal char
|
||||
|
||||
Q_strncpyz(oldval, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)), MAX_INFO_STRING);
|
||||
Q_strncpyz(oldval, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)), sizeof(oldval));
|
||||
|
||||
#ifdef VM_Q1
|
||||
if (Q1QVM_UserInfoChanged(sv_player))
|
||||
|
@ -3656,8 +3656,6 @@ void SV_SetInfo_f (void)
|
|||
|
||||
basic = SV_UserInfoIsBasic(key);
|
||||
|
||||
if (basic)
|
||||
Info_SetValueForKey (host_client->userinfobasic, key, val, sizeof(host_client->userinfobasic));
|
||||
for (j = 0; j < MAX_CLIENTS; j++)
|
||||
{
|
||||
client = svs.clients+j;
|
||||
|
@ -3690,7 +3688,7 @@ void SV_SetInfo_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
if (sv.mvdrecording)
|
||||
if (sv.mvdrecording && (basic || (demo.recorder.fteprotocolextensions & PEXT_BIGUSERINFOS)))
|
||||
{
|
||||
sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, strlen(key)+strlen(val)+4);
|
||||
MSG_WriteByte (msg, svc_setinfo);
|
||||
|
@ -4218,7 +4216,6 @@ void Cmd_Join_f (void)
|
|||
// turn the spectator into a player
|
||||
host_client->spectator = false;
|
||||
Info_RemoveKey (host_client->userinfo, "*spectator");
|
||||
Info_RemoveKey (host_client->userinfobasic, "*spectator");
|
||||
|
||||
// FIXME, bump the client's userid?
|
||||
|
||||
|
@ -4328,7 +4325,6 @@ void Cmd_Observe_f (void)
|
|||
// turn the player into a spectator
|
||||
host_client->spectator = true;
|
||||
Info_SetValueForStarKey (host_client->userinfo, "*spectator", "1", sizeof(host_client->userinfo));
|
||||
Info_SetValueForStarKey (host_client->userinfobasic, "*spectator", "1", sizeof(host_client->userinfobasic));
|
||||
|
||||
// FIXME, bump the client's userid?
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ static void *Dec_Create(char *medianame)
|
|||
medianame = medianame + 10;
|
||||
else if (!strcmp(medianame, "berkelium"))
|
||||
medianame = (char*)"about:blank";
|
||||
else if (!strncmp(medianame, "http:", 5))
|
||||
else if (!strncmp(medianame, "http:", 5) || !strncmp(medianame, "https:", 6))
|
||||
medianame = medianame; //and direct http requests.
|
||||
else
|
||||
return NULL;
|
||||
|
@ -304,33 +304,31 @@ static void Dec_Key (void *vctx, int code, int unicode, int isup)
|
|||
}
|
||||
else
|
||||
{
|
||||
int mods = 0;
|
||||
if (code == 127)
|
||||
code = 0x08;
|
||||
else if (code == 140) //del
|
||||
code = 0x2e;
|
||||
else if (code == 143) //home
|
||||
code = 0x24;
|
||||
else if (code == 144) //end
|
||||
code = 0x23;
|
||||
else if (code == 141) //pgdn
|
||||
code = 0x22;
|
||||
else if (code == 142) //pgup
|
||||
code = 0x21;
|
||||
else if (code == 139) //ins
|
||||
code = 0x2d;
|
||||
else if (code == 132) //up
|
||||
code = 0x26;
|
||||
else if (code == 133) //down
|
||||
code = 0x28;
|
||||
else if (code == 134) //left
|
||||
code = 0x25;
|
||||
else if (code == 135) //right
|
||||
code = 0x27;
|
||||
if (code)
|
||||
{
|
||||
int mods = 0;
|
||||
if (code == 127)
|
||||
code = 0x08;
|
||||
else if (code == 140) //del
|
||||
code = 0x2e;
|
||||
else if (code == 143) //home
|
||||
code = 0x24;
|
||||
else if (code == 144) //end
|
||||
code = 0x23;
|
||||
else if (code == 141) //pgdn
|
||||
code = 0x22;
|
||||
else if (code == 142) //pgup
|
||||
code = 0x21;
|
||||
else if (code == 139) //ins
|
||||
code = 0x2d;
|
||||
else if (code == 132) //up
|
||||
code = 0x26;
|
||||
else if (code == 133) //down
|
||||
code = 0x28;
|
||||
else if (code == 134) //left
|
||||
code = 0x25;
|
||||
else if (code == 135) //right
|
||||
code = 0x27;
|
||||
ctx->wnd->keyEvent(!isup, mods, code, 0);
|
||||
}
|
||||
if (unicode && !isup)
|
||||
{
|
||||
wchar_t chars[2] = {unicode};
|
||||
|
|
|
@ -362,7 +362,50 @@ static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
|
|||
|
||||
|
||||
|
||||
char *MD5_ToHex(char *input, int inputlen, char *ret, int retlen)
|
||||
{
|
||||
int v, i;
|
||||
unsigned char digest[16];
|
||||
MD5_CTX ctx;
|
||||
|
||||
if (retlen < 33)
|
||||
return NULL;
|
||||
|
||||
MD5Init (&ctx);
|
||||
MD5Update (&ctx, (unsigned char *)input, inputlen);
|
||||
MD5Final ( (unsigned char *)digest, &ctx);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
v = digest[i]>>4;
|
||||
if (v >= 10)
|
||||
ret[i*2+0] = (v-10) + 'a';
|
||||
else
|
||||
ret[i*2+0] = v + '0';
|
||||
v = digest[i]&0xf;
|
||||
if (v >= 10)
|
||||
ret[i*2+1] = (v-10) + 'a';
|
||||
else
|
||||
ret[i*2+1] = v + '0';
|
||||
}
|
||||
ret[i*2] = '\0';
|
||||
return ret;
|
||||
}
|
||||
char *MD5_ToBinary(char *input, int inputlen, char *ret, int retlen)
|
||||
{
|
||||
int v, i;
|
||||
unsigned char digest[16];
|
||||
MD5_CTX ctx;
|
||||
|
||||
if (retlen < 16)
|
||||
return NULL;
|
||||
|
||||
MD5Init (&ctx);
|
||||
MD5Update (&ctx, (unsigned char *)input, inputlen);
|
||||
MD5Final ( (unsigned char *)ret, &ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *MD5_GetPop3APOPString(char *timestamp, char *secrit)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -43,6 +43,7 @@ void XML_AddParameteri(xmltree_t *t, char *paramname, int value)
|
|||
}
|
||||
xmltree_t *XML_CreateNode(xmltree_t *parent, char *name, char *xmlns, char *body)
|
||||
{
|
||||
int bodylen = strlen(body);
|
||||
struct subtree_s *node = malloc(sizeof(*node));
|
||||
|
||||
//clear out links
|
||||
|
@ -52,14 +53,26 @@ xmltree_t *XML_CreateNode(xmltree_t *parent, char *name, char *xmlns, char *body
|
|||
//link into parent if we actually have a parent.
|
||||
if (parent)
|
||||
{
|
||||
node->sibling = parent->child;
|
||||
parent->child = node;
|
||||
if (parent->child)
|
||||
{ //add at tail
|
||||
xmltree_t *prev;
|
||||
for(prev = parent->child; prev->sibling; prev = prev->sibling)
|
||||
;
|
||||
prev->sibling = node;
|
||||
node->sibling = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->sibling = parent->child;
|
||||
parent->child = node;
|
||||
}
|
||||
}
|
||||
|
||||
Q_strlcpy(node->name, name, sizeof(node->name));
|
||||
Q_strlcpy(node->xmlns, xmlns, sizeof(node->xmlns));
|
||||
Q_strlcpy(node->xmlns_dflt, xmlns, sizeof(node->xmlns_dflt));
|
||||
Q_strlcpy(node->body, body, sizeof(node->xmlns_dflt));
|
||||
node->body = malloc(bodylen+1);
|
||||
memcpy(node->body, body, bodylen+1);
|
||||
|
||||
if (*xmlns)
|
||||
XML_AddParameter(node, "xmlns", xmlns);
|
||||
|
@ -221,10 +234,10 @@ static void XML_DumpToBuf(struct buf_ctx *buf, xmltree_t *t, int indent)
|
|||
buf_cat(buf, "\n", 1);
|
||||
}
|
||||
|
||||
char *XML_GenerateString(xmltree_t *root)
|
||||
char *XML_GenerateString(xmltree_t *root, qboolean readable)
|
||||
{
|
||||
struct buf_ctx buf = {NULL, 0, 0};
|
||||
XML_DumpToBuf(&buf, root, -1);
|
||||
XML_DumpToBuf(&buf, root, readable?0:-1);
|
||||
buf_cat(&buf, "", 1);
|
||||
return buf.buf;
|
||||
}
|
||||
|
@ -234,6 +247,7 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
xmltree_t *child;
|
||||
xmltree_t *ret;
|
||||
int bodypos;
|
||||
int bodymax = 0;
|
||||
int pos, i;
|
||||
char *tagend;
|
||||
char *tagstart;
|
||||
|
@ -283,7 +297,7 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
tagstart++;
|
||||
for (i = 0; i < sizeof(token)-1 && *tagstart; )
|
||||
{
|
||||
if (*tagstart == ' ' || *tagstart == '\n' || *tagstart == '\r' || *tagstart == '\t')
|
||||
if (*tagstart == ' ' || (i&&*tagstart == '/') || (i&&*tagstart == '?') || *tagstart == '\n' || *tagstart == '\r' || *tagstart == '\t')
|
||||
break;
|
||||
token[i++] = *tagstart++;
|
||||
}
|
||||
|
@ -315,7 +329,7 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
int nlen;
|
||||
|
||||
|
||||
while(*tagstart <= ' ' && *tagstart)
|
||||
while(*(unsigned char*)tagstart <= ' ' && *tagstart)
|
||||
tagstart++; //skip whitespace (note that we know there is a null terminator before the end of the buffer)
|
||||
|
||||
if (!*tagstart)
|
||||
|
@ -325,7 +339,7 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
nlen = 0;
|
||||
while (nlen < sizeof(p->name)-2)
|
||||
{
|
||||
if(*tagstart <= ' ')
|
||||
if (*(unsigned char*)tagstart <= ' ' || *tagstart == '/' || *tagstart == '?')
|
||||
break;
|
||||
|
||||
if (*tagstart == '=')
|
||||
|
@ -334,14 +348,14 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
}
|
||||
p->name[nlen++] = '\0';
|
||||
|
||||
while(*tagstart <= ' ' && *tagstart)
|
||||
while(*(unsigned char*)tagstart <= ' ' && *tagstart)
|
||||
tagstart++; //skip whitespace (note that we know there is a null terminator before the end of the buffer)
|
||||
|
||||
if (*tagstart != '=')
|
||||
continue;
|
||||
break;
|
||||
tagstart++;
|
||||
|
||||
while(*tagstart <= ' ' && *tagstart)
|
||||
while(*(unsigned char*)tagstart <= ' ' && *tagstart)
|
||||
tagstart++; //skip whitespace (note that we know there is a null terminator before the end of the buffer)
|
||||
|
||||
nlen = 0;
|
||||
|
@ -397,6 +411,8 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
|
||||
if (tagend[-2] == '/')
|
||||
{ //no body
|
||||
ret->body = malloc(1);
|
||||
*ret->body = 0;
|
||||
*startpos = pos;
|
||||
return ret;
|
||||
}
|
||||
|
@ -405,6 +421,8 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
//no body either
|
||||
if (tagend[-2] == '?')
|
||||
{
|
||||
ret->body = malloc(1);
|
||||
*ret->body = 0;
|
||||
*startpos = pos;
|
||||
return ret;
|
||||
}
|
||||
|
@ -459,10 +477,27 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
else
|
||||
{
|
||||
char c = buffer[pos++];
|
||||
if (bodypos < sizeof(ret->body)-1)
|
||||
ret->body[bodypos++] = c;
|
||||
if (bodypos == bodymax)
|
||||
{
|
||||
int nlen = bodypos*2 + 64;
|
||||
char *nb = malloc(nlen);
|
||||
memcpy(nb, ret->body, bodypos);
|
||||
free(ret->body);
|
||||
ret->body = nb;
|
||||
bodymax = nlen;
|
||||
}
|
||||
ret->body[bodypos++] = c;
|
||||
}
|
||||
}
|
||||
if (bodypos == bodymax)
|
||||
{
|
||||
int nlen = bodypos+1;
|
||||
char *nb = malloc(nlen);
|
||||
memcpy(nb, ret->body, bodypos);
|
||||
free(ret->body);
|
||||
ret->body = nb;
|
||||
bodymax = nlen;
|
||||
}
|
||||
ret->body[bodypos++] = '\0';
|
||||
|
||||
XML_Unmark(ret->body);
|
||||
|
@ -486,6 +521,7 @@ void XML_Destroy(xmltree_t *t)
|
|||
np = p->next;
|
||||
free(p);
|
||||
}
|
||||
free(t->body);
|
||||
free(t);
|
||||
}
|
||||
|
||||
|
@ -504,6 +540,28 @@ xmltree_t *XML_ChildOfTree(xmltree_t *t, char *name, int childnum)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
xmltree_t *XML_ChildOfTreeNS(xmltree_t *t, char *xmlns, char *name, int childnum)
|
||||
{
|
||||
if (t)
|
||||
{
|
||||
for (t = t->child; t; t = t->sibling)
|
||||
{
|
||||
if (!strcmp(t->xmlns, xmlns) && !strcmp(t->name, name))
|
||||
{
|
||||
if (childnum-- == 0)
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
char *XML_GetChildBody(xmltree_t *t, char *paramname, char *def)
|
||||
{
|
||||
xmltree_t *c = XML_ChildOfTree(t, paramname, 0);
|
||||
if (c)
|
||||
return c->body;
|
||||
return def;
|
||||
}
|
||||
|
||||
void XML_ConPrintTree(xmltree_t *t, int indent)
|
||||
{
|
||||
|
@ -527,3 +585,114 @@ void XML_ConPrintTree(xmltree_t *t, int indent)
|
|||
|
||||
free(buf.buf);
|
||||
}
|
||||
|
||||
|
||||
static void XML_SkipWhite(char *msg, int *pos, int max)
|
||||
{
|
||||
while (*pos < max && (
|
||||
msg[*pos] == ' ' ||
|
||||
msg[*pos] == '\t' ||
|
||||
msg[*pos] == '\r' ||
|
||||
msg[*pos] == '\n'
|
||||
))
|
||||
*pos+=1;
|
||||
}
|
||||
static qboolean XML_ParseString(char *msg, int *pos, int max, char *out, int outlen)
|
||||
{
|
||||
*out = 0;
|
||||
if (*pos < max && msg[*pos] == '\"')
|
||||
{
|
||||
*pos+=1;
|
||||
|
||||
outlen--;
|
||||
while (*pos < max && msg[*pos] != '\"')
|
||||
{
|
||||
if (!outlen)
|
||||
return false;
|
||||
*out = msg[*pos];
|
||||
out++;
|
||||
outlen--;
|
||||
*pos+=1;
|
||||
}
|
||||
if (*pos < max && msg[*pos] == '\"')
|
||||
{
|
||||
*out = 0;
|
||||
*pos+=1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outlen--;
|
||||
while (*pos < max
|
||||
&& msg[*pos] != ' '
|
||||
&& msg[*pos] != '\t'
|
||||
&& msg[*pos] != '\r'
|
||||
&& msg[*pos] != '\n'
|
||||
&& msg[*pos] != ':'
|
||||
&& msg[*pos] != ','
|
||||
&& msg[*pos] != '}'
|
||||
&& msg[*pos] != '{')
|
||||
{
|
||||
if (!outlen)
|
||||
return false;
|
||||
*out = msg[*pos];
|
||||
out++;
|
||||
outlen--;
|
||||
*pos+=1;
|
||||
}
|
||||
*out = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
xmltree_t *XML_FromJSON(xmltree_t *t, char *name, char *json, int *jsonpos, int jsonlen)
|
||||
{
|
||||
char child[4096];
|
||||
char *start;
|
||||
char *end;
|
||||
XML_SkipWhite(json, jsonpos, jsonlen);
|
||||
|
||||
if (*jsonpos < jsonlen && json[*jsonpos] == '{')
|
||||
{
|
||||
*jsonpos+=1;
|
||||
XML_SkipWhite(json, jsonpos, jsonlen);
|
||||
|
||||
t = XML_CreateNode(t, name, "", "");
|
||||
|
||||
while (*jsonpos < jsonlen && json[*jsonpos] == '\"')
|
||||
{
|
||||
if (!XML_ParseString(json, jsonpos, jsonlen, child, sizeof(child)))
|
||||
break;
|
||||
XML_SkipWhite(json, jsonpos, jsonlen);
|
||||
if (*jsonpos < jsonlen && json[*jsonpos] == ':')
|
||||
{
|
||||
*jsonpos+=1;
|
||||
if (!XML_FromJSON(t, child, json, jsonpos, jsonlen))
|
||||
break;
|
||||
}
|
||||
XML_SkipWhite(json, jsonpos, jsonlen);
|
||||
|
||||
if (*jsonpos < jsonlen && json[*jsonpos] == ',')
|
||||
{
|
||||
*jsonpos+=1;
|
||||
XML_SkipWhite(json, jsonpos, jsonlen);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (*jsonpos < jsonlen && json[*jsonpos] == '}')
|
||||
{
|
||||
*jsonpos+=1;
|
||||
return t;
|
||||
}
|
||||
XML_Destroy(t);
|
||||
}
|
||||
else if (*jsonpos < jsonlen)
|
||||
{
|
||||
if (XML_ParseString(json, jsonpos, jsonlen, child, sizeof(child)))
|
||||
return XML_CreateNode(t, name, "", child);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ typedef struct subtree_s
|
|||
char name[64]; //FIXME: make pointer to tail of structure
|
||||
char xmlns[64]; //namespace of the element //FIXME: make pointer to tail of structure
|
||||
char xmlns_dflt[64]; //default namespace of children //FIXME: make pointer to tail of structure
|
||||
char body[2048]; //FIXME: make pointer+variablesized
|
||||
char *body;//[2048]; //FIXME: make pointer+variablesized
|
||||
|
||||
xmlparams_t *params;
|
||||
|
||||
|
@ -26,8 +26,12 @@ void XML_AddParameteri(xmltree_t *t, char *paramname, int value);
|
|||
xmltree_t *XML_CreateNode(xmltree_t *parent, char *name, char *xmlns, char *body);
|
||||
char *XML_Markup(char *s, char *d, int dlen);
|
||||
void XML_Unmark(char *s);
|
||||
char *XML_GenerateString(xmltree_t *root);
|
||||
char *XML_GenerateString(xmltree_t *root, qboolean readable);
|
||||
xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronly, char *defaultnamespace);
|
||||
void XML_Destroy(xmltree_t *t);
|
||||
xmltree_t *XML_ChildOfTree(xmltree_t *t, char *name, int childnum);
|
||||
xmltree_t *XML_ChildOfTreeNS(xmltree_t *t, char *xmlns, char *name, int childnum);
|
||||
char *XML_GetChildBody(xmltree_t *t, char *paramname, char *def);
|
||||
void XML_ConPrintTree(xmltree_t *t, int indent);
|
||||
|
||||
xmltree_t *XML_FromJSON(xmltree_t *t, char *name, char *json, int *jsonpos, int jsonlen);
|
Loading…
Reference in a new issue