mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-01-31 20:50:47 +00:00
Add a maptimes log, to display best times (and whether a map has actually been completed).
update the qi plugin a little, and for maptimes. Try to fix a bug with android. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5480 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
5fabdcd186
commit
9c7ba654b5
19 changed files with 349 additions and 76 deletions
|
@ -1069,7 +1069,7 @@ void PM_EnumeratePlugins(void (*callback)(const char *name))
|
|||
{
|
||||
if (d->dtype == DEP_FILE)
|
||||
{
|
||||
if (!Q_strncasecmp(d->name, "fteplug_", 8))
|
||||
if (!Q_strncasecmp(d->name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
|
||||
callback(d->name);
|
||||
}
|
||||
}
|
||||
|
@ -1094,8 +1094,8 @@ static int QDECL PM_EnumeratedPlugin (const char *name, qofs_t size, time_t mtim
|
|||
char vmname[MAX_QPATH];
|
||||
int len, l, a;
|
||||
char *dot;
|
||||
if (!strncmp(name, "fteplug_", 8))
|
||||
Q_strncpyz(vmname, name+8, sizeof(vmname));
|
||||
if (!strncmp(name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
|
||||
Q_strncpyz(vmname, name+strlen(PLUGINPREFIX), sizeof(vmname));
|
||||
else
|
||||
Q_strncpyz(vmname, name, sizeof(vmname));
|
||||
len = strlen(vmname);
|
||||
|
@ -1192,7 +1192,7 @@ static void PM_PreparePackageList(void)
|
|||
char nat[MAX_OSPATH];
|
||||
FS_NativePath("", FS_BINARYPATH, nat, sizeof(nat));
|
||||
Con_DPrintf("Loading plugins from \"%s\"\n", nat);
|
||||
Sys_EnumerateFiles(nat, "fteplug_*" ARCH_DL_POSTFIX, PM_EnumeratedPlugin, &foundone, NULL);
|
||||
Sys_EnumerateFiles(nat, PLUGINPREFIX"*" ARCH_DL_POSTFIX, PM_EnumeratedPlugin, &foundone, NULL);
|
||||
if (foundone && !pluginpromptshown)
|
||||
{
|
||||
pluginpromptshown = true;
|
||||
|
@ -2076,7 +2076,7 @@ static void PM_PackageEnabled(package_t *p)
|
|||
if (!stricmp(ext, "pak") || !stricmp(ext, "pk3"))
|
||||
FS_ReloadPackFiles();
|
||||
#ifdef PLUGINS
|
||||
if ((p->flags & DPF_PLUGIN) && !Q_strncasecmp(dep->name, "fteplug_", 8))
|
||||
if ((p->flags & DPF_PLUGIN) && !Q_strncasecmp(dep->name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
|
||||
Cmd_ExecuteString(va("plug_load %s\n", dep->name), RESTRICT_LOCAL);
|
||||
#endif
|
||||
#ifdef MENU_DAT
|
||||
|
@ -2173,7 +2173,7 @@ static void PM_Download_Got(struct dl_download *dl)
|
|||
if (!stricmp(ext, "pak") || !stricmp(ext, "pk3"))
|
||||
FS_UnloadPackFiles(); //we reload them after
|
||||
#ifdef PLUGINS
|
||||
if ((!stricmp(ext, "dll") || !stricmp(ext, "so")) && !Q_strncmp(dep->name, "fteplug_", 8))
|
||||
if ((!stricmp(ext, "dll") || !stricmp(ext, "so")) && !Q_strncmp(dep->name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
|
||||
Cmd_ExecuteString(va("plug_close %s\n", dep->name), RESTRICT_LOCAL); //try to purge plugins so there's no files left open
|
||||
#endif
|
||||
|
||||
|
@ -2509,7 +2509,7 @@ void PM_ApplyChanges(void)
|
|||
reloadpacks = true;
|
||||
|
||||
#ifdef PLUGINS //when disabling/purging plugins, be sure to unload them first (unfortunately there might be some latency before this can actually happen).
|
||||
if ((p->flags & DPF_PLUGIN) && !Q_strncasecmp(dep->name, "fteplug_", 8))
|
||||
if ((p->flags & DPF_PLUGIN) && !Q_strncasecmp(dep->name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
|
||||
Cmd_ExecuteString(va("plug_close %s\n", dep->name), RESTRICT_LOCAL); //try to purge plugins so there's no files left open
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1173,7 +1173,7 @@ static jboolean FTENativeActivity_startup(JNIEnv *jni, jobject this, jstring ext
|
|||
|
||||
static void FTENativeActivity_surfacechange(JNIEnv *env, jobject this, jboolean teardown, jboolean recreate, jobject surface)
|
||||
{
|
||||
if (this == sys_activity)
|
||||
if (!(*env)->IsSameObject(env, this, sys_activity))
|
||||
{
|
||||
LOGI("FTENativeActivity_surfacechange: inactive %p, active %p\n", this, sys_activity);
|
||||
return; //wasn't me...
|
||||
|
@ -1200,7 +1200,7 @@ static void FTENativeActivity_surfacechange(JNIEnv *env, jobject this, jboolean
|
|||
}
|
||||
static void FTENativeActivity_shutdown(JNIEnv *env, jobject this)
|
||||
{
|
||||
if (this != sys_activity)
|
||||
if (!(*env)->IsSameObject(env, this, sys_activity))
|
||||
{
|
||||
LOGI("FTENativeActivity_shutdown: inactive %p, active %p\n", this, sys_activity);
|
||||
return; //wasn't me...
|
||||
|
|
|
@ -526,9 +526,10 @@ struct vfsfile_s;
|
|||
//standard return value is 0 on failure, or depth on success.
|
||||
int FS_FLocateFile(const char *filename, unsigned int flags, flocation_t *loc);
|
||||
struct vfsfile_s *FS_OpenReadLocation(flocation_t *location);
|
||||
char *FS_WhichPackForLocation(flocation_t *loc, qboolean makereferenced);
|
||||
const char *FS_WhichPackForLocation(flocation_t *loc, qboolean makereferenced);
|
||||
qboolean FS_GetLocMTime(flocation_t *location, time_t *modtime);
|
||||
char *FS_GetPackageDownloadFilename(flocation_t *loc);
|
||||
const char *FS_GetPackageDownloadFilename(flocation_t *loc); //returns only packages (or null)
|
||||
const char *FS_GetRootPackagePath(flocation_t *loc); //favours packages, but falls back on gamedirs.
|
||||
|
||||
qboolean FS_GetPackageDownloadable(const char *package);
|
||||
char *FS_GetPackHashes(char *buffer, int buffersize, qboolean referencedonly);
|
||||
|
@ -867,6 +868,11 @@ qboolean IPLog_Merge_File(const char *fname);
|
|||
#endif
|
||||
qboolean CertLog_ConnectOkay(const char *hostname, void *cert, size_t certsize);
|
||||
|
||||
#if defined(HAVE_SERVER) && defined(HAVE_CLIENT)
|
||||
qboolean Log_CheckMapCompletion(const char *packagename, const char *mapname, float *besttime, float *fulltime, float *bestkills, float *bestsecrets);
|
||||
void Log_MapNowCompleted(void);
|
||||
#endif
|
||||
|
||||
|
||||
/*used by and for botlib and q3 gamecode*/
|
||||
#define MAX_TOKENLENGTH 1024
|
||||
|
|
|
@ -1387,10 +1387,38 @@ fail:
|
|||
return depth+1;
|
||||
}
|
||||
|
||||
//returns the location's root package (or gamedir).
|
||||
//(aka: loc->search->purepath, but stripping contained nested packs)
|
||||
const char *FS_GetRootPackagePath(flocation_t *loc)
|
||||
{
|
||||
searchpath_t *sp, *search;
|
||||
|
||||
for (sp = loc->search; ;)
|
||||
{
|
||||
for (search = com_searchpaths; search; search = search->next)
|
||||
{
|
||||
if (search != sp)
|
||||
if (search->handle->GeneratePureCRC) //only consider files that have a pure hash. this excludes system paths
|
||||
if (!strncmp(search->purepath, sp->purepath, strlen(search->purepath)))
|
||||
if (sp->purepath[strlen(search->purepath)] == '/') //also ensures that the path gets shorter, avoiding infinite loops as it fights between base+home dirs.
|
||||
break;
|
||||
}
|
||||
if (search)
|
||||
sp = search;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (sp)
|
||||
return sp->purepath;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//returns the package/'gamedir/foo.pk3' filename to tell the client to download
|
||||
//unfortunately foo.pk3 may contain a 'bar.pk3' and downloading dir/foo.pk3/bar.pk3 won't work
|
||||
//so if loc->search is dir/foo.pk3/bar.pk3 find dir/foo.pk3 instead
|
||||
char *FS_GetPackageDownloadFilename(flocation_t *loc)
|
||||
const char *FS_GetPackageDownloadFilename(flocation_t *loc)
|
||||
{
|
||||
searchpath_t *sp, *search;
|
||||
|
||||
|
@ -1414,7 +1442,7 @@ char *FS_GetPackageDownloadFilename(flocation_t *loc)
|
|||
return sp->purepath;
|
||||
return NULL;
|
||||
}
|
||||
char *FS_WhichPackForLocation(flocation_t *loc, qboolean makereferenced)
|
||||
const char *FS_WhichPackForLocation(flocation_t *loc, qboolean makereferenced)
|
||||
{
|
||||
char *ret;
|
||||
if (!loc->search)
|
||||
|
@ -6199,6 +6227,12 @@ static void FS_ChangeMod_f(void)
|
|||
arg = va("map \"%s\"\n", Cmd_Argv(i++));
|
||||
fs_loadedcommand = Z_StrDup(arg);
|
||||
}
|
||||
else if (!strcmp(arg, "spmap"))
|
||||
{
|
||||
Z_Free(fs_loadedcommand);
|
||||
arg = va("deathmatch 0;coop 0;spmap \"%s\"\n", Cmd_Argv(i++));
|
||||
fs_loadedcommand = Z_StrDup(arg);
|
||||
}
|
||||
else if (!strcmp(arg, "restart"))
|
||||
{
|
||||
Z_Free(fs_loadedcommand);
|
||||
|
|
|
@ -795,8 +795,164 @@ qboolean CertLog_ConnectOkay(const char *hostname, void *cert, size_t certsize)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(HAVE_SERVER) && defined(HAVE_CLIENT)
|
||||
static struct maplog_entry
|
||||
{
|
||||
struct maplog_entry *next;
|
||||
float bestkills;
|
||||
float bestsecrets;
|
||||
float besttime; //updated when besttime<newtime (note: doesn't respond to user changelevels from the console...)
|
||||
float fulltime; //updated when bestkills>=newkills
|
||||
char name[1];
|
||||
} *maplog_enties;
|
||||
static void Log_MapsRead(void)
|
||||
{
|
||||
struct maplog_entry *m, **link = &maplog_enties;
|
||||
vfsfile_t *f;
|
||||
static qboolean maplog_loaded;
|
||||
char line[8192], *s;
|
||||
if (maplog_loaded)
|
||||
return;
|
||||
maplog_loaded = true;
|
||||
f = FS_OpenVFS("maptimes.txt", "rb", FS_ROOT);
|
||||
if (!f)
|
||||
return; //no info yet.
|
||||
while (VFS_GETS(f, line, sizeof(line)))
|
||||
{
|
||||
s = line;
|
||||
s = COM_Parse(s);
|
||||
m = Z_Malloc(sizeof(*m) + strlen(com_token));
|
||||
strcpy(m->name, com_token);
|
||||
|
||||
s = COM_Parse(s);
|
||||
m->besttime = atof(com_token);
|
||||
s = COM_Parse(s);
|
||||
m->fulltime = atof(com_token);
|
||||
s = COM_Parse(s);
|
||||
m->bestkills = atof(com_token);
|
||||
s = COM_Parse(s);
|
||||
m->bestsecrets = atof(com_token);
|
||||
|
||||
*link = m;
|
||||
link = &m->next;
|
||||
}
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
struct maplog_entry *Log_FindMap(const char *purepackage, const char *mapname)
|
||||
{
|
||||
const char *name = va("%s/%s", purepackage, mapname);
|
||||
struct maplog_entry *m;
|
||||
Log_MapsRead();
|
||||
for (m = maplog_enties; m; m = m->next)
|
||||
{
|
||||
if (!strcmp(m->name, name))
|
||||
break;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
static void Log_MapsDump(void)
|
||||
{
|
||||
if (maplog_enties)
|
||||
{
|
||||
struct maplog_entry *m;
|
||||
vfsfile_t *f = FS_OpenVFS("maptimes.txt", "wbp", FS_ROOT);
|
||||
if (f)
|
||||
{
|
||||
for(m = maplog_enties; m; m = m->next)
|
||||
{
|
||||
VFS_PRINTF(f, "\"%s\" %.9g %.9g %.9g %.9g\n", m->name, m->besttime, m->fulltime, m->bestkills, m->bestsecrets);
|
||||
}
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
qboolean Log_CheckMapCompletion(const char *packagename, const char *mapname, float *besttime, float *fulltime, float *bestkills, float *bestsecrets)
|
||||
{
|
||||
struct maplog_entry *m;
|
||||
if (!packagename)
|
||||
{
|
||||
flocation_t loc;
|
||||
if (!FS_FLocateFile(mapname, FSLF_DONTREFERENCE|FSLF_IGNORELINKS, &loc))
|
||||
return false; //no idea which package, don't guess.
|
||||
packagename = FS_GetRootPackagePath(&loc);
|
||||
if (!packagename)
|
||||
return false;
|
||||
}
|
||||
m = Log_FindMap(packagename, mapname);
|
||||
if (m)
|
||||
{
|
||||
*besttime = m->besttime;
|
||||
*fulltime = m->fulltime;
|
||||
*bestkills = m->bestkills;
|
||||
*bestsecrets = m->bestsecrets;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void Log_MapNowCompleted(void)
|
||||
{
|
||||
struct maplog_entry *m;
|
||||
flocation_t loc;
|
||||
float kills, secrets, oldprogress, newprogress, maptime;
|
||||
const char *packagename;
|
||||
|
||||
//don't log it if its deathmatch/coop/cheating.
|
||||
extern int sv_allow_cheats;
|
||||
if (deathmatch.ival || coop.ival || sv_allow_cheats == 1)
|
||||
return;
|
||||
|
||||
if (!FS_FLocateFile(sv.world.worldmodel->name, FSLF_DONTREFERENCE|FSLF_IGNORELINKS, &loc))
|
||||
{
|
||||
Con_Printf("completion log: unable to determine logical path for map\n");
|
||||
return; //don't know
|
||||
}
|
||||
packagename = FS_GetRootPackagePath(&loc);
|
||||
if (!packagename)
|
||||
{
|
||||
Con_Printf("completion log: unable to determine logical path for map\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m = Log_FindMap(packagename, sv.world.worldmodel->name);
|
||||
if (!m)
|
||||
{
|
||||
m = Z_Malloc(sizeof(*m)+strlen(packagename)+strlen(sv.world.worldmodel->name)+2);
|
||||
sprintf(m->name, "%s/%s", packagename, sv.world.worldmodel->name);
|
||||
|
||||
m->fulltime = m->besttime = INFINITY;
|
||||
m->bestkills = m->bestsecrets = 0;
|
||||
m->next = maplog_enties;
|
||||
maplog_enties = m;
|
||||
}
|
||||
|
||||
kills = pr_global_struct->killed_monsters;
|
||||
secrets = pr_global_struct->found_secrets;
|
||||
maptime = sv.world.physicstime;
|
||||
|
||||
newprogress = secrets*10+kills;
|
||||
oldprogress = m->bestsecrets*10+m->bestkills;
|
||||
|
||||
//if they got a new time record, update.
|
||||
if (maptime<m->besttime)
|
||||
m->besttime = maptime;
|
||||
//if they got a new kills record, update
|
||||
if (newprogress > oldprogress || (newprogress==oldprogress && maptime<m->fulltime))
|
||||
{
|
||||
m->bestkills = kills;
|
||||
m->bestsecrets = secrets;
|
||||
m->fulltime = maptime;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Log_ShutDown(void)
|
||||
{
|
||||
#if defined(HAVE_SERVER) && defined(HAVE_CLIENT)
|
||||
Log_MapsDump();
|
||||
#endif
|
||||
|
||||
#ifdef IPLOG
|
||||
if (iplog_autodump.ival)
|
||||
IPLog_Dump("iplog.txt");
|
||||
|
|
|
@ -252,8 +252,8 @@ static char *Plug_CleanName(const char *file, char *out, size_t sizeof_out)
|
|||
//"fteplug_ezhud_x86.REV.dll" gets converted into "ezhud"
|
||||
|
||||
//skip fteplug_
|
||||
if (!Q_strncasecmp(file, "fteplug_", 8))
|
||||
file += 8;
|
||||
if (!Q_strncasecmp(file, PLUGINPREFIX, strlen(PLUGINPREFIX)))
|
||||
file += strlen(PLUGINPREFIX);
|
||||
|
||||
//strip .REV.dll
|
||||
COM_StripAllExtensions(file, out, sizeof_out);
|
||||
|
@ -283,19 +283,21 @@ static plugin_t *Plug_Load(const char *file, int type)
|
|||
newplug->name = (char*)(newplug+1);
|
||||
strcpy(newplug->name, temp);
|
||||
|
||||
if (!newplug->vm && (type & PLUG_NATIVE) && !Q_strncasecmp(file, "fteplug_", 8) && !Q_strcasecmp(ARCH_DL_POSTFIX+1, COM_FileExtension(file, temp, sizeof(temp))))
|
||||
if (!newplug->vm && (type & PLUG_NATIVE) && !Q_strncasecmp(file, PLUGINPREFIX, strlen(PLUGINPREFIX)) && !Q_strcasecmp(ARCH_DL_POSTFIX+1, COM_FileExtension(file, temp, sizeof(temp))))
|
||||
{
|
||||
COM_StripExtension(file, temp, sizeof(temp));
|
||||
newplug->vm = VM_Create(temp, Plug_SystemCallsNative, NULL, NULL);
|
||||
}
|
||||
#ifndef ANDROID
|
||||
if (!newplug->vm && (type & PLUG_NATIVE))
|
||||
{
|
||||
Q_snprintfz(temp, sizeof(temp), "fteplug_%s_", file);
|
||||
Q_snprintfz(temp, sizeof(temp), PLUGINPREFIX"%s_", file);
|
||||
newplug->vm = VM_Create(temp, Plug_SystemCallsNative, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
if (!newplug->vm && (type & PLUG_NATIVE))
|
||||
{
|
||||
Q_snprintfz(temp, sizeof(temp), "fteplug_%s", file);
|
||||
Q_snprintfz(temp, sizeof(temp), PLUGINPREFIX"%s", file);
|
||||
newplug->vm = VM_Create(temp, Plug_SystemCallsNative, NULL, NULL);
|
||||
}
|
||||
if (!newplug->vm && (type & PLUG_QVM))
|
||||
|
@ -355,7 +357,7 @@ static int QDECL Plug_EnumeratedRoot (const char *name, qofs_t size, time_t mtim
|
|||
char vmname[MAX_QPATH];
|
||||
int len;
|
||||
char *dot;
|
||||
if (!strncmp(name, "fteplug_", 8))
|
||||
if (!strncmp(name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
|
||||
name += 8;
|
||||
Q_strncpyz(vmname, name, sizeof(vmname));
|
||||
len = strlen(vmname);
|
||||
|
@ -1530,6 +1532,28 @@ static qintptr_t VARGS Plug_UpdateInputBuffer(void *offset, quintptr_t mask, con
|
|||
return bufferlen;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SERVER) && defined(HAVE_CLIENT)
|
||||
qboolean FS_PathURLCache(const char *url, char *path, size_t pathsize);
|
||||
static qintptr_t VARGS Plug_MapLog_Query(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
const char *packagename = VM_POINTER(arg[0]);
|
||||
const char *mapname = VM_POINTER(arg[1]);
|
||||
float *vals = VM_POINTER(arg[2]);
|
||||
if (VM_OOB(arg[2], sizeof(*vals)*4))
|
||||
return false;
|
||||
if (!strncmp(packagename, "http://", 7) || !strncmp(packagename, "https://", 8))
|
||||
{
|
||||
char temp[MAX_OSPATH];
|
||||
if (!FS_PathURLCache(packagename, temp, sizeof(temp)))
|
||||
return false;
|
||||
if (Log_CheckMapCompletion(temp, mapname, &vals[0], &vals[1], &vals[2], &vals[3]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return Log_CheckMapCompletion(packagename, mapname, &vals[0], &vals[1], &vals[2], &vals[3]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USERBE
|
||||
#include "pr_common.h"
|
||||
//functions useful for rigid body engines.
|
||||
|
@ -1567,7 +1591,7 @@ static void Plug_Load_f(void)
|
|||
Con_Printf("Loads a plugin\n");
|
||||
Con_Printf("plug_load [pluginpath]\n");
|
||||
Con_Printf("example pluginpath: blah\n");
|
||||
Con_Printf("will load fteplug_blah"ARCH_CPU_POSTFIX ARCH_DL_POSTFIX" or $gamedir/plugins/blah.qvm\n");
|
||||
Con_Printf("will load "PLUGINPREFIX"blah"ARCH_CPU_POSTFIX ARCH_DL_POSTFIX" or $gamedir/plugins/blah.qvm\n");
|
||||
return;
|
||||
}
|
||||
if (!Plug_Load(plugin, PLUG_EITHER))
|
||||
|
@ -1695,6 +1719,10 @@ void Plug_Initialise(qboolean fromgamedir)
|
|||
#endif
|
||||
Plug_RegisterBuiltin("PR_GetVMInstance", Plug_PR_GetVMInstance, PLUG_BIF_DLLONLY);
|
||||
|
||||
#if defined(HAVE_SERVER) && defined(HAVE_CLIENT)
|
||||
Plug_RegisterBuiltin("MapLog_Query", Plug_MapLog_Query, 0);
|
||||
#endif
|
||||
|
||||
Plug_Client_Init();
|
||||
}
|
||||
|
||||
|
@ -1707,7 +1735,7 @@ void Plug_Initialise(qboolean fromgamedir)
|
|||
{
|
||||
FS_NativePath("", FS_BINARYPATH, nat, sizeof(nat));
|
||||
Con_DPrintf("Loading plugins from \"%s\"\n", nat);
|
||||
Sys_EnumerateFiles(nat, "fteplug_*" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, Plug_EnumeratedRoot, NULL, NULL);
|
||||
Sys_EnumerateFiles(nat, PLUGINPREFIX"*" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, Plug_EnumeratedRoot, NULL, NULL);
|
||||
}
|
||||
if (fromgamedir)
|
||||
{
|
||||
|
@ -2201,7 +2229,7 @@ int QDECL Plug_List_Print(const char *fname, qofs_t fsize, time_t modtime, void
|
|||
if (!Q_strncasecmp(existing, parm, strlen(parm)) && !Q_strcasecmp(existing+strlen(parm), fname))
|
||||
return true;
|
||||
}
|
||||
Con_Printf("^[%s%s\\type\\plug_load %s\\^]: not loaded\n", (const char*)parm, fname, plugname+((!Q_strncasecmp(plugname,"fteplug_", 8))?8:0));
|
||||
Con_Printf("^[%s%s\\type\\plug_load %s\\^]: not loaded\n", (const char*)parm, fname, plugname+((!Q_strncasecmp(plugname,PLUGINPREFIX, strlen(PLUGINPREFIX)))?strlen(PLUGINPREFIX):0));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -2223,14 +2251,14 @@ void Plug_List_f(void)
|
|||
{
|
||||
while ((mssuck=strchr(binarypath, '\\')))
|
||||
*mssuck = '/';
|
||||
Sys_EnumerateFiles(binarypath, "fteplug_*" ARCH_DL_POSTFIX, Plug_List_Print, binarypath, NULL);
|
||||
Sys_EnumerateFiles(binarypath, PLUGINPREFIX"*" ARCH_DL_POSTFIX, Plug_List_Print, binarypath, NULL);
|
||||
}
|
||||
if (FS_NativePath("", FS_ROOT, rootpath, sizeof(rootpath)))
|
||||
{
|
||||
while ((mssuck=strchr(rootpath, '\\')))
|
||||
*mssuck = '/';
|
||||
if (strcmp(binarypath, rootpath))
|
||||
Sys_EnumerateFiles(rootpath, "fteplug_*" ARCH_DL_POSTFIX, Plug_List_Print, rootpath, NULL);
|
||||
Sys_EnumerateFiles(rootpath, PLUGINPREFIX"*" ARCH_DL_POSTFIX, Plug_List_Print, rootpath, NULL);
|
||||
}
|
||||
|
||||
for (u = 0; staticplugins[u].name; u++)
|
||||
|
|
|
@ -106,7 +106,10 @@ qboolean QVM_LoadDLL(vm_t *vm, const char *name, qboolean binroot, void **vmMain
|
|||
if (binroot)
|
||||
{
|
||||
Con_DPrintf("Attempting to load native library: %s\n", name);
|
||||
|
||||
#ifdef ANDROID
|
||||
if (!hVM && FS_NativePath(dllname_anycpu, FS_BINARYPATH, fname, sizeof(fname)))
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
#else
|
||||
if (!hVM && FS_NativePath(dllname_archpri, FS_BINARYPATH, fname, sizeof(fname)))
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
if (!hVM && FS_NativePath(dllname_anycpu, FS_BINARYPATH, fname, sizeof(fname)))
|
||||
|
@ -116,27 +119,32 @@ qboolean QVM_LoadDLL(vm_t *vm, const char *name, qboolean binroot, void **vmMain
|
|||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
if (!hVM && FS_NativePath(dllname_anycpu, FS_ROOT, fname, sizeof(fname)))
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
#endif
|
||||
|
||||
// run through the search paths
|
||||
iterator = NULL;
|
||||
while (!hVM && COM_IteratePaths(&iterator, NULL, 0, gpath, sizeof(gpath)))
|
||||
{
|
||||
#ifndef ANDROID
|
||||
if (!hVM && FS_NativePath(va("%s_%s_"ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, name, gpath), FS_BINARYPATH, fname, sizeof(fname)))
|
||||
{
|
||||
Con_DLPrintf(2, "Loading native: %s\n", fname);
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
}
|
||||
#endif
|
||||
if (!hVM && FS_NativePath(va("%s_%s"ARCH_DL_POSTFIX, name, gpath), FS_BINARYPATH, fname, sizeof(fname)))
|
||||
{
|
||||
Con_DLPrintf(2, "Loading native: %s\n", fname);
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
}
|
||||
|
||||
#ifndef ANDROID
|
||||
if (!hVM && FS_NativePath(va("%s_%s_"ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, name, gpath), FS_ROOT, fname, sizeof(fname)))
|
||||
{
|
||||
Con_DLPrintf(2, "Loading native: %s\n", fname);
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
}
|
||||
#endif
|
||||
if (!hVM && FS_NativePath(va("%s_%s"ARCH_DL_POSTFIX, name, gpath), FS_ROOT, fname, sizeof(fname)))
|
||||
{
|
||||
Con_DLPrintf(2, "Loading native: %s\n", fname);
|
||||
|
|
|
@ -49,6 +49,12 @@ void Plug_SBar(playerview_t *pv);
|
|||
qboolean Plug_ServerMessage(char *buffer, int messagelevel);
|
||||
void Plug_Tick(void);
|
||||
qboolean Plugin_ExecuteString(void);
|
||||
|
||||
#ifdef ANDROID
|
||||
#define PLUGINPREFIX "libplug_" //android is kinda annoying and only extracts specific files.
|
||||
#else
|
||||
#define PLUGINPREFIX "fteplug_" //this string defines what consitutes a plugin, as opposed to some other dll
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -104,8 +104,6 @@ public class FTENativeActivity extends android.app.Activity implements android.v
|
|||
// }
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
//Needed because the InputQueue stuff blocks dispatchKeyEvent
|
||||
getWindow().takeInputQueue(null);
|
||||
}
|
||||
|
||||
//random helpers
|
||||
|
@ -134,7 +132,7 @@ public class FTENativeActivity extends android.app.Activity implements android.v
|
|||
{
|
||||
try
|
||||
{
|
||||
String secondary = (String) android.content.pm.ApplicationInfo.class.getField("nativeLibraryRootDir").get(context.getApplicationInfo());
|
||||
String secondary = (String) android.content.pm.ApplicationInfo.class.getField("nativeLibraryDir").get(context.getApplicationInfo());
|
||||
return secondary;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -7866,42 +7866,34 @@ void R_RemapShader(const char *sourcename, const char *destname, float timeoffse
|
|||
{
|
||||
shader_t *o;
|
||||
shader_t *n;
|
||||
int i;
|
||||
|
||||
//make sure all types of the shader are remapped properly.
|
||||
//if there's a .shader file with it then it should 'just work'.
|
||||
char cleansrcname[MAX_QPATH];
|
||||
Q_strncpyz(cleansrcname, sourcename, sizeof(cleansrcname));
|
||||
COM_CleanUpPath(cleansrcname);
|
||||
|
||||
o = R_LoadShader (sourcename, SUF_NONE, NULL, NULL);
|
||||
n = R_LoadShader (destname, SUF_NONE, NULL, NULL);
|
||||
if (o)
|
||||
for (i = 0; i < r_numshaders; i++)
|
||||
{
|
||||
o = r_shaders[i];
|
||||
if (o && o->uses)
|
||||
{
|
||||
if (!strcmp(o->name, cleansrcname))
|
||||
{
|
||||
n = R_LoadShader (destname, o->usageflags, NULL, NULL);
|
||||
if (!n)
|
||||
{ //if it isn't actually available on disk then don't care about usageflags, just find ANY that's already loaded.
|
||||
// check the hash first
|
||||
char cleandstname[MAX_QPATH];
|
||||
Q_strncpyz(cleandstname, destname, sizeof(cleandstname));
|
||||
COM_CleanUpPath(cleandstname);
|
||||
n = Hash_Get(&shader_active_hash, cleandstname);
|
||||
if (!n || !n->uses)
|
||||
n = o;
|
||||
}
|
||||
o->remapto = n;
|
||||
o->remaptime = timeoffset; //this just feels wrong.
|
||||
}
|
||||
|
||||
o = R_LoadShader (sourcename, SUF_2D, NULL, NULL);
|
||||
n = R_LoadShader (destname, SUF_2D, NULL, NULL);
|
||||
if (o)
|
||||
{
|
||||
if (!n)
|
||||
n = o;
|
||||
o->remapto = n;
|
||||
o->remaptime = timeoffset;
|
||||
}
|
||||
|
||||
o = R_LoadShader (sourcename, SUF_LIGHTMAP, NULL, NULL);
|
||||
n = R_LoadShader (destname, SUF_LIGHTMAP, NULL, NULL);
|
||||
if (o)
|
||||
{
|
||||
if (!n)
|
||||
{
|
||||
n = R_LoadShader (destname, SUF_2D, NULL, NULL);
|
||||
if (!n)
|
||||
n = o;
|
||||
}
|
||||
o->remapto = n;
|
||||
o->remaptime = timeoffset;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ SOCKET FTP_BeginListening(int aftype, int port)
|
|||
{
|
||||
struct sockaddr_qstorage address;
|
||||
unsigned long _true = true;
|
||||
unsigned long _false = false;
|
||||
int i;
|
||||
SOCKET sock;
|
||||
|
||||
|
@ -116,6 +115,7 @@ SOCKET FTP_BeginListening(int aftype, int port)
|
|||
//2=ipv6 only
|
||||
if (aftype == 0)
|
||||
{
|
||||
unsigned long _false = false;
|
||||
if (0 > setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&_false, sizeof(_false)))
|
||||
{
|
||||
//abort and do ipv4 only if hybrid sockets don't work.
|
||||
|
|
|
@ -728,6 +728,10 @@ void NPP_NQFlush(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CLIENT)
|
||||
Log_MapNowCompleted();
|
||||
#endif
|
||||
|
||||
for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++)
|
||||
{
|
||||
if (cl->state == cs_spawned && ISQWCLIENT(cl))
|
||||
|
@ -1758,6 +1762,9 @@ void NPP_QWFlush(void)
|
|||
break;
|
||||
//ignore these.
|
||||
case svc_intermission:
|
||||
#if defined(HAVE_CLIENT)
|
||||
Log_MapNowCompleted();
|
||||
#endif
|
||||
// if (writedest == &sv.reliable_datagram)
|
||||
{
|
||||
client_t *cl;
|
||||
|
|
|
@ -5925,6 +5925,10 @@ void QCBUILTIN PF_changelevel (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
return;
|
||||
sv.mapchangelocked = true;
|
||||
|
||||
#ifdef HAVE_CLIENT
|
||||
Log_MapNowCompleted();
|
||||
#endif
|
||||
|
||||
#ifdef HEXEN2
|
||||
if (progstype == PROG_H2)
|
||||
{
|
||||
|
|
|
@ -392,8 +392,24 @@ static int QDECL ShowMapList (const char *name, qofs_t flags, time_t mtime, void
|
|||
};
|
||||
size_t u;
|
||||
char stripped[64];
|
||||
char completed[256];
|
||||
if (name[5] == 'b' && name[6] == '_') //skip box models
|
||||
return true;
|
||||
|
||||
*completed = 0;
|
||||
#ifdef HAVE_CLIENT
|
||||
{
|
||||
float besttime, fulltime, kills, secrets;
|
||||
if (Log_CheckMapCompletion(NULL, name, &besttime, &fulltime, &kills, &secrets))
|
||||
{
|
||||
if (kills || secrets)
|
||||
Q_snprintfz(completed, sizeof(completed), "^7 - ^2best: ^1%.1f^2, full: ^1%.1f^2 (^1%.0f^2 kills, ^1%.0f^2 secrets)", besttime, fulltime, kills, secrets);
|
||||
else
|
||||
Q_snprintfz(completed, sizeof(completed), "^7 - ^2best: ^1%.1f^2", besttime);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
COM_StripExtension(name+5, stripped, sizeof(stripped));
|
||||
for (u = 0; u < countof(levelshots); u++)
|
||||
{
|
||||
|
@ -401,11 +417,11 @@ static int QDECL ShowMapList (const char *name, qofs_t flags, time_t mtime, void
|
|||
if (COM_FCheckExists(ls))
|
||||
{
|
||||
Con_Printf("^[\\map\\%s\\img\\%s\\w\\64\\h\\48^]", stripped, ls);
|
||||
Con_Printf("^[[%s]\\map\\%s\\tipimg\\%s^]\n", stripped, stripped, ls);
|
||||
Con_Printf("^[[%s]%s\\map\\%s\\tipimg\\%s^]\n", stripped, completed, stripped, ls);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Con_Printf("^[[%s]\\map\\%s^]\n", stripped, stripped);
|
||||
Con_Printf("^[[%s]%s\\map\\%s^]\n", stripped, completed, stripped);
|
||||
return true;
|
||||
}
|
||||
static int QDECL ShowMapListExt (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
|
||||
|
|
|
@ -3220,7 +3220,7 @@ static int SV_LocateDownload(const char *name, flocation_t *loc, char **replacem
|
|||
if (replacementname)
|
||||
{
|
||||
#if 1
|
||||
char *pakname = FS_GetPackageDownloadFilename(loc);
|
||||
const char *pakname = FS_GetPackageDownloadFilename(loc);
|
||||
if (pakname && strchr(pakname, '/'))
|
||||
{
|
||||
extern cvar_t allow_download_packages,allow_download_copyrighted; //non authoritive, but should normally match.
|
||||
|
|
|
@ -68,7 +68,7 @@ ifeq ($(PLUG_NATIVE_EXT),)
|
|||
endif
|
||||
ifeq ($(FTE_TARGET),droid)
|
||||
#plugins get written to the tmp build dir, to avoid conflicts
|
||||
PLUG_PREFIX=$(OUT_DIR)/m_droid-$(DROID_ARCH)/fteplug_
|
||||
PLUG_PREFIX=$(OUT_DIR)/m_droid-$(DROID_ARCH)/libplug_
|
||||
#don't bother with cpu arch postfixes. they'll be in separate directories anyway.
|
||||
PLUG_NATIVE_EXT=.so
|
||||
#libresolv has no public api on android...
|
||||
|
|
|
@ -170,6 +170,10 @@ BUILTINR(int, GetLastInputFrame, (int seat, usercmd_t *playercmd));
|
|||
BUILTINR(float, GetTrackerOwnFrags, (int seat, char *text, size_t textsize));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,packagename,mapname,stats
|
||||
BUILTINR(qboolean, MapLog_Query, (const char *packagename, const char *mapname, float *stats));
|
||||
#undef ARGNAMES
|
||||
|
||||
#ifndef Q3_VM
|
||||
#define ARGNAMES ,vmid
|
||||
BUILTINR(struct pubprogfuncs_s*, PR_GetVMInstance, (int vmid/*0=ss,1=cs,2=m*/));
|
||||
|
@ -526,6 +530,8 @@ static void Plug_InitStandardBuiltins(void)
|
|||
CHECKBUILTIN(Con_GetConsoleString);
|
||||
CHECKBUILTIN(Con_SetConsoleString);
|
||||
CHECKBUILTIN(Con_POpen);
|
||||
|
||||
CHECKBUILTIN(MapLog_Query);
|
||||
}
|
||||
|
||||
#ifndef Q3_VM
|
||||
|
|
|
@ -261,6 +261,8 @@ EBUILTIN(int, GetLastInputFrame, (int seat, usercmd_t *playercmd));
|
|||
#endif
|
||||
EBUILTIN(float, GetTrackerOwnFrags, (int seat, char *text, size_t textsize));
|
||||
|
||||
EBUILTIN(qboolean, MapLog_Query, (const char *packagename, const char *mapname, float *stats));
|
||||
|
||||
#ifndef Q3_VM
|
||||
struct pubprogfuncs_s;
|
||||
EBUILTIN(struct pubprogfuncs_s*, PR_GetVMInstance, (int vmid/*0=ss,1=cs,2=m*/));
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
</file>
|
||||
*/
|
||||
|
||||
xmltree_t *thedatabase;
|
||||
qhandle_t dlcontext = -1;
|
||||
static xmltree_t *thedatabase;
|
||||
static qhandle_t dlcontext = -1;
|
||||
|
||||
struct
|
||||
static struct
|
||||
{
|
||||
char namefilter[256];
|
||||
int minrating;
|
||||
|
@ -215,6 +215,7 @@ static void QI_RefreshMapList(qboolean forcedisplay)
|
|||
xmltree_t *file;
|
||||
const char *console = WINDOWNAME;
|
||||
char descbuf[1024];
|
||||
float donestats[4];
|
||||
if (!QI_SetupWindow(console, forcedisplay))
|
||||
return;
|
||||
|
||||
|
@ -257,16 +258,19 @@ static void QI_RefreshMapList(qboolean forcedisplay)
|
|||
switch(atoi(type))
|
||||
{
|
||||
case 1:
|
||||
type = "map";
|
||||
type = "map"; //'single map file(s)'
|
||||
break;
|
||||
case 2:
|
||||
type = "mod";
|
||||
type = "mod"; //'Partial conversion'
|
||||
break;
|
||||
case 4:
|
||||
type = "spd"; //'speedmapping'
|
||||
break;
|
||||
case 5:
|
||||
type = "otr";
|
||||
type = "otr"; //'misc files'
|
||||
break;
|
||||
default:
|
||||
type = "???";
|
||||
type = "???"; //no idea
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -320,20 +324,26 @@ static void QI_RefreshMapList(qboolean forcedisplay)
|
|||
year += 2000;
|
||||
else if (year < 1900)
|
||||
year += 1900;
|
||||
Q_snprintf(descbuf, sizeof(descbuf), "Id: %s\nAuthor: %s\nDate: %04u-%02u-%02u\nRating: %s\n\n", id, author, year, month, day, ratingtext);
|
||||
Q_snprintf(descbuf, sizeof(descbuf), "^aId:^a %s\n^aAuthor(s):^a %s\n^aDate:^a %04u-%02u-%02u\n^aRating:^a %s\n\n", id, author, year, month, day, ratingtext);
|
||||
|
||||
QI_DeHTML(desc, descbuf + strlen(descbuf), sizeof(descbuf) - strlen(descbuf));
|
||||
desc = descbuf;
|
||||
|
||||
Con_SubPrintf(console, "%s %s ^[^4%s: ^1%s\\tip\\%s\\tipimg\\"FILEIMAGEURL"\\id\\%s^]", type, ratingtext, id, XML_GetChildBody(file, "title", "<NO TITLE>"), desc, id, id);
|
||||
for (startmapnum = 0; ; startmapnum++)
|
||||
{
|
||||
char bspfile[MAX_QPATH];
|
||||
startmap = XML_ChildOfTree(tech, "startmap", startmapnum);
|
||||
if (!startmap)
|
||||
break;
|
||||
Con_SubPrintf(console, "%s ^[%s (%s)\\tip\\%s\\tipimg\\"FILEIMAGEURL"\\id\\%s\\startmap\\%s^]\n", type, XML_GetChildBody(file, "title", "<NO TITLE>"), startmap->body, desc, id, id, startmap->body);
|
||||
|
||||
Q_snprintf(bspfile, sizeof(bspfile), "maps/%s.bsp", startmap->body);
|
||||
if (BUILTINISVALID(MapLog_Query) && pMapLog_Query(va(FILEDOWNLOADURL, id), bspfile, donestats))
|
||||
Con_SubPrintf(console, " ^[^2[%s, complete %.1f]\\tip\\^7^aBest Time:^a ^2%.9f^7\n^aCompletion Time:^a %.9f\n^aKills:^a %.9f\n^aSecrets:^a %.9f\n\n\n%s\\tipimg\\"FILEIMAGEURL"\\id\\%s\\startmap\\%s^]", startmap->body, donestats[0], donestats[0], donestats[1], donestats[2], donestats[3], desc, id, id, startmap->body);
|
||||
else
|
||||
Con_SubPrintf(console, " ^[^4[%s]\\tip\\%s\\tipimg\\"FILEIMAGEURL"\\id\\%s\\startmap\\%s^]", startmap->body, desc, id, id, startmap->body);
|
||||
}
|
||||
if (!startmapnum)
|
||||
Con_SubPrintf(console, "%s ^[%s\\tip\\%s\\tipimg\\"FILEIMAGEURL"\\id\\%s^]\n", type, XML_GetChildBody(file, "title", "<NO TITLE>"), desc, id, id);
|
||||
Con_SubPrintf(console, "\n");
|
||||
}
|
||||
|
||||
Con_SubPrintf(console, "\nFilter:\n");
|
||||
|
@ -489,7 +499,7 @@ static void QI_RunMap(xmltree_t *qifile, const char *map)
|
|||
map = "";
|
||||
|
||||
|
||||
pCmd_AddText("fs_changemod map \"", false);
|
||||
pCmd_AddText("fs_changemod spmap \"", false);
|
||||
pCmd_AddText(map, false);
|
||||
pCmd_AddText("\"", false);
|
||||
QI_AddPackages(qifile);
|
||||
|
|
Loading…
Reference in a new issue