mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-02-20 13:54:14 +01:00
fix for bug amb233
--HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40381
This commit is contained in:
parent
923164bb69
commit
66a8a085fb
@ -454,9 +454,33 @@ void CSmmAPI::ClientConPrintf(edict_t *client, const char *fmt, ...)
|
||||
|
||||
void CSmmAPI::LoadAsVSP()
|
||||
{
|
||||
char command[350];
|
||||
size_t len;
|
||||
char engine_file[PATH_SIZE];
|
||||
char rel_path[PATH_SIZE * 2];
|
||||
|
||||
GetFileOfAddress(g_Engine.engine, engine_file, sizeof(engine_file));
|
||||
|
||||
/* Chop off the "engine" file part */
|
||||
len = strlen(engine_file);
|
||||
for (size_t i = len - 1; i >= 0 && i < len; i--)
|
||||
{
|
||||
if (engine_file[i] == '/'
|
||||
|| engine_file[i] == '\\')
|
||||
{
|
||||
engine_file[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *usepath = g_SmmPath.c_str();
|
||||
if (UTIL_Relatize(rel_path, sizeof(rel_path), engine_file, g_SmmPath.c_str()))
|
||||
{
|
||||
usepath = rel_path;
|
||||
}
|
||||
|
||||
char command[PATH_SIZE * 2];
|
||||
g_VspListener.SetLoadable(true);
|
||||
UTIL_Format(command, sizeof(command), "plugin_load \"%s\"\n", g_SmmPath.c_str());
|
||||
UTIL_Format(command, sizeof(command), "plugin_load \"%s\"\n", usepath);
|
||||
g_Engine.engine->ServerCommand(command);
|
||||
}
|
||||
|
||||
|
@ -239,3 +239,171 @@ size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
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 WIN32
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Forms a relative path given two absolute paths.
|
||||
*
|
||||
* @param buffer Buffer to store relative path in.
|
||||
* @param maxlength Maximum length of the output buffer.
|
||||
* @param relTo Destination folder to use as a working directory.
|
||||
* Final folder name should not be pathchar-terminated.
|
||||
* @param relFrom Source file or folder to use as a target.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
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 WIN32
|
||||
/* 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. */
|
||||
char *ptr = buffer;
|
||||
size_t len, total = 0;
|
||||
while (numLevels--)
|
||||
{
|
||||
len = _snprintf(&buffer[total], maxlength - total, "..\\");
|
||||
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;
|
||||
}
|
||||
|
||||
size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list params)
|
||||
{
|
||||
size_t len = vsnprintf(buffer, maxlength, fmt, params);
|
||||
|
||||
if (len >= maxlength)
|
||||
{
|
||||
len = maxlength - 1;
|
||||
buffer[len] = '\0';
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
@ -56,17 +56,21 @@ size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
|
||||
/**
|
||||
* @brief Same as vsnprintf except that it ensures the string buffer is null terminated.
|
||||
*/
|
||||
inline size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list params)
|
||||
{
|
||||
size_t len = vsnprintf(buffer, maxlength, fmt, params);
|
||||
size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list params);
|
||||
|
||||
if (len >= maxlength)
|
||||
{
|
||||
len = maxlength - 1;
|
||||
buffer[len] = '\0';
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
/**
|
||||
* @brief Forms a relative path given two absolute paths.
|
||||
*
|
||||
* @param buffer Buffer to store relative path in.
|
||||
* @param maxlength Maximum length of the output buffer.
|
||||
* @param relTo Destination folder to use as a working directory.
|
||||
* Final folder name should not be pathchar-terminated.
|
||||
* @param relFrom Source file or folder to use as a target.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
bool UTIL_Relatize(char buffer[],
|
||||
size_t maxlength,
|
||||
const char *relTo,
|
||||
const char *relFrom);
|
||||
|
||||
#endif //_INCLUDE_UTIL_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user