2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2025-04-02 07:39:02 +03:00
2018-03-11 02:23:01 +03:00

220 lines
4.4 KiB
C++

#include "precompiled.h"
const char* g_platform_postfixes[4] =
{
"_i386.so",
"_i486.so",
"_i586.so",
"_i686.so",
};
bool is_yes(const char* str)
{
return !Q_strcmp(str, "true") || !Q_strcmp(str, "yes") || !Q_strcmp(str, "1");
}
bool is_no(const char* str)
{
return !Q_strcmp(str, "false") || !Q_strcmp(str, "no") || !Q_strcmp(str, "0");
}
char* ENTITY_KEYVALUE(edict_t* entity, char* key)
{
return INFOKEY_VALUE(GET_INFOKEYBUFFER(entity), key);
}
const char* LOCALINFO(char* key)
{
return ENTITY_KEYVALUE(nullptr, key);
}
char* trimbuf(char* str)
{
char* ibuf;
if (str == nullptr) return nullptr;
for (ibuf = str; *ibuf && (byte)(*ibuf) < (byte)0x80 && isspace(*ibuf); ++ibuf)
;
int i = Q_strlen(ibuf);
if (str != ibuf)
Q_memmove(str, ibuf, i);
while (--i >= 0) {
if (!isspace(str[i]))
break;
}
str[i + 1] = '\0';
return str;
}
void normalize_path(char* path)
{
#ifdef _WIN32
for (char* cp = path; *cp; cp++) {
if (isupper(*cp))
*cp = tolower(*cp);
if (*cp == '\\')
*cp = '/';
}
#endif
}
bool is_abs_path(const char* path)
{
if (path[0] == '/') return true;
#ifdef _WIN32
if (path[1] == ':') return true;
if (path[0] == '\\') return true;
#endif // _WIN32
return false;
}
bool is_valid_path(const char* path)
{
struct stat64 st;
return !stat64(path, &st) && S_ISREG(st.st_mode);
}
bool is_platform_postfix(const char* pf)
{
if (pf) {
for (size_t i = 0; i < arraysize(g_platform_postfixes); i++) {
if (!Q_strcmp(pf, g_platform_postfixes[i]))
return true;
}
}
return false;
}
#ifdef _WIN32
char* realpath(const char* file_name, char* resolved_name)
{
int ret = GetFullPathName(file_name, MAX_PATH, resolved_name, nullptr);
if (ret > MAX_PATH) {
errno = ENAMETOOLONG;
return nullptr;
}
if (ret > 0) {
WIN32_FIND_DATA find_data;
HANDLE handle = FindFirstFile(resolved_name, &find_data);
if (INVALID_HANDLE_VALUE == handle) {
errno = ENOENT;
return nullptr;
}
FindClose(handle);
normalize_path(resolved_name);
return resolved_name;
}
return nullptr;
}
#endif // _WIN32
bool is_file_exists(const char* file)
{
struct stat64 st;
int ret = stat64(file, &st);
if (ret != 0) {
META_DEBUG(5, "Unable to stat '%s': %s", file, strerror(errno));
return false;
}
int reg = S_ISREG(st.st_mode);
if (!reg) {
META_DEBUG(5, "Not a regular file: %s", file);
return false;
}
if (!st.st_size) {
META_DEBUG(5, "Empty file: %s", file);
return false;
}
return true;
}
// Checks for a non-empty file, relative to the gamedir if necessary.
// Formerly used LOAD_FILE_FOR_ME, which provided a simple way to check for
// a file under the gamedir, but which would _also_ look in the sibling
// "valve" directory, thus sometimes finding files that weren't desired.
// Also, formerly named just "valid_file".
//
// Special-case-recognize "/dev/null" as a valid file.
bool is_file_exists_in_gamedir(const char* path)
{
char buf[MAX_PATH];
if (!path)
return false;
if (!Q_strcmp(path, "/dev/null"))
return true;
if (is_abs_path(path)) {
Q_strlcpy(buf, path);
}
else {
Q_snprintf(buf, sizeof buf, "%s/%s", g_GameDLL.gamedir, path);
}
return is_file_exists(buf);
}
// Turns path into a full path:
// - if not absolute, prepends gamedir
// - calls realpath() to collapse ".." and such
// - calls NormalizePath() to fix backslashes, etc
//
// Much like realpath, buffer pointed to by fullpath is assumed to be
// able to store a string of MAX_PATH length.
char* full_gamedir_path(const char* path, char (&fullpath)[MAX_PATH])
{
char buf[MAX_PATH];
// Build pathname from filename, plus gamedir if relative path.
if (is_abs_path(path)) {
Q_strlcpy(buf, path);
}
else {
Q_snprintf(buf, sizeof buf, "%s/%s", g_GameDLL.gamedir, path);
}
// Remove relative path components, if possible.
if (!realpath(buf, fullpath)) {
META_DEBUG(4, "Unable to get realpath for '%s': %s", buf, strerror(errno));
Q_strlcpy(fullpath, path);
}
// Replace backslashes, etc.
normalize_path(fullpath);
return fullpath;
}
void NORETURN Sys_Error(const char *error, ...)
{
va_list argptr;
static char text[1024];
va_start(argptr, error);
Q_vsnprintf(text, sizeof(text), error, argptr);
va_end(argptr);
META_CONS("FATAL ERROR (shutting down): %s\n", text);
META_ERROR(text);
#ifdef _WIN32
MessageBox(GetForegroundWindow(), text, "Fatal error - Metamod", MB_ICONERROR | MB_OK);
#endif // _WIN32
// Allow chance to read the message, before any window closes.
sleep(3);
int *null = nullptr;
*null = 0;
exit(-1);
}