'Relatized' the path passed to FileToKeyValues() native.
This eliminates the annoying warning in L4D: ***VPK: FindFile Attempting to use full path with VPK file!
This commit is contained in:
parent
9ae456b9d1
commit
2acf1b08d5
@ -91,6 +91,151 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* From MM:S - metamod_util.cpp */
|
||||||
|
inline bool pathchar_isalpha(char a)
|
||||||
|
{
|
||||||
|
return (((a & 1<<7) == 0) && isalpha(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool pathchar_sep(char a)
|
||||||
|
{
|
||||||
|
#if defined WIN32
|
||||||
|
return (a == '/' || a == '\\');
|
||||||
|
#elif defined __linux__
|
||||||
|
return (a == '/');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool pathstr_isabsolute(const char *str)
|
||||||
|
{
|
||||||
|
#if defined WIN32
|
||||||
|
return (pathchar_isalpha(str[0])
|
||||||
|
&& str[1] == ':'
|
||||||
|
&& pathchar_sep(str[2]));
|
||||||
|
#elif defined __linux__
|
||||||
|
return (str[0] == '/');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool pathchar_cmp(char a, char b)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
if (pathchar_isalpha(a) && pathchar_isalpha(b))
|
||||||
|
{
|
||||||
|
return (tolower(a) == tolower(b));
|
||||||
|
}
|
||||||
|
/* Either path separator is acceptable */
|
||||||
|
if (pathchar_sep(a))
|
||||||
|
{
|
||||||
|
return pathchar_sep(b);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return (a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UTIL_Relatize(char buffer[],
|
||||||
|
size_t maxlength,
|
||||||
|
const char *relTo,
|
||||||
|
const char *relFrom)
|
||||||
|
{
|
||||||
|
/* We don't allow relative paths in here, force
|
||||||
|
* the user to resolve these himself!
|
||||||
|
*/
|
||||||
|
if (!pathstr_isabsolute(relTo)
|
||||||
|
|| !pathstr_isabsolute(relFrom))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
/* Relative paths across drives are not possible */
|
||||||
|
if (!pathchar_cmp(relTo[0], relFrom[0]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Get rid of the drive and semicolon part */
|
||||||
|
relTo = &relTo[2];
|
||||||
|
relFrom = &relFrom[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Eliminate the common root between the paths */
|
||||||
|
const char *rootTo = NULL;
|
||||||
|
const char *rootFrom = NULL;
|
||||||
|
while (*relTo != '\0' && *relFrom != '\0')
|
||||||
|
{
|
||||||
|
/* If we get to a new path sequence, start over */
|
||||||
|
if (pathchar_sep(*relTo)
|
||||||
|
&& pathchar_sep(*relFrom))
|
||||||
|
{
|
||||||
|
rootTo = relTo;
|
||||||
|
rootFrom = relFrom;
|
||||||
|
/* If the paths don't compare, stop looking for a common root */
|
||||||
|
} else if (!pathchar_cmp(*relTo, *relFrom)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
relTo++;
|
||||||
|
relFrom++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NULLs shouldn't happen! */
|
||||||
|
if (rootTo == NULL
|
||||||
|
|| rootFrom == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t numLevels = 0;
|
||||||
|
|
||||||
|
/* The root case is special!
|
||||||
|
* Don't count anything from it.
|
||||||
|
*/
|
||||||
|
if (*(rootTo + 1) != '\0')
|
||||||
|
{
|
||||||
|
/* Search for how many levels we need to go up.
|
||||||
|
* Since the root pointer points to a '/', we increment
|
||||||
|
* the initial pointer by one.
|
||||||
|
*/
|
||||||
|
while (*rootTo != '\0')
|
||||||
|
{
|
||||||
|
if (pathchar_sep(*rootTo))
|
||||||
|
{
|
||||||
|
/* Check for an improper trailing slash,
|
||||||
|
* just to be nice even though the user
|
||||||
|
* should NOT have done this!
|
||||||
|
*/
|
||||||
|
if (*(rootTo + 1) == '\0')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
numLevels++;
|
||||||
|
}
|
||||||
|
rootTo++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now build the new relative path. */
|
||||||
|
size_t len, total = 0;
|
||||||
|
while (numLevels--)
|
||||||
|
{
|
||||||
|
len = _snprintf(&buffer[total], maxlength - total, ".." PLATFORM_SEP_STR);
|
||||||
|
if (len >= maxlength - total)
|
||||||
|
{
|
||||||
|
/* Not enough space in the buffer */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
total += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the absolute path. */
|
||||||
|
len = _snprintf(&buffer[total], maxlength - total, "%s", &rootFrom[1]);
|
||||||
|
if (len >= maxlength - total)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
KeyValues *SourceModBase::ReadKeyValuesHandle(Handle_t hndl, HandleError *err, bool root)
|
KeyValues *SourceModBase::ReadKeyValuesHandle(Handle_t hndl, HandleError *err, bool root)
|
||||||
{
|
{
|
||||||
HandleError herr;
|
HandleError herr;
|
||||||
@ -771,9 +916,11 @@ static cell_t smn_KeyValuesToFile(IPluginContext *pCtx, const cell_t *params)
|
|||||||
pCtx->LocalToString(params[2], &path);
|
pCtx->LocalToString(params[2], &path);
|
||||||
|
|
||||||
char realpath[PLATFORM_MAX_PATH];
|
char realpath[PLATFORM_MAX_PATH];
|
||||||
|
char relpath[PLATFORM_MAX_PATH * 2];
|
||||||
g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
||||||
|
UTIL_Relatize(relpath, sizeof(relpath), g_SourceMod.GetGamePath(), realpath);
|
||||||
|
|
||||||
return pStk->pCurRoot.front()->SaveToFile(basefilesystem, realpath);
|
return pStk->pCurRoot.front()->SaveToFile(basefilesystem, relpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
|
static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
|
||||||
@ -797,10 +944,12 @@ static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
|
|||||||
pCtx->LocalToString(params[2], &path);
|
pCtx->LocalToString(params[2], &path);
|
||||||
|
|
||||||
char realpath[PLATFORM_MAX_PATH];
|
char realpath[PLATFORM_MAX_PATH];
|
||||||
|
char relpath[PLATFORM_MAX_PATH * 2];
|
||||||
g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
||||||
|
UTIL_Relatize(relpath, sizeof(relpath), g_SourceMod.GetGamePath(), realpath);
|
||||||
|
|
||||||
kv = pStk->pCurRoot.front();
|
kv = pStk->pCurRoot.front();
|
||||||
return g_HL2.KVLoadFromFile(kv, basefilesystem, realpath);
|
return g_HL2.KVLoadFromFile(kv, basefilesystem, relpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
|
static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#define PLATFORM_LIB_EXT "dll"
|
#define PLATFORM_LIB_EXT "dll"
|
||||||
#define PLATFORM_MAX_PATH MAX_PATH
|
#define PLATFORM_MAX_PATH MAX_PATH
|
||||||
|
#define PLATFORM_SEP_STR "\\"
|
||||||
#define PLATFORM_SEP_CHAR '\\'
|
#define PLATFORM_SEP_CHAR '\\'
|
||||||
#define PLATFORM_SEP_ALTCHAR '/'
|
#define PLATFORM_SEP_ALTCHAR '/'
|
||||||
#define PLATFORM_EXTERN_C extern "C" __declspec(dllexport)
|
#define PLATFORM_EXTERN_C extern "C" __declspec(dllexport)
|
||||||
@ -68,8 +69,9 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#define PLATFORM_MAX_PATH PATH_MAX
|
|
||||||
#define PLATFORM_LIB_EXT "so"
|
#define PLATFORM_LIB_EXT "so"
|
||||||
|
#define PLATFORM_MAX_PATH PATH_MAX
|
||||||
|
#define PLATFORM_SEP_STR "/"
|
||||||
#define PLATFORM_SEP_CHAR '/'
|
#define PLATFORM_SEP_CHAR '/'
|
||||||
#define PLATFORM_SEP_ALTCHAR '\\'
|
#define PLATFORM_SEP_ALTCHAR '\\'
|
||||||
#define PLATFORM_EXTERN_C extern "C" __attribute__((visibility("default")))
|
#define PLATFORM_EXTERN_C extern "C" __attribute__((visibility("default")))
|
||||||
|
Loading…
Reference in New Issue
Block a user