prepare for proper binary auth instead of depending upon tls certs (using sha2(512) to ensure no modification). probably buggy on windows so not fully enabled yet.
allow for binary updates on linux as on windows (-allowupdate for modified/nonsvn builds). dlightmask is now size_t, because we might as well allow that on 64bit cpus, this allows for 64 lightmaphack lights instead of 32. fix potential openal issue with source=0. added q3bsp_ignorestyles cvar to ignore rbsp styles (and reduce needed batch counts), should only be used on maps with subtle lighting changes (ones that are properly lit without toggling any lightswitches). add support for directly loading foo.bsp.gz Added prints to clarify why servers might be listed under the 'UNKNOWN' category in the master server. Attempt to show hostnames anyway, to make it a little more obvious who's responsible for those badly configured servers. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5656 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
9aa87ad28e
commit
b63dc8b880
59 changed files with 1970 additions and 421 deletions
|
@ -469,6 +469,7 @@ SET(FTE_COMMON_FILES
|
|||
engine/common/q3common.c
|
||||
engine/common/qvm.c
|
||||
engine/common/sha1.c
|
||||
engine/common/sha2.c
|
||||
engine/common/translate.c
|
||||
engine/common/zone.c
|
||||
|
||||
|
@ -773,7 +774,7 @@ ELSE()
|
|||
${FTE_CLIENT_FILES}
|
||||
)
|
||||
SET_TARGET_PROPERTIES(fteqw PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_DEFINES};${FTE_REVISON}")
|
||||
TARGET_LINK_LIBRARIES(fteqw ${FTE_LIBS} )
|
||||
TARGET_LINK_LIBRARIES(fteqw ${FTE_LIBS})
|
||||
SET(INSTALLTARGS ${INSTALLTARGS} fteqw)
|
||||
|
||||
ADD_EXECUTABLE(fteqw-sv
|
||||
|
|
|
@ -859,6 +859,7 @@ COMMON_OBJS = \
|
|||
huff.o \
|
||||
md4.o \
|
||||
sha1.o \
|
||||
sha2.o \
|
||||
log.o \
|
||||
net_chan.o \
|
||||
net_wins.o \
|
||||
|
|
|
@ -1620,12 +1620,13 @@ void CL_UseIndepPhysics(qboolean allow)
|
|||
}
|
||||
else
|
||||
{
|
||||
CL_AllowIndependantSendCmd(true);
|
||||
//shut it down.
|
||||
runningindepphys = false; //tell thread to exit gracefully
|
||||
Sys_LockMutex(indeplock);
|
||||
Sys_WaitOnThread(indepthread);
|
||||
Sys_UnlockMutex(indeplock);
|
||||
indepthread = NULL;
|
||||
Sys_DestroyMutex(indeplock);
|
||||
indeplock = NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -1506,6 +1506,7 @@ void CL_Rcon_f (void)
|
|||
const unsigned char **tokens = alloca(sizeof(*tokens)*(4+Cmd_Argc()*2));
|
||||
size_t *tokensizes = alloca(sizeof(*tokensizes)*(4+Cmd_Argc()*2));
|
||||
int j, k;
|
||||
void *ctx = alloca(hash_sha1.contextsize);
|
||||
|
||||
for (j = 0; j < sizeof(time_t); j++)
|
||||
{ //little-endian byte order, but big-endian nibble order. just screwed. for compat with ezquake.
|
||||
|
@ -1523,9 +1524,11 @@ void CL_Rcon_f (void)
|
|||
tokens[4+j*2+0] = Cmd_Argv(i+j);
|
||||
tokens[4+j*2+1] = " ";
|
||||
}
|
||||
hash_sha1.init(ctx);
|
||||
for (k = 0; k < 4+j*2; k++)
|
||||
tokensizes[k] = strlen(tokens[k]);
|
||||
digestsize = SHA1_m(digest, sizeof(digest), k, tokens, tokensizes);
|
||||
hash_sha1.process(ctx, tokens[k], strlen(tokens[k]));
|
||||
hash_sha1.terminate(digest, ctx);
|
||||
digestsize = hash_sha1.digestsize;
|
||||
|
||||
for (j = 0; j < digestsize; j++)
|
||||
{
|
||||
|
|
|
@ -4517,15 +4517,18 @@ static void CLQ2_ParseConfigString (void)
|
|||
}
|
||||
else if (i == Q2CS_MAPCHECKSUM)
|
||||
{
|
||||
extern int map_checksum;
|
||||
int serverchecksum = atoi(s);
|
||||
int mapchecksum = 0;
|
||||
|
||||
if (cl.worldmodel && (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3))
|
||||
if (cl.worldmodel)
|
||||
{
|
||||
// the Q2 client normally exits here, however for our purposes we might as well ignore it
|
||||
if (map_checksum != serverchecksum)
|
||||
Con_Printf(CON_WARNING "WARNING: Client checksum does not match server checksum (%i != %i)", map_checksum, serverchecksum);
|
||||
if (cl.worldmodel->loadstate == MLS_LOADING)
|
||||
COM_WorkerPartialSync(cl.worldmodel, &cl.worldmodel->loadstate, MLS_LOADING);
|
||||
mapchecksum = cl.worldmodel->checksum;
|
||||
}
|
||||
// the Q2 client normally exits here, however for our purposes we might as well ignore it
|
||||
if (mapchecksum != serverchecksum)
|
||||
Con_Printf(CON_WARNING "WARNING: Client checksum does not match server checksum (%i != %i)", mapchecksum, serverchecksum);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -295,8 +295,9 @@ typedef struct
|
|||
//the light array works thusly:
|
||||
//dlights are allocated DL_LAST downwards to 0, static wlights are allocated DL_LAST+1 to MAX_RTLIGHTS.
|
||||
//thus to clear the dlights but not rtlights, set the first light to RTL_FIRST
|
||||
#define DL_LAST (sizeof(unsigned int)*8-1)
|
||||
#define RTL_FIRST (sizeof(unsigned int)*8)
|
||||
#define dlightbitmask_t size_t
|
||||
#define DL_LAST (sizeof(dlightbitmask_t)*8-1)
|
||||
#define RTL_FIRST (sizeof(dlightbitmask_t)*8)
|
||||
|
||||
#define LFLAG_NORMALMODE (1<<0) /*ppl with r_shadow_realtime_dlight*/
|
||||
#define LFLAG_REALTIMEMODE (1<<1) /*ppl with r_shadow_realtime_world*/
|
||||
|
@ -1488,6 +1489,7 @@ qboolean CSQC_Accelerometer(float x, float y, float z);
|
|||
qboolean CSQC_Gyroscope(float x, float y, float z);
|
||||
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation, float pitchmod, float timeofs, unsigned int flags);
|
||||
void CSQC_ParseEntities(void);
|
||||
const char *CSQC_GetExtraFieldInfo(void *went, char *out, size_t outsize);
|
||||
void CSQC_ResetTrails(void);
|
||||
|
||||
qboolean CSQC_DeltaPlayer(int playernum, player_state_t *state);
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
//copyright 'Spike', license gplv2+
|
||||
//provides both a package manager and downloads menu.
|
||||
//FIXME: block downloads of exe/dll/so/etc if not an https url (even if inside zips). also block such files from package lists over http.
|
||||
|
||||
//Note: for a while we didn't have strong hashes, nor signing, so we depended upon known-self-signed tls certificates to prove authenticity
|
||||
//we now have sha256 hashes(and sizes) to ensure that the file we wanted hasn't been changed in transit.
|
||||
//and we have signature info, to prove that the hash specified was released by a known authority. This means that we should now be able to download such things over http without worries (or at least that we can use an untrustworthy CA that's trusted by insecurity-mafia browsers).
|
||||
//WARNING: paks/pk3s may still be installed without signatures, without allowing dlls/exes/etc to be installed.
|
||||
//signaturedata+hashes can be generated with 'fteqw -privkey key.priv -pubkey key.pub -certhost MyAuthority -sign pathtofile', but Auth_GetKnownCertificate will need to be updated for any allowed authorities.
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "shader.h"
|
||||
#include "netinc.h"
|
||||
|
||||
#ifdef PACKAGEMANAGER
|
||||
#if !defined(NOBUILTINMENUS) && !defined(SERVERONLY)
|
||||
|
@ -63,6 +71,9 @@ extern cvar_t pm_downloads_url;
|
|||
#define DPF_PLUGIN (1u<<13) //this is a plugin package, with a dll
|
||||
|
||||
#define DPF_TRUSTED (1u<<14) //flag used when parsing package lists. if not set then packages will be ignored if they are anything but paks/pk3s
|
||||
#define DPF_SIGNATUREREJECTED (1u<<15) //signature is bad
|
||||
#define DPF_SIGNATUREACCEPTED (1u<<16) //signature is good (required for dll/so/exe files)
|
||||
#define DPF_SIGNATUREUNKNOWN (1u<<17) //signature is unknown
|
||||
|
||||
#define DPF_MARKED (DPF_USERMARKED|DPF_AUTOMARKED)
|
||||
#define DPF_PRESENT (DPF_NATIVE|DPF_CACHED)
|
||||
|
@ -117,6 +128,11 @@ typedef struct package_s {
|
|||
char *arch;
|
||||
char *qhash;
|
||||
|
||||
quint64_t filesize; //in bytes, as part of verifying the hash.
|
||||
char *filesha1;
|
||||
char *filesha512;
|
||||
char *signature;
|
||||
|
||||
char *title;
|
||||
char *description;
|
||||
char *license;
|
||||
|
@ -137,6 +153,7 @@ typedef struct package_s {
|
|||
enum
|
||||
{
|
||||
DEP_CONFLICT, //don't install if we have the named package installed.
|
||||
DEP_REPLACE, //obsoletes the specified package (or just acts as a conflict marker for now).
|
||||
DEP_FILECONFLICT, //don't install if this file already exists.
|
||||
DEP_REQUIRE, //don't install unless we have the named package installed.
|
||||
DEP_RECOMMEND, //like depend, but uninstalling will not bubble.
|
||||
|
@ -192,6 +209,7 @@ static int downloadablessequence; //bumped any time any package is purged
|
|||
|
||||
static void PM_WriteInstalledPackages(void);
|
||||
static void PM_PreparePackageList(void);
|
||||
static qboolean PM_SignatureOkay(package_t *p);
|
||||
|
||||
static void PM_FreePackage(package_t *p)
|
||||
{
|
||||
|
@ -252,13 +270,98 @@ static qboolean PM_PurgeOnDisable(package_t *p)
|
|||
//hashed packages can also be present and not enabled, but only if they're in the cache and not native
|
||||
if (*p->gamedir && p->qhash && (p->flags & DPF_PRESENT))
|
||||
return false;
|
||||
//FIXME: add basedir-plugins to the package manager so they can be enabled/disabled properly.
|
||||
//if (p->arch)
|
||||
// return false;
|
||||
//all other packages must be deleted to disable them
|
||||
return true;
|
||||
}
|
||||
|
||||
void PM_ValidateAuthenticity(package_t *p)
|
||||
{
|
||||
qbyte hashdata[512];
|
||||
size_t hashsize = 0;
|
||||
qbyte signdata[1024];
|
||||
size_t signsize = 0;
|
||||
int r;
|
||||
char authority[MAX_QPATH], *sig;
|
||||
|
||||
#if 1
|
||||
#pragma message("Temporary code.")
|
||||
//this is temporary code and should be removed once everything else has been fixed.
|
||||
//ignore the signature (flag as accepted) for any packages with all mirrors on our own update site.
|
||||
//we can get away with this because we enforce a known certificate for the download.
|
||||
if (!COM_CheckParm("-notlstrust"))
|
||||
{
|
||||
conchar_t musite[256], *e;
|
||||
char site[256];
|
||||
char *oldprefix = "http://fte.";
|
||||
char *newprefix = "https://updates.";
|
||||
int m;
|
||||
e = COM_ParseFunString(CON_WHITEMASK, ENGINEWEBSITE, musite, sizeof(musite), false);
|
||||
COM_DeFunString(musite, e, site, sizeof(site)-1, true, true);
|
||||
if (!strncmp(site, oldprefix, strlen(oldprefix)))
|
||||
{
|
||||
memmove(site+strlen(newprefix), site+strlen(oldprefix), strlen(site)-strlen(oldprefix)+1);
|
||||
memcpy(site, newprefix, strlen(newprefix));
|
||||
}
|
||||
Q_strncatz(site, "/", sizeof(site));
|
||||
for (m = 0; m < countof(p->mirror); m++)
|
||||
{
|
||||
if (p->mirror[m] && strncmp(p->mirror[m], site, strlen(site)))
|
||||
break; //some other host
|
||||
}
|
||||
if (m == countof(p->mirror))
|
||||
{
|
||||
p->flags |= DPF_SIGNATUREACCEPTED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
*authority = 0;
|
||||
if (!p->signature)
|
||||
r = VH_AUTHORITY_UNKNOWN;
|
||||
else if (!p->filesha512)
|
||||
r = VH_INCORRECT;
|
||||
else
|
||||
{
|
||||
sig = strchr(p->signature, ':');
|
||||
if (sig && sig-p->signature<countof(authority)-1)
|
||||
{
|
||||
memcpy(authority, p->signature, sig-p->signature);
|
||||
authority[sig-p->signature] = 0;
|
||||
sig++;
|
||||
}
|
||||
else
|
||||
sig = p->signature;
|
||||
hashsize = Base16_DecodeBlock(p->filesha512, hashdata, sizeof(hashdata));
|
||||
signsize = Base64_DecodeBlock(sig, NULL, signdata, sizeof(signdata));
|
||||
r = VH_UNSUPPORTED;//preliminary
|
||||
}
|
||||
|
||||
(void)signsize;
|
||||
(void)hashsize;
|
||||
|
||||
//try and get one of our providers to verify it...
|
||||
#ifdef HAVE_WINSSPI
|
||||
if (r == VH_UNSUPPORTED)
|
||||
r = SSPI_VerifyHash(hashdata, hashsize, authority, signdata, signsize);
|
||||
#endif
|
||||
#ifdef HAVE_GNUTLS
|
||||
if (r == VH_UNSUPPORTED)
|
||||
r = GNUTLS_VerifyHash(hashdata, hashsize, authority, signdata, signsize);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (r == VH_UNSUPPORTED)
|
||||
r = OSSL_VerifyHash(hashdata, hashsize, authority, signdata, signsize);
|
||||
#endif
|
||||
|
||||
if (r == VH_CORRECT)
|
||||
p->flags |= DPF_SIGNATUREACCEPTED;
|
||||
else if (r == VH_INCORRECT)
|
||||
p->flags |= DPF_SIGNATUREREJECTED;
|
||||
else if (p->signature)
|
||||
p->flags |= DPF_SIGNATUREUNKNOWN;
|
||||
}
|
||||
|
||||
//checks the status of each package
|
||||
static void PM_ValidatePackage(package_t *p)
|
||||
{
|
||||
|
@ -952,6 +1055,8 @@ static qboolean PM_ParsePackageList(const char *f, int parseflags, const char *u
|
|||
PM_AddDep(p, DEP_REQUIRE, val);
|
||||
else if (!strcmp(key, "conflict"))
|
||||
PM_AddDep(p, DEP_CONFLICT, val);
|
||||
else if (!strcmp(key, "replace"))
|
||||
PM_AddDep(p, DEP_REPLACE, val);
|
||||
else if (!strcmp(key, "fileconflict"))
|
||||
PM_AddDep(p, DEP_FILECONFLICT, val);
|
||||
else if (!strcmp(key, "recommend"))
|
||||
|
@ -975,6 +1080,14 @@ static qboolean PM_ParsePackageList(const char *f, int parseflags, const char *u
|
|||
else
|
||||
fsroot = FS_ROOT;
|
||||
}
|
||||
else if (!strcmp(key, "dlsize"))
|
||||
p->filesize = strtoull(val, NULL, 0);
|
||||
else if (!strcmp(key, "sha1"))
|
||||
Z_StrDupPtr(&p->filesha1, val);
|
||||
else if (!strcmp(key, "sha512"))
|
||||
Z_StrDupPtr(&p->filesha512, val);
|
||||
else if (!strcmp(key, "sign"))
|
||||
Z_StrDupPtr(&p->signature, val);
|
||||
else
|
||||
{
|
||||
Con_DPrintf("Unknown package property\n");
|
||||
|
@ -1051,6 +1164,9 @@ static qboolean PM_ParsePackageList(const char *f, int parseflags, const char *u
|
|||
p->mirror[m] = Z_StrDup(va("%s%s%s", mirror[m], relurl, ext));
|
||||
}
|
||||
}
|
||||
|
||||
PM_ValidateAuthenticity(p);
|
||||
|
||||
Z_Free(ver);
|
||||
Z_Free(file);
|
||||
Z_Free(url);
|
||||
|
@ -1462,19 +1578,20 @@ static void PM_UnmarkPackage(package_t *package, unsigned int markflag)
|
|||
}
|
||||
|
||||
//just flags, doesn't install
|
||||
static void PM_MarkPackage(package_t *package, unsigned int markflag)
|
||||
//returns true if it was marked (or already enabled etc), false if we're not allowed.
|
||||
static qboolean PM_MarkPackage(package_t *package, unsigned int markflag)
|
||||
{
|
||||
package_t *o;
|
||||
struct packagedep_s *dep, *dep2;
|
||||
qboolean replacing = false;
|
||||
|
||||
if (pkg_updating)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (package->flags & DPF_MARKED)
|
||||
{
|
||||
package->flags |= markflag;
|
||||
return; //looks like its already picked. marking it again will do no harm.
|
||||
return true; //looks like its already picked. marking it again will do no harm.
|
||||
}
|
||||
|
||||
#ifndef WEBCLIENT
|
||||
|
@ -1482,10 +1599,13 @@ static void PM_MarkPackage(package_t *package, unsigned int markflag)
|
|||
if (!(package->flags & DPF_PRESENT))
|
||||
{ //though we can at least unmark it for deletion...
|
||||
package->flags &= ~DPF_PURGE;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!PM_SignatureOkay(package))
|
||||
return false;
|
||||
|
||||
//any file-conflicts prevent the package from being installable.
|
||||
//this is mostly for pak1.pak
|
||||
for (dep = package->deps; dep; dep = dep->next)
|
||||
|
@ -1498,7 +1618,7 @@ static void PM_MarkPackage(package_t *package, unsigned int markflag)
|
|||
else
|
||||
n = dep->name;
|
||||
if (PM_CheckFile(n, package->fsroot))
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1545,7 +1665,7 @@ static void PM_MarkPackage(package_t *package, unsigned int markflag)
|
|||
|
||||
//if we are replacing an existing one, then dependancies are already settled (only because we don't do version deps)
|
||||
if (replacing)
|
||||
return;
|
||||
return true;
|
||||
|
||||
//satisfy our dependancies.
|
||||
for (dep = package->deps; dep; dep = dep->next)
|
||||
|
@ -1567,7 +1687,7 @@ static void PM_MarkPackage(package_t *package, unsigned int markflag)
|
|||
Con_DPrintf("Couldn't find dependancy \"%s\"\n", dep->name);
|
||||
}
|
||||
}
|
||||
if (dep->dtype == DEP_CONFLICT)
|
||||
if (dep->dtype == DEP_CONFLICT || dep->dtype == DEP_REPLACE)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1583,10 +1703,11 @@ static void PM_MarkPackage(package_t *package, unsigned int markflag)
|
|||
for (o = availablepackages; o; o = o->next)
|
||||
{
|
||||
for (dep = o->deps; dep; dep = dep->next)
|
||||
if (dep->dtype == DEP_CONFLICT)
|
||||
if (dep->dtype == DEP_CONFLICT || dep->dtype == DEP_REPLACE)
|
||||
if (!strcmp(dep->name, package->name))
|
||||
PM_UnmarkPackage(o, DPF_MARKED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean PM_NameIsInStrings(const char *strings, const char *match)
|
||||
|
@ -2086,6 +2207,11 @@ static void PM_WriteInstalledPackages(void)
|
|||
Q_strncatz(buf, " ", sizeof(buf));
|
||||
COM_QuotedConcat(va("preview=%s", p->previewimage), buf, sizeof(buf));
|
||||
}
|
||||
if (p->filesize)
|
||||
{
|
||||
Q_strncatz(buf, " ", sizeof(buf));
|
||||
COM_QuotedConcat(va("filesize=%s", p->previewimage), buf, sizeof(buf));
|
||||
}
|
||||
|
||||
if (p->fsroot == FS_BINARYPATH)
|
||||
{
|
||||
|
@ -2110,6 +2236,11 @@ static void PM_WriteInstalledPackages(void)
|
|||
Q_strncatz(buf, " ", sizeof(buf));
|
||||
COM_QuotedConcat(va("conflict=%s", dep->name), buf, sizeof(buf));
|
||||
}
|
||||
else if (dep->dtype == DEP_REPLACE)
|
||||
{
|
||||
Q_strncatz(buf, " ", sizeof(buf));
|
||||
COM_QuotedConcat(va("replace=%s", dep->name), buf, sizeof(buf));
|
||||
}
|
||||
else if (dep->dtype == DEP_FILECONFLICT)
|
||||
{
|
||||
Q_strncatz(buf, " ", sizeof(buf));
|
||||
|
@ -2224,11 +2355,11 @@ static int QDECL PM_ExtractFiles(const char *fname, qofs_t fsize, time_t mtime,
|
|||
n = fname;
|
||||
if (FS_WriteFile(n, f, loc.len, p->fsroot))
|
||||
p->flags |= DPF_NATIVE|DPF_ENABLED;
|
||||
free(f);
|
||||
|
||||
//keep track of the installed files, so we can delete them properly after.
|
||||
PM_AddDep(p, DEP_FILE, fname);
|
||||
}
|
||||
free(f);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -2250,9 +2381,12 @@ static void PM_Download_Got(struct dl_download *dl)
|
|||
|
||||
if (dl->file)
|
||||
{
|
||||
VFS_CLOSE(dl->file);
|
||||
if (!VFS_CLOSE(dl->file))
|
||||
successful = false;
|
||||
dl->file = NULL;
|
||||
}
|
||||
else
|
||||
successful = false;
|
||||
|
||||
if (p)
|
||||
{
|
||||
|
@ -2434,6 +2568,111 @@ static char *PM_GetTempName(package_t *p)
|
|||
Z_Free(ts);
|
||||
return Z_StrDup(destname);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
vfsfile_t pub;
|
||||
vfsfile_t *f;
|
||||
hashfunc_t *hashfunc;
|
||||
qofs_t sz;
|
||||
qofs_t needsize;
|
||||
qboolean fail;
|
||||
qbyte need[256];
|
||||
qbyte ctx[1];
|
||||
char *fname;
|
||||
} hashfile_t;
|
||||
static int QDECL SHA1File_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestowrite)
|
||||
{
|
||||
hashfile_t *f = (hashfile_t*)file;
|
||||
f->hashfunc->process(&f->ctx, buffer, bytestowrite);
|
||||
if (bytestowrite != VFS_WRITE(f->f, buffer, bytestowrite))
|
||||
f->fail = true; //something went wrong.
|
||||
if (f->fail)
|
||||
return -1; //error! abort! fail! give up!
|
||||
f->sz += bytestowrite;
|
||||
return bytestowrite;
|
||||
}
|
||||
static void QDECL SHA1File_Flush (struct vfsfile_s *file)
|
||||
{
|
||||
hashfile_t *f = (hashfile_t*)file;
|
||||
VFS_FLUSH(f->f);
|
||||
}
|
||||
static qboolean QDECL SHA1File_Close (struct vfsfile_s *file)
|
||||
{
|
||||
qbyte digest[256];
|
||||
hashfile_t *f = (hashfile_t*)file;
|
||||
if (!VFS_CLOSE(f->f))
|
||||
f->fail = true; //something went wrong.
|
||||
|
||||
f->hashfunc->terminate(digest, &f->ctx);
|
||||
if (f->fail)
|
||||
Con_Printf("Filesystem problems downloading %s\n", f->fname); //don't error if we failed on actual disk problems
|
||||
else if (f->sz != f->needsize)
|
||||
{
|
||||
Con_Printf("Download truncated: %s\n", f->fname); //don't error if we failed on actual disk problems
|
||||
f->fail = true;
|
||||
}
|
||||
else if (memcmp(digest, f->need, f->hashfunc->digestsize))
|
||||
{
|
||||
Con_Printf("Invalid hash for downloaded file %s, try again later?\n", f->fname);
|
||||
f->fail = true;
|
||||
}
|
||||
|
||||
return !f->fail; //true if all okay!
|
||||
}
|
||||
static vfsfile_t *FS_Sha1_ValidateWrites(vfsfile_t *f, const char *fname, qofs_t needsize, hashfunc_t *hashfunc, const char *hash)
|
||||
{ //wraps a writable file with a layer that'll cause failures when the hash differs from what we expect.
|
||||
if (f)
|
||||
{
|
||||
hashfile_t *n = Z_Malloc(sizeof(*n) + hashfunc->contextsize + strlen(fname));
|
||||
n->pub.WriteBytes = SHA1File_WriteBytes;
|
||||
n->pub.Flush = SHA1File_Flush;
|
||||
n->pub.Close = SHA1File_Close;
|
||||
n->pub.seekstyle = SS_UNSEEKABLE;
|
||||
n->f = f;
|
||||
n->hashfunc = hashfunc;
|
||||
n->fname = n->ctx+hashfunc->contextsize;
|
||||
strcpy(n->fname, fname);
|
||||
n->needsize = needsize;
|
||||
Base16_DecodeBlock(hash, n->need, sizeof(n->need));
|
||||
n->fail = false;
|
||||
f = &n->pub;
|
||||
|
||||
n->hashfunc->init(&n->ctx);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
static qboolean PM_SignatureOkay(package_t *p)
|
||||
{
|
||||
struct packagedep_s *dep;
|
||||
char ext[MAX_QPATH];
|
||||
|
||||
// if (p->flags & (DPF_SIGNATUREREJECTED|DPF_SIGNATUREUNKNOWN)) //the sign key didn't match its sha512 hash
|
||||
// return false; //just block it entirely.
|
||||
if (p->flags & DPF_SIGNATUREACCEPTED) //sign value is present and correct
|
||||
return true; //go for it.
|
||||
if (p->flags & DPF_PRESENT)
|
||||
return true; //we don't know where it came from, but someone manually installed it...
|
||||
|
||||
//packages without a signature are only allowed under some limited conditions.
|
||||
//basically we only allow meta packages, pk3s, and paks.
|
||||
|
||||
if (p->extract == EXTRACT_ZIP)
|
||||
return false; //extracting files is bad (there might be some weird .pif or whatever file in there, don't risk it)
|
||||
for (dep = p->deps; dep; dep = dep->next)
|
||||
{
|
||||
if (dep->dtype != DEP_FILE)
|
||||
continue;
|
||||
|
||||
COM_FileExtension(dep->name, ext, sizeof(ext));
|
||||
if ((!stricmp(ext, "pak") || !stricmp(ext, "pk3")) && p->qhash)
|
||||
;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*static void PM_AddDownloadedPackage(const char *filename)
|
||||
|
@ -2545,6 +2784,11 @@ static void PM_StartADownload(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!PM_SignatureOkay(p) || (qofs_t)p->filesize != p->filesize)
|
||||
{
|
||||
p->flags &= ~DPF_MARKED; //refusing to do it.
|
||||
continue;
|
||||
}
|
||||
|
||||
temp = PM_GetTempName(p);
|
||||
|
||||
|
@ -2584,6 +2828,11 @@ static void PM_StartADownload(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (p->filesha512 && tmpfile)
|
||||
tmpfile = FS_Sha1_ValidateWrites(tmpfile, p->name, p->filesize, &hash_sha512, p->filesha512);
|
||||
else if (p->filesha1 && tmpfile)
|
||||
tmpfile = FS_Sha1_ValidateWrites(tmpfile, p->name, p->filesize, &hash_sha1, p->filesha1);
|
||||
|
||||
if (tmpfile)
|
||||
{
|
||||
p->download = HTTP_CL_Get(mirror, NULL, PM_Download_Got);
|
||||
|
@ -2999,6 +3248,7 @@ void PM_Command_f(void)
|
|||
{
|
||||
for (p = availablepackages; p; p=p->next)
|
||||
{
|
||||
char quoted[8192];
|
||||
const char *status;
|
||||
char *markup;
|
||||
if ((p->flags & DPF_HIDDEN) && !(p->flags & (DPF_MARKED|DPF_ENABLED|DPF_PURGE|DPF_CACHED)))
|
||||
|
@ -3035,7 +3285,13 @@ void PM_Command_f(void)
|
|||
else
|
||||
status = "";
|
||||
|
||||
Con_Printf(" ^["S_COLOR_GRAY"%s%s%s%s%s^] %s"S_COLOR_GRAY" %s (%s%s)\n", p->category?p->category:"", markup, p->name, p->arch?":":"", p->arch?p->arch:"", status, strcmp(p->name, p->title)?p->title:"", p->version, (p->flags&DPF_TESTING)?"-testing":"");
|
||||
Con_Printf(" ^["S_COLOR_GRAY"%s%s%s%s%s^] %s"S_COLOR_GRAY" %s (%s%s)", p->category?p->category:"", markup, p->name, p->arch?":":"", p->arch?p->arch:"", status, strcmp(p->name, p->title)?p->title:"", p->version, (p->flags&DPF_TESTING)?"-testing":"");
|
||||
|
||||
if (!(p->flags&DPF_MARKED) && p == PM_FindPackage(p->name))
|
||||
Con_Printf(" ^[[Add]\\type\\pkg add %s;pkg apply^]", COM_QuotedString(p->name, quoted, sizeof(quoted), false));
|
||||
if ((p->flags&DPF_MARKED) && p == PM_MarkedPackage(p->name, DPF_MARKED))
|
||||
Con_Printf(" ^[[Remove]\\type\\pkg rem %s;pkg apply^]", COM_QuotedString(p->name, quoted, sizeof(quoted), false));
|
||||
Con_Printf("\n");
|
||||
}
|
||||
Con_Printf("<end of list>\n");
|
||||
}
|
||||
|
@ -3401,6 +3657,8 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
|
|||
|
||||
if (!PM_CheckPackageFeatures(p))
|
||||
Draw_FunStringWidth(0, y, "!", x+8, true, true);
|
||||
if (!PM_SignatureOkay(p))
|
||||
Draw_FunStringWidth(0, y, "^b!", x+8, true, true);
|
||||
|
||||
// if (!(p->flags & (DPF_ENABLED|DPF_MARKED|DPF_PRESENT))
|
||||
// continue;
|
||||
|
@ -3616,11 +3874,25 @@ static int MD_AddItemsToDownloadMenu(emenu_t *m, int y, const char *pathprefix)
|
|||
slash = strchr(p->category+prefixlen, '/');
|
||||
if (!slash)
|
||||
{
|
||||
char *desc;
|
||||
char *head;
|
||||
char *desc = p->description;
|
||||
if (p->author || p->license || p->website)
|
||||
desc = va("^aauthor: ^a%s\n^alicense: ^a%s\n^awebsite: ^a%s\n%s", p->author?p->author:"^hUnknown^h", p->license?p->license:"^hUnknown^h", p->website?p->website:"^hUnknown^h", p->description);
|
||||
head = va("^aauthor:^U00A0^a%s\n^alicense:^U00A0^a%s\n^awebsite:^U00A0^a%s\n", p->author?p->author:"^hUnknown^h", p->license?p->license:"^hUnknown^h", p->website?p->website:"^hUnknown^h");
|
||||
else
|
||||
desc = p->description;
|
||||
head = NULL;
|
||||
if (p->filesize)
|
||||
{
|
||||
if (!head)
|
||||
head = "";
|
||||
if (p->filesize < 1024)
|
||||
head = va("%s^asize:^U00A0^a%.4f bytes\n", head, (double)p->filesize);
|
||||
else if (p->filesize < 1024*1024)
|
||||
head = va("%s^asize:^U00A0^a%.4f KB\n", head, (p->filesize/(1024.0)));
|
||||
else if (p->filesize < 1024*1024*1024)
|
||||
head = va("%s^asize:^U00A0^a%.4f MB\n", head, (p->filesize/(1024.0*1024)));
|
||||
else
|
||||
head = va("%s^asize:^U00A0^a%.4f GB\n", head, (p->filesize/(1024.0*1024*1024)));
|
||||
}
|
||||
|
||||
for (dep = p->deps; dep; dep = dep->next)
|
||||
{
|
||||
|
@ -3630,12 +3902,28 @@ static int MD_AddItemsToDownloadMenu(emenu_t *m, int y, const char *pathprefix)
|
|||
if (!PM_CheckFeature(dep->name, &featname, &enablecmd))
|
||||
{
|
||||
if (enablecmd)
|
||||
desc = va("^aDisabled: ^a%s\n%s", featname, desc);
|
||||
head = va("^aDisabled: ^a%s\n%s", featname, head?head:"");
|
||||
else
|
||||
desc = va("^aUnavailable: ^a%s\n%s", featname, desc);
|
||||
head = va("^aUnavailable: ^a%s\n%s", featname, head?head:"");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!PM_SignatureOkay(p))
|
||||
{
|
||||
if (!p->signature)
|
||||
head = va(CON_ERROR"Signature missing"CON_DEFAULT"\n%s", head?head:""); //some idiot forgot to include a signature
|
||||
else if (p->flags & DPF_SIGNATUREREJECTED)
|
||||
head = va(CON_ERROR"Signature invalid"CON_DEFAULT"\n%s", head?head:""); //some idiot got the wrong auth/sig/hash
|
||||
else if (p->flags & DPF_SIGNATUREUNKNOWN)
|
||||
head = va(CON_ERROR"Signature is not trusted"CON_DEFAULT"\n%s", head?head:""); //clientside permission.
|
||||
else
|
||||
head = va(CON_ERROR"Unable to verify signature"CON_DEFAULT"\n%s", head?head:""); //clientside problem.
|
||||
}
|
||||
|
||||
if (head && desc)
|
||||
desc = va("%s\n%s", head, desc);
|
||||
else if (head)
|
||||
desc = head;
|
||||
|
||||
c = MC_AddCustom(m, 0, y, p, downloadablessequence, desc);
|
||||
c->draw = MD_Draw;
|
||||
|
|
|
@ -2830,10 +2830,10 @@ void M_Menu_Video_f (void)
|
|||
};
|
||||
|
||||
static const char *srgbopts[] = {
|
||||
"Non-Linear",
|
||||
"sRGB-Aware (PBR)",
|
||||
"Linear (HDR)",
|
||||
"Linearised", //-1
|
||||
"Non-Linear", //0 (legacy buggy linear->srgb non-transforms)
|
||||
"sRGB-Aware", //1 (linear->srgb transforms)
|
||||
"Linear (HDR)", //2 (try to use a float framebuffer, otherwise fall back on srgb framebuffer)
|
||||
"Linearised", //-1
|
||||
NULL
|
||||
};
|
||||
static const char *srgbvalues[] = { "0", "1", "2", "-1", NULL};
|
||||
|
|
|
@ -608,9 +608,6 @@ static void CS_CheckVelocity(csqcedict_t *ent)
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t *fte_restrict out)
|
||||
{
|
||||
//FTE_CSQC_HALFLIFE_MODELS
|
||||
|
@ -1052,6 +1049,53 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *fte_restrict in, entity_t *ft
|
|||
return true;
|
||||
}
|
||||
|
||||
const char *CSQC_GetExtraFieldInfo(void *went, char *out, size_t outsize)
|
||||
{
|
||||
csqcedict_t *ent = went;
|
||||
char *r = out;
|
||||
char *e = out+outsize;
|
||||
int i;
|
||||
skinfile_t *sk = Mod_LookupSkin((ent->skinobject<0)?-ent->skinobject:ent->skinobject);
|
||||
if (sk)
|
||||
{
|
||||
Q_snprintfz(out, e-out, "skin %s\nrefs %i\n", sk->skinname, sk->refcount);
|
||||
out+=strlen(out);
|
||||
for (i = 0; i < sk->nummappings; i++)
|
||||
{
|
||||
Q_snprintfz(out, e-out, "replace \"%s\" \"%s\"\n", sk->mappings[i].surface, sk->mappings[i].shader?sk->mappings[i].shader->name:"NULL SHADER");
|
||||
out+=strlen(out);
|
||||
}
|
||||
for (i = 0; i < MAX_GEOMSETS; i++)
|
||||
{
|
||||
if (sk->geomset[i])
|
||||
{
|
||||
Q_snprintfz(out, e-out, "geomset %i %i\n", i, sk->geomset[i]);
|
||||
out+=strlen(out);
|
||||
}
|
||||
}
|
||||
#ifdef QWSKINS
|
||||
if (*sk->qwskinname)
|
||||
{
|
||||
Q_snprintfz(out, e-out, "qwskin %s\n", sk->qwskinname);
|
||||
out+=strlen(out);
|
||||
}
|
||||
if (sk->q1upper != Q1UNSPECIFIED)
|
||||
{
|
||||
Q_snprintfz(out, e-out, "q1upper %#x\n", sk->q1upper);
|
||||
out+=strlen(out);
|
||||
}
|
||||
if (sk->q1lower != Q1UNSPECIFIED)
|
||||
{
|
||||
Q_snprintfz(out, e-out, "q1lower %#x\n", sk->q1lower);
|
||||
out+=strlen(out);
|
||||
}
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
return r==out?NULL:r;
|
||||
}
|
||||
|
||||
static void QCBUILTIN PF_cs_makestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{ //still does a remove.
|
||||
csqcedict_t *in = (void*)G_EDICT(prinst, OFS_PARM0);
|
||||
|
|
|
@ -325,9 +325,9 @@ void Surf_LessenStains(void)
|
|||
R_AddDynamicLights
|
||||
===============
|
||||
*/
|
||||
static void Surf_AddDynamicLights (msurface_t *surf)
|
||||
static void Surf_AddDynamicLights_Lum (msurface_t *surf)
|
||||
{
|
||||
int lnum;
|
||||
size_t lnum;
|
||||
int sd, td;
|
||||
float dist, rad, minlight;
|
||||
vec3_t impact, local;
|
||||
|
@ -344,7 +344,7 @@ static void Surf_AddDynamicLights (msurface_t *surf)
|
|||
|
||||
for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++)
|
||||
{
|
||||
if ( !(surf->dlightbits & (1<<lnum) ) )
|
||||
if ( !(surf->dlightbits & ((dlightbitmask_t)1u<<lnum) ) )
|
||||
continue; // not lit by this light
|
||||
|
||||
if (!(cl_dlights[lnum].flags & LFLAG_LIGHTMAP))
|
||||
|
@ -415,7 +415,7 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf)
|
|||
|
||||
for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++)
|
||||
{
|
||||
if ( !(surf->dlightbits & (1<<lnum) ) )
|
||||
if ( !(surf->dlightbits & ((dlightbitmask_t)1u<<lnum) ) )
|
||||
continue; // not lit by this light
|
||||
|
||||
if (!(cl_dlights[lnum].flags & LFLAG_ALLOW_LMHACK))
|
||||
|
@ -471,7 +471,7 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf)
|
|||
*/
|
||||
|
||||
#ifdef PEXT_LIGHTSTYLECOL
|
||||
static void Surf_AddDynamicLightsColours (msurface_t *surf)
|
||||
static void Surf_AddDynamicLights_RGB (msurface_t *surf)
|
||||
{
|
||||
int lnum;
|
||||
int sd, td;
|
||||
|
@ -492,7 +492,7 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
|
|||
|
||||
for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++)
|
||||
{
|
||||
if ( !(surf->dlightbits & (1<<lnum) ) )
|
||||
if ( !(surf->dlightbits & ((dlightbitmask_t)1u<<lnum) ) )
|
||||
continue; // not lit by this light
|
||||
|
||||
rad = cl_dlights[lnum].radius;
|
||||
|
@ -637,7 +637,7 @@ static void Surf_BuildDeluxMap (model_t *wmodel, msurface_t *surf, qbyte *dest,
|
|||
{
|
||||
case LM_E5BGR9:
|
||||
deluxmap = ((surf->samples - wmodel->lightdata)/4)*3 + wmodel->deluxdata;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
for (i=0 ; i<size ; i++)
|
||||
|
@ -654,7 +654,7 @@ static void Surf_BuildDeluxMap (model_t *wmodel, msurface_t *surf, qbyte *dest,
|
|||
break;
|
||||
case LM_RGB8:
|
||||
deluxmap = surf->samples - wmodel->lightdata + wmodel->deluxdata;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
for (i=0 ; i<size ; i++)
|
||||
|
@ -670,7 +670,7 @@ static void Surf_BuildDeluxMap (model_t *wmodel, msurface_t *surf, qbyte *dest,
|
|||
break;
|
||||
case LM_L8:
|
||||
deluxmap = (surf->samples - wmodel->lightdata)*3 + wmodel->deluxdata;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
for (i=0 ; i<size ; i++)
|
||||
|
@ -769,22 +769,22 @@ store:
|
|||
static unsigned int Surf_PackE5BRG9(int r, int g, int b, int shift)
|
||||
{ //5 bits exponent, 3*9 bits of mantissa. no sign bit.
|
||||
int e = 0;
|
||||
float m = max(max(r, g), b) / (float)(1<<shift);
|
||||
float m = max(max(r, g), b) / (float)(1u<<shift);
|
||||
float scale;
|
||||
|
||||
if (m >= 0.5)
|
||||
{ //positive exponent
|
||||
while (m >= (1<<(e)) && e < 30-15) //don't do nans.
|
||||
while (m >= (1u<<(e)) && e < 30-15) //don't do nans.
|
||||
e++;
|
||||
}
|
||||
else
|
||||
{ //negative exponent...
|
||||
while (m < 1/(1<<-e) && e > -15) //don't do denormals.
|
||||
while (m < 1/(1u<<-e) && e > -15) //don't do denormals.
|
||||
e--;
|
||||
}
|
||||
|
||||
scale = pow(2, e-9);
|
||||
scale *= (1<<shift);
|
||||
scale *= (1u<<shift);
|
||||
|
||||
r = bound(0, r/scale + 0.5, 0x1ff);
|
||||
g = bound(0, g/scale + 0.5, 0x1ff);
|
||||
|
@ -794,7 +794,9 @@ static unsigned int Surf_PackE5BRG9(int r, int g, int b, int shift)
|
|||
}
|
||||
|
||||
static unsigned short Surf_GenHalf(float val)
|
||||
{
|
||||
{ //1-bit sign (ignored here)
|
||||
//5-bit exponent (biased by 15)
|
||||
//10-bit mantissa (normalised, so effectively 11 bits when exponent!=0)
|
||||
union
|
||||
{
|
||||
float f;
|
||||
|
@ -809,7 +811,7 @@ static unsigned short Surf_GenHalf(float val)
|
|||
if (e > 15)
|
||||
m = 0; //infinity instead of a nan
|
||||
else
|
||||
m = (u.u&((1<<23)-1))>>13;
|
||||
m = (u.u&((1u<<23)-1))>>13;
|
||||
return ((e+15)<<10) | m;
|
||||
}
|
||||
static void Surf_PackRGB16F(void *result, int r, int g, int b, int one)
|
||||
|
@ -830,10 +832,10 @@ static void Surf_PackRGB16F(void *result, int r, int g, int b, int one)
|
|||
((unsigned short*)result)[0] = Surf_GenHalf(r / (float)one);
|
||||
((unsigned short*)result)[1] = Surf_GenHalf(g / (float)one);
|
||||
((unsigned short*)result)[2] = Surf_GenHalf(b / (float)one);
|
||||
((unsigned short*)result)[3] = /*Surf_GenHalf(1.0);*/0x0f<<10; //a standard ieee float should have all but the lead bit set of its exponent, and its mantissa 0.
|
||||
((unsigned short*)result)[3] = /*Surf_GenHalf(1.0);*/0x0fu<<10; //a standard ieee float should have all but the lead bit set of its exponent, and its mantissa 0.
|
||||
#endif
|
||||
}
|
||||
static void Surf_PackRGB32F(void *result, int r, int g, int b, int one)
|
||||
static void Surf_PackRGBX32F(void *result, int r, int g, int b, int one)
|
||||
{
|
||||
((float*)result)[0] = r/(float)one;
|
||||
((float*)result)[1] = g/(float)one;
|
||||
|
@ -886,7 +888,7 @@ static void Surf_StoreLightmap_RGB(qbyte *dest, unsigned int *bl, int smax, int
|
|||
b *= 1023.0/m;
|
||||
}
|
||||
|
||||
*(unsigned int*)dest = (3<<30) | ((b&0x3ff)<<20) | ((g&0x3ff)<<10) | (r&0x3ff);
|
||||
*(unsigned int*)dest = (3u<<30) | ((b&0x3ff)<<20) | ((g&0x3ff)<<10) | (r&0x3ff);
|
||||
dest += 4;
|
||||
}
|
||||
if (stainsrc)
|
||||
|
@ -944,6 +946,7 @@ static void Surf_StoreLightmap_RGB(qbyte *dest, unsigned int *bl, int smax, int
|
|||
}
|
||||
break;
|
||||
case PTI_RGBA32F:
|
||||
shift = 1u<<(shift+8);
|
||||
stride = (lm->width-smax)<<4;
|
||||
for (i=0 ; i<tmax ; i++, dest += stride)
|
||||
{
|
||||
|
@ -960,7 +963,7 @@ static void Surf_StoreLightmap_RGB(qbyte *dest, unsigned int *bl, int smax, int
|
|||
b = (127+b*(*stainsrc++)) >> 8;
|
||||
}
|
||||
|
||||
Surf_PackRGB32F(dest, r,g,b,1<<(shift+8));
|
||||
Surf_PackRGBX32F(dest, r,g,b,shift);
|
||||
dest += sizeof(float)*4;
|
||||
}
|
||||
if (stainsrc)
|
||||
|
@ -1312,7 +1315,7 @@ static void Surf_StoreLightmap_RGB(qbyte *dest, unsigned int *bl, int smax, int
|
|||
break;
|
||||
}
|
||||
}
|
||||
static void Surf_StoreLightmap_Grey(qbyte *dest, unsigned int *bl, int smax, int tmax, unsigned int shift, stmap *stainsrc, unsigned int lmwidth)
|
||||
static void Surf_StoreLightmap_Lum(qbyte *dest, unsigned int *bl, int smax, int tmax, unsigned int shift, stmap *stainsrc, unsigned int lmwidth)
|
||||
{
|
||||
int t;
|
||||
unsigned int i, j;
|
||||
|
@ -1414,7 +1417,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
t = (-1-ambient)*255;
|
||||
for (i=0 ; i<size*3 ; i++)
|
||||
blocklights[i] = t;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS ; maps++)
|
||||
{
|
||||
surf->cached_light[maps] = -1-ambient;
|
||||
surf->cached_colour[maps] = 0xff;
|
||||
|
@ -1461,7 +1464,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
switch(currentmodel->lightmaps.fmt)
|
||||
{
|
||||
case LM_E5BGR9:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]]; // 8.8 fraction
|
||||
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
|
||||
|
@ -1481,7 +1484,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
}
|
||||
break;
|
||||
case LM_RGB8:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]];
|
||||
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
|
||||
|
@ -1502,7 +1505,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
break;
|
||||
|
||||
case LM_L8:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ;
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ;
|
||||
maps++)
|
||||
{
|
||||
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]]; // 8.8 fraction
|
||||
|
@ -1529,7 +1532,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
|
||||
// add all the dynamic lights
|
||||
if (surf->dlightframe == r_framecount)
|
||||
Surf_AddDynamicLightsColours (surf);
|
||||
Surf_AddDynamicLights_RGB (surf);
|
||||
|
||||
Surf_StoreLightmap_RGB(dest, blocklights, smax, tmax, shift, stainsrc, lm);
|
||||
}
|
||||
|
@ -1541,7 +1544,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
t = (-1-ambient)*255;
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] = t;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS ; maps++)
|
||||
{
|
||||
surf->cached_light[maps] = -1-ambient;
|
||||
surf->cached_colour[maps] = 0xff;
|
||||
|
@ -1581,7 +1584,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
switch(currentmodel->lightmaps.fmt)
|
||||
{
|
||||
case LM_E5BGR9:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
surf->cached_light[maps] = scale; // 8.8 fraction
|
||||
|
@ -1595,7 +1598,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
}
|
||||
break;
|
||||
case LM_RGB8:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
surf->cached_light[maps] = scale; // 8.8 fraction
|
||||
|
@ -1606,7 +1609,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
}
|
||||
break;
|
||||
case LM_L8:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
surf->cached_light[maps] = scale; // 8.8 fraction
|
||||
|
@ -1620,10 +1623,10 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
|
|||
}
|
||||
// add all the dynamic lights
|
||||
if (surf->dlightframe == r_framecount)
|
||||
Surf_AddDynamicLights (surf);
|
||||
Surf_AddDynamicLights_Lum (surf);
|
||||
}
|
||||
|
||||
Surf_StoreLightmap_Grey(dest, blocklights, smax, tmax, shift, stainsrc, lm->width);
|
||||
Surf_StoreLightmap_Lum(dest, blocklights, smax, tmax, shift, stainsrc, lm->width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1682,44 +1685,33 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
{
|
||||
// set to full bright if no light data
|
||||
if (ambient < 0)
|
||||
{
|
||||
{ //abslight for hexen2
|
||||
t = (-1-ambient)*255;
|
||||
for (i=0 ; i<size*3 ; i++)
|
||||
{
|
||||
blocklights[i] = t;
|
||||
}
|
||||
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS ; maps++)
|
||||
{
|
||||
surf->cached_light[maps] = -1-ambient;
|
||||
surf->cached_colour[maps] = 0xff;
|
||||
}
|
||||
}
|
||||
else if (r_fullbright.value>0) //not qw
|
||||
{
|
||||
else if (r_fullbright.value>0)
|
||||
{ //fullbright cheat
|
||||
for (i=0 ; i<size*3 ; i++)
|
||||
{
|
||||
blocklights[i] = r_fullbright.value*255*256;
|
||||
}
|
||||
}
|
||||
else if (!wmodel->lightdata)
|
||||
{
|
||||
/*fullbright if map is not lit. but not overbright*/
|
||||
{ /*fullbright if map is not lit. but not overbright*/
|
||||
for (i=0 ; i<size*3 ; i++)
|
||||
{
|
||||
blocklights[i] = 128*256;
|
||||
}
|
||||
}
|
||||
else if (!surf->samples)
|
||||
{
|
||||
/*no samples, but map is otherwise lit = pure black*/
|
||||
for (i=0 ; i<size*3 ; i++)
|
||||
{
|
||||
blocklights[i] = 0;
|
||||
}
|
||||
surf->cached_light[0] = 0;
|
||||
surf->cached_colour[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// clear to no light
|
||||
|
@ -1758,7 +1750,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
else switch(cl.worldmodel->lightmaps.fmt)
|
||||
{
|
||||
case LM_E5BGR9:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]]; // 8.8 fraction
|
||||
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
|
||||
|
@ -1768,7 +1760,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
for (i=0 ; i<size ; i++)
|
||||
{
|
||||
unsigned int l = ((unsigned int*)src)[i];
|
||||
float e = rgb9e5tab[l>>27]*(1<<7);
|
||||
float e = rgb9e5tab[l>>27]*(1u<<7);
|
||||
blocklights[i*3+0] += scalergb[0] * e * ((l>> 0)&0x1ff);
|
||||
blocklights[i*3+1] += scalergb[1] * e * ((l>> 9)&0x1ff);
|
||||
blocklights[i*3+2] += scalergb[2] * e * ((l>>18)&0x1ff);
|
||||
|
@ -1778,7 +1770,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
}
|
||||
break;
|
||||
case LM_RGB8:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]];
|
||||
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
|
||||
|
@ -1799,7 +1791,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
break;
|
||||
|
||||
case LM_L8:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ;
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ;
|
||||
maps++)
|
||||
{
|
||||
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]]; // 8.8 fraction
|
||||
|
@ -1846,16 +1838,11 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
surf->cached_light[0] = d_lightstylevalue[0];
|
||||
surf->cached_colour[0] = cl_lightstyle[0].colourkey;
|
||||
}
|
||||
else if (!surf->samples)
|
||||
{
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// clear to no light
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] = 0;
|
||||
blocklights[i] = ambient;
|
||||
|
||||
// add all the lightmaps
|
||||
if (src)
|
||||
|
@ -1863,38 +1850,41 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
switch(cl.worldmodel->lightmaps.fmt)
|
||||
{
|
||||
case LM_E5BGR9:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
surf->cached_light[maps] = scale; // 8.8 fraction
|
||||
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
|
||||
for (i=0 ; i<size ; i++)
|
||||
{
|
||||
unsigned int lm = ((unsigned int *)lightmap)[i];
|
||||
blocklights[i] += max3(((lm>>0)&0x1ff),((lm>>9)&0x1ff),((lm>>18)&0x1ff)) * scale * (rgb9e5tab[lm>>27]*(1<<7));
|
||||
}
|
||||
if (scale)
|
||||
for (i=0 ; i<size ; i++)
|
||||
{
|
||||
unsigned int lm = ((unsigned int *)lightmap)[i];
|
||||
blocklights[i] += max3(((lm>>0)&0x1ff),((lm>>9)&0x1ff),((lm>>18)&0x1ff)) * scale * (rgb9e5tab[lm>>27]*(1<<7));
|
||||
}
|
||||
lightmap += size*4; // skip to next lightmap
|
||||
}
|
||||
break;
|
||||
case LM_RGB8:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
surf->cached_light[maps] = scale; // 8.8 fraction
|
||||
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] += max3(src[i*3],src[i*3+1],src[i*3+2]) * scale;
|
||||
if (scale)
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] += max3(src[i*3],src[i*3+1],src[i*3+2]) * scale;
|
||||
src += size*3; // skip to next lightmap
|
||||
}
|
||||
break;
|
||||
case LM_L8:
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
surf->cached_light[maps] = scale; // 8.8 fraction
|
||||
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] += src[i] * scale;
|
||||
if (scale)
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] += src[i] * scale;
|
||||
src += size; // skip to next lightmap
|
||||
}
|
||||
break;
|
||||
|
@ -1902,7 +1892,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
}
|
||||
}
|
||||
|
||||
Surf_StoreLightmap_Grey(dest, blocklights, smax, tmax, shift, stainsrc, lm->width);
|
||||
Surf_StoreLightmap_Lum(dest, blocklights, smax, tmax, shift, stainsrc, lm->width);
|
||||
}
|
||||
|
||||
//make sure we flag the output rect properly.
|
||||
|
@ -1965,7 +1955,7 @@ void Surf_RenderDynamicLightmaps (msurface_t *fa)
|
|||
}
|
||||
else
|
||||
{
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && fa->styles[maps] != INVALID_LIGHTSTYLE ;
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && fa->styles[maps] != INVALID_LIGHTSTYLE ;
|
||||
maps++)
|
||||
if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]
|
||||
|| cl_lightstyle[fa->styles[maps]].colourkey != fa->cached_colour[maps])
|
||||
|
@ -2008,7 +1998,7 @@ static void Surf_RenderDynamicLightmaps_Worker (model_t *wmodel, msurface_t *fa,
|
|||
}
|
||||
else
|
||||
{
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && fa->styles[maps] != INVALID_LIGHTSTYLE ;
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && fa->styles[maps] != INVALID_LIGHTSTYLE ;
|
||||
maps++)
|
||||
if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]
|
||||
|| cl_lightstyle[fa->styles[maps]].colourkey != fa->cached_colour[maps])
|
||||
|
|
|
@ -129,7 +129,7 @@ typedef struct entity_s
|
|||
// only used for static objects
|
||||
|
||||
// int dlightframe; // dynamic lighting
|
||||
// int dlightbits;
|
||||
// dlightbitmask_t dlightbits;
|
||||
|
||||
// FIXME: could turn these into a union
|
||||
// int trivial_accept;
|
||||
|
|
|
@ -683,11 +683,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, chanupdat
|
|||
qboolean srcrel;
|
||||
|
||||
if (chnum >= oali->max_sources)
|
||||
{
|
||||
size_t oc = oali->max_sources;
|
||||
Z_ReallocElements((void**)&oali->source, &oali->max_sources, chnum+1+64, sizeof(*oali->source));
|
||||
memset(oali->source+oc, 0, sizeof(*oali->source)*(oali->max_sources-oc));
|
||||
}
|
||||
|
||||
//alcMakeContextCurrent
|
||||
|
||||
|
@ -696,7 +692,6 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, chanupdat
|
|||
sfx = NULL;
|
||||
#endif
|
||||
|
||||
src = oali->source[chnum].handle;
|
||||
if (!oali->source[chnum].allocated)
|
||||
{
|
||||
//not currently playing. be prepared to create one
|
||||
|
@ -722,58 +717,54 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, chanupdat
|
|||
oali->source[chnum].allocated = true;
|
||||
schanged |= CUR_EVERYTHING; //should normally be true anyway, but hey
|
||||
}
|
||||
else
|
||||
src = oali->source[chnum].handle;
|
||||
|
||||
PrintALError("pre start sound");
|
||||
|
||||
if ((schanged&CUR_SOUNDCHANGE) && src)
|
||||
if (schanged&CUR_SOUNDCHANGE)
|
||||
palSourceStop(src);
|
||||
|
||||
//reclaim any queued buffers
|
||||
if (src)
|
||||
palGetSourcei(src, AL_SOURCE_TYPE, &buf);
|
||||
if (buf == AL_STREAMING)
|
||||
{
|
||||
palGetSourcei(src, AL_SOURCE_TYPE, &buf);
|
||||
if (buf == AL_STREAMING)
|
||||
for(;;)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
palGetSourcei(src, AL_BUFFERS_PROCESSED, &buf);
|
||||
if (!buf)
|
||||
break;
|
||||
palSourceUnqueueBuffers(src, 1, &buf);
|
||||
palDeleteBuffers(1, &buf);
|
||||
}
|
||||
palGetSourcei(src, AL_BUFFERS_PROCESSED, &buf);
|
||||
if (!buf)
|
||||
break;
|
||||
palSourceUnqueueBuffers(src, 1, &buf);
|
||||
palDeleteBuffers(1, &buf);
|
||||
}
|
||||
else if (!schanged && sfx) //if we don't figure out when they've finished, they'll not get replaced properly.
|
||||
}
|
||||
else if (!schanged && sfx) //if we don't figure out when they've finished, they'll not get replaced properly.
|
||||
{
|
||||
palGetSourcei(src, AL_SOURCE_STATE, &buf);
|
||||
if (buf != AL_PLAYING)
|
||||
{
|
||||
palGetSourcei(src, AL_SOURCE_STATE, &buf);
|
||||
if (buf != AL_PLAYING)
|
||||
{
|
||||
schanged |= CUR_EVERYTHING;
|
||||
if(sfx->loopstart != -1)
|
||||
chan->pos = sfx->loopstart<<PITCHSHIFT;
|
||||
else if (chan->flags & CF_FORCELOOP)
|
||||
chan->pos = 0;
|
||||
else
|
||||
sfx = chan->sfx = NULL;
|
||||
}
|
||||
schanged |= CUR_EVERYTHING;
|
||||
if(sfx->loopstart != -1)
|
||||
chan->pos = sfx->loopstart<<PITCHSHIFT;
|
||||
else if (chan->flags & CF_FORCELOOP)
|
||||
chan->pos = 0;
|
||||
else
|
||||
sfx = chan->sfx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*just wanted to stop it?*/
|
||||
if (!sfx)
|
||||
{
|
||||
if (src)
|
||||
{
|
||||
#ifdef FTE_TARGET_WEB
|
||||
//emscripten's webaudio wrapper spams error messages after alDeleteSources has been called, if the context isn't also killed.
|
||||
if (!schanged)
|
||||
palSourceStop(src);
|
||||
//emscripten's webaudio wrapper spams error messages after alDeleteSources has been called, if the context isn't also killed.
|
||||
if (!schanged)
|
||||
palSourceStop(src);
|
||||
#else
|
||||
palDeleteSources(1, &src);
|
||||
oali->source[chnum].handle = 0;
|
||||
oali->source[chnum].allocated = false;
|
||||
palDeleteSources(1, &src);
|
||||
oali->source[chnum].handle = 0;
|
||||
oali->source[chnum].allocated = false;
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -791,11 +782,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, chanupdat
|
|||
int sndnum = sfx-known_sfx;
|
||||
int buf;
|
||||
if (sndnum >= oali->max_sounds)
|
||||
{
|
||||
size_t oc = oali->max_sounds;
|
||||
Z_ReallocElements((void**)&oali->sounds, &oali->max_sounds, sndnum+1+64, sizeof(*oali->sounds));
|
||||
memset(oali->sounds+oc, 0, sizeof(*oali->sounds)*(oali->max_sounds-oc));
|
||||
}
|
||||
buf = oali->sounds[sndnum].buffer;
|
||||
if (!oali->sounds[sndnum].allocated || stream)
|
||||
{
|
||||
|
@ -852,8 +839,8 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, chanupdat
|
|||
{
|
||||
//build a buffer with it and queue it up.
|
||||
//buffer will be purged later on when its unqueued
|
||||
OpenAL_LoadCache(oali, &buf, &sbuf, max(1,cvolume));
|
||||
palSourceQueueBuffers(src, 1, &buf);
|
||||
if (OpenAL_LoadCache(oali, &buf, &sbuf, max(1,cvolume)))
|
||||
palSourceQueueBuffers(src, 1, &buf);
|
||||
}
|
||||
else
|
||||
{ //decoder isn't ready yet, but didn't signal an error/eof. queue a little silence, because that's better than constant micro stutters
|
||||
|
@ -864,8 +851,8 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, chanupdat
|
|||
silence.data = NULL;
|
||||
silence.length = 0.1 * silence.speed;
|
||||
silence.soundoffset = 0;
|
||||
OpenAL_LoadCache(oali, &buf, &silence, 1);
|
||||
palSourceQueueBuffers(src, 1, &buf);
|
||||
if (OpenAL_LoadCache(oali, &buf, &silence, 1))
|
||||
palSourceQueueBuffers(src, 1, &buf);
|
||||
}
|
||||
queuedbufs++;
|
||||
|
||||
|
@ -893,8 +880,8 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, chanupdat
|
|||
silence.data = NULL;
|
||||
silence.length = 0.1 * silence.speed;
|
||||
silence.soundoffset = 0;
|
||||
OpenAL_LoadCache(oali, &buf, &silence, 1);
|
||||
palSourceQueueBuffers(src, 1, &buf);
|
||||
if (OpenAL_LoadCache(oali, &buf, &silence, 1))
|
||||
palSourceQueueBuffers(src, 1, &buf);
|
||||
queuedbufs++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "netinc.h"
|
||||
|
||||
#undef malloc
|
||||
|
||||
|
@ -946,6 +947,46 @@ char *Sys_ConsoleInput(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
static void DoSign(const char *fname)
|
||||
{
|
||||
qbyte digest[1024];
|
||||
qbyte signature[2048];
|
||||
qbyte base64[2048*4];
|
||||
int sigsize;
|
||||
vfsfile_t *f;
|
||||
const char *auth = "Unknown";
|
||||
int i = COM_CheckParm("-certhost");
|
||||
if (i)
|
||||
auth = com_argv[i+1];
|
||||
|
||||
f = FS_OpenVFS(fname, "rb", FS_SYSTEM);
|
||||
if (f)
|
||||
{
|
||||
hashfunc_t *h = &hash_sha512;
|
||||
size_t l, ts = 0;
|
||||
void *ctx = alloca(h->contextsize);
|
||||
qbyte data[65536*16];
|
||||
h->init(ctx);
|
||||
while ((l=VFS_READ(f, data, sizeof(data)))>0)
|
||||
{
|
||||
h->process(ctx, data, l);
|
||||
ts += l;
|
||||
}
|
||||
h->terminate(digest, ctx);
|
||||
VFS_CLOSE(f);
|
||||
printf(" \\\"dlsize=%zu\\\"", ts);
|
||||
|
||||
Base16_EncodeBlock(digest, h->digestsize, base64, sizeof(base64));
|
||||
printf(" \\\"sha512=%s\\\"", base64);
|
||||
|
||||
sigsize = GNUTLS_GenerateSignature(digest, h->digestsize, signature, sizeof(signature));
|
||||
Base64_EncodeBlock(signature, sigsize, base64, sizeof(base64));
|
||||
printf(" \\\"sign=%s:%s\\\"\n", auth, base64);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
static void SigCont(int code)
|
||||
{
|
||||
|
@ -1029,15 +1070,19 @@ int main (int c, const char **v)
|
|||
memset(bindir, 0, sizeof(bindir)); //readlink does NOT null terminate, apparently.
|
||||
#ifdef __linux__
|
||||
//attempt to figure out where the exe is located
|
||||
if (readlink("/proc/self/exe", bindir, sizeof(bindir)-1) > 0)
|
||||
i = readlink("/proc/self/exe", bindir, sizeof(bindir)-1);
|
||||
if (i > 0)
|
||||
{
|
||||
bindir[i] = 0;
|
||||
*COM_SkipPath(bindir) = 0;
|
||||
parms.binarydir = bindir;
|
||||
}
|
||||
/*#elif defined(__bsd__)
|
||||
//attempt to figure out where the exe is located
|
||||
if (readlink("/proc/self/file", bindir, sizeof(bindir)-1) > 0)
|
||||
i = readlink("/proc/self/file", bindir, sizeof(bindir)-1);
|
||||
if (i > 0)
|
||||
{
|
||||
bindir[i] = 0;
|
||||
*COM_SkipPath(bindir) = 0;
|
||||
parms.binarydir = bindir;
|
||||
}
|
||||
|
@ -1066,6 +1111,22 @@ int main (int c, const char **v)
|
|||
if (COM_CheckParm("-nostdout"))
|
||||
nostdout = 1;
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
//fteqw -privcert privcert.key -pubcert pubcert.key -sign binaryfile.pk3
|
||||
i = COM_CheckParm("-sign");
|
||||
if (i)
|
||||
{
|
||||
//init some useless crap
|
||||
host_parms = parms;
|
||||
Cvar_Init();
|
||||
Memory_Init ();
|
||||
COM_Init ();
|
||||
|
||||
DoSign(com_argv[i+1]);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (parms.binarydir)
|
||||
Sys_Printf("Binary is located at \"%s\"\n", bindir);
|
||||
|
||||
|
@ -1088,7 +1149,6 @@ int main (int c, const char **v)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
Host_Init(&parms);
|
||||
|
||||
for (i = 1; i < parms.argc; i++)
|
||||
|
@ -1230,4 +1290,3 @@ qboolean Sys_RunInstaller(void)
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2883,15 +2883,18 @@ qboolean Sys_EngineMayUpdate(void)
|
|||
{
|
||||
char *e;
|
||||
|
||||
//no revision info in this build, meaning its custom built and thus cannot check against the available updated versions.
|
||||
if (!strcmp(SVNREVISIONSTR, "-"))
|
||||
return false;
|
||||
if (!COM_CheckParm("-allowupdate"))
|
||||
{
|
||||
//no revision info in this build, meaning its custom built and thus cannot check against the available updated versions.
|
||||
if (!strcmp(SVNREVISIONSTR, "-"))
|
||||
return false;
|
||||
|
||||
//svn revision didn't parse as an exact number. this implies it has an 'M' in it to mark it as modified.
|
||||
//either way, its bad and autoupdates when we don't know what we're updating from is a bad idea.
|
||||
strtoul(SVNREVISIONSTR, &e, 10);
|
||||
if (!*SVNREVISIONSTR || *e)
|
||||
return false;
|
||||
//svn revision didn't parse as an exact number. this implies it has an 'M' in it to mark it as modified.
|
||||
//either way, its bad and autoupdates when we don't know what we're updating from is a bad idea.
|
||||
strtoul(SVNREVISIONSTR, &e, 10);
|
||||
if (!*SVNREVISIONSTR || *e)
|
||||
return false;
|
||||
}
|
||||
|
||||
//update blocked via commandline
|
||||
if (COM_CheckParm("-noupdate") || COM_CheckParm("--noupdate") || COM_CheckParm("-noautoupdate") || COM_CheckParm("--noautoupdate"))
|
||||
|
|
|
@ -503,7 +503,7 @@ void Validation_FileLoaded(const char *filename, const qbyte *filedata, size_t f
|
|||
{
|
||||
if (!strcmp(filename, modifiles[i].name) && (modifiles[i].flags & (cl.teamfortress?FMOD_TF:FMOD_DM)))
|
||||
{
|
||||
SHA1(digest, sizeof(digest), filedata, filesize);
|
||||
CalcHash(&hash_sha1, digest, sizeof(digest), filedata, filesize);
|
||||
|
||||
for (j = 0; j < modifiles[i].hashes; j++)
|
||||
{
|
||||
|
|
|
@ -2193,7 +2193,7 @@ void R_DrawNameTags(void)
|
|||
if (Matrix4x4_CM_Project(org, screenspace, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y))
|
||||
{
|
||||
char asciibuffer[8192];
|
||||
char *entstr;
|
||||
const char *entstr;
|
||||
size_t buflen;
|
||||
int x, y;
|
||||
|
||||
|
@ -2205,7 +2205,19 @@ void R_DrawNameTags(void)
|
|||
vec2_t scale = {8,8};
|
||||
x = screenspace[0]*r_refdef.vrect.width+r_refdef.vrect.x;
|
||||
y = (1-screenspace[1])*r_refdef.vrect.height+r_refdef.vrect.y;
|
||||
R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_console, scale);
|
||||
y += scale[1]*R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_console, scale);
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
{
|
||||
extern world_t csqc_world;
|
||||
if (w == &csqc_world)
|
||||
{
|
||||
entstr = CSQC_GetExtraFieldInfo(e, asciibuffer, sizeof(asciibuffer));
|
||||
if (entstr)
|
||||
y += scale[1]*R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_console, scale);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -839,8 +839,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define MAX_BACKBUFLEN 1200
|
||||
|
||||
#ifdef Q1BSPS
|
||||
#define lightstyleindex_t unsigned short
|
||||
#else
|
||||
#define lightstyleindex_t qbyte
|
||||
#endif
|
||||
#define INVALID_LIGHTSTYLE ((lightstyleindex_t)(~0u)) //the style that's invalid, signifying to stop adding more.
|
||||
#define INVALID_VLIGHTSTYLE ((qbyte)(~0u)) //the style that's invalid for verticies, signifying to stop adding more.
|
||||
|
||||
//
|
||||
// per-level limits
|
||||
|
|
|
@ -24,6 +24,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define MAX_MAP_HULLSDQ1 4
|
||||
#define MAX_MAP_HULLSDH2 8
|
||||
#define MAX_MAP_HULLSM 8
|
||||
#define RBSP_STYLESPERSURF 4
|
||||
#define Q1Q2BSP_STYLESPERSURF 4
|
||||
#ifdef Q1BSPS
|
||||
#define MAXCPULIGHTMAPS 16 //max lightmaps mixed by the cpu (vanilla q1bsp=4, fte extensions=no real cap, must be >=MAXRLIGHTMAPS)
|
||||
#elif defined(Q1BSPS)
|
||||
#define MAXCPULIGHTMAPS Q1Q2BSP_STYLESPERSURF //max lightmaps mixed by the cpu (vanilla q1bsp=4, fte extensions=no real cap, must be >=MAXRLIGHTMAPS)
|
||||
#else
|
||||
#define MAXCPULIGHTMAPS MAXRLIGHTMAPS //max lightmaps mixed by the cpu (vanilla q1bsp=4, fte extensions=no real cap, must be >=MAXRLIGHTMAPS)
|
||||
#endif
|
||||
|
||||
//#define MAX_MAP_MODELS 256
|
||||
//#define MAX_MAP_BRUSHES 0x8000
|
||||
|
@ -235,11 +244,10 @@ typedef struct
|
|||
} dledge_t;
|
||||
|
||||
#ifdef RFBSPS
|
||||
#define MAXRLIGHTMAPS 4 //max lightmaps mixed by the renderer (rbsp=4, otherwise 1)
|
||||
#define MAXRLIGHTMAPS 4 //max lightmaps mixed by the gpu (rbsp=4, otherwise 1)
|
||||
#else
|
||||
#define MAXRLIGHTMAPS 1 //max lightmaps mixed by the renderer (rbsp=4, otherwise 1)
|
||||
#define MAXRLIGHTMAPS 1 //max lightmaps mixed by the gpu (rbsp=4, otherwise 1)
|
||||
#endif
|
||||
#define MAXQ1LIGHTMAPS 16
|
||||
typedef struct
|
||||
{
|
||||
short planenum;
|
||||
|
@ -250,7 +258,7 @@ typedef struct
|
|||
short texinfo;
|
||||
|
||||
// lighting info
|
||||
qbyte styles[4];
|
||||
qbyte styles[Q1Q2BSP_STYLESPERSURF];
|
||||
int lightofs; // start of [numstyles*surfsize] samples
|
||||
} dsface_t;
|
||||
typedef struct
|
||||
|
@ -263,7 +271,7 @@ typedef struct
|
|||
int texinfo;
|
||||
|
||||
// lighting info
|
||||
qbyte styles[4];
|
||||
qbyte styles[Q1Q2BSP_STYLESPERSURF];
|
||||
int lightofs; // start of [numstyles*surfsize] samples
|
||||
} dlface_t;
|
||||
|
||||
|
@ -821,9 +829,10 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
float point[3];
|
||||
float texcoords[5][2];
|
||||
float stcoords[2];
|
||||
float lmtexcoords[RBSP_STYLESPERSURF][2];
|
||||
float normal[3];
|
||||
unsigned char color[4][4];
|
||||
unsigned char color[RBSP_STYLESPERSURF][4];
|
||||
} rbspvertex_t;
|
||||
|
||||
struct Q3FOG
|
||||
|
@ -854,8 +863,7 @@ typedef struct
|
|||
int firstindex;
|
||||
int num_indexes;
|
||||
int lightmapnum;
|
||||
int lightmap_x;
|
||||
int lightmap_y;
|
||||
int lightmap_offs[2];
|
||||
int lightmap_width;
|
||||
int lightmap_height;
|
||||
float lightmap_origin[3];
|
||||
|
@ -874,10 +882,10 @@ typedef struct
|
|||
int num_vertices;
|
||||
int firstindex;
|
||||
int num_indexes;
|
||||
unsigned char lm_styles[4];
|
||||
unsigned char vt_styles[4];
|
||||
int lightmapnum[4];
|
||||
int lightmap_offs[2][4];
|
||||
unsigned char lm_styles[RBSP_STYLESPERSURF];
|
||||
unsigned char vt_styles[RBSP_STYLESPERSURF];
|
||||
int lightmapnum[RBSP_STYLESPERSURF];
|
||||
int lightmap_offs[2][RBSP_STYLESPERSURF]; //yes, weird ordering.
|
||||
int lightmap_width;
|
||||
int lightmap_height;
|
||||
float lightmap_origin[3];
|
||||
|
|
|
@ -5466,6 +5466,16 @@ const char *Mod_SkinNameForNum(model_t *model, int surfaceidx, int num)
|
|||
galiasinfo_t *inf;
|
||||
galiasskin_t *skin;
|
||||
|
||||
if (!model || model->loadstate != MLS_LOADED)
|
||||
{
|
||||
if (model && model->loadstate == MLS_NOTLOADED)
|
||||
Mod_LoadModel(model, MLV_SILENT);
|
||||
if (model && model->loadstate == MLS_LOADING)
|
||||
COM_WorkerPartialSync(model, &model->loadstate, MLS_LOADING);
|
||||
if (!model || model->loadstate != MLS_LOADED)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!model || model->type != mod_alias)
|
||||
{
|
||||
if (model->type == mod_brush && surfaceidx < model->numtextures && !num)
|
||||
|
|
|
@ -6040,6 +6040,97 @@ static int Base64_Decode(char inp)
|
|||
//if (inp == '=') //padding char
|
||||
return 0; //invalid
|
||||
}
|
||||
|
||||
size_t Base64_EncodeBlock(const qbyte *in, size_t length, char *out, size_t outsize)
|
||||
{
|
||||
char *start = out;
|
||||
char *end = out+outsize-1;
|
||||
unsigned int v;
|
||||
while(length > 0)
|
||||
{
|
||||
v = 0;
|
||||
if (length > 0)
|
||||
v |= in[0]<<16;
|
||||
if (length > 1)
|
||||
v |= in[1]<<8;
|
||||
if (length > 2)
|
||||
v |= in[2]<<0;
|
||||
|
||||
if (out < end) *out++ = (length>=1)?Base64_Encode((v>>18)&63):'=';
|
||||
if (out < end) *out++ = (length>=1)?Base64_Encode((v>>12)&63):'=';
|
||||
if (out < end) *out++ = (length>=2)?Base64_Encode((v>>6)&63):'=';
|
||||
if (out < end) *out++ = (length>=3)?Base64_Encode((v>>0)&63):'=';
|
||||
|
||||
in+=3;
|
||||
length -= 3;
|
||||
}
|
||||
end++;
|
||||
if (out < end)
|
||||
*out = 0;
|
||||
return out-start;
|
||||
}
|
||||
size_t Base64_DecodeBlock(const char *in, const char *in_end, qbyte *out, size_t outsize)
|
||||
{
|
||||
qbyte *start = out;
|
||||
unsigned int v;
|
||||
if (!in_end)
|
||||
in_end = in + strlen(in);
|
||||
if (!out)
|
||||
return ((in_end-in+3)/4)*3 + 1; //upper estimate, with null terminator for convienience.
|
||||
|
||||
for (; outsize > 1;)
|
||||
{
|
||||
while(*in > 0 && *in < ' ')
|
||||
in++;
|
||||
if (in >= in_end || !*in || outsize < 1)
|
||||
break; //end of message when EOF, otherwise error
|
||||
v = Base64_Decode(*in++)<<18;
|
||||
while(*in > 0 && *in < ' ')
|
||||
in++;
|
||||
if (in >= in_end || !*in || outsize < 1)
|
||||
break; //some kind of error
|
||||
v |= Base64_Decode(*in++)<<12;
|
||||
*out++ = (v>>16)&0xff;
|
||||
if (in >= in_end || *in == '=' || !*in || outsize < 2)
|
||||
break; //end of message when '=', otherwise error
|
||||
v |= Base64_Decode(*in++)<<6;
|
||||
*out++ = (v>>8)&0xff;
|
||||
if (in >= in_end || *in == '=' || !*in || outsize < 3)
|
||||
break; //end of message when '=', otherwise error
|
||||
v |= Base64_Decode(*in++)<<0;
|
||||
*out++ = (v>>0)&0xff;
|
||||
outsize -= 3;
|
||||
}
|
||||
return out-start; //total written (no null, output is considered binary)
|
||||
}
|
||||
size_t Base16_DecodeBlock(const char *in, qbyte *out, size_t outsize)
|
||||
{
|
||||
qbyte *start = out;
|
||||
if (!out)
|
||||
return ((strlen(in)+1)/2) + 1;
|
||||
|
||||
for (; ishexcode(in[0]) && ishexcode(in[1]) && outsize > 0; outsize--, in+=2)
|
||||
*out++ = (dehex(in[0])<<4) | dehex(in[1]);
|
||||
return out-start;
|
||||
}
|
||||
size_t Base16_EncodeBlock(const char *in, size_t length, qbyte *out, size_t outsize)
|
||||
{
|
||||
const char tab[16] = "0123456789abcdef";
|
||||
qbyte *start = out;
|
||||
if (!out)
|
||||
return (length*2) + 1;
|
||||
|
||||
if (outsize > length*2)
|
||||
*out = 0;
|
||||
while (length --> 0)
|
||||
{
|
||||
*out++ = tab[(*in>>4)&0xf];
|
||||
*out++ = tab[(*in>>0)&0xf];
|
||||
in++;
|
||||
}
|
||||
return out-start;
|
||||
}
|
||||
|
||||
/*
|
||||
Info Buffers
|
||||
*/
|
||||
|
|
|
@ -742,7 +742,7 @@ char *FS_GetManifestArgs(void);
|
|||
int FS_GetManifestArgv(char **argv, int maxargs);
|
||||
|
||||
struct zonegroup_s;
|
||||
void *FS_LoadMallocGroupFile(struct zonegroup_s *ctx, char *path, size_t *fsize);
|
||||
void *FS_LoadMallocGroupFile(struct zonegroup_s *ctx, char *path, size_t *fsize, qboolean filters);
|
||||
qbyte *FS_LoadMallocFile (const char *path, size_t *fsize);
|
||||
qofs_t FS_LoadFile(const char *name, void **file);
|
||||
void FS_FreeFile(void *file);
|
||||
|
@ -848,13 +848,26 @@ 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);
|
||||
|
||||
typedef size_t hashfunc_t(unsigned char *digest, size_t maxdigestsize, size_t numstrings, const unsigned char **strings, size_t *stringlens);
|
||||
#define SHA1 SHA1_quake
|
||||
#define HMAC HMAC_quake
|
||||
hashfunc_t SHA1_m;
|
||||
//int SHA1_m(char *digest, size_t maxdigestsize, size_t numstrings, const char **strings, size_t *stringlens);
|
||||
//#define SHA1(digest,maxdigestsize,string,stringlen) SHA1_m(digest, maxdigestsize, 1, &string, &stringlen)
|
||||
size_t SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen);
|
||||
size_t Base64_EncodeBlock(const qbyte *in, size_t length, char *out, size_t outsize); //tries to null terminate, but returns length without termination.
|
||||
size_t Base64_DecodeBlock(const char *in, const char *in_end, qbyte *out, size_t outsize); // +/ and =
|
||||
size_t Base16_EncodeBlock(const char *in, size_t length, qbyte *out, size_t outsize);
|
||||
size_t Base16_DecodeBlock(const char *in, qbyte *out, size_t outsize);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int digestsize;
|
||||
unsigned int contextsize; //you need to alloca(te) this much memory...
|
||||
void (*init) (void *context);
|
||||
void (*process) (void *context, const void *data, size_t datasize);
|
||||
void (*terminate) (unsigned char *digest, void *context);
|
||||
} hashfunc_t;
|
||||
extern hashfunc_t hash_sha1;
|
||||
extern hashfunc_t hash_sha224;
|
||||
extern hashfunc_t hash_sha256;
|
||||
extern hashfunc_t hash_sha384;
|
||||
extern hashfunc_t hash_sha512;
|
||||
#define HMAC HMAC_quake //stop conflicts...
|
||||
size_t CalcHash(hashfunc_t *hash, unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen);
|
||||
size_t HMAC(hashfunc_t *hashfunc, unsigned char *digest, size_t maxdigestsize, const unsigned char *data, size_t datalen, const unsigned char *key, size_t keylen);
|
||||
|
||||
int version_number(void);
|
||||
|
|
|
@ -1824,7 +1824,7 @@ static vfsfile_t *VFS_Filter(const char *filename, vfsfile_t *handle)
|
|||
{
|
||||
// char *ext;
|
||||
|
||||
if (!handle || handle->WriteBytes || handle->seekstyle == SS_SLOW || handle->seekstyle == SS_UNSEEKABLE) //only on readonly files for which we can undo any header read damage
|
||||
if (!handle || !handle->ReadBytes || handle->seekstyle == SS_SLOW || handle->seekstyle == SS_UNSEEKABLE) //only on readonly files for which we can undo any header read damage
|
||||
return handle;
|
||||
// ext = COM_FileExtension (filename);
|
||||
#ifdef AVAIL_GZDEC
|
||||
|
@ -2170,7 +2170,7 @@ vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_rela
|
|||
|
||||
if (loc.search)
|
||||
{
|
||||
return VFS_Filter(filename, loc.search->handle->OpenVFS(loc.search->handle, &loc, mode));
|
||||
return loc.search->handle->OpenVFS(loc.search->handle, &loc, mode);
|
||||
}
|
||||
|
||||
//if we're meant to be writing, best write to it.
|
||||
|
@ -2406,14 +2406,19 @@ qbyte *FS_LoadMallocFile (const char *path, size_t *fsize)
|
|||
return COM_LoadFile (path, 0, 5, fsize);
|
||||
}
|
||||
|
||||
void *FS_LoadMallocGroupFile(zonegroup_t *ctx, char *path, size_t *fsize)
|
||||
void *FS_LoadMallocGroupFile(zonegroup_t *ctx, char *path, size_t *fsize, qboolean filters)
|
||||
{
|
||||
char *mem = NULL;
|
||||
vfsfile_t *f = FS_OpenVFS(path, "rb", FS_GAME);
|
||||
if (f && filters)
|
||||
f = VFS_Filter(path, f);
|
||||
if (f)
|
||||
{
|
||||
int len = VFS_GETLEN(f);
|
||||
mem = ZG_Malloc(ctx, len+1);
|
||||
if (ctx)
|
||||
mem = ZG_Malloc(ctx, len+1);
|
||||
else
|
||||
mem = BZ_Malloc(len+1);
|
||||
if (mem)
|
||||
{
|
||||
mem[len] = 0;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
cvar_t q3bsp_surf_meshcollision_flag = CVARD("q3bsp_surf_meshcollision_flag", "0x80000000", "The surfaceparm flag(s) that enables q3bsp trisoup collision");
|
||||
cvar_t q3bsp_surf_meshcollision_force = CVARD("q3bsp_surf_meshcollision_force", "0", "Force mesh-based collisions on all q3bsp trisoup surfaces.");
|
||||
cvar_t q3bsp_mergeq3lightmaps = CVARD("q3bsp_mergelightmaps", "1", "Specifies whether to merge lightmaps into atlases in order to boost performance. Unfortunately this breaks tcgen on lightmap passes - if you care, set this to 0.");
|
||||
cvar_t q3bsp_ignorestyles = CVARD("q3bsp_ignorestyles", "0", "Ignores multiple lightstyles in Raven's q3bsp variant(and derivatives) for better batch/rendering performance.");
|
||||
cvar_t q3bsp_bihtraces = CVARFD("_q3bsp_bihtraces", "0", CVAR_RENDERERLATCH, "Uses runtime-generated bih collision culling for faster traces.");
|
||||
|
||||
#if Q3SURF_NODRAW != TI_NODRAW
|
||||
|
@ -1696,7 +1697,7 @@ static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, lump
|
|||
out->styles[i] = style;
|
||||
}
|
||||
}
|
||||
for ( ; i<MAXQ1LIGHTMAPS ; i++)
|
||||
for ( ; i<MAXCPULIGHTMAPS ; i++)
|
||||
out->styles[i] = INVALID_LIGHTSTYLE;
|
||||
if (overrides.offsets)
|
||||
i = overrides.offsets[surfnum];
|
||||
|
@ -2476,11 +2477,11 @@ static qboolean CModRBSP_LoadVertexes (model_t *mod, qbyte *mod_base, lump_t *l)
|
|||
}
|
||||
for ( j=0 ; j < 2 ; j++)
|
||||
{
|
||||
stout[i][j] = LittleFloat ( ((float *)in->texcoords)[j] );
|
||||
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
|
||||
prv->vertlstmexcoords[sty][i][j] = LittleFloat ( ((float *)in->texcoords)[j+2*(sty+1)] );
|
||||
stout[i][j] = LittleFloat (in->stcoords[j]);
|
||||
for (sty = 0; sty < min(MAXRLIGHTMAPS, RBSP_STYLESPERSURF); sty++)
|
||||
prv->vertlstmexcoords[sty][i][j] = LittleFloat(in->lmtexcoords[sty][j]);
|
||||
}
|
||||
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
|
||||
for (sty = 0; sty < min(MAXRLIGHTMAPS, RBSP_STYLESPERSURF); sty++)
|
||||
{
|
||||
prv->colors4f_array[sty][i][0] = lmgamma[in->color[sty][0]]/255.0f;
|
||||
prv->colors4f_array[sty][i][1] = lmgamma[in->color[sty][1]]/255.0f;
|
||||
|
@ -3203,17 +3204,17 @@ static qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
|
|||
else if (out->lightmaptexturenums[0] < 0 /*|| facetype == MST_TRIANGLE_SOUP*/ || r_vertexlight.value)
|
||||
out->texinfo += mod->numtexinfo; //various surfaces use a different version of the same shader (with all the lightmaps collapsed)
|
||||
|
||||
out->light_s[0] = LittleLong(in->lightmap_x);
|
||||
out->light_t[0] = LittleLong(in->lightmap_y);
|
||||
out->light_s[0] = LittleLong(in->lightmap_offs[0]);
|
||||
out->light_t[0] = LittleLong(in->lightmap_offs[1]);
|
||||
out->styles[0] = INVALID_LIGHTSTYLE;
|
||||
out->vlstyles[0] = 255;
|
||||
out->vlstyles[0] = INVALID_VLIGHTSTYLE;
|
||||
for (sty = 1; sty < MAXRLIGHTMAPS; sty++)
|
||||
{
|
||||
out->styles[sty] = INVALID_LIGHTSTYLE;
|
||||
out->vlstyles[sty] = 255;
|
||||
out->vlstyles[sty] = INVALID_VLIGHTSTYLE;
|
||||
out->lightmaptexturenums[sty] = -1;
|
||||
}
|
||||
for (; sty < MAXQ1LIGHTMAPS; sty++)
|
||||
for (; sty < MAXCPULIGHTMAPS; sty++)
|
||||
out->styles[sty] = INVALID_LIGHTSTYLE;
|
||||
out->lmshift = LMSHIFT_DEFAULT;
|
||||
//fixme: determine texturemins from lightmap_origin
|
||||
|
@ -3300,6 +3301,8 @@ static qboolean CModRBSP_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
|
|||
|
||||
mesh_t *mesh;
|
||||
|
||||
int maxstyle = q3bsp_ignorestyles.ival?1:min(MAXRLIGHTMAPS, RBSP_STYLESPERSURF);
|
||||
|
||||
|
||||
in = (void *)(mod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
|
@ -3320,18 +3323,26 @@ static qboolean CModRBSP_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
|
|||
out->plane = pl;
|
||||
facetype = LittleLong(in->facetype);
|
||||
out->texinfo = mod->texinfo + LittleLong(in->shadernum);
|
||||
for (j = 0; j < 4 && j < MAXRLIGHTMAPS; j++)
|
||||
for (j = 0; j < maxstyle; j++)
|
||||
{
|
||||
out->lightmaptexturenums[j] = LittleLong(in->lightmapnum[j]);
|
||||
out->light_s[j] = LittleLong(in->lightmap_offs[0][j]);
|
||||
out->light_t[j] = LittleLong(in->lightmap_offs[1][j]);
|
||||
out->styles[j] = (in->lm_styles[j]!=255)?in->lm_styles[j]:INVALID_LIGHTSTYLE;
|
||||
out->vlstyles[j] = in->vt_styles[j];
|
||||
out->vlstyles[j] = (in->vt_styles[j]!=255)?in->vt_styles[j]:INVALID_VLIGHTSTYLE;
|
||||
|
||||
if (mod->lightmaps.count < out->lightmaptexturenums[j]+1)
|
||||
mod->lightmaps.count = out->lightmaptexturenums[j]+1;
|
||||
}
|
||||
for (; j < MAXQ1LIGHTMAPS; j++)
|
||||
for (; j < MAXRLIGHTMAPS; j++)
|
||||
{
|
||||
out->lightmaptexturenums[j] = -1;
|
||||
out->light_s[j] = 0;
|
||||
out->light_t[j] = 0;
|
||||
out->styles[j] = INVALID_LIGHTSTYLE;
|
||||
out->vlstyles[j] = INVALID_VLIGHTSTYLE;
|
||||
}
|
||||
for (; j < MAXCPULIGHTMAPS; j++)
|
||||
out->styles[j] = INVALID_LIGHTSTYLE;
|
||||
if (facetype == MST_FLARE)
|
||||
out->texinfo = mod->texinfo + mod->numtexinfo*2;
|
||||
|
@ -4217,7 +4228,7 @@ static qbyte *CM_LeafnumPVS (model_t *model, int leafnum, qbyte *buffer, unsigne
|
|||
#define GLQ2BSP_LightPointValues GLQ1BSP_LightPointValues
|
||||
|
||||
extern int r_dlightframecount;
|
||||
static void Q2BSP_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
||||
static void Q2BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
|
@ -4264,7 +4275,7 @@ static void Q2BSP_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
|||
{
|
||||
if (surf->dlightframe != r_dlightframecount)
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightbits = 0u;
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
|
@ -4322,18 +4333,18 @@ CM_LoadMap
|
|||
Loads in the map and all submodels
|
||||
==================
|
||||
*/
|
||||
static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboolean clientload, unsigned *checksum)
|
||||
static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboolean clientload)
|
||||
{
|
||||
unsigned *buf;
|
||||
int i;
|
||||
q2dheader_t header;
|
||||
int length;
|
||||
static unsigned last_checksum;
|
||||
qboolean noerrors = true;
|
||||
model_t *wmod = mod;
|
||||
char loadname[32];
|
||||
qbyte *mod_base = (qbyte *)filein;
|
||||
bspx_header_t *bspx = NULL;
|
||||
unsigned int checksum;
|
||||
#ifdef Q3BSPS
|
||||
extern cvar_t gl_overbright;
|
||||
#endif
|
||||
|
@ -4360,7 +4371,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
|
|||
mod->leafs = ZG_Malloc(&mod->memgroup, 1 * sizeof(*mod->leafs));
|
||||
prv->numcmodels = 1;
|
||||
prv->numareas = 1;
|
||||
*checksum = 0;
|
||||
mod->checksum = mod->checksum2 = 0;
|
||||
prv->cmodels[0].headnode = (mnode_t*)mod->leafs; //directly start with the empty leaf
|
||||
return &prv->cmodels[0]; // cinematic servers won't have anything at all
|
||||
}
|
||||
|
@ -4376,8 +4387,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
|
|||
return NULL;
|
||||
}
|
||||
|
||||
last_checksum = LittleLong (Com_BlockChecksum (buf, length));
|
||||
*checksum = last_checksum;
|
||||
checksum = LittleLong (Com_BlockChecksum (buf, length));
|
||||
|
||||
header = *(q2dheader_t *)(buf);
|
||||
header.ident = LittleLong(header.ident);
|
||||
|
@ -4775,7 +4785,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
|
|||
#endif
|
||||
FloodAreaConnections (prv);
|
||||
|
||||
mod->checksum = mod->checksum2 = *checksum;
|
||||
mod->checksum = mod->checksum2 = checksum;
|
||||
|
||||
mod->nummodelsurfaces = mod->numsurfaces;
|
||||
memset(&mod->batches, 0, sizeof(mod->batches));
|
||||
|
@ -7702,11 +7712,10 @@ unsigned int Q2BSP_PointContents(model_t *mod, const vec3_t axis[3], const vec3_
|
|||
|
||||
|
||||
|
||||
int map_checksum;
|
||||
qboolean QDECL Mod_LoadQ2BrushModel (model_t *mod, void *buffer, size_t fsize)
|
||||
{
|
||||
mod->fromgame = fg_quake2;
|
||||
return CM_LoadMap(mod, buffer, fsize, true, &map_checksum) != NULL;
|
||||
return CM_LoadMap(mod, buffer, fsize, true) != NULL;
|
||||
}
|
||||
|
||||
void CM_Init(void) //register cvars.
|
||||
|
@ -7718,6 +7727,7 @@ void CM_Init(void) //register cvars.
|
|||
Cvar_Register(&q3bsp_surf_meshcollision_flag, MAPOPTIONS);
|
||||
Cvar_Register(&q3bsp_surf_meshcollision_force, MAPOPTIONS);
|
||||
Cvar_Register(&q3bsp_mergeq3lightmaps, MAPOPTIONS);
|
||||
Cvar_Register(&q3bsp_ignorestyles, MAPOPTIONS);
|
||||
Cvar_Register(&q3bsp_bihtraces, MAPOPTIONS);
|
||||
Cvar_Register(&r_subdivisions, MAPOPTIONS);
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ typedef struct netadr_s
|
|||
} address;
|
||||
|
||||
unsigned short port;
|
||||
unsigned short connum; //which quake connection/socket the address is talking about. 1-based. 0 is unspecified.
|
||||
unsigned short connum; //which quake connection/socket the address is talking about. 1-based. 0 is unspecified. this is NOT used for address equivelency.
|
||||
unsigned int scopeid; //ipv6 interface id thing.
|
||||
} netadr_t;
|
||||
|
||||
|
|
|
@ -477,7 +477,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
|
||||
HMAC(SHA1_m, integ, sizeof(integ), data, buf.cursize, con->rpwd, strlen(con->rpwd));
|
||||
HMAC(&hash_sha1, 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
|
||||
|
@ -1523,7 +1523,7 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
|
|||
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));
|
||||
HMAC(SHA1_m, key, sizeof(key), (qbyte*)stun, integritypos-4 - (char*)stun, con->lpwd, strlen(con->lpwd));
|
||||
HMAC(&hash_sha1, 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);
|
||||
|
@ -1690,7 +1690,7 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
|
|||
data[2] = ((buf.cursize+4+sizeof(integrity)-20)>>8)&0xff; //hashed header length is up to the end of the hmac attribute
|
||||
data[3] = ((buf.cursize+4+sizeof(integrity)-20)>>0)&0xff;
|
||||
//but the hash is to the start of the attribute's header
|
||||
HMAC(SHA1_m, integrity, sizeof(integrity), data, buf.cursize, con->lpwd, strlen(con->lpwd));
|
||||
HMAC(&hash_sha1, integrity, sizeof(integrity), data, buf.cursize, con->lpwd, strlen(con->lpwd));
|
||||
MSG_WriteShort(&buf, BigShort(0x8)); //MESSAGE-INTEGRITY
|
||||
MSG_WriteShort(&buf, BigShort(sizeof(integrity))); //sha1 key length
|
||||
SZ_Write(&buf, integrity, sizeof(integrity)); //integrity data
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
#define privname "privkey.pem"
|
||||
#define pubname "cert.pem"
|
||||
|
||||
#if defined(_WIN32) && !defined(MINGW) && 0
|
||||
|
||||
|
@ -205,6 +203,7 @@ static int (VARGS *qgnutls_x509_crt_set_dn)(gnutls_x509_crt_t crt, const char *
|
|||
static int (VARGS *qgnutls_x509_crt_set_issuer_dn)(gnutls_x509_crt_t crt, const char *dn, const char **err);
|
||||
static int (VARGS *qgnutls_x509_crt_set_key)(gnutls_x509_crt_t crt, gnutls_x509_privkey_t key);
|
||||
static int (VARGS *qgnutls_x509_crt_export2)(gnutls_x509_crt_t cert, gnutls_x509_crt_fmt_t format, gnutls_datum_t * out);
|
||||
static int (VARGS *qgnutls_x509_crt_import)(gnutls_x509_crt_t cert, const gnutls_datum_t *data, gnutls_x509_crt_fmt_t format);
|
||||
static int (VARGS *qgnutls_x509_privkey_init)(gnutls_x509_privkey_t * key);
|
||||
static void (VARGS *qgnutls_x509_privkey_deinit)(gnutls_x509_privkey_t key);
|
||||
static int (VARGS *qgnutls_x509_privkey_generate)(gnutls_x509_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags);
|
||||
|
@ -213,7 +212,14 @@ static int (VARGS *qgnutls_x509_crt_privkey_sign)(gnutls_x509_crt_t crt, gnutls
|
|||
static int (VARGS *qgnutls_privkey_init)(gnutls_privkey_t * key);
|
||||
static void (VARGS *qgnutls_privkey_deinit)(gnutls_privkey_t key);
|
||||
static int (VARGS *qgnutls_privkey_import_x509)(gnutls_privkey_t pkey, gnutls_x509_privkey_t key, unsigned int flags);
|
||||
//static int (VARGS *qgnutls_privkey_sign_hash2)(gnutls_privkey_t signer, gnutls_sign_algorithm_t algo, unsigned int flags, const gnutls_datum_t * hash_data, gnutls_datum_t * signature);
|
||||
static int (VARGS *qgnutls_privkey_sign_hash)(gnutls_privkey_t signer, gnutls_digest_algorithm_t hash_algo, unsigned int flags, const gnutls_datum_t * hash_data, gnutls_datum_t * signature);
|
||||
static int (VARGS *qgnutls_pubkey_init)(gnutls_pubkey_t * key);
|
||||
static int (VARGS *qgnutls_pubkey_import_x509)(gnutls_pubkey_t key, gnutls_x509_crt_t crt, unsigned int flags);
|
||||
static int (VARGS *qgnutls_pubkey_verify_hash2)(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo, unsigned int flags, const gnutls_datum_t * hash, const gnutls_datum_t * signature);
|
||||
static int (VARGS *qgnutls_certificate_set_x509_key_mem)(gnutls_certificate_credentials_t res, const gnutls_datum_t * cert, const gnutls_datum_t * key, gnutls_x509_crt_fmt_t type);
|
||||
static int (VARGS *qgnutls_certificate_get_x509_key)(gnutls_certificate_credentials_t res, unsigned index, gnutls_x509_privkey_t *key);
|
||||
static void (VARGS *qgnutls_certificate_free_credentials)(gnutls_certificate_credentials_t sc);
|
||||
|
||||
static qboolean Init_GNUTLS(void)
|
||||
{
|
||||
|
@ -384,6 +390,13 @@ static qboolean Init_GNUTLS(void)
|
|||
{(void**)&qgnutls_privkey_import_x509, "gnutls_privkey_import_x509"},
|
||||
{(void**)&qgnutls_certificate_set_x509_key_mem, "gnutls_certificate_set_x509_key_mem"},
|
||||
|
||||
{(void**)&qgnutls_certificate_get_x509_key, "gnutls_certificate_get_x509_key"},
|
||||
{(void**)&qgnutls_certificate_free_credentials, "gnutls_certificate_free_credentials"},
|
||||
{(void**)&qgnutls_pubkey_init, "gnutls_pubkey_init"},
|
||||
{(void**)&qgnutls_pubkey_import_x509, "gnutls_pubkey_import_x509"},
|
||||
{(void**)&qgnutls_privkey_sign_hash, "gnutls_privkey_sign_hash"},
|
||||
{(void**)&qgnutls_pubkey_verify_hash2, "gnutls_pubkey_verify_hash2"},
|
||||
{(void**)&qgnutls_x509_crt_import, "gnutls_x509_crt_import"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -835,17 +848,68 @@ static gnutls_certificate_credentials_t xcred[2];
|
|||
static gnutls_datum_t cookie_key;
|
||||
#endif
|
||||
|
||||
vfsfile_t *SSL_OpenPrivKey(char *nativename, size_t nativesize)
|
||||
{
|
||||
#define privname "privkey.pem"
|
||||
vfsfile_t *privf;
|
||||
const char *mode = nativename?"wb":"rb";
|
||||
int i = COM_CheckParm("-privkey");
|
||||
if (i++)
|
||||
{
|
||||
if (nativename)
|
||||
Q_strncpyz(nativename, com_argv[i], nativesize);
|
||||
privf = FS_OpenVFS(com_argv[i], mode, FS_SYSTEM);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nativename)
|
||||
if (!FS_NativePath(privname, FS_ROOT, nativename, nativesize))
|
||||
return NULL;
|
||||
|
||||
privf = FS_OpenVFS(privname, mode, FS_ROOT);
|
||||
}
|
||||
return privf;
|
||||
#undef privname
|
||||
}
|
||||
vfsfile_t *SSL_OpenPubKey(char *nativename, size_t nativesize)
|
||||
{
|
||||
#define pubname "cert.pem"
|
||||
vfsfile_t *pubf;
|
||||
const char *mode = nativename?"wb":"rb";
|
||||
int i = COM_CheckParm("-pubkey");
|
||||
if (i++)
|
||||
{
|
||||
if (nativename)
|
||||
Q_strncpyz(nativename, com_argv[i], nativesize);
|
||||
pubf = FS_OpenVFS(com_argv[i], mode, FS_SYSTEM);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nativename)
|
||||
if (!FS_NativePath(pubname, FS_ROOT, nativename, nativesize))
|
||||
return NULL;
|
||||
pubf = FS_OpenVFS(pubname, mode, FS_ROOT);
|
||||
}
|
||||
return pubf;
|
||||
#undef pubname
|
||||
}
|
||||
|
||||
static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
|
||||
{
|
||||
int ret = -1;
|
||||
gnutls_datum_t priv, pub;
|
||||
vfsfile_t *privf = FS_OpenVFS(privname, "rb", FS_ROOT);
|
||||
vfsfile_t *pubf = FS_OpenVFS(pubname, "rb", FS_ROOT);
|
||||
vfsfile_t *privf = SSL_OpenPrivKey(NULL, 0);
|
||||
vfsfile_t *pubf = SSL_OpenPubKey(NULL, 0);
|
||||
const char *hostname = NULL;
|
||||
|
||||
int i = COM_CheckParm("-certhost");
|
||||
if (i)
|
||||
hostname = com_argv[i+1];
|
||||
|
||||
memset(&priv, 0, sizeof(priv));
|
||||
memset(&pub, 0, sizeof(pub));
|
||||
|
||||
if (!privf || !pubf)
|
||||
if ((!privf || !pubf) && hostname)
|
||||
{ //not found? generate a new one.
|
||||
//FIXME: how to deal with race conditions with multiple servers on the same host?
|
||||
//delay till the first connection? we at least write both files at the sameish time.
|
||||
|
@ -856,7 +920,7 @@ static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
|
|||
char serial[64];
|
||||
const char *errstr;
|
||||
gnutls_pk_algorithm_t privalgo = GNUTLS_PK_RSA;
|
||||
|
||||
|
||||
if (privf)VFS_CLOSE(privf);privf=NULL;
|
||||
if (pubf)VFS_CLOSE(pubf);pubf=NULL;
|
||||
|
||||
|
@ -880,11 +944,16 @@ static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
|
|||
qgnutls_x509_crt_set_activation_time(cert, time(NULL)-1);
|
||||
qgnutls_x509_crt_set_expiration_time(cert, time(NULL)+(time_t)10*365*24*60*60);
|
||||
qgnutls_x509_crt_set_serial(cert, serial, strlen(serial));
|
||||
if (qgnutls_x509_crt_set_dn(cert, "CN=localhost", &errstr) < 0)
|
||||
Con_Printf("gnutls_x509_crt_set_dn failed: %s\n", errstr);
|
||||
if (qgnutls_x509_crt_set_issuer_dn(cert, "CN=localhost", &errstr) < 0)
|
||||
Con_Printf("gnutls_x509_crt_set_issuer_dn failed: %s\n", errstr);
|
||||
// qgnutls_x509_crt_set_key_usage(cert, GNUTLS_KEY_KEY_ENCIPHERMENT|GNUTLS_KEY_DATA_ENCIPHERMENT|);
|
||||
if (!hostname)
|
||||
/*qgnutls_x509_crt_set_key_usage(cert, GNUTLS_KEY_DIGITAL_SIGNATURE)*/;
|
||||
else
|
||||
{
|
||||
if (qgnutls_x509_crt_set_dn(cert, va("CN=%s", hostname), &errstr) < 0)
|
||||
Con_Printf("gnutls_x509_crt_set_dn failed: %s\n", errstr);
|
||||
if (qgnutls_x509_crt_set_issuer_dn(cert, va("CN=%s", hostname), &errstr) < 0)
|
||||
Con_Printf("gnutls_x509_crt_set_issuer_dn failed: %s\n", errstr);
|
||||
// qgnutls_x509_crt_set_key_usage(cert, GNUTLS_KEY_KEY_ENCIPHERMENT|GNUTLS_KEY_DATA_ENCIPHERMENT|);
|
||||
}
|
||||
qgnutls_x509_crt_set_key(cert, key);
|
||||
|
||||
/*sign it with our private key*/
|
||||
|
@ -906,31 +975,29 @@ static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
|
|||
if (priv.size && pub.size)
|
||||
{
|
||||
char fullname[MAX_OSPATH];
|
||||
privf = FS_OpenVFS(privname, "wb", FS_ROOT);
|
||||
privf = SSL_OpenPrivKey(fullname, sizeof(fullname));
|
||||
if (privf)
|
||||
{
|
||||
VFS_WRITE(privf, priv.data, priv.size);
|
||||
VFS_CLOSE(privf);
|
||||
FS_NativePath(privname, FS_ROOT, fullname, sizeof(fullname));
|
||||
Con_Printf("Wrote %s\n", fullname);
|
||||
}
|
||||
// memset(priv.data, 0, priv.size);
|
||||
(*qgnutls_free)(priv.data);
|
||||
memset(&priv, 0, sizeof(priv));
|
||||
|
||||
pubf = FS_OpenVFS(pubname, "wb", FS_ROOT);
|
||||
pubf = SSL_OpenPubKey(fullname, sizeof(fullname));
|
||||
if (pubf)
|
||||
{
|
||||
VFS_WRITE(pubf, pub.data, pub.size);
|
||||
VFS_CLOSE(pubf);
|
||||
FS_NativePath(pubname, FS_ROOT, fullname, sizeof(fullname));
|
||||
Con_Printf("Wrote %s\n", fullname);
|
||||
}
|
||||
(*qgnutls_free)(pub.data);
|
||||
memset(&pub, 0, sizeof(pub));
|
||||
|
||||
privf = FS_OpenVFS(privname, "rb", FS_ROOT);
|
||||
pubf = FS_OpenVFS(pubname, "rb", FS_ROOT);
|
||||
privf = SSL_OpenPrivKey(NULL, 0);
|
||||
pubf = SSL_OpenPubKey(NULL, 0);
|
||||
|
||||
Con_Printf("Certificate generated\n");
|
||||
}
|
||||
|
@ -961,7 +1028,7 @@ static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
|
|||
Con_Printf("gnutls_certificate_set_x509_key_mem failed: %i\n", ret);
|
||||
}
|
||||
else
|
||||
Con_Printf("Unable to read/generate cert\n");
|
||||
Con_Printf("Unable to read/generate cert ('-certhost HOSTNAME' commandline arguments to autogenerate one)\n");
|
||||
|
||||
memset(priv.data, 0, priv.size);//just in case. FIXME: we didn't scrub the filesystem code. libc has its own caches etc. lets hope that noone comes up with some way to scrape memory remotely (although if they can inject code then we've lost either way so w/e)
|
||||
if (priv.data)
|
||||
|
@ -1167,7 +1234,84 @@ int GNUTLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize)
|
|||
}
|
||||
}
|
||||
|
||||
//generates a signed blob
|
||||
int GNUTLS_GenerateSignature(qbyte *hashdata, size_t hashsize, qbyte *signdata, size_t signsizemax)
|
||||
{
|
||||
gnutls_datum_t hash = {hashdata, hashsize};
|
||||
gnutls_datum_t sign = {NULL, 0};
|
||||
|
||||
gnutls_certificate_credentials_t cred;
|
||||
if (Init_GNUTLS())
|
||||
{
|
||||
qgnutls_certificate_allocate_credentials (&cred);
|
||||
if (SSL_LoadPrivateCert(cred))
|
||||
{
|
||||
gnutls_x509_privkey_t xkey;
|
||||
gnutls_privkey_t privkey;
|
||||
qgnutls_privkey_init(&privkey);
|
||||
qgnutls_certificate_get_x509_key(cred, 0, &xkey);
|
||||
qgnutls_privkey_import_x509(privkey, xkey, 0);
|
||||
|
||||
qgnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA512, 0, &hash, &sign);
|
||||
qgnutls_privkey_deinit(privkey);
|
||||
}
|
||||
else
|
||||
sign.size = 0;
|
||||
qgnutls_certificate_free_credentials(cred);
|
||||
}
|
||||
else
|
||||
Con_Printf("Unable to init gnutls\n");
|
||||
memcpy(signdata, sign.data, sign.size);
|
||||
return sign.size;
|
||||
}
|
||||
|
||||
//windows equivelent https://docs.microsoft.com/en-us/windows/win32/seccrypto/example-c-program-signing-a-hash-and-verifying-the-hash-signature
|
||||
enum hashvalidation_e GNUTLS_VerifyHash(qbyte *hashdata, size_t hashsize, const char *authority, qbyte *signdata, size_t signsize)
|
||||
{
|
||||
gnutls_datum_t hash = {hashdata, hashsize};
|
||||
gnutls_datum_t sign = {signdata, signsize};
|
||||
int r;
|
||||
|
||||
gnutls_datum_t rawcert;
|
||||
#if 1
|
||||
size_t sz;
|
||||
gnutls_pubkey_t pubkey;
|
||||
gnutls_x509_crt_t cert;
|
||||
|
||||
rawcert.data = Auth_GetKnownCertificate(authority, &sz);
|
||||
if (!rawcert.data)
|
||||
return VH_AUTHORITY_UNKNOWN;
|
||||
if (!Init_GNUTLS())
|
||||
return VH_UNSUPPORTED;
|
||||
rawcert.size = sz;
|
||||
|
||||
qgnutls_pubkey_init(&pubkey);
|
||||
qgnutls_x509_crt_init(&cert);
|
||||
qgnutls_x509_crt_import(cert, &rawcert, GNUTLS_X509_FMT_PEM);
|
||||
|
||||
qgnutls_pubkey_import_x509(pubkey, cert, 0);
|
||||
#else
|
||||
qgnutls_pubkey_import(pubkey, rawcert, GNUTLS_X509_FMT_PEM);
|
||||
#endif
|
||||
|
||||
r = qgnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA512, 0, &hash, &sign);
|
||||
if (r < 0)
|
||||
{
|
||||
if (r == GNUTLS_E_PK_SIG_VERIFY_FAILED)
|
||||
{
|
||||
Con_Printf("GNUTLS_VerifyHash: GNUTLS_E_PK_SIG_VERIFY_FAILED!\n");
|
||||
return VH_INCORRECT;
|
||||
}
|
||||
else if (r == GNUTLS_E_INSUFFICIENT_SECURITY)
|
||||
{
|
||||
Con_Printf("GNUTLS_VerifyHash: GNUTLS_E_INSUFFICIENT_SECURITY\n");
|
||||
return VH_AUTHORITY_UNKNOWN; //should probably be incorrect or something, but oh well
|
||||
}
|
||||
return VH_INCORRECT;
|
||||
}
|
||||
else
|
||||
return VH_CORRECT;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DTLS
|
||||
|
||||
|
|
|
@ -1290,4 +1290,78 @@ const dtlsfuncs_t *SSPI_DTLS_InitClient(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#include <ntstatus.h>
|
||||
enum hashvalidation_e SSPI_VerifyHash(qbyte *hashdata, size_t hashsize, const char *authority, qbyte *signdata, size_t signsize)
|
||||
{
|
||||
NTSTATUS status;
|
||||
BCRYPT_KEY_HANDLE pubkey;
|
||||
size_t sz;
|
||||
const char *pem = Auth_GetKnownCertificate(authority, &sz);
|
||||
const char *pemend;
|
||||
qbyte *der;
|
||||
size_t dersize;
|
||||
|
||||
static const void *(WINAPI *pCertCreateContext) (DWORD dwContextType, DWORD dwEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCERT_CREATE_CONTEXT_PARA pCreatePara);
|
||||
static WINBOOL (WINAPI *pCryptImportPublicKeyInfoEx2) (DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, DWORD dwFlags, void *pvAuxInfo, BCRYPT_KEY_HANDLE *phKey);
|
||||
static WINBOOL (WINAPI *pCertFreeCertificateContext) (PCCERT_CONTEXT pCertContext);
|
||||
static dllhandle_t *crypt32;
|
||||
static dllfunction_t crypt32funcs[] = {
|
||||
{(void**)&pCertCreateContext, "CertCreateContext"},
|
||||
{(void**)&pCryptImportPublicKeyInfoEx2, "CryptImportPublicKeyInfoEx2"}, //WARNING: fails on wine.
|
||||
{(void**)&pCertFreeCertificateContext, "CertFreeCertificateContext"},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
static NTSTATUS (WINAPI *pBCryptVerifySignature) (BCRYPT_KEY_HANDLE hKey, VOID *pPaddingInfo, PUCHAR pbHash, ULONG cbHash, PUCHAR pbSignature, ULONG cbSignature, ULONG dwFlags);
|
||||
static NTSTATUS (WINAPI *pBCryptDestroyKey) (BCRYPT_KEY_HANDLE hKey);
|
||||
static dllhandle_t *bcrypt;
|
||||
static dllfunction_t bcryptfuncs[] = {
|
||||
{(void**)&pBCryptVerifySignature, "BCryptVerifySignature"},
|
||||
{(void**)&pBCryptDestroyKey, "BCryptDestroyKey"},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
if (!crypt32)
|
||||
crypt32 = Sys_LoadLibrary("crypt32.dll", crypt32funcs);
|
||||
if (!bcrypt)
|
||||
bcrypt = Sys_LoadLibrary("bcrypt.dll", bcryptfuncs);
|
||||
if (!crypt32 || !bcrypt)
|
||||
{
|
||||
Con_Printf("Unable to obtain required crypto functions\n");
|
||||
return VH_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (!pem)
|
||||
return VH_AUTHORITY_UNKNOWN; //no public cert/key for authority.
|
||||
pem = strstr(pem, "-----BEGIN CERTIFICATE-----");
|
||||
if (!pem)
|
||||
return VH_UNSUPPORTED; //not a pem
|
||||
pem += strlen("-----BEGIN CERTIFICATE-----");
|
||||
pemend = strstr(pem, "-----END CERTIFICATE-----");
|
||||
if (!pemend)
|
||||
return VH_UNSUPPORTED;
|
||||
dersize = Base64_DecodeBlock(pem, pemend, NULL, 0); //guess
|
||||
der = alloca(dersize);
|
||||
dersize = Base64_DecodeBlock(pem, pemend, der, dersize);
|
||||
//okay, now its in binary der format.
|
||||
|
||||
//make sense of the cert and pull out its public key...
|
||||
{
|
||||
const CERT_CONTEXT* cert = pCertCreateContext(CERT_STORE_CERTIFICATE_CONTEXT, X509_ASN_ENCODING, der, dersize, 0, NULL);
|
||||
if (!pCryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, &cert->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &pubkey))
|
||||
return VH_UNSUPPORTED;
|
||||
pCertFreeCertificateContext(cert);
|
||||
}
|
||||
|
||||
//yay, now we can do what we actually wanted in the first place.
|
||||
status = pBCryptVerifySignature(pubkey, NULL, hashdata, hashsize, signdata, signsize, 0);
|
||||
pBCryptDestroyKey(pubkey);
|
||||
if (status == STATUS_SUCCESS)
|
||||
return VH_CORRECT; //its okay
|
||||
else if (status == STATUS_INVALID_SIGNATURE)
|
||||
return VH_INCORRECT; //its bad
|
||||
return VH_UNSUPPORTED; //some weird transient error...?
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2178,6 +2178,49 @@ qboolean NET_IsLoopBackAddress (netadr_t *adr)
|
|||
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
void *Auth_GetKnownCertificate(const char *certname, size_t *size)
|
||||
{ //our 'code signing' certs
|
||||
//we only allow packages to be installed into the root dir (or with dll/so/exe extensions) when their signature is signed by one of these certificates
|
||||
static struct
|
||||
{
|
||||
const char *name;
|
||||
qbyte *cert;
|
||||
} certs[] =
|
||||
{ //the contents of a -pubcert FILE
|
||||
{"Spike", "-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDnTCCAgUCCjE1ODQ4ODg2OTEwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAxMF\n"
|
||||
"U3Bpa2UwHhcNMjAwMzIyMTQ1MTMwWhcNMzAwMzIwMTQ1MTMxWjAQMQ4wDAYDVQQD\n"
|
||||
"EwVTcGlrZTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAN07KHTPc0Pn\n"
|
||||
"lC8MlQNiI+OEUEJBakTjfNq+IJzJ6oTWXxfQbHrN+UpKXwxploDbeyxTE1Fniisi\n"
|
||||
"nLWhOkW/XQqyXLXAv/3lxiSwe4QcVMOhQlw5U05VrdB7xHvFMShLsyc12sNvBiIa\n"
|
||||
"Vw05wFJgIXYTd9nJfm9x3kpxRoTJBvdDbYl8OagT6SxzJfHkdmfI2TYVYxGUH9nX\n"
|
||||
"R9zvwXTIXvV47cko2ON8scH9QQ6KgwMfcwyIBL74Btvl4ye+TrL2srj38FBxyyPG\n"
|
||||
"SSdKPk4LN2zsfNsJm31hzWrdLEkl3CTOX5gHHSweOKpuPwmX/GPd1xo0nIMwDou4\n"
|
||||
"BsMMBAhK/JSyLpUUzk5gbRmy4PwFccktHdFW6LF8ZvPY7e7LEiD5KOWZ7a7c1WR/\n"
|
||||
"4oJrjo0t+7OugVADolxzLXFrq9ACBGrD8r6QlsGC8O7WqpKGQCT+4q3tUup9tPkh\n"
|
||||
"3dhjC0jEkKljS+39uukbisV702bHwoEZPzjMpz4O9bHf6JbIJLlQzQIDAQABMA0G\n"
|
||||
"CSqGSIb3DQEBCwUAA4IBgQC5rj7R7a9LLnqgiXMUITGnygK1lp0EV2BdnIrg/MHr\n"
|
||||
"y+Gk9BA+XgFSI4W9odiG/hJnA7aQ0S2kk1GNYQ+NNzU2bQIMkaobaZApV9ojD4lL\n"
|
||||
"s33Qbgt/Ocpadtpj8EiMInjLkn1B+wnqcX3S76Zcrf8RT4WP2A4klxcN3zBNBiBL\n"
|
||||
"DAJ3SrH8hZ9wmruwAY5tMZhQzDHkeK8uaDb7nE0HA5GXeT4QYA/L7Ys2nGYgxj1O\n"
|
||||
"L5YlGddBcX3O6XyJpSeCO2Z2kwl4qg8oiM+Y546lILotuL5qD/+FTDeX3dGd8nyD\n"
|
||||
"e1g/7xd0V4IyKUjii8Vu2V1F7t0xVTPWEe13TqU/JTfKX4zvQnMF7zxgGFIwabHX\n"
|
||||
"lzk2olte4rPp+iQzPmnynLiUrdkxGXLnE0V545VO+iGO8+bwclbJ+7SG6N5l8xox\n"
|
||||
"WjGunhXXkEjitAk+ssBjbEh8kIfpFdVA09v60rMdm7BdfO3//QOsjwiwKkBOXcYW\n"
|
||||
"QGE0Ue4J7anLVAKiQq4n1aU=\n"
|
||||
"-----END CERTIFICATE-----\n"},
|
||||
};
|
||||
size_t i;
|
||||
for (i = 0; i < countof(certs); i++)
|
||||
{
|
||||
if (!strcmp(certname, certs[i].name))
|
||||
{
|
||||
*size = strlen(certs[i].cert);
|
||||
return certs[i].cert;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void *TLS_GetKnownCertificate(const char *certname, size_t *size)
|
||||
{
|
||||
//Note: This is XORed because of shitty scanners flagging binaries through false positive, flagging the sites that they were downloaded from, flagging binaries that contain references to those sites, and flagging any site that contains binaries.
|
||||
|
@ -4851,7 +4894,7 @@ qboolean FTENET_TCP_ParseHTTPRequest(ftenet_tcp_connection_t *con, ftenet_tcp_st
|
|||
char *protoname = "";
|
||||
|
||||
blurgh = va("%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", arg[WCATTR_WSKEY]);
|
||||
tobase64(acceptkey, sizeof(acceptkey), sha1digest, SHA1(sha1digest, sizeof(sha1digest), blurgh, strlen(blurgh)));
|
||||
tobase64(acceptkey, sizeof(acceptkey), sha1digest, CalcHash(&hash_sha1, sha1digest, sizeof(sha1digest), blurgh, strlen(blurgh)));
|
||||
|
||||
if (st->remoteaddr.prot == NP_TLS)
|
||||
st->remoteaddr.prot = NP_WSS;
|
||||
|
@ -8114,12 +8157,14 @@ qboolean NET_Sleep(float seconds, qboolean stdinissocket)
|
|||
FD_ZERO(&readfdset);
|
||||
FD_ZERO(&writefdset);
|
||||
|
||||
#ifndef _WIN32
|
||||
if (stdinissocket)
|
||||
{
|
||||
sock = STDIN_FILENO; //stdin tends to be socket/filehandle 0 in unix
|
||||
FD_SET(sock, &readfdset);
|
||||
maxfd = sock;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SV_MASTER
|
||||
{
|
||||
|
@ -8185,8 +8230,10 @@ qboolean NET_Sleep(float seconds, qboolean stdinissocket)
|
|||
select(maxfd+1, &readfdset, &writefdset, NULL, &timeout);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
if (stdinissocket)
|
||||
return FD_ISSET(STDIN_FILENO, &readfdset);
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -337,6 +337,13 @@ typedef struct ftenet_generic_connection_s {
|
|||
#endif
|
||||
} ftenet_generic_connection_t;
|
||||
|
||||
enum hashvalidation_e
|
||||
{
|
||||
VH_UNSUPPORTED, //library not loaded (bad but not malicious)
|
||||
VH_AUTHORITY_UNKNOWN, //don't know who signed it / untrusted (bad but probably not malicious)
|
||||
VH_INCORRECT, //signature is wrong for that authority (bad, probably maliciously so)
|
||||
VH_CORRECT //all is well.
|
||||
};
|
||||
#ifdef HAVE_DTLS
|
||||
typedef struct dtlsfuncs_s
|
||||
{
|
||||
|
@ -355,18 +362,22 @@ const dtlsfuncs_t *DTLS_InitClient(void);
|
|||
int SSPI_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize);
|
||||
const dtlsfuncs_t *SSPI_DTLS_InitServer(void); //returns NULL if there's no cert available.
|
||||
const dtlsfuncs_t *SSPI_DTLS_InitClient(void); //should always return something, if implemented.
|
||||
enum hashvalidation_e SSPI_VerifyHash(qbyte *hashdata, size_t hashsize, const char *authority, qbyte *signdata, size_t signsize);
|
||||
#endif
|
||||
#ifdef HAVE_GNUTLS
|
||||
vfsfile_t *GNUTLS_OpenVFS(const char *hostname, vfsfile_t *source, qboolean isserver);
|
||||
int GNUTLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize);
|
||||
const dtlsfuncs_t *GNUDTLS_InitServer(void); //returns NULL if there's no cert available.
|
||||
const dtlsfuncs_t *GNUDTLS_InitClient(void); //should always return something, if implemented.
|
||||
enum hashvalidation_e GNUTLS_VerifyHash(qbyte *hashdata, size_t hashsize, const char *authority, qbyte *signdata, size_t signsize);
|
||||
int GNUTLS_GenerateSignature(qbyte *hashdata, size_t hashsize, qbyte *signdata, size_t signsizemax);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
vfsfile_t *OSSL_OpenVFS(const char *hostname, vfsfile_t *source, qboolean isserver);
|
||||
int OSSL_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize);
|
||||
const dtlsfuncs_t *OSSL_InitServer(void); //returns NULL if there's no cert available.
|
||||
const dtlsfuncs_t *OSSL_InitClient(void); //should always return something, if implemented.
|
||||
enum hashvalidation_e OSSL_VerifyHash(qbyte *hashdata, size_t hashsize, const char *authority, qbyte *signdata, size_t signsize);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -436,6 +447,7 @@ qboolean FTENET_AddToCollection(struct ftenet_connections_s *col, const char *na
|
|||
int NET_EnumerateAddresses(ftenet_connections_t *collection, struct ftenet_generic_connection_s **con, unsigned int *adrflags, netadr_t *addresses, const char **adrparams, int maxaddresses);
|
||||
|
||||
void *TLS_GetKnownCertificate(const char *certname, size_t *size);
|
||||
void *Auth_GetKnownCertificate(const char *certname, size_t *size);
|
||||
vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server);
|
||||
int TLS_GetChannelBinding(vfsfile_t *stream, qbyte *data, size_t *datasize); //datasize should be preinitialised to the max length allowed. -1 for not implemented. 0 for peer problems. 1 for success
|
||||
#ifdef HAVE_PACKET
|
||||
|
|
|
@ -4649,15 +4649,15 @@ static void QCBUILTIN PF_digest_internal (pubprogfuncs_t *prinst, struct globalv
|
|||
}
|
||||
//md5?
|
||||
else if (!strcmp(hashtype, "SHA1"))
|
||||
{
|
||||
digestsize = SHA1(digest, sizeof(digest), str, len);
|
||||
}
|
||||
// else if (!strcmp(hashtype, "SHA256"))
|
||||
// {
|
||||
// digestsize = SHA2(digest, sizeof(digest), str, len);
|
||||
// }
|
||||
//sha384
|
||||
//sha512
|
||||
digestsize = CalcHash(&hash_sha1, digest, sizeof(digest), str, len);
|
||||
else if (!strcmp(hashtype, "SHA224"))
|
||||
digestsize = CalcHash(&hash_sha224, digest, sizeof(digest), str, len);
|
||||
else if (!strcmp(hashtype, "SHA256"))
|
||||
digestsize = CalcHash(&hash_sha256, digest, sizeof(digest), str, len);
|
||||
else if (!strcmp(hashtype, "SHA384"))
|
||||
digestsize = CalcHash(&hash_sha384, digest, sizeof(digest), str, len);
|
||||
else if (!strcmp(hashtype, "SHA512"))
|
||||
digestsize = CalcHash(&hash_sha512, digest, sizeof(digest), str, len);
|
||||
else if (!strcmp(hashtype, "CRC16"))
|
||||
{
|
||||
digestsize = 2;
|
||||
|
|
|
@ -1727,7 +1727,7 @@ Rendering functions (Client only)
|
|||
extern int r_dlightframecount;
|
||||
|
||||
//goes through the nodes marking the surfaces near the dynamic light as lit.
|
||||
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
||||
void Q1BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
|
|
|
@ -14,11 +14,20 @@ A million repetitions of "a"
|
|||
This file came to FTE via EzQuake.
|
||||
*/
|
||||
|
||||
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||
#define SHA1HANDSOFF
|
||||
#include "quakedef.h"
|
||||
#include <string.h>
|
||||
|
||||
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||
#define SHA1HANDSOFF
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int state[5];
|
||||
size_t count[2];
|
||||
unsigned char buffer[64];
|
||||
} SHA1_CTX;
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
#define BigLong(l) (((unsigned char*)&l)[0]<<24) | (((unsigned char*)&l)[1]<<16) | (((unsigned char*)&l)[2]<<8) | (((unsigned char*)&l)[3]<<0)
|
||||
|
||||
|
||||
|
@ -36,23 +45,9 @@ This file came to FTE via EzQuake.
|
|||
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
||||
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int state[5];
|
||||
size_t count[2];
|
||||
unsigned char buffer[64];
|
||||
} SHA1_CTX;
|
||||
|
||||
#define DIGEST_SIZE 20
|
||||
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]);
|
||||
void SHA1Init(SHA1_CTX* context);
|
||||
void SHA1Update(SHA1_CTX* context, const unsigned char* data, size_t len);
|
||||
void SHA1Final(unsigned char digest[DIGEST_SIZE], SHA1_CTX* context);
|
||||
|
||||
|
||||
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||
|
||||
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
|
||||
static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
|
||||
{
|
||||
unsigned int a, b, c, d, e;
|
||||
typedef union
|
||||
|
@ -108,8 +103,9 @@ void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
|
|||
|
||||
/* SHA1Init - Initialize new context */
|
||||
|
||||
void SHA1Init(SHA1_CTX* context)
|
||||
static void SHA1Init(void *ctx)
|
||||
{
|
||||
SHA1_CTX *context = ctx;
|
||||
/* SHA1 initialization constants */
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xEFCDAB89;
|
||||
|
@ -122,8 +118,9 @@ void SHA1Init(SHA1_CTX* context)
|
|||
|
||||
/* Run your data through this. */
|
||||
|
||||
void SHA1Update(SHA1_CTX* context, const unsigned char* data, size_t len)
|
||||
static void SHA1Update(void *ctx, const void* data, size_t len)
|
||||
{
|
||||
SHA1_CTX *context = ctx;
|
||||
size_t i, j;
|
||||
|
||||
j = (context->count[0] >> 3) & 63;
|
||||
|
@ -135,20 +132,21 @@ void SHA1Update(SHA1_CTX* context, const unsigned char* data, size_t len)
|
|||
SHA1Transform(context->state, context->buffer);
|
||||
for ( ; i + 63 < len; i += 64)
|
||||
{
|
||||
SHA1Transform(context->state, &data[i]);
|
||||
SHA1Transform(context->state, (const qbyte*)data + i);
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
memcpy(&context->buffer[j], &data[i], len - i);
|
||||
memcpy(&context->buffer[j], (const qbyte*)data + i, len - i);
|
||||
}
|
||||
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
|
||||
void SHA1Final(unsigned char digest[DIGEST_SIZE], SHA1_CTX* context)
|
||||
static void SHA1Final(unsigned char digest[SHA1_DIGEST_SIZE], void *ctx)
|
||||
{
|
||||
SHA1_CTX *context = ctx;
|
||||
unsigned int i, j;
|
||||
unsigned char finalcount[8];
|
||||
|
||||
|
@ -162,7 +160,7 @@ void SHA1Final(unsigned char digest[DIGEST_SIZE], SHA1_CTX* context)
|
|||
SHA1Update(context, (unsigned char *)"\0", 1);
|
||||
}
|
||||
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
|
||||
for (i = 0; i < DIGEST_SIZE; i++)
|
||||
for (i = 0; i < SHA1_DIGEST_SIZE; i++)
|
||||
{
|
||||
digest[i] = (unsigned char)
|
||||
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
||||
|
@ -178,33 +176,26 @@ memset(&finalcount, 0, 8);
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
size_t SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen)
|
||||
hashfunc_t hash_sha1 =
|
||||
{
|
||||
SHA1_CTX context;
|
||||
if (maxdigestsize < DIGEST_SIZE)
|
||||
return 0;
|
||||
SHA1_DIGEST_SIZE,
|
||||
sizeof(SHA1_CTX),
|
||||
SHA1Init,
|
||||
SHA1Update,
|
||||
SHA1Final,
|
||||
};
|
||||
|
||||
SHA1Init(&context);
|
||||
SHA1Update(&context, (unsigned char*) string, stringlen);
|
||||
SHA1Final(digest, &context);
|
||||
|
||||
return DIGEST_SIZE;
|
||||
}
|
||||
|
||||
size_t SHA1_m(unsigned char *digest, size_t maxdigestsize, size_t numstrings, const unsigned char **strings, size_t *stringlens)
|
||||
size_t CalcHash(hashfunc_t *func, unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen)
|
||||
{
|
||||
size_t i;
|
||||
SHA1_CTX context;
|
||||
if (maxdigestsize < DIGEST_SIZE)
|
||||
return 0;
|
||||
|
||||
SHA1Init(&context);
|
||||
for (i = 0; i < numstrings; i++)
|
||||
SHA1Update(&context, (unsigned char*) strings[i], stringlens[i]);
|
||||
SHA1Final(digest, &context);
|
||||
|
||||
return DIGEST_SIZE;
|
||||
void *ctx = alloca(func->contextsize);
|
||||
if (maxdigestsize < func->digestsize)
|
||||
return 0; //panic
|
||||
func->init(ctx);
|
||||
func->process(ctx, string, stringlen);
|
||||
func->terminate(digest, ctx);
|
||||
return func->digestsize;
|
||||
}
|
||||
|
||||
/* hmac-sha1.c -- hashed message authentication codes
|
||||
|
@ -245,18 +236,23 @@ size_t HMAC(hashfunc_t *hashfunc, unsigned char *digest, size_t maxdigestsize,
|
|||
const unsigned char *data, size_t datalen,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
#define HMAC_DIGEST_MAXSIZE 20
|
||||
char optkeybuf[HMAC_DIGEST_MAXSIZE];
|
||||
char innerhash[HMAC_DIGEST_MAXSIZE];
|
||||
#define HMAC_DIGEST_MAXSIZE 64
|
||||
qbyte optkeybuf[HMAC_DIGEST_MAXSIZE];
|
||||
qbyte innerhash[HMAC_DIGEST_MAXSIZE];
|
||||
|
||||
char block[64];
|
||||
size_t innerhashsize;
|
||||
qbyte block[64];
|
||||
|
||||
if (hashfunc->digestsize > HMAC_DIGEST_MAXSIZE || hashfunc->digestsize > maxdigestsize)
|
||||
return 0;
|
||||
|
||||
/* Reduce the key's size, so that it is never larger than a block. */
|
||||
|
||||
if (keylen > sizeof(block))
|
||||
{
|
||||
keylen = hashfunc(optkeybuf, sizeof(optkeybuf), 1, &key, &keylen);
|
||||
qbyte *ctx = alloca(hashfunc->contextsize);
|
||||
hashfunc->init(ctx);
|
||||
hashfunc->process(ctx, key, keylen);
|
||||
hashfunc->terminate(optkeybuf, ctx);
|
||||
key=optkeybuf;
|
||||
}
|
||||
|
||||
|
@ -266,9 +262,11 @@ size_t HMAC(hashfunc_t *hashfunc, unsigned char *digest, size_t maxdigestsize,
|
|||
memxor (block, key, keylen);
|
||||
|
||||
{
|
||||
const unsigned char *strings_i[2] = {block, data};
|
||||
size_t stringlens_i[2] = {sizeof(block), datalen};
|
||||
innerhashsize = hashfunc(innerhash, sizeof(innerhash), 2, strings_i, stringlens_i);
|
||||
qbyte *ctx = alloca(hashfunc->contextsize);
|
||||
hashfunc->init(ctx);
|
||||
hashfunc->process(ctx, block, sizeof(block));
|
||||
hashfunc->process(ctx, data, datalen);
|
||||
hashfunc->terminate(innerhash, ctx);
|
||||
}
|
||||
|
||||
/* Compute result from KEY and INNERHASH. */
|
||||
|
@ -277,8 +275,11 @@ size_t HMAC(hashfunc_t *hashfunc, unsigned char *digest, size_t maxdigestsize,
|
|||
memxor (block, key, keylen);
|
||||
|
||||
{
|
||||
const unsigned char *strings_o[2] = {block, innerhash};
|
||||
size_t stringlens_o[2] = {sizeof(block), innerhashsize};
|
||||
return hashfunc(digest, maxdigestsize, 2, strings_o, stringlens_o);
|
||||
qbyte *ctx = alloca(hashfunc->contextsize);
|
||||
hashfunc->init(ctx);
|
||||
hashfunc->process(ctx, block, sizeof(block));
|
||||
hashfunc->process(ctx, innerhash, hashfunc->digestsize);
|
||||
hashfunc->terminate(digest, ctx);
|
||||
return hashfunc->digestsize;
|
||||
}
|
||||
}
|
||||
|
|
563
engine/common/sha2.c
Normal file
563
engine/common/sha2.c
Normal file
|
@ -0,0 +1,563 @@
|
|||
/* sha512.c - SHA384 and SHA512 hash functions
|
||||
* Copyright (C) 2003, 2008, 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser general Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/* Test vectors from FIPS-180-2:
|
||||
*
|
||||
* "abc"
|
||||
* 384:
|
||||
* CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163
|
||||
* 1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7
|
||||
* 512:
|
||||
* DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
|
||||
* 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
|
||||
*
|
||||
* "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
* 384:
|
||||
* 09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2
|
||||
* 2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039
|
||||
* 512:
|
||||
* 8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018
|
||||
* 501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909
|
||||
*
|
||||
* "a" x 1000000
|
||||
* 384:
|
||||
* 9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852
|
||||
* 7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985
|
||||
* 512:
|
||||
* E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB
|
||||
* DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B
|
||||
*/
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
#ifndef SHA2
|
||||
#define SHA2 256
|
||||
#include "sha2.c"
|
||||
#undef SHA2
|
||||
#define SHA2 512
|
||||
#endif
|
||||
|
||||
#undef U64_C
|
||||
#undef U64_C_LOW
|
||||
#undef u64
|
||||
#undef ROUNDS
|
||||
#undef SHA2_CONTEXT
|
||||
#undef sha2trunc_init
|
||||
#undef sha2_init
|
||||
#if SHA2==256
|
||||
#define U64_C(n) (n##ull>>32)
|
||||
#define U64_C_LOW(n) (u64)U64_C(n)
|
||||
#define u64 quint32_t
|
||||
#define ROUNDS 64
|
||||
#define SHA2_CONTEXT SHA256_CONTEXT
|
||||
#define sha2trunc_init sha224_init
|
||||
#define sha2_init sha256_init
|
||||
#else
|
||||
#define U64_C(n) n##ull
|
||||
#define U64_C_LOW(n) n##ull
|
||||
#define u64 quint64_t
|
||||
#define ROUNDS 80
|
||||
#define SHA2_CONTEXT SHA512_CONTEXT
|
||||
#define ROTR ROTR64
|
||||
#define Ch Ch64
|
||||
#define Maj Maj64
|
||||
#define Sum0 Sum0_64
|
||||
#define Sum1 Sum1_64
|
||||
#define transform transform_64
|
||||
#define sha2trunc_init sha384_init
|
||||
#define sha2_init sha512_init
|
||||
#define sha2_write sha512_write
|
||||
#define sha2_final sha512_final
|
||||
#endif
|
||||
#define BLOCKBYTES (16*sizeof(u64))
|
||||
#define byte qbyte
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 h0, h1, h2, h3, h4, h5, h6, h7;
|
||||
u64 nblocks;
|
||||
byte buf[BLOCKBYTES];
|
||||
int count;
|
||||
} SHA2_CONTEXT;
|
||||
|
||||
static void
|
||||
sha2_init (void *context)
|
||||
{
|
||||
SHA2_CONTEXT *hd = context;
|
||||
|
||||
hd->h0 = U64_C(0x6a09e667f3bcc908);
|
||||
hd->h1 = U64_C(0xbb67ae8584caa73b);
|
||||
hd->h2 = U64_C(0x3c6ef372fe94f82b);
|
||||
hd->h3 = U64_C(0xa54ff53a5f1d36f1);
|
||||
hd->h4 = U64_C(0x510e527fade682d1);
|
||||
hd->h5 = U64_C(0x9b05688c2b3e6c1f);
|
||||
hd->h6 = U64_C(0x1f83d9abfb41bd6b);
|
||||
hd->h7 = U64_C(0x5be0cd19137e2179);
|
||||
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
static void sha2trunc_init (void *context)
|
||||
{
|
||||
SHA2_CONTEXT *hd = context;
|
||||
|
||||
//sha224 uses only the low parts.
|
||||
hd->h0 = U64_C_LOW(0xcbbb9d5dc1059ed8);
|
||||
hd->h1 = U64_C_LOW(0x629a292a367cd507);
|
||||
hd->h2 = U64_C_LOW(0x9159015a3070dd17);
|
||||
hd->h3 = U64_C_LOW(0x152fecd8f70e5939);
|
||||
hd->h4 = U64_C_LOW(0x67332667ffc00b31);
|
||||
hd->h5 = U64_C_LOW(0x8eb44a8768581511);
|
||||
hd->h6 = U64_C_LOW(0xdb0c2e0d64f98fa7);
|
||||
hd->h7 = U64_C_LOW(0x47b5481dbefa4fa4);
|
||||
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
static inline u64
|
||||
ROTR (u64 x, u64 n)
|
||||
{
|
||||
return ((x >> n) | (x << (64 - n)));
|
||||
}
|
||||
|
||||
static inline u64
|
||||
Ch (u64 x, u64 y, u64 z)
|
||||
{
|
||||
return ((x & y) ^ ( ~x & z));
|
||||
}
|
||||
|
||||
static inline u64
|
||||
Maj (u64 x, u64 y, u64 z)
|
||||
{
|
||||
return ((x & y) ^ (x & z) ^ (y & z));
|
||||
}
|
||||
|
||||
#undef S0
|
||||
#undef S1
|
||||
#if SHA2==256
|
||||
#define S0(x) (ROTR((x),7) ^ ROTR((x),18) ^ ((x)>>3))
|
||||
#define S1(x) (ROTR((x),17) ^ ROTR((x),19) ^ ((x)>>10))
|
||||
|
||||
static inline u64
|
||||
Sum0 (u64 x)
|
||||
{
|
||||
return (ROTR (x, 2) ^ ROTR (x, 13) ^ ROTR (x, 22));
|
||||
}
|
||||
|
||||
static inline u64
|
||||
Sum1 (u64 x)
|
||||
{
|
||||
return (ROTR (x, 6) ^ ROTR (x, 11) ^ ROTR (x, 25));
|
||||
}
|
||||
#else
|
||||
#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
|
||||
#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
|
||||
|
||||
static inline u64
|
||||
Sum0 (u64 x)
|
||||
{
|
||||
return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39));
|
||||
}
|
||||
|
||||
static inline u64
|
||||
Sum1 (u64 x)
|
||||
{
|
||||
return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************
|
||||
* Transform the message W which consists of 16 64-bit-words
|
||||
*/
|
||||
static void
|
||||
transform (SHA2_CONTEXT *hd, const unsigned char *data)
|
||||
{
|
||||
u64 a, b, c, d, e, f, g, h;
|
||||
u64 w[ROUNDS];
|
||||
int t;
|
||||
static const u64 k[] =
|
||||
{
|
||||
U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
|
||||
U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
|
||||
U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
|
||||
U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
|
||||
U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
|
||||
U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
|
||||
U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
|
||||
U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
|
||||
U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
|
||||
U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
|
||||
U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
|
||||
U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
|
||||
U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
|
||||
U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
|
||||
U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
|
||||
U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
|
||||
U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
|
||||
U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
|
||||
U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
|
||||
U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
|
||||
U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
|
||||
U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
|
||||
U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
|
||||
U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
|
||||
U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
|
||||
U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
|
||||
U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
|
||||
U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
|
||||
U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
|
||||
U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
|
||||
U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
|
||||
U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
|
||||
U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
|
||||
U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
|
||||
U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
|
||||
U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
|
||||
U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
|
||||
U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
|
||||
U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
|
||||
U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* get values from the chaining vars */
|
||||
a = hd->h0;
|
||||
b = hd->h1;
|
||||
c = hd->h2;
|
||||
d = hd->h3;
|
||||
e = hd->h4;
|
||||
f = hd->h5;
|
||||
g = hd->h6;
|
||||
h = hd->h7;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
memcpy (w, data, BLOCKBYTES);
|
||||
#else
|
||||
{
|
||||
int i;
|
||||
byte *p2;
|
||||
|
||||
for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += sizeof(*w))
|
||||
{
|
||||
#if SHA2==512
|
||||
p2[7] = *data++;
|
||||
p2[6] = *data++;
|
||||
p2[5] = *data++;
|
||||
p2[4] = *data++;
|
||||
#endif
|
||||
p2[3] = *data++;
|
||||
p2[2] = *data++;
|
||||
p2[1] = *data++;
|
||||
p2[0] = *data++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (t = 16; t < ROUNDS; t++)
|
||||
w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
|
||||
|
||||
|
||||
for (t = 0; t < ROUNDS; )
|
||||
{
|
||||
u64 t1, t2;
|
||||
|
||||
/* Performance on a AMD Athlon(tm) Dual Core Processor 4050e
|
||||
with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes
|
||||
initialized to 0,1,2,3...255,0,... and 1000 iterations:
|
||||
Not unrolled with macros: 440ms
|
||||
Unrolled with macros: 350ms
|
||||
Unrolled with inline: 330ms
|
||||
*/
|
||||
#if 0 /* Not unrolled. */
|
||||
t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
|
||||
t2 = Sum0 (a) + Maj (a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
#else /* Unrolled to interweave the chain variables. */
|
||||
t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
|
||||
t2 = Sum0 (a) + Maj (a, b, c);
|
||||
d += t1;
|
||||
h = t1 + t2;
|
||||
|
||||
t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[t+1];
|
||||
t2 = Sum0 (h) + Maj (h, a, b);
|
||||
c += t1;
|
||||
g = t1 + t2;
|
||||
|
||||
t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[t+2];
|
||||
t2 = Sum0 (g) + Maj (g, h, a);
|
||||
b += t1;
|
||||
f = t1 + t2;
|
||||
|
||||
t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[t+3];
|
||||
t2 = Sum0 (f) + Maj (f, g, h);
|
||||
a += t1;
|
||||
e = t1 + t2;
|
||||
|
||||
t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[t+4];
|
||||
t2 = Sum0 (e) + Maj (e, f, g);
|
||||
h += t1;
|
||||
d = t1 + t2;
|
||||
|
||||
t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[t+5];
|
||||
t2 = Sum0 (d) + Maj (d, e, f);
|
||||
g += t1;
|
||||
c = t1 + t2;
|
||||
|
||||
t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[t+6];
|
||||
t2 = Sum0 (c) + Maj (c, d, e);
|
||||
f += t1;
|
||||
b = t1 + t2;
|
||||
|
||||
t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[t+7];
|
||||
t2 = Sum0 (b) + Maj (b, c, d);
|
||||
e += t1;
|
||||
a = t1 + t2;
|
||||
|
||||
t += 8;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Update chaining vars. */
|
||||
hd->h0 += a;
|
||||
hd->h1 += b;
|
||||
hd->h2 += c;
|
||||
hd->h3 += d;
|
||||
hd->h4 += e;
|
||||
hd->h5 += f;
|
||||
hd->h6 += g;
|
||||
hd->h7 += h;
|
||||
}
|
||||
|
||||
|
||||
/* Update the message digest with the contents
|
||||
* of INBUF with length INLEN.
|
||||
*/
|
||||
static void
|
||||
sha2_write (void *context, const void *inbuf_arg, size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
SHA2_CONTEXT *hd = context;
|
||||
|
||||
if (hd->count == BLOCKBYTES)
|
||||
{ /* flush the buffer */
|
||||
transform (hd, hd->buf);
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if (!inbuf)
|
||||
return;
|
||||
if (hd->count)
|
||||
{
|
||||
for (; inlen && hd->count < BLOCKBYTES; inlen--)
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
sha2_write (context, NULL, 0);
|
||||
if (!inlen)
|
||||
return;
|
||||
}
|
||||
|
||||
while (inlen >= BLOCKBYTES)
|
||||
{
|
||||
transform (hd, inbuf);
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= BLOCKBYTES;
|
||||
inbuf += BLOCKBYTES;
|
||||
}
|
||||
for (; inlen && hd->count < BLOCKBYTES; inlen--)
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
|
||||
/* The routine final terminates the computation and
|
||||
* returns the digest.
|
||||
* The handle is prepared for a new cycle, but adding bytes to the
|
||||
* handle will the destroy the returned buffer.
|
||||
* Returns: 64 bytes representing the digest. When used for sha384,
|
||||
* we take the leftmost 48 of those bytes.
|
||||
*/
|
||||
|
||||
static void
|
||||
sha2_final (void *context)
|
||||
{
|
||||
SHA2_CONTEXT *hd = context;
|
||||
u64 t, msb, lsb;
|
||||
byte *p;
|
||||
|
||||
sha2_write (context, NULL, 0); /* flush */ ;
|
||||
|
||||
t = hd->nblocks;
|
||||
/* multiply by 128 to make a byte count */
|
||||
lsb = t * BLOCKBYTES;
|
||||
msb = t >> (sizeof(u64)*8-((BLOCKBYTES==128)?7:6));
|
||||
/* add the count */
|
||||
t = lsb;
|
||||
if ((lsb += hd->count) < t)
|
||||
msb++;
|
||||
/* multiply by 8 to make a bit count */
|
||||
t = lsb;
|
||||
lsb <<= 3;
|
||||
msb <<= 3;
|
||||
msb |= t >> (sizeof(u64)*8-3);
|
||||
|
||||
if (hd->count < BLOCKBYTES-sizeof(u64)*2)
|
||||
{ /* enough room */
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while (hd->count < BLOCKBYTES-sizeof(u64)*2)
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else
|
||||
{ /* need one extra block */
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while (hd->count < BLOCKBYTES)
|
||||
hd->buf[hd->count++] = 0;
|
||||
sha2_write (context, NULL, 0); /* flush */ ;
|
||||
memset (hd->buf, 0, BLOCKBYTES-sizeof(u64)*2); /* fill next block with zeroes */
|
||||
}
|
||||
|
||||
#if SHA2==256
|
||||
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
|
||||
*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while (0)
|
||||
|
||||
/* append the 128 bit count */
|
||||
hd->buf[56] = msb >> 24;
|
||||
hd->buf[57] = msb >> 16;
|
||||
hd->buf[58] = msb >> 8;
|
||||
hd->buf[59] = msb;
|
||||
|
||||
hd->buf[60] = lsb >> 24;
|
||||
hd->buf[61] = lsb >> 16;
|
||||
hd->buf[62] = lsb >> 8;
|
||||
hd->buf[63] = lsb;
|
||||
#else
|
||||
#define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48; \
|
||||
*p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32; \
|
||||
*p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
|
||||
*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while (0)
|
||||
|
||||
/* append the 128 bit count */
|
||||
hd->buf[112] = msb >> 56;
|
||||
hd->buf[113] = msb >> 48;
|
||||
hd->buf[114] = msb >> 40;
|
||||
hd->buf[115] = msb >> 32;
|
||||
hd->buf[116] = msb >> 24;
|
||||
hd->buf[117] = msb >> 16;
|
||||
hd->buf[118] = msb >> 8;
|
||||
hd->buf[119] = msb;
|
||||
|
||||
hd->buf[120] = lsb >> 56;
|
||||
hd->buf[121] = lsb >> 48;
|
||||
hd->buf[122] = lsb >> 40;
|
||||
hd->buf[123] = lsb >> 32;
|
||||
hd->buf[124] = lsb >> 24;
|
||||
hd->buf[125] = lsb >> 16;
|
||||
hd->buf[126] = lsb >> 8;
|
||||
hd->buf[127] = lsb;
|
||||
#endif
|
||||
transform (hd, hd->buf);
|
||||
|
||||
p = hd->buf;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#undef X
|
||||
#define X(a) do { *(u64*)p = hd->h##a ; p += sizeof(u64); } while (0)
|
||||
#endif
|
||||
X (0);
|
||||
X (1);
|
||||
X (2);
|
||||
X (3);
|
||||
X (4);
|
||||
X (5);
|
||||
/* Note that these last two chunks are included even for SHA384.
|
||||
We just ignore them. */
|
||||
X (6);
|
||||
X (7);
|
||||
#undef X
|
||||
}
|
||||
|
||||
#if SHA2==256
|
||||
static void sha224_finish (qbyte *digest, void *context)
|
||||
{
|
||||
SHA2_CONTEXT *hd = (SHA2_CONTEXT *) context;
|
||||
sha2_final(context);
|
||||
memcpy(digest, hd->buf, 224/8); //only the first 224 bits of the result...
|
||||
}
|
||||
static void sha256_finish (qbyte *digest, void *context)
|
||||
{
|
||||
SHA2_CONTEXT *hd = (SHA2_CONTEXT *) context;
|
||||
sha2_final(context);
|
||||
memcpy(digest, hd->buf, 256/8);
|
||||
}
|
||||
|
||||
hashfunc_t hash_sha224 =
|
||||
{
|
||||
224/8,
|
||||
sizeof(SHA2_CONTEXT),
|
||||
sha224_init,
|
||||
sha2_write,
|
||||
sha224_finish
|
||||
};
|
||||
hashfunc_t hash_sha256 =
|
||||
{
|
||||
256/8,
|
||||
sizeof(SHA2_CONTEXT),
|
||||
sha256_init,
|
||||
sha2_write,
|
||||
sha256_finish
|
||||
};
|
||||
#endif
|
||||
#if SHA2==512
|
||||
static void sha384_finish (qbyte *digest, void *context)
|
||||
{
|
||||
SHA2_CONTEXT *hd = (SHA2_CONTEXT *) context;
|
||||
sha2_final(context);
|
||||
memcpy(digest, hd->buf, 384/8);
|
||||
}
|
||||
|
||||
static void sha512_finish (qbyte *digest, void *context)
|
||||
{
|
||||
SHA2_CONTEXT *hd = (SHA2_CONTEXT *) context;
|
||||
sha2_final(context);
|
||||
memcpy(digest, hd->buf, 512/8);
|
||||
}
|
||||
|
||||
hashfunc_t hash_sha384 =
|
||||
{
|
||||
384/8,
|
||||
sizeof(SHA2_CONTEXT),
|
||||
sha384_init,
|
||||
sha2_write,
|
||||
sha384_finish
|
||||
};
|
||||
hashfunc_t hash_sha512 =
|
||||
{
|
||||
512/8,
|
||||
sizeof(SHA2_CONTEXT),
|
||||
sha512_init,
|
||||
sha2_write,
|
||||
sha512_finish
|
||||
};
|
||||
#endif
|
|
@ -182,17 +182,21 @@ void NPQTV_Sys_MainLoop(void);
|
|||
#define UPD_STABLE 1
|
||||
#define UPD_TESTING 2
|
||||
|
||||
#if defined(WEBCLIENT) && defined(_WIN32) && !defined(SERVERONLY) && !defined(_XBOX)
|
||||
int StartLocalServer(int close);
|
||||
#if defined(WEBCLIENT) && defined(PACKAGEMANAGER)
|
||||
#if defined(_WIN32) && !defined(SERVERONLY) && !defined(_XBOX)
|
||||
#define HAVEAUTOUPDATE
|
||||
#endif
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
#define HAVEAUTOUPDATE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define HAVEAUTOUPDATE
|
||||
qboolean Sys_SetUpdatedBinary(const char *fname); //legacy, so old build can still deal with updates properly
|
||||
qboolean Sys_EngineMayUpdate(void); //says whether the system code is able to invoke new binaries properly
|
||||
//qboolean Sys_EngineWasUpdated(char *newbinary); //invoke the given system-path binary
|
||||
#ifdef HAVEAUTOUPDATE
|
||||
qboolean Sys_SetUpdatedBinary(const char *fname); //attempts to overwrite the working binary.
|
||||
qboolean Sys_EngineMayUpdate(void); //says whether the system code is able/allowed to overwrite itself.
|
||||
#else
|
||||
#define Sys_EngineMayUpdate() false
|
||||
#define Sys_SetUpdatedBinary(n) false
|
||||
//#define Sys_EngineWasUpdated(n) false
|
||||
#endif
|
||||
|
||||
void Sys_Init (void);
|
||||
|
|
|
@ -546,3 +546,100 @@ void SSV_CheckFromMaster(void)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef HAVEAUTOUPDATE
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
qboolean Sys_SetUpdatedBinary(const char *newbinary)
|
||||
{
|
||||
char enginebinary[MAX_OSPATH];
|
||||
char tmpbinary[MAX_OSPATH];
|
||||
// char enginebinarybackup[MAX_OSPATH+4];
|
||||
// size_t len;
|
||||
int i;
|
||||
struct stat src, dst;
|
||||
|
||||
//windows is annoying. we can't delete a file that's in use (no orphaning)
|
||||
//we can normally rename it to something else before writing a new file with the original name.
|
||||
//then delete the old file later (sadly only on reboot)
|
||||
|
||||
//get the binary name
|
||||
i = readlink("/proc/self/exe", enginebinary, sizeof(enginebinary)-1);
|
||||
if (i <= 0)
|
||||
return false;
|
||||
enginebinary[i] = 0;
|
||||
|
||||
//generate the temp name
|
||||
/*memcpy(enginebinarybackup, enginebinary, sizeof(enginebinary));
|
||||
len = strlen(enginebinarybackup);
|
||||
if (len > 4 && !strcasecmp(enginebinarybackup+len-4, ".bin"))
|
||||
len -= 4; //swap its extension over, if we can.
|
||||
strcpy(enginebinarybackup+len, ".bak");*/
|
||||
|
||||
//copy over file permissions (don't ignore the user)
|
||||
if (stat(enginebinary, &dst)<0)
|
||||
dst.st_mode = 0777;
|
||||
if (stat(newbinary, &src)<0)
|
||||
src.st_mode = 0777;
|
||||
|
||||
// if (src.st_dev != dst.st_dev)
|
||||
{ //oops, its on a different filesystem. create a copy
|
||||
Q_snprintfz(tmpbinary, sizeof(tmpbinary), "%s.new", enginebinary);
|
||||
if (!FS_Copy(newbinary, tmpbinary, FS_SYSTEM, FS_SYSTEM))
|
||||
return false;
|
||||
newbinary = tmpbinary;
|
||||
}
|
||||
chmod(newbinary, dst.st_mode|S_IXUSR); //but make sure its executable, just in case...
|
||||
|
||||
//overwrite the name we were started through. this is supposed to be atomic.
|
||||
if (rename(newbinary, enginebinary) < 0)
|
||||
{
|
||||
Con_Printf("Failed to overwrite %s with %s\n", enginebinary, newbinary);
|
||||
return false; //failed
|
||||
}
|
||||
return true; //succeeded.
|
||||
}
|
||||
qboolean Sys_EngineMayUpdate(void)
|
||||
{
|
||||
char enginebinary[MAX_OSPATH];
|
||||
char *e;
|
||||
int len;
|
||||
|
||||
#define SVNREVISIONSTR STRINGIFY(SVNREVISION)
|
||||
if (!COM_CheckParm("-allowupdate"))
|
||||
{
|
||||
//no revision info in this build, meaning its custom built and thus cannot check against the available updated versions.
|
||||
if (!strcmp(SVNREVISIONSTR, "-"))
|
||||
return false;
|
||||
|
||||
//svn revision didn't parse as an exact number. this implies it has an 'M' in it to mark it as modified.
|
||||
//either way, its bad and autoupdates when we don't know what we're updating from is a bad idea.
|
||||
strtoul(SVNREVISIONSTR, &e, 10);
|
||||
if (!*SVNREVISIONSTR || *e)
|
||||
return false;
|
||||
}
|
||||
|
||||
//update blocked via commandline
|
||||
if (COM_CheckParm("-noupdate") || COM_CheckParm("--noupdate") || COM_CheckParm("-noautoupdate") || COM_CheckParm("--noautoupdate"))
|
||||
return false;
|
||||
|
||||
|
||||
//check that we can actually do it.
|
||||
len = readlink("/proc/self/exe", enginebinary, sizeof(enginebinary)-1);
|
||||
if (len <= 0)
|
||||
return false;
|
||||
enginebinary[len] = 0;
|
||||
if (access(enginebinary, R_OK|W_OK|X_OK) < 0)
|
||||
return false; //can't write it. don't try downloading updates.
|
||||
*COM_SkipPath(enginebinary) = 0;
|
||||
if (access(enginebinary, R_OK|W_OK) < 0)
|
||||
return false; //can't write to the containing directory. this does not bode well for moves/overwrites.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -93,6 +93,12 @@ Zone block
|
|||
void Memory_Init (void);
|
||||
void Memory_DeInit(void);
|
||||
|
||||
//Prefixes:
|
||||
//Z - just general 'zone' memory.
|
||||
//B - allocated memory is not zero-filled.
|
||||
//F - allocation can return NULL (otherwise sys_errors)
|
||||
//G - special set of functions with its own rules. Frees must not be mixed.
|
||||
//Tag - additional special set of functions with their own rules. Frees must not be mixed.
|
||||
void VARGS Z_Free (void *ptr);
|
||||
void *Z_Malloc (size_t size); // returns 0 filled memory
|
||||
void *ZF_Malloc (size_t size); // allowed to fail
|
||||
|
|
|
@ -1354,6 +1354,13 @@ static struct charcache_s *Font_GetChar(font_t *f, unsigned int codepoint)
|
|||
return &tc;
|
||||
}
|
||||
|
||||
if (charidx == 0x00a0) //nbsp
|
||||
{
|
||||
c = Font_GetCharIfLoaded(f, ' ');
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
|
||||
//not cached, can't get.
|
||||
c = Font_TryLoadGlyph(f, charidx);
|
||||
|
||||
|
|
|
@ -4365,7 +4365,7 @@ void Heightmap_LightPointValues (model_t *mod, const vec3_t point, vec3_t res_di
|
|||
void Heightmap_StainNode (mnode_t *node, float *parms)
|
||||
{
|
||||
}
|
||||
void Heightmap_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
||||
void Heightmap_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -590,7 +590,7 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
|
|||
return;
|
||||
}
|
||||
if (!model->animcache[sequence->seqindex])
|
||||
model->animcache[sequence->seqindex] = FS_LoadMallocGroupFile(model->memgroup, sequencedata->name+32, &fz);
|
||||
model->animcache[sequence->seqindex] = FS_LoadMallocGroupFile(model->memgroup, sequencedata->name+32, &fz, true);
|
||||
if (!model->animcache[sequence->seqindex] || model->animcache[sequence->seqindex]->magic != (('I'<<0)|('D'<<8)|('S'<<16)|('Q'<<24)) || model->animcache[sequence->seqindex]->version != 10)
|
||||
{
|
||||
Sys_Error("Unable to load %s\n", sequencedata->name+32);
|
||||
|
|
|
@ -1159,7 +1159,7 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
|
|||
char altname[MAX_QPATH];
|
||||
Q_snprintfz(altname, sizeof(altname), "%s.%s", mdlbase, token);
|
||||
TRACE(("Mod_LoadModel: Trying to load (replacement) model \"%s\"\n", altname));
|
||||
buf = (unsigned *)FS_LoadMallocFile (altname, &filesize);
|
||||
buf = (unsigned *)FS_LoadMallocGroupFile(NULL, altname, &filesize, true);
|
||||
|
||||
if (buf)
|
||||
Q_strncpyz(mod->name, altname, sizeof(mod->name));
|
||||
|
@ -1167,7 +1167,7 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
|
|||
else
|
||||
{
|
||||
TRACE(("Mod_LoadModel: Trying to load model \"%s\"\n", mod->publicname));
|
||||
buf = (unsigned *)FS_LoadMallocFile (mod->publicname, &filesize);
|
||||
buf = (unsigned *)FS_LoadMallocGroupFile(NULL, mod->publicname, &filesize, true);
|
||||
if (buf)
|
||||
Q_strncpyz(mod->name, mod->publicname, sizeof(mod->name));
|
||||
else if (!buf)
|
||||
|
@ -1682,7 +1682,7 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
|
|||
Q_snprintfz(litname, sizeof(litname), litnames[best].pattern, litbase);
|
||||
else
|
||||
Q_snprintfz(litname, sizeof(litname), litnames[best].pattern, litbasep);
|
||||
litdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, litname, &litsize);
|
||||
litdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, litname, &litsize, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1832,7 +1832,7 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
|
|||
Q_strncpyz(luxname, loadmodel->name, sizeof(luxname));
|
||||
COM_StripExtension(loadmodel->name, luxname, sizeof(luxname));
|
||||
COM_DefaultExtension(luxname, ".lux", sizeof(luxname));
|
||||
luxdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, luxname, &luxsz);
|
||||
luxdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, luxname, &luxsz, false);
|
||||
luxtmp = false;
|
||||
}
|
||||
if (!luxdata)
|
||||
|
@ -1841,14 +1841,14 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
|
|||
COM_StripExtension(COM_SkipPath(loadmodel->name), luxname+5, sizeof(luxname)-5);
|
||||
Q_strncatz(luxname, ".lux", sizeof(luxname));
|
||||
|
||||
luxdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, luxname, &luxsz);
|
||||
luxdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, luxname, &luxsz, false);
|
||||
luxtmp = false;
|
||||
}
|
||||
if (!luxdata) //dp...
|
||||
{
|
||||
COM_StripExtension(loadmodel->name, luxname, sizeof(luxname));
|
||||
COM_DefaultExtension(luxname, ".dlit", sizeof(luxname));
|
||||
luxdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, luxname, &luxsz);
|
||||
luxdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, luxname, &luxsz, false);
|
||||
luxtmp = false;
|
||||
}
|
||||
//make sure the .lux has the correct size
|
||||
|
@ -1974,8 +1974,8 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
|
|||
overrides->stylesperface = size / (sizeof(*overrides->styles16)*loadmodel->numsurfaces); //rounding issues will be caught on the next line...
|
||||
if (!overrides->stylesperface || size != loadmodel->numsurfaces * sizeof(*overrides->styles16)*overrides->stylesperface)
|
||||
overrides->styles16 = NULL;
|
||||
else if (overrides->stylesperface > MAXQ1LIGHTMAPS)
|
||||
Con_Printf(CON_WARNING "LMSTYLE16 lump provides %i styles, only the first %i will be used.\n", overrides->stylesperface, MAXQ1LIGHTMAPS);
|
||||
else if (overrides->stylesperface > MAXCPULIGHTMAPS)
|
||||
Con_Printf(CON_WARNING "LMSTYLE16 lump provides %i styles, only the first %i will be used.\n", overrides->stylesperface, MAXCPULIGHTMAPS);
|
||||
}
|
||||
if (!overrides->styles8 && !overrides->styles16)
|
||||
{ //16bit per-face lightmap styles index
|
||||
|
@ -1984,8 +1984,8 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
|
|||
overrides->stylesperface = size / (sizeof(*overrides->styles8)*loadmodel->numsurfaces); //rounding issues will be caught on the next line...
|
||||
if (!overrides->stylesperface || size != loadmodel->numsurfaces * sizeof(*overrides->styles8)*overrides->stylesperface)
|
||||
overrides->styles8 = NULL;
|
||||
else if (overrides->stylesperface > MAXQ1LIGHTMAPS)
|
||||
Con_Printf(CON_WARNING "LMSTYLE lump provides %i styles, only the first %i will be used.\n", overrides->stylesperface, MAXQ1LIGHTMAPS);
|
||||
else if (overrides->stylesperface > MAXCPULIGHTMAPS)
|
||||
Con_Printf(CON_WARNING "LMSTYLE lump provides %i styles, only the first %i will be used.\n", overrides->stylesperface, MAXCPULIGHTMAPS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ typedef struct {
|
|||
|
||||
void (*LightPointValues) (struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
|
||||
void (*StainNode) (struct mnode_s *node, float *parms);
|
||||
void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node);
|
||||
void (*MarkLights) (struct dlight_s *light, dlightbitmask_t bit, struct mnode_s *node);
|
||||
|
||||
int (*ClusterForPoint) (struct model_s *model, const vec3_t point, int *areaout); //pvs index (leaf-1 for q1bsp). may be negative (ie: no pvs).
|
||||
qbyte *(*ClusterPVS) (struct model_s *model, int cluster, pvsbuffer_t *pvsbuffer, pvsmerge_t merge);
|
||||
|
@ -437,20 +437,22 @@ typedef struct msurface_s
|
|||
batch_t *sbatch;
|
||||
mtexinfo_t *texinfo;
|
||||
int visframe; // should be drawn when node is crossed
|
||||
#ifdef RTLIGHTS
|
||||
int shadowframe;
|
||||
int clipcount;
|
||||
#endif
|
||||
// int clipcount;
|
||||
|
||||
// legacy lighting info
|
||||
dlightbitmask_t dlightbits;
|
||||
int dlightframe;
|
||||
int dlightbits;
|
||||
qboolean cached_dlight; // true if dynamic light in cache
|
||||
|
||||
//static lighting
|
||||
int lightmaptexturenums[MAXRLIGHTMAPS]; //rbsp+fbsp formats have multiple lightmaps
|
||||
lightstyleindex_t styles[MAXQ1LIGHTMAPS];
|
||||
lightstyleindex_t styles[MAXCPULIGHTMAPS];
|
||||
qbyte vlstyles[MAXRLIGHTMAPS];
|
||||
int cached_light[MAXQ1LIGHTMAPS]; // values currently used in lightmap
|
||||
int cached_colour[MAXQ1LIGHTMAPS]; // values currently used in lightmap
|
||||
qboolean cached_dlight; // true if dynamic light in cache
|
||||
int cached_light[MAXCPULIGHTMAPS]; // values currently used in lightmap
|
||||
int cached_colour[MAXCPULIGHTMAPS]; // values currently used in lightmap
|
||||
#ifndef NOSTAINS
|
||||
qboolean stained;
|
||||
#endif
|
||||
|
@ -565,7 +567,7 @@ void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts, shade
|
|||
size_t Fragment_ClipPlaneToBrush(vecV_t *points, size_t maxpoints, void *planes, size_t planestride, size_t numplanes, vec4_t face);
|
||||
void Mod_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, unsigned int surfflagmask, unsigned int surflagmatch, void (*callback)(void *ctx, vec3_t *fte_restrict points, size_t numpoints, shader_t *shader), void *ctx);
|
||||
|
||||
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
|
||||
void Q1BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node);
|
||||
void GLQ1BSP_LightPointValues(struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
|
||||
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, const vec3_t p1, const vec3_t p2, unsigned int hitcontents, struct trace_s *trace);
|
||||
|
||||
|
|
|
@ -2521,7 +2521,7 @@ static int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
|
|||
{
|
||||
case LM_E5BGR9:
|
||||
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)<<2;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
unsigned int l = *(unsigned int*)lightmap;
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
|
@ -2534,7 +2534,7 @@ static int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
|
|||
break;
|
||||
case LM_RGB8:
|
||||
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
r += max3(lightmap[0],lightmap[1],lightmap[2]) * scale;
|
||||
|
@ -2543,7 +2543,7 @@ static int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
|
|||
break;
|
||||
case LM_L8:
|
||||
lightmap += dt * ((surf->extents[0]>>surf->lmshift)+1) + ds;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
r += *lightmap * scale;
|
||||
|
@ -2695,7 +2695,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
|
|||
|
||||
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)<<2;
|
||||
deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)<<4;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
unsigned int lm = *(unsigned int*)lightmap;
|
||||
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
|
||||
|
@ -2720,7 +2720,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
|
|||
|
||||
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
|
||||
deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
|
||||
|
||||
|
@ -2743,7 +2743,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
|
|||
|
||||
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds);
|
||||
deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
|
||||
|
||||
|
@ -2770,7 +2770,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
|
|||
{
|
||||
case LM_E5BGR9:
|
||||
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)<<2;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
unsigned int lm = *(unsigned int*)lightmap;
|
||||
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
|
||||
|
@ -2786,7 +2786,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
|
|||
break;
|
||||
case LM_RGB8:
|
||||
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
|
||||
|
||||
|
@ -2800,7 +2800,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
|
|||
break;
|
||||
case LM_L8:
|
||||
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds);
|
||||
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ static float Com_FloatArgument(const char *shadername, char *arg, size_t arglen,
|
|||
#define HASH_SIZE 128
|
||||
|
||||
#define SPF_DEFAULT 0u /*quake3/fte internal*/
|
||||
#define SPF_PROGRAMIFY (1u<<0) /*quake3/fte internal*/
|
||||
#define SPF_PROGRAMIFY (1u<<0) /*automatically replace known glsl, pulling in additional textures+effects from a single primary pass*/
|
||||
#define SPF_DOOM3 (1u<<1) /*any commands, args, etc, should be interpretted according to doom3's norms*/
|
||||
|
||||
typedef struct shaderparsestate_s
|
||||
|
|
|
@ -308,8 +308,8 @@ typedef struct llightinfo_s
|
|||
{
|
||||
struct relight_ctx_s *ctx; //relight context, shared between threads.
|
||||
|
||||
vec3_t lightmaps[MAXQ1LIGHTMAPS][SINGLEMAP];
|
||||
vec3_t lightnorm[MAXQ1LIGHTMAPS][SINGLEMAP];
|
||||
vec3_t lightmaps[MAXCPULIGHTMAPS][SINGLEMAP];
|
||||
vec3_t lightnorm[MAXCPULIGHTMAPS][SINGLEMAP];
|
||||
int numlightstyles;
|
||||
vec_t *light;
|
||||
vec_t facedist;
|
||||
|
@ -325,7 +325,7 @@ typedef struct llightinfo_s
|
|||
vec_t exactmins[2], exactmaxs[2];
|
||||
|
||||
int texmins[2], texsize[2];
|
||||
int lightstyles[MAXQ1LIGHTMAPS];
|
||||
int lightstyles[MAXCPULIGHTMAPS];
|
||||
} llightinfo_t;
|
||||
|
||||
const size_t lightthreadctxsize = sizeof(llightinfo_t);
|
||||
|
@ -628,7 +628,7 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l)
|
|||
if (mapnum == l->numlightstyles)
|
||||
{ // init a new light map
|
||||
#ifdef UTILITY
|
||||
if (mapnum == MAXQ1LIGHTMAPS)
|
||||
if (mapnum == MAXCPULIGHTMAPS)
|
||||
{
|
||||
printf ("WARNING: Too many light styles on a face\n");
|
||||
return;
|
||||
|
@ -715,7 +715,7 @@ static void FixMinlight (llightinfo_t *l)
|
|||
}
|
||||
if (i == l->numlightstyles)
|
||||
{
|
||||
if (l->numlightstyles == MAXQ1LIGHTMAPS)
|
||||
if (l->numlightstyles == MAXCPULIGHTMAPS)
|
||||
return; // oh well..
|
||||
for (j=0 ; j<l->numsurfpt ; j++)
|
||||
{
|
||||
|
@ -771,7 +771,7 @@ static unsigned int PackE5BRG9(vec3_t rgb)
|
|||
LightFace
|
||||
============
|
||||
*/
|
||||
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, lightstyleindex_t surf_styles[MAXQ1LIGHTMAPS], unsigned int *surf_expsamples, qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale)
|
||||
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, lightstyleindex_t surf_styles[MAXCPULIGHTMAPS], unsigned int *surf_expsamples, qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale)
|
||||
{
|
||||
int s, t;
|
||||
int i,c,ch;
|
||||
|
@ -820,7 +820,7 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, lightstylein
|
|||
|
||||
i = 0;
|
||||
#ifndef UTILITY
|
||||
for (; surf_styles[i] != INVALID_LIGHTSTYLE && i < MAXQ1LIGHTMAPS; i++)
|
||||
for (; surf_styles[i] != INVALID_LIGHTSTYLE && i < MAXCPULIGHTMAPS; i++)
|
||||
{
|
||||
l->lightstyles[i] = surf_styles[i];
|
||||
memset(&l->lightmaps[i], 0, sizeof(l->lightmaps[i][0])*l->numsurfpt);
|
||||
|
@ -828,7 +828,7 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, lightstylein
|
|||
}
|
||||
#endif
|
||||
l->numlightstyles = i;
|
||||
for ( ; i<MAXQ1LIGHTMAPS ; i++)
|
||||
for ( ; i<MAXCPULIGHTMAPS ; i++)
|
||||
l->lightstyles[i] = INVALID_LIGHTSTYLE;
|
||||
|
||||
//
|
||||
|
@ -853,7 +853,7 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, lightstylein
|
|||
//
|
||||
// save out the values
|
||||
//
|
||||
for (i=0 ; i <MAXQ1LIGHTMAPS ; i++)
|
||||
for (i=0 ; i <MAXCPULIGHTMAPS ; i++)
|
||||
surf_styles[i] = l->lightstyles[i];
|
||||
|
||||
|
||||
|
|
|
@ -4921,7 +4921,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
|
|||
// externs->Printf ("to build a clean data tree: qcc -copy <srcdir> <destdir>\n");
|
||||
// externs->Printf ("to build a clean pak file: qcc -pak <srcdir> <packfile>\n");
|
||||
// externs->Printf ("to bsp all bmodels: qcc -bspmodels <gamedir>\n");
|
||||
externs->Printf ("-Kwasm causes FTEQCC to dump all asm to qc.asm\n");
|
||||
externs->Printf ("-Fwasm causes FTEQCC to dump all asm to qc.asm\n");
|
||||
externs->Printf ("-O0 to disable optimisations\n");
|
||||
externs->Printf ("-O1 to optimise for size\n");
|
||||
externs->Printf ("-O2 to optimise more - some behaviours may change\n");
|
||||
|
|
|
@ -8606,17 +8606,6 @@ static void QCBUILTIN PF_h2rain_go(pubprogfuncs_t *prinst, struct globalvars_s *
|
|||
SV_MulticastProtExt (NULL, MULTICAST_ALL, pr_global_struct->dimension_send, 0, 0);
|
||||
}
|
||||
|
||||
static void QCBUILTIN PF_h2StopSound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int channel;
|
||||
edict_t *entity;
|
||||
|
||||
entity = G_EDICT(prinst, OFS_PARM0);
|
||||
channel = G_FLOAT(OFS_PARM1);
|
||||
|
||||
SVQ1_StartSound (NULL, (wedict_t*)entity, channel, NULL, 1, 0, 0, 0, CF_SV_RELIABLE);
|
||||
}
|
||||
|
||||
static void QCBUILTIN PF_h2updatesoundpos(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
Con_DPrintf("FTE-H2 FIXME: updatesoundpos not implemented\n");
|
||||
|
@ -8639,6 +8628,13 @@ static void QCBUILTIN PF_h2getstring(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
RETURN_PSTRING(s);
|
||||
}
|
||||
#endif
|
||||
static void QCBUILTIN PF_StopSound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
edict_t *entity = G_EDICT(prinst, OFS_PARM0);
|
||||
int channel = G_FLOAT(OFS_PARM1);
|
||||
|
||||
SVQ1_StartSound (NULL, (wedict_t*)entity, channel, NULL, 1, 0, 0, 0, CF_SV_RELIABLE);
|
||||
}
|
||||
|
||||
static void QCBUILTIN PF_RegisterTEnt(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -10732,10 +10728,12 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"precache_file4", PF_precache_file, 0, 0, 103, 0},
|
||||
{"dowhiteflash", PF_h2whiteflash, 0, 0, 104, 0},
|
||||
{"updatesoundpos", PF_h2updatesoundpos,0, 0, 105, 0},
|
||||
{"stopsound", PF_h2StopSound, 0, 0, 106, 0},
|
||||
{"stopsound", PF_StopSound, 0, 0, 106, 0, D("void(entity ent, float channel)", "Terminates playback of sounds on the specified entity-channel. CHAN_AUTO should not be used.")},
|
||||
|
||||
{"precache_model4", PF_precache_model, 0, 0, 116, 0},//please don't use...
|
||||
{"precache_sound4", PF_precache_sound, 0, 0, 117, 0},
|
||||
#else
|
||||
{"stopsound", PF_StopSound, 0, 0, 0, 0, D("void(entity ent, float channel)", "Terminates playback of sounds on the specified entity-channel. CHAN_AUTO should not be used.")},
|
||||
#endif
|
||||
|
||||
{"tracebox", PF_traceboxdp, 0, 0, 0, 90, D("void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent)", "Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values.")},
|
||||
|
|
|
@ -47,6 +47,7 @@ oh, wait, ktx no longer supports those properly.
|
|||
13: 2009/june gamecode no longer aware of edict_t data (just 'qc' fields).
|
||||
14: 2017/march gamedata_t.maxentities added
|
||||
15: 2017/june for-64bit string indirection changes. added GAME_CLEAR_EDICT.
|
||||
16: wasted_edict_t_size is finally 0
|
||||
*/
|
||||
#define GAME_API_VERSION 15
|
||||
#define GAME_API_VERSION_MIN 8
|
||||
|
@ -2279,6 +2280,7 @@ qboolean PR_LoadQ1QVM(void)
|
|||
gd.maxedicts = MAX_Q1QVM_EDICTS;
|
||||
}
|
||||
gd.maxedicts = bound(1, pr_maxedicts.ival, gd.maxedicts);
|
||||
gd.maxedicts = bound(1, gd.maxedicts, MAX_EDICTS);
|
||||
|
||||
qvm_api_version = gd.APIversion;
|
||||
if (!(GAME_API_VERSION_MIN <= qvm_api_version && qvm_api_version <= GAME_API_VERSION))
|
||||
|
|
|
@ -444,7 +444,9 @@ static int QDECL ShowMapListExt (const char *name, qofs_t flags, time_t mtime, v
|
|||
static void SV_MapList_f(void)
|
||||
{
|
||||
COM_EnumerateFiles("maps/*.bsp", ShowMapList, NULL);
|
||||
COM_EnumerateFiles("maps/*.bsp.gz", ShowMapListExt, NULL);
|
||||
COM_EnumerateFiles("maps/*.map", ShowMapListExt, NULL);
|
||||
COM_EnumerateFiles("maps/*.map.gz", ShowMapListExt, NULL);
|
||||
COM_EnumerateFiles("maps/*.cm", ShowMapList, NULL);
|
||||
COM_EnumerateFiles("maps/*.hmp", ShowMapList, NULL);
|
||||
}
|
||||
|
@ -474,7 +476,9 @@ static void SV_Map_c(int argn, const char *partial, struct xcommandargcompletion
|
|||
if (argn == 1)
|
||||
{
|
||||
COM_EnumerateFiles(va("maps/%s*.bsp", partial), CompleteMapList, ctx);
|
||||
COM_EnumerateFiles(va("maps/%s*.bsp.gz", partial), CompleteMapListExt, ctx);
|
||||
COM_EnumerateFiles(va("maps/%s*.map", partial), CompleteMapListExt, ctx);
|
||||
COM_EnumerateFiles(va("maps/%s*.map.gz", partial), CompleteMapListExt, ctx);
|
||||
COM_EnumerateFiles(va("maps/%s*.cm", partial), CompleteMapList, ctx);
|
||||
COM_EnumerateFiles(va("maps/%s*.hmp", partial), CompleteMapList, ctx);
|
||||
}
|
||||
|
@ -718,7 +722,7 @@ void SV_Map_f (void)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ /*"maps/%s.ent",*/ NULL};
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.bsp.gz", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ /*"maps/%s.ent",*/ NULL};
|
||||
int i, j;
|
||||
|
||||
for (i = 0; exts[i]; i++)
|
||||
|
|
|
@ -1002,7 +1002,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
|
|||
{
|
||||
//.map is commented out because quite frankly, they're a bit annoying when the engine loads the gpled start.map when really you wanted to just play the damn game intead of take it apart.
|
||||
//if you want to load a .map, just use 'map foo.map' instead.
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ NULL};
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ "maps/%s.bsp.gz", NULL};
|
||||
int depth, bestdepth;
|
||||
flocation_t loc;
|
||||
time_t filetime;
|
||||
|
@ -1244,7 +1244,6 @@ MSV_OpenUserDatabase();
|
|||
else if (svs.gametype == GT_QUAKE2)
|
||||
{
|
||||
int subs;
|
||||
extern int map_checksum;
|
||||
extern cvar_t sv_airaccelerate;
|
||||
|
||||
sv.stringsalloced = true;
|
||||
|
@ -1256,10 +1255,7 @@ MSV_OpenUserDatabase();
|
|||
sv.strings.configstring[Q2CS_AIRACCEL] = Z_StrDup("0");
|
||||
|
||||
// init map checksum config string but only for Q2/Q3 maps
|
||||
if (sv.world.worldmodel->fromgame == fg_quake2 || sv.world.worldmodel->fromgame == fg_quake3)
|
||||
sv.strings.configstring[Q2CS_MAPCHECKSUM] = Z_StrDup(va("%i", map_checksum));
|
||||
else
|
||||
sv.strings.configstring[Q2CS_MAPCHECKSUM] = Z_StrDup("0");
|
||||
sv.strings.configstring[Q2CS_MAPCHECKSUM] = Z_StrDup(va("%i", sv.world.worldmodel->checksum));
|
||||
|
||||
subs = sv.world.worldmodel->numsubmodels;
|
||||
if (subs > MAX_PRECACHE_MODELS-1)
|
||||
|
|
|
@ -3510,11 +3510,13 @@ static qboolean Rcon_Validate (void)
|
|||
intptr_t timediff;
|
||||
qbyte b;
|
||||
|
||||
const hashfunc_t *hashfunc = &hash_sha1;
|
||||
void *hashctx = alloca(hashfunc->contextsize);
|
||||
|
||||
const size_t digestsize = 20;
|
||||
size_t i, k;
|
||||
unsigned char digest[512];
|
||||
const unsigned char **tokens = alloca(sizeof(*tokens)*(Cmd_Argc()*2+5)); //overallocation in case argc is 0.
|
||||
size_t *toksizes = alloca(sizeof(*toksizes)*(Cmd_Argc()*2+5)); //overallocation in case argc is 0.
|
||||
if (strlen(pass) > digestsize*2)
|
||||
{
|
||||
for (i = 0; pass[digestsize*2+i] && i < sizeof(time_t)*2; i++)
|
||||
|
@ -3539,20 +3541,20 @@ static qboolean Rcon_Validate (void)
|
|||
tokens[5+i*2+0] = Cmd_Argv(i+2);
|
||||
tokens[5+i*2+1] = " "; //a trailing space is required.
|
||||
}
|
||||
hashfunc->init(hashctx);
|
||||
for (k = 0; k < 5+i*2; k++)
|
||||
toksizes[k] = strlen(tokens[k]);
|
||||
if (digestsize > 0 && digestsize == SHA1_m(digest, sizeof(digest), k, tokens, toksizes))
|
||||
hashfunc->process(hashctx, tokens[k], strlen(tokens[k]));
|
||||
hashfunc->terminate(digest, hashctx);
|
||||
|
||||
for (i = 0;;i++)
|
||||
{
|
||||
for (i = 0;;i++)
|
||||
{
|
||||
if (i == digestsize)
|
||||
return true;
|
||||
if (!pass[i*2+0] || !pass[i*2+1])
|
||||
break; //premature termination
|
||||
b = dehex(pass[i*2+0])*16+dehex(pass[i*2+1]);
|
||||
if (b != digest[i])
|
||||
break;
|
||||
}
|
||||
if (i == digestsize)
|
||||
return true;
|
||||
if (!pass[i*2+0] || !pass[i*2+1])
|
||||
break; //premature termination
|
||||
b = dehex(pass[i*2+0])*16+dehex(pass[i*2+1]);
|
||||
if (b != digest[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef struct svm_server_s {
|
|||
int protover;
|
||||
unsigned int clients;
|
||||
unsigned int maxclients;
|
||||
qboolean needpass;
|
||||
int needpass;
|
||||
char hostname[48]; //just for our own listings.
|
||||
char mapname[16]; //just for our own listings.
|
||||
char gamedir[16]; //again...
|
||||
|
@ -551,7 +551,7 @@ vfsfile_t *SVM_GenerateIndex(const char *requesthost, const char *fname)
|
|||
if (server)
|
||||
{
|
||||
QuakeCharsToHTML(hostname, sizeof(hostname), server->hostname, false);
|
||||
VFS_PRINTF(f, "<tr><td>%s</td><td>%s</td><td>%s%s</td><td>%s</td><td>%s</td><td>%u/%u</td></tr>\n", server->game?server->game->name:"Unknown", NET_AdrToString(tmpbuf, sizeof(tmpbuf), &server->adr), server->needpass?"🔒":"", hostname, server->gamedir, server->mapname, server->clients, server->maxclients);
|
||||
VFS_PRINTF(f, "<tr><td>%s</td><td>%s</td><td>%s%s</td><td>%s</td><td>%s</td><td>%u/%u</td></tr>\n", server->game?server->game->name:"Unknown", NET_AdrToString(tmpbuf, sizeof(tmpbuf), &server->adr), (server->needpass&1)?"🔒":"", hostname, server->gamedir, server->mapname, server->clients, server->maxclients);
|
||||
}
|
||||
else
|
||||
VFS_PRINTF(f, "<tr><td>?</td><td>%s</td><td>?</td><td>?</td><td>?</td><td>?/?</td></tr>\n", NET_AdrToString(tmpbuf, sizeof(tmpbuf), &adr[count]));
|
||||
|
@ -567,7 +567,19 @@ vfsfile_t *SVM_GenerateIndex(const char *requesthost, const char *fname)
|
|||
VFS_PRINTF(f, "%s", master_css);
|
||||
|
||||
if (!strcmp(gamename, "UNKNOWN"))
|
||||
VFS_PRINTF(f, "<h1>Firewalled/NATed/Unresponsive/Congested (Misconfigured) Servers</h1>\n");
|
||||
{
|
||||
VFS_PRINTF(f, "<h1>Unresponsive Servers</h1>\n");
|
||||
VFS_PRINTF(f, "These servers have sent a heartbeat but have failed to respond to an appropriate query from a different port. This can happen when:<ul>"
|
||||
"<li>Server is firewalled and all inbound packets are dropped. Try reconfiguring your firewall to allow packets to that process or port.</li>"
|
||||
"<li>An intermediate router implements an Address/Port-Dependant-Filtering NAT. Try setting up port forwarding.</li>"
|
||||
"<li>Outgoing connections are asynchronous with regard to port forwarding. Such servers will show with arbitrary ephemerial ports. Docker: you can supposedly work around this with --net=host.</li>"
|
||||
"<li>Plain and simple packet loss, servers in this state for less than 5 mins may still be fine.</li>"
|
||||
"<li>Server crashed or was reconfigured before it could respond.</li>"
|
||||
"<li>MTU limits with failed defragmentation.</li>"
|
||||
"<li>Routing table misconfiguration.</li>"
|
||||
"<li>Other.</li>"
|
||||
"</ul>\n");
|
||||
}
|
||||
else
|
||||
VFS_PRINTF(f, "<h1>Servers for %s</h1>\n", QuakeCharsToHTML(tmpbuf, sizeof(tmpbuf), gamename, true));
|
||||
|
||||
|
@ -587,7 +599,7 @@ vfsfile_t *SVM_GenerateIndex(const char *requesthost, const char *fname)
|
|||
else
|
||||
url = NET_AdrToString(tmpbuf, sizeof(tmpbuf), &server->adr);
|
||||
QuakeCharsToHTML(hostname, sizeof(hostname), server->hostname, false);
|
||||
VFS_PRINTF(f, "<tr><td>%s</td><td>%s%s</td><td>%s</td><td>%s</td><td>%u/%u</td></tr>\n", url, server->needpass?"🔒":"", hostname, server->gamedir, server->mapname, server->clients, server->maxclients);
|
||||
VFS_PRINTF(f, "<tr><td>%s</td><td>%s%s</td><td>%s</td><td>%s</td><td>%u/%u</td></tr>\n", url, (server->needpass&1)?"🔒":"", hostname, server->gamedir, server->mapname, server->clients, server->maxclients);
|
||||
clients += server->clients;
|
||||
maxclients += server->maxclients;
|
||||
}
|
||||
|
@ -607,7 +619,7 @@ vfsfile_t *SVM_GenerateIndex(const char *requesthost, const char *fname)
|
|||
for (server = (game?game->firstserver:NULL); server; server = server->next)
|
||||
{
|
||||
if (server->brokerid)
|
||||
VFS_PRINTF(f, "rtc:///%s \\maxclients\\%u\\clients\\%u\\hostname\\%s\\modname\\%s\\mapname\\%s%s\n", server->brokerid, server->maxclients, server->clients, server->hostname, server->gamedir, server->mapname, server->needpass?"\\needpass\\1":"");
|
||||
VFS_PRINTF(f, "rtc:///%s \\maxclients\\%u\\clients\\%u\\hostname\\%s\\modname\\%s\\mapname\\%s\\needpass\\%i\n", server->brokerid, server->maxclients, server->clients, server->hostname, server->gamedir, server->mapname, server->needpass);
|
||||
else
|
||||
VFS_PRINTF(f, "%s\n", NET_AdrToString(tmpbuf, sizeof(tmpbuf), &server->adr));
|
||||
}
|
||||
|
@ -724,7 +736,7 @@ static svm_server_t *SVM_Heartbeat(const char *gamename, netadr_t *adr, int numc
|
|||
if (server)
|
||||
{ //it still exists, renew it, but don't otherwise care too much.
|
||||
server->expiretime = validuntil;
|
||||
return NULL;
|
||||
return server;
|
||||
}
|
||||
game = SVM_FindGame("UNKNOWN", true);
|
||||
}
|
||||
|
@ -813,7 +825,7 @@ void SVM_GenChallenge(char *out, size_t outsize, netadr_t *foradr)
|
|||
}
|
||||
|
||||
//switch net_from's reported connection, so we reply from a different udp socket from the one a packet was received from.
|
||||
static void SVM_SwitchQuerySocket(void)
|
||||
static qboolean SVM_SwitchQuerySocket(void)
|
||||
{
|
||||
size_t c;
|
||||
//switch the info query to our other udp socket, so any firewall/nat over the server blocks it.
|
||||
|
@ -829,9 +841,10 @@ static void SVM_SwitchQuerySocket(void)
|
|||
(svm_sockets->conn[c]->addrtype[0] == net_from.type || svm_sockets->conn[c]->addrtype[1] == net_from.type))
|
||||
{ //okay, looks like we should be able to respond on this one. lets see if their firewall stops us from finding out more about them.
|
||||
net_from.connum = c+1;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void SVM_ProcessUDPPacket(void)
|
||||
|
@ -877,7 +890,7 @@ static void SVM_ProcessUDPPacket(void)
|
|||
line = MSG_ReadStringLine();
|
||||
s = COM_Parse(line);
|
||||
if (!strcmp(com_token, "getservers") || !strcmp(com_token, "getserversExt"))
|
||||
{ //q3
|
||||
{ //q3/dpmaster
|
||||
sizebuf_t sb;
|
||||
int ver;
|
||||
char *eos;
|
||||
|
@ -892,7 +905,7 @@ static void SVM_ProcessUDPPacket(void)
|
|||
s = COM_ParseOut(s, game, sizeof(game));
|
||||
ver = strtol(game, &eos, 0);
|
||||
if (*eos)
|
||||
{ //not a number, must have been a game name.
|
||||
{ //not a number, must have been a dpmaster game name.
|
||||
s = COM_Parse(s);
|
||||
ver = strtol(com_token, NULL, 0);
|
||||
}
|
||||
|
@ -955,13 +968,19 @@ static void SVM_ProcessUDPPacket(void)
|
|||
else
|
||||
{ //dp/q3/etc are annoying, but we can query from an emphemerial socket to check NAT rules.
|
||||
sizebuf_t sb;
|
||||
netadr_t a;
|
||||
|
||||
char ourchallenge[256];
|
||||
SVM_GenChallenge(ourchallenge, sizeof(ourchallenge), &net_from);
|
||||
svm.total.queries++;
|
||||
|
||||
//placeholder listing...
|
||||
SVM_Heartbeat(NULL, &net_from, 0, svm.time + sv_heartbeattimeout.ival);
|
||||
SVM_SwitchQuerySocket();
|
||||
if (SVM_Heartbeat(NULL, &net_from, 0, svm.time + sv_heartbeattimeout.ival))
|
||||
a = net_from;
|
||||
else
|
||||
a.type = NA_INVALID;
|
||||
if (!SVM_SwitchQuerySocket())
|
||||
a.type = NA_INVALID;
|
||||
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
sb.maxsize = sizeof(net_message_buffer);
|
||||
|
@ -970,6 +989,17 @@ static void SVM_ProcessUDPPacket(void)
|
|||
MSG_WriteString(&sb, va("getinfo %s\n", ourchallenge));
|
||||
sb.cursize--;
|
||||
NET_SendPacket(svm_sockets, sb.cursize, sb.data, &net_from);
|
||||
|
||||
if (a.type != NA_INVALID)
|
||||
{ //they were unknown... send a special getinfo, so we can get their hostname while leaving them as 'unknown'
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
sb.maxsize = sizeof(net_message_buffer);
|
||||
sb.data = net_message_buffer;
|
||||
MSG_WriteLong(&sb, -1);
|
||||
MSG_WriteString(&sb, va("getinfo ?%s\n", ourchallenge));
|
||||
sb.cursize--;
|
||||
NET_SendPacket(svm_sockets, sb.cursize, sb.data, &a);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(com_token, "infoResponse"))
|
||||
|
@ -978,9 +1008,12 @@ static void SVM_ProcessUDPPacket(void)
|
|||
int clients;
|
||||
const char *game, *chal;
|
||||
svm_server_t *srv;
|
||||
qboolean unknownresp = false;
|
||||
s = MSG_ReadStringLine();
|
||||
svm.total.heartbeats++;
|
||||
chal = Info_ValueForKey(s, "challenge");
|
||||
unknownresp = *chal=='?';
|
||||
chal += unknownresp?1:0;
|
||||
SVM_GenChallenge(ourchallenge, sizeof(ourchallenge), &net_from);
|
||||
if (!strcmp(chal, ourchallenge))
|
||||
{
|
||||
|
@ -988,14 +1021,18 @@ static void SVM_ProcessUDPPacket(void)
|
|||
game = Info_ValueForKey(s, "gamename");
|
||||
if (!*game)
|
||||
game = QUAKE3PROTOCOLNAME;
|
||||
if (unknownresp)
|
||||
game = NULL; //ignore the gamename and classify it as unknown. this won't break anything if we've already has a proper heartbeat from them.
|
||||
srv = SVM_Heartbeat(game, &net_from, clients, svm.time + sv_heartbeattimeout.ival);
|
||||
if (srv)
|
||||
{
|
||||
if (developer.ival)
|
||||
Info_Print(s, "\t");
|
||||
srv->protover = atoi(Info_ValueForKey(s, "protocol"));
|
||||
srv->clients = clients;
|
||||
if (game)
|
||||
srv->protover = atoi(Info_ValueForKey(s, "protocol"));
|
||||
srv->maxclients = atoi(Info_ValueForKey(s, "sv_maxclients"));
|
||||
srv->needpass = !!atoi(Info_ValueForKey(s, "needpass"));
|
||||
srv->needpass = atoi(Info_ValueForKey(s, "needpass"));
|
||||
Q_strncpyz(srv->hostname, Info_ValueForKey(s, "hostname"), sizeof(srv->hostname));
|
||||
Q_strncpyz(srv->gamedir, Info_ValueForKey(s, "modname"), sizeof(srv->gamedir));
|
||||
Q_strncpyz(srv->mapname, Info_ValueForKey(s, "mapname"), sizeof(srv->mapname));
|
||||
|
@ -1058,7 +1095,7 @@ static void SVM_ProcessUDPPacket(void)
|
|||
Info_Print(s, "\t");
|
||||
srv->protover = 3;//atoi(Info_ValueForKey(s, "protocol"));
|
||||
srv->maxclients = atoi(Info_ValueForKey(s, "maxclients"));
|
||||
srv->needpass = !!atoi(Info_ValueForKey(s, "needpass"));
|
||||
srv->needpass = atoi(Info_ValueForKey(s, "needpass"));
|
||||
Q_strncpyz(srv->hostname, Info_ValueForKey(s, "hostname"), sizeof(srv->hostname));
|
||||
Q_strncpyz(srv->gamedir, Info_ValueForKey(s, "*gamedir"), sizeof(srv->gamedir));
|
||||
Q_strncpyz(srv->mapname, Info_ValueForKey(s, "map"), sizeof(srv->mapname));
|
||||
|
|
|
@ -451,7 +451,7 @@ int SV_MVD_GotQTVRequest(vfsfile_t *clientstream, char *headerstart, char *heade
|
|||
int digest[5];
|
||||
|
||||
Q_snprintfz(hash, sizeof(hash), "%s%s", p->challenge, qtv_password.string);
|
||||
SHA1((char*)digest, sizeof(digest), hash, strlen(hash));
|
||||
CalcHash(&hash_sha1, (char*)digest, sizeof(digest), hash, strlen(hash));
|
||||
Q_snprintfz(hash, sizeof(hash), "%08X%08X%08X%08X%08X", digest[0], digest[1], digest[2], digest[3], digest[4]);
|
||||
p->hasauthed = !strcmp(password, hash);
|
||||
}
|
||||
|
|
|
@ -495,7 +495,7 @@ int main(int argc, const char **argv)
|
|||
|
||||
if (argc == 1)
|
||||
{
|
||||
printf("%s input.glsl output.fvb\n");
|
||||
printf("%s input.glsl output.fvb\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -4312,9 +4312,11 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre
|
|||
#ifdef VK_EXT_debug_report
|
||||
qboolean havedebugreport = false;
|
||||
#endif
|
||||
vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||
if (VK_SUCCESS!=vkEnumerateInstanceExtensionProperties(NULL, &count, NULL))
|
||||
count = 0;
|
||||
ext = malloc(sizeof(*ext)*count);
|
||||
vkEnumerateInstanceExtensionProperties(NULL, &count, ext);
|
||||
if (!ext || VK_SUCCESS!=vkEnumerateInstanceExtensionProperties(NULL, &count, ext))
|
||||
count = 0;
|
||||
for (i = 0; i < count && extensions_count < countof(extensions); i++)
|
||||
{
|
||||
Con_DLPrintf(2, " vki: %s\n", ext[i].extensionName);
|
||||
|
|
|
@ -1078,7 +1078,7 @@ void HTTPSV_GetMethod(cluster_t *cluster, oproxy_t *pend)
|
|||
unsigned char sha1digest[20];
|
||||
char padkey[512];
|
||||
snprintf(padkey, sizeof(padkey), "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key);
|
||||
tobase64(acceptkey, sizeof(acceptkey), sha1digest, SHA1(sha1digest, sizeof(sha1digest), padkey, strlen(padkey)));
|
||||
tobase64(acceptkey, sizeof(acceptkey), sha1digest, CalcHash(&hash_sha1, sha1digest, sizeof(sha1digest), padkey, strlen(padkey)));
|
||||
|
||||
snprintf(padkey, sizeof(padkey),
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
|
|
19
fteqtv/qtv.h
19
fteqtv/qtv.h
|
@ -238,8 +238,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
|
||||
#define SHA1 SHA1_quake
|
||||
size_t SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int digestsize;
|
||||
unsigned int contextsize; //you need to alloca(te) this much memory...
|
||||
void (*init) (void *context);
|
||||
void (*process) (void *context, const void *data, size_t datasize);
|
||||
void (*terminate) (unsigned char *digest, void *context);
|
||||
} hashfunc_t;
|
||||
extern hashfunc_t hash_sha1;
|
||||
/*extern hashfunc_t hash_sha224;
|
||||
extern hashfunc_t hash_sha256;
|
||||
extern hashfunc_t hash_sha384;
|
||||
extern hashfunc_t hash_sha512;*/
|
||||
#define HMAC HMAC_quake //stop conflicts...
|
||||
size_t CalcHash(hashfunc_t *hash, unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen);
|
||||
size_t HMAC(hashfunc_t *hashfunc, unsigned char *digest, size_t maxdigestsize, const unsigned char *data, size_t datalen, const unsigned char *key, size_t keylen);
|
||||
|
||||
|
||||
#ifdef LIBQTV
|
||||
|
|
|
@ -477,7 +477,7 @@ void Net_SendQTVConnectionRequest(sv_t *qtv, char *authmethod, char *challenge)
|
|||
str = "PASSWORD: \""; Net_QueueUpstream(qtv, strlen(str), str);
|
||||
|
||||
snprintf(hash, sizeof(hash), "%s%s", challenge, qtv->connectpassword);
|
||||
SHA1((unsigned char*)digest, sizeof(digest), hash, strlen(hash));
|
||||
CalcHash(&hash_sha1, (unsigned char*)digest, sizeof(digest), hash, strlen(hash));
|
||||
sprintf(hash, "%08X%08X%8X%08X%08X", digest[0], digest[1], digest[2], digest[3], digest[4]);
|
||||
|
||||
str = hash; Net_QueueUpstream(qtv, strlen(str), str);
|
||||
|
|
|
@ -1228,11 +1228,11 @@ static int sasl_scram_initial(struct sasl_ctx_s *ctx, char *buf, int bufsize, ha
|
|||
}
|
||||
static int sasl_scramsha1minus_initial(struct sasl_ctx_s *ctx, char *buf, int bufsize)
|
||||
{
|
||||
return sasl_scram_initial(ctx, buf, bufsize, SHA1_m, 20, false);
|
||||
return sasl_scram_initial(ctx, buf, bufsize, &hash_sha1, 20, false);
|
||||
}
|
||||
static int sasl_scramsha1plus_initial(struct sasl_ctx_s *ctx, char *buf, int bufsize)
|
||||
{
|
||||
return sasl_scram_initial(ctx, buf, bufsize, SHA1_m, 20, true);
|
||||
return sasl_scram_initial(ctx, buf, bufsize, &hash_sha1, 20, true);
|
||||
}
|
||||
|
||||
static void buf_cat(buf_t *buf, char *data, int len)
|
||||
|
@ -1347,7 +1347,7 @@ static int sasl_scram_challenge(struct sasl_ctx_s *ctx, char *in, int inlen, cha
|
|||
HMAC(func, clientkey, sizeof(clientkey), "Client Key", strlen("Client Key"), salted_password, digestsize);
|
||||
//Note: if we wanted to be fancy, we could store both clientkey and serverkey instead of salted_password, but I'm not sure there's all that much point.
|
||||
tmp = clientkey;
|
||||
func(storedkey, sizeof(storedkey), 1, &tmp, &digestsize);
|
||||
CalcHash(func, storedkey, sizeof(storedkey), tmp, digestsize);
|
||||
HMAC(func, clientsignature, sizeof(clientsignature), sigkey.buf, sigkey.len, storedkey, digestsize);
|
||||
|
||||
for (i = 0; i < digestsize; i++)
|
||||
|
@ -3621,7 +3621,7 @@ static qboolean JCL_BuddyVCardReply(jclient_t *jcl, xmltree_t *tree, struct iq_s
|
|||
free(bi->image);
|
||||
free(bi->imagehash);
|
||||
free(bi->imagemime);
|
||||
SHA1(hash, sizeof(hash), photodata, photosize);
|
||||
CalcHash(&hash_sha1, hash, sizeof(hash), photodata, photosize);
|
||||
for (i = 0, o = 0; i < sizeof(hash); i++)
|
||||
{
|
||||
hasha[o++] = hex[(hash[i]>>4) & 0xf];
|
||||
|
@ -3676,7 +3676,7 @@ static qboolean JCL_MyVCardReply(jclient_t *jcl, xmltree_t *tree, struct iq_s *i
|
|||
else
|
||||
{
|
||||
int photosize = Base64_Decode(photodata, sizeof(photodata), photobinval->body, strlen(photobinval->body));
|
||||
SHA1(digest, sizeof(digest), photodata, photosize);
|
||||
CalcHash(&hash_sha1, digest, sizeof(digest), photodata, photosize);
|
||||
if (jcl->vcardphotohashstatus != VCP_KNOWN || memcmp(jcl->vcardphotohash, digest, sizeof(jcl->vcardphotohash)))
|
||||
{
|
||||
memcpy(jcl->vcardphotohash, digest, sizeof(jcl->vcardphotohash));
|
||||
|
@ -3950,7 +3950,7 @@ char *buildcapshash(jclient_t *jcl)
|
|||
Q_strlcat(out, caps[i].name, outlen);
|
||||
Q_strlcat(out, "<", outlen);
|
||||
}
|
||||
l = SHA1(digest, sizeof(digest), out, strlen(out));
|
||||
l = CalcHash(&hash_sha1, digest, sizeof(digest), out, strlen(out));
|
||||
for (i = 0; i < l; i++)
|
||||
Base64_Byte(digest[i]);
|
||||
Base64_Finish();
|
||||
|
|
|
@ -63,7 +63,7 @@ void XMPP_FT_Frame(jclient_t *jcl)
|
|||
//server has accepted us, woo.
|
||||
//sid+requester(them)+target(us)
|
||||
req = va("%s%s%s", ft->sid, ft->with, jcl->fulljid);
|
||||
SHA1(digest, sizeof(digest), req, strlen(req));
|
||||
CalcHash(&hash_sha1, digest, sizeof(digest), req, strlen(req));
|
||||
//in hex
|
||||
for (req = domain, j=0; j < 20; j++)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue