Merge pull request #217 from Arkshine/feature/valve-fs-support
Add support for Valve FS to natives that use file handles
This commit is contained in:
commit
b4b86113e4
|
@ -93,6 +93,7 @@ binary.sources = [
|
||||||
'cvars.cpp',
|
'cvars.cpp',
|
||||||
'../public/memtools/CDetour/detours.cpp',
|
'../public/memtools/CDetour/detours.cpp',
|
||||||
'../public/memtools/CDetour/asm/asm.c',
|
'../public/memtools/CDetour/asm/asm.c',
|
||||||
|
'CLibrarySys.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
if builder.target_platform == 'windows':
|
if builder.target_platform == 'windows':
|
||||||
|
|
256
amxmodx/CFileSystem.h
Normal file
256
amxmodx/CFileSystem.h
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
// vim: set ts=4 sw=4 tw=99 noet:
|
||||||
|
//
|
||||||
|
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
||||||
|
// Copyright (C) The AMX Mod X Development Team.
|
||||||
|
//
|
||||||
|
// This software is licensed under the GNU General Public License, version 3 or higher.
|
||||||
|
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||||
|
// https://alliedmods.net/amxmodx-license
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_CFILESYSTEM_H_
|
||||||
|
#define _INCLUDE_CFILESYSTEM_H_
|
||||||
|
|
||||||
|
#include <FileSystem.h> // IFileSystem, FileSystemSeek_t, FileHandle_t (HLSDK)
|
||||||
|
#include <stdio.h> // FILE*
|
||||||
|
#include <am-cxx.h> // KE_OVERRIDE
|
||||||
|
|
||||||
|
extern IFileSystem* g_FileSystem;
|
||||||
|
|
||||||
|
class ValveFile;
|
||||||
|
class SystemFile;
|
||||||
|
|
||||||
|
class FileObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~FileObject() {};
|
||||||
|
|
||||||
|
virtual size_t Read(void* pOut, size_t size) = 0;
|
||||||
|
virtual char* ReadLine(char* pOut, size_t size) = 0;
|
||||||
|
virtual size_t Write(const void* pData, size_t size) = 0;
|
||||||
|
|
||||||
|
virtual bool Seek(int pos, int seek_type) = 0;
|
||||||
|
virtual int Tell() = 0;
|
||||||
|
virtual int Flush() = 0;
|
||||||
|
|
||||||
|
virtual bool HasError() = 0;
|
||||||
|
|
||||||
|
virtual bool EndOfFile() = 0;
|
||||||
|
virtual void Close() = 0;
|
||||||
|
|
||||||
|
virtual ValveFile *AsValveFile()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual SystemFile *AsSystemFile()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ValveFile : public FileObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ValveFile(FileHandle_t handle) : handle_(handle) {}
|
||||||
|
|
||||||
|
~ValveFile()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Exists(const char* file)
|
||||||
|
{
|
||||||
|
return g_FileSystem->FileExists(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ValveFile* Open(const char* filename, const char* mode, const char* pathID)
|
||||||
|
{
|
||||||
|
FileHandle_t handle = g_FileSystem->OpenFromCacheForRead(filename, mode, pathID);
|
||||||
|
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ValveFile(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Delete(const char* filename, const char* pathID)
|
||||||
|
{
|
||||||
|
if (!Exists(filename))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_FileSystem->RemoveFile(filename, pathID);
|
||||||
|
|
||||||
|
if (Exists(filename))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Read(void* pOut, size_t size) KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return static_cast<size_t>(g_FileSystem->Read(pOut, size, handle_));
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ReadLine(char* pOut, size_t size) KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return g_FileSystem->ReadLine(pOut, size, handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Write(const void* pData, size_t size) KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return static_cast<size_t>(g_FileSystem->Write(pData, size, handle_));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Seek(int pos, int seek_type) KE_OVERRIDE
|
||||||
|
{
|
||||||
|
g_FileSystem->Seek(handle_, pos, static_cast<FileSystemSeek_t>(seek_type));
|
||||||
|
return !HasError();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tell() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return g_FileSystem->Tell(handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasError() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return !handle_ || !g_FileSystem->IsOk(handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Flush() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
g_FileSystem->Flush(handle_);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EndOfFile() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return g_FileSystem->EndOfFile(handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Close() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
if (handle_)
|
||||||
|
{
|
||||||
|
g_FileSystem->Close(handle_);
|
||||||
|
handle_ = nullptr;;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ValveFile* AsValveFile()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileHandle_t handle() const
|
||||||
|
{
|
||||||
|
return handle_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FileHandle_t handle_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SystemFile : public FileObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
SystemFile(FILE* fp) : fp_(fp) {}
|
||||||
|
|
||||||
|
~SystemFile()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static SystemFile* Open(const char* path, const char* mode)
|
||||||
|
{
|
||||||
|
FILE* fp = fopen(path, mode);
|
||||||
|
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SystemFile(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Delete(const char* path)
|
||||||
|
{
|
||||||
|
return unlink(path) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Read(void* pOut, size_t size) KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return fread(pOut, 1, size, fp_);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ReadLine(char* pOut, size_t size) KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return fgets(pOut, size, fp_);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Write(const void* pData, size_t size) KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return fwrite(pData, 1, size, fp_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Seek(int pos, int seek_type) KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return fseek(fp_, pos, seek_type) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tell() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return ftell(fp_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasError() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return ferror(fp_) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Flush() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return fflush(fp_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EndOfFile() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
return feof(fp_) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Close() KE_OVERRIDE
|
||||||
|
{
|
||||||
|
if (fp_)
|
||||||
|
{
|
||||||
|
fclose(fp_);
|
||||||
|
fp_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual SystemFile* AsSystemFile()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* handle() const
|
||||||
|
{
|
||||||
|
return fp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FILE* fp_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _INCLUDE_CFILESYSTEM_H_
|
|
@ -12,6 +12,8 @@
|
||||||
#include "CLang.h"
|
#include "CLang.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
|
CVector<FILE *> FileList;
|
||||||
|
|
||||||
#define LITIDX_NONE 0
|
#define LITIDX_NONE 0
|
||||||
#define LITIDX_BRACKET 1
|
#define LITIDX_BRACKET 1
|
||||||
#define LITIDX_DEFINITION 2
|
#define LITIDX_DEFINITION 2
|
||||||
|
|
532
amxmodx/CLibrarySys.cpp
Normal file
532
amxmodx/CLibrarySys.cpp
Normal file
|
@ -0,0 +1,532 @@
|
||||||
|
// vim: set ts=4 sw=4 tw=99 noet:
|
||||||
|
//
|
||||||
|
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
||||||
|
// Copyright (C) The AMX Mod X Development Team.
|
||||||
|
//
|
||||||
|
// This software is licensed under the GNU General Public License, version 3 or higher.
|
||||||
|
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||||
|
// https://alliedmods.net/amxmodx-license
|
||||||
|
|
||||||
|
#include "CLibrarySys.h"
|
||||||
|
#include <amxmodx.h>
|
||||||
|
|
||||||
|
LibrarySystem g_LibSys;
|
||||||
|
|
||||||
|
/******************/
|
||||||
|
/* Directory Code */
|
||||||
|
/******************/
|
||||||
|
|
||||||
|
CDirectory::CDirectory(const char *path)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
char newpath[PLATFORM_MAX_PATH];
|
||||||
|
UTIL_Format(newpath, sizeof(newpath) - 1, "%s\\*.*", path);
|
||||||
|
|
||||||
|
m_dir = FindFirstFile(newpath, &m_fd);
|
||||||
|
|
||||||
|
if (!IsValid())
|
||||||
|
{
|
||||||
|
m_fd.cFileName[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
m_dir = opendir(path);
|
||||||
|
|
||||||
|
if (IsValid())
|
||||||
|
{
|
||||||
|
m_ep = readdir(m_dir); // TODO: we need to read past "." and ".."!
|
||||||
|
UTIL_Format(m_origpath, sizeof(m_origpath) - 1, "%s", path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ep = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CDirectory::~CDirectory()
|
||||||
|
{
|
||||||
|
if (IsValid())
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
FindClose(m_dir);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
closedir(m_dir);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DirHandle CDirectory::GetHandle()
|
||||||
|
{
|
||||||
|
return m_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDirectory::NextEntry()
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
if (FindNextFile(m_dir, &m_fd) == 0)
|
||||||
|
{
|
||||||
|
FindClose(m_dir);
|
||||||
|
m_dir = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
if (!(m_ep = readdir(m_dir)))
|
||||||
|
{
|
||||||
|
closedir(m_dir);
|
||||||
|
m_dir = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDirectory::IsEntryValid()
|
||||||
|
{
|
||||||
|
return IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDirectory::IsEntryDirectory()
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
char temppath[PLATFORM_MAX_PATH];
|
||||||
|
UTIL_Format(temppath, sizeof(temppath) - 1, "%s/%s", m_origpath, GetEntryName());
|
||||||
|
|
||||||
|
return g_LibSys.IsPathDirectory(temppath);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDirectory::IsEntryFile()
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
char temppath[PLATFORM_MAX_PATH];
|
||||||
|
UTIL_Format(temppath, sizeof(temppath) - 1, "%s/%s", m_origpath, GetEntryName());
|
||||||
|
|
||||||
|
return g_LibSys.IsPathFile(temppath);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* CDirectory::GetEntryName()
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
return m_fd.cFileName;
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
return m_ep ? m_ep->d_name : "";
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDirectory::MoreFiles()
|
||||||
|
{
|
||||||
|
return IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDirectory::IsValid()
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
return (m_dir != INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
return (m_dir != nullptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Library Code */
|
||||||
|
/****************/
|
||||||
|
|
||||||
|
CLibrary::~CLibrary()
|
||||||
|
{
|
||||||
|
if (m_lib)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
FreeLibrary(m_lib);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
dlclose(m_lib);
|
||||||
|
#endif
|
||||||
|
m_lib = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CLibrary::CLibrary(LibraryHandle me)
|
||||||
|
{
|
||||||
|
m_lib = me;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLibrary::CloseLibrary()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *CLibrary::GetSymbolAddress(const char* symname)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
return GetProcAddress(m_lib, symname);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
return dlsym(m_lib, symname);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* Library System Code */
|
||||||
|
/***********************/
|
||||||
|
|
||||||
|
bool LibrarySystem::PathExists(const char *path)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
DWORD attr = GetFileAttributesA(path);
|
||||||
|
|
||||||
|
return (attr != INVALID_FILE_ATTRIBUTES);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
return (stat(path, &s) == 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibrarySystem::IsPathFile(const char* path)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
DWORD attr = GetFileAttributes(path);
|
||||||
|
|
||||||
|
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
if (stat(path, &s) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_ISREG(s.st_mode) ? true : false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibrarySystem::IsPathDirectory(const char* path)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
DWORD attr = GetFileAttributes(path);
|
||||||
|
|
||||||
|
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
if (stat(path, &s) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S_ISDIR(s.st_mode))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDirectory *LibrarySystem::OpenDirectory(const char* path)
|
||||||
|
{
|
||||||
|
CDirectory* dir = new CDirectory(path);
|
||||||
|
|
||||||
|
if (!dir->IsValid())
|
||||||
|
{
|
||||||
|
delete dir;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLibrary* LibrarySystem::OpenLibrary(const char* path, char* error, size_t maxlength)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
LibraryHandle lib = LoadLibrary(path);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
LibraryHandle lib = dlopen(path, RTLD_NOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!lib)
|
||||||
|
{
|
||||||
|
if (error && maxlength)
|
||||||
|
{
|
||||||
|
GetLoaderError(error, maxlength);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CLibrary(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibrarySystem::GetPlatformError(char* error, size_t maxlength)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
return GetPlatformErrorEx(GetLastError(), error, maxlength);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
return GetPlatformErrorEx(errno, error, maxlength);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibrarySystem::GetPlatformErrorEx(int code, char* error, size_t maxlength)
|
||||||
|
{
|
||||||
|
if (error && maxlength)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
nullptr,
|
||||||
|
(DWORD)code,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPSTR)error,
|
||||||
|
maxlength,
|
||||||
|
nullptr) == 0)
|
||||||
|
{
|
||||||
|
UTIL_Format(error, maxlength, "error code %08x", code);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined PLATFORM_LINUX
|
||||||
|
|
||||||
|
const char *ae = strerror_r(code, error, maxlength);
|
||||||
|
|
||||||
|
if (ae != error)
|
||||||
|
{
|
||||||
|
UTIL_Format(error, maxlength, "%s", ae);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
strerror_r(code, error, maxlength);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibrarySystem::GetLoaderError(char* buffer, size_t maxlength)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
GetPlatformError(buffer, maxlength);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
if (buffer && maxlength)
|
||||||
|
{
|
||||||
|
strncopy(buffer, dlerror(), maxlength);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibrarySystem::CloseDirectory(CDirectory *dir)
|
||||||
|
{
|
||||||
|
delete dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t LibrarySystem::PathFormat(char* buffer, size_t len, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
size_t mylen = vsnprintf(buffer, len, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (mylen >= len)
|
||||||
|
{
|
||||||
|
mylen = len - 1;
|
||||||
|
buffer[mylen] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mylen; i++)
|
||||||
|
{
|
||||||
|
if (buffer[i] == PLATFORM_SEP_ALTCHAR)
|
||||||
|
{
|
||||||
|
buffer[i] = PLATFORM_SEP_CHAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mylen;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* LibrarySystem::PathFormat(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
static char buffer[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
size_t mylen = vsnprintf(buffer, sizeof(buffer), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (mylen >= sizeof(buffer))
|
||||||
|
{
|
||||||
|
mylen = sizeof(buffer) - 1;
|
||||||
|
buffer[mylen] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mylen; i++)
|
||||||
|
{
|
||||||
|
if (buffer[i] == PLATFORM_SEP_ALTCHAR)
|
||||||
|
{
|
||||||
|
buffer[i] = PLATFORM_SEP_CHAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* LibrarySystem::GetFileExtension(const char* filename)
|
||||||
|
{
|
||||||
|
size_t len, end;
|
||||||
|
|
||||||
|
len = strlen(filename);
|
||||||
|
|
||||||
|
/* Minimum string length for filename with ext would be 3; example: a.a */
|
||||||
|
if (len < 3)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = len - 1;
|
||||||
|
|
||||||
|
for (size_t i = end; i <= end; i--)
|
||||||
|
{
|
||||||
|
if (filename[i] == PLATFORM_SEP_CHAR || filename[i] == PLATFORM_SEP_ALTCHAR)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename[i] == '.' && i != end && i != 0)
|
||||||
|
{
|
||||||
|
return &filename[++i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibrarySystem::CreateFolder(const char* path)
|
||||||
|
{
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
return (mkdir(path) != -1);
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
return (mkdir(path, 0775) != -1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t LibrarySystem::GetFileFromPath(char* buffer, size_t maxlength, const char* path)
|
||||||
|
{
|
||||||
|
size_t length = strlen(path);
|
||||||
|
|
||||||
|
for (size_t i = length - 1; i <= length - 1; i--)
|
||||||
|
{
|
||||||
|
if (path[i] == '/'
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|| path[i] == '\\'
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return UTIL_Format(buffer, maxlength, "%s", &path[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We scanned and found no path separator */
|
||||||
|
return UTIL_Format(buffer, maxlength, "%s", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibrarySystem::FileTime(const char* path, FileTimeType type, time_t* pTime)
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
if (stat(path, &s) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case FileTime_LastAccess:
|
||||||
|
{
|
||||||
|
*pTime = s.st_atime;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FileTime_Created:
|
||||||
|
{
|
||||||
|
*pTime = s.st_ctime;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FileTime_LastChange:
|
||||||
|
{
|
||||||
|
*pTime = s.st_mtime;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
182
amxmodx/CLibrarySys.h
Normal file
182
amxmodx/CLibrarySys.h
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
// vim: set ts=4 sw=4 tw=99 noet:
|
||||||
|
//
|
||||||
|
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
||||||
|
// Copyright (C) The AMX Mod X Development Team.
|
||||||
|
//
|
||||||
|
// This software is licensed under the GNU General Public License, version 3 or higher.
|
||||||
|
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||||
|
// https://alliedmods.net/amxmodx-license
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_LIBRARY_SYS_H_
|
||||||
|
#define _INCLUDE_LIBRARY_SYS_H_
|
||||||
|
|
||||||
|
#include "amx.h" // cell
|
||||||
|
#include <interface.h> // Interface (HLSDK)
|
||||||
|
#include <am-utility.h> // AutoPtr
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
# ifndef PLATFORM_WINDOWS
|
||||||
|
# define PLATFORM_WINDOWS 1
|
||||||
|
# endif
|
||||||
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# endif
|
||||||
|
# include <windows.h>
|
||||||
|
# include <direct.h>
|
||||||
|
# include <io.h>
|
||||||
|
# define PLATFORM_LIB_EXT "dll"
|
||||||
|
# define PLATFORM_SEP_CHAR '\\'
|
||||||
|
# define PLATFORM_SEP_ALTCHAR '/'
|
||||||
|
# define PLATFORM_EXTERN_C extern "C" __declspec(dllexport)
|
||||||
|
#elif defined(__linux__) || defined(__APPLE__)
|
||||||
|
# if defined(__linux__)
|
||||||
|
# define PLATFORM_LINUX 1
|
||||||
|
# define PLATFORM_LIB_EXT "so"
|
||||||
|
# elif defined(__APPLE__)
|
||||||
|
# define PLATFORM_APPLE 1
|
||||||
|
# define PLATFORM_LIB_EXT "dylib"
|
||||||
|
# endif
|
||||||
|
# ifndef PLATFORM_POSIX
|
||||||
|
# define PLATFORM_POSIX 1
|
||||||
|
# endif
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/stat.h>
|
||||||
|
# include <errno.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <dirent.h>
|
||||||
|
# include <dlfcn.h>
|
||||||
|
# if defined(PLATFORM_APPLE)
|
||||||
|
# include <sys/syslimits.h>
|
||||||
|
# endif
|
||||||
|
# define PLATFORM_SEP_CHAR '/'
|
||||||
|
# define PLATFORM_SEP_ALTCHAR '\\'
|
||||||
|
# define PLATFORM_EXTERN_C extern "C" __attribute__((visibility("default")))
|
||||||
|
# define WINAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PLATFORM_MAX_PATH 260
|
||||||
|
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
typedef HMODULE LibraryHandle;
|
||||||
|
typedef HANDLE DirHandle;
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
typedef void* LibraryHandle;
|
||||||
|
typedef DIR* DirHandle;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum FileTimeType
|
||||||
|
{
|
||||||
|
FileTime_LastAccess = 0, /* Last access (not available on FAT) */
|
||||||
|
FileTime_Created = 1, /* Creation (not available on FAT) */
|
||||||
|
FileTime_LastChange = 2, /* Last modification */
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDirectory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CDirectory(const char* path);
|
||||||
|
~CDirectory();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool MoreFiles();
|
||||||
|
void NextEntry();
|
||||||
|
const char* GetEntryName();
|
||||||
|
bool IsEntryDirectory();
|
||||||
|
bool IsEntryFile();
|
||||||
|
bool IsEntryValid();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool IsValid();
|
||||||
|
DirHandle GetHandle();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
HANDLE m_dir;
|
||||||
|
WIN32_FIND_DATAA m_fd;
|
||||||
|
|
||||||
|
#elif defined PLATFORM_POSIX
|
||||||
|
|
||||||
|
DIR* m_dir;
|
||||||
|
struct dirent* m_ep;
|
||||||
|
char m_origpath[PLATFORM_MAX_PATH];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class CLibrary
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CLibrary(LibraryHandle me);
|
||||||
|
~CLibrary();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void CloseLibrary();
|
||||||
|
void *GetSymbolAddress(const char* symname);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
LibraryHandle m_lib;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LibrarySystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CLibrary* OpenLibrary(const char* path, char* error = nullptr, size_t maxlength = 0);
|
||||||
|
CDirectory* OpenDirectory(const char* path);
|
||||||
|
void CloseDirectory(CDirectory *dir);
|
||||||
|
|
||||||
|
bool PathExists(const char* path);
|
||||||
|
bool IsPathFile(const char* path);
|
||||||
|
bool IsPathDirectory(const char* path);
|
||||||
|
|
||||||
|
void GetPlatformError(char* error, size_t maxlength);
|
||||||
|
void GetPlatformErrorEx(int code, char* error, size_t maxlength);
|
||||||
|
|
||||||
|
size_t PathFormat(char* buffer, size_t len, const char* fmt, ...);
|
||||||
|
char* PathFormat(const char* fmt, ...);
|
||||||
|
|
||||||
|
const char* GetFileExtension(const char* filename);
|
||||||
|
bool CreateFolder(const char* path);
|
||||||
|
size_t GetFileFromPath(char* buffer, size_t maxlength, const char* path);
|
||||||
|
|
||||||
|
bool FileTime(const char* path, FileTimeType type, time_t* pTime);
|
||||||
|
void GetLoaderError(char* buffer, size_t maxlength);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern LibrarySystem g_LibSys;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool GET_IFACE(const char* library, T*& var, const char* version)
|
||||||
|
{
|
||||||
|
const char* path = g_LibSys.PathFormat("%s.%s", library, PLATFORM_LIB_EXT);
|
||||||
|
|
||||||
|
ke::AutoPtr<CLibrary> lib(g_LibSys.OpenLibrary(path));
|
||||||
|
|
||||||
|
if (lib)
|
||||||
|
{
|
||||||
|
CreateInterfaceFn factory = reinterpret_cast<CreateInterfaceFn>(lib->GetSymbolAddress(CREATEINTERFACE_PROCNAME));
|
||||||
|
|
||||||
|
if (factory)
|
||||||
|
{
|
||||||
|
var = reinterpret_cast<T*>(factory(version, nullptr));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _INCLUDE_LIBRARY_SYS_H_
|
|
@ -152,6 +152,11 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
|
||||||
{
|
{
|
||||||
*get_amxaddr(plugin->getAMX(), addr) = gpGlobals->maxClients;
|
*get_amxaddr(plugin->getAMX(), addr) = gpGlobals->maxClients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (amx_FindPubVar(plugin->getAMX(), "NULL_STRING", &addr) != AMX_ERR_NOTFOUND)
|
||||||
|
{
|
||||||
|
plugin->m_pNullStringOfs = get_amxaddr(plugin->getAMX(), addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +261,7 @@ const char* CPluginMngr::CPlugin::getStatus() const
|
||||||
return "error";
|
return "error";
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n)
|
CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n), m_pNullStringOfs(nullptr)
|
||||||
{
|
{
|
||||||
const char* unk = "unknown";
|
const char* unk = "unknown";
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
~CPlugin();
|
~CPlugin();
|
||||||
|
|
||||||
bool m_Debug;
|
bool m_Debug;
|
||||||
|
cell* m_pNullStringOfs;
|
||||||
public:
|
public:
|
||||||
inline const char* getName() { return name.c_str();}
|
inline const char* getName() { return name.c_str();}
|
||||||
inline const char* getVersion() { return version.c_str();}
|
inline const char* getVersion() { return version.c_str();}
|
||||||
|
@ -90,6 +91,7 @@ public:
|
||||||
|
|
||||||
const char* getStatus() const;
|
const char* getStatus() const;
|
||||||
inline bool isDebug() const { return m_Debug; }
|
inline bool isDebug() const { return m_Debug; }
|
||||||
|
inline cell* getNullStringOfs() const { return m_pNullStringOfs; }
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -29,7 +29,7 @@ static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params)
|
||||||
char* sName = get_amxstring(amx, params[1], 0, len);
|
char* sName = get_amxstring(amx, params[1], 0, len);
|
||||||
cell ptr;
|
cell ptr;
|
||||||
|
|
||||||
if (!strcmp(sName, "MaxClients"))
|
if (!strcmp(sName, "MaxClients") || !strcmp(sName, "NULL_STRING"))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -3784,19 +3784,6 @@ cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_mkdir(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
char *path = get_amxstring(amx, params[1], 0, len);
|
|
||||||
char *realpath = build_pathname("%s", path);
|
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__APPLE__)
|
|
||||||
return mkdir(realpath, 0700);
|
|
||||||
#else
|
|
||||||
return mkdir(realpath);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL find_plugin_byfile(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL find_plugin_byfile(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
typedef int (*STRCOMPARE)(const char*, const char*);
|
typedef int (*STRCOMPARE)(const char*, const char*);
|
||||||
|
@ -4561,7 +4548,6 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
|
||||||
{"hash_string", amx_hash_string},
|
{"hash_string", amx_hash_string},
|
||||||
{"hash_file", amx_hash_file},
|
{"hash_file", amx_hash_file},
|
||||||
{"module_exists", module_exists},
|
{"module_exists", module_exists},
|
||||||
{"mkdir", amx_mkdir},
|
|
||||||
{"next_hudchannel", next_hudchannel},
|
{"next_hudchannel", next_hudchannel},
|
||||||
{"num_to_word", num_to_word},
|
{"num_to_word", num_to_word},
|
||||||
{"parse_loguser", parse_loguser},
|
{"parse_loguser", parse_loguser},
|
||||||
|
|
|
@ -276,6 +276,7 @@ char* format_amxstring(AMX *amx, cell *params, int parm, int& len);
|
||||||
AMX* get_amxscript(int, void**, const char**);
|
AMX* get_amxscript(int, void**, const char**);
|
||||||
const char* get_amxscriptname(AMX* amx);
|
const char* get_amxscriptname(AMX* amx);
|
||||||
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len);
|
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len);
|
||||||
|
char *get_amxstring_null(AMX *amx, cell amx_addr, int id, int& len);
|
||||||
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen);
|
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen);
|
||||||
|
|
||||||
int amxstring_len(cell* cstr);
|
int amxstring_len(cell* cstr);
|
||||||
|
|
1536
amxmodx/file.cpp
1536
amxmodx/file.cpp
File diff suppressed because it is too large
Load Diff
|
@ -8,13 +8,6 @@
|
||||||
// https://alliedmods.net/amxmodx-license
|
// https://alliedmods.net/amxmodx-license
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#if defined WIN32
|
|
||||||
#include <direct.h>
|
|
||||||
#else
|
|
||||||
#include <dirent.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "fakemeta.h"
|
#include "fakemeta.h"
|
||||||
#include "CMenu.h"
|
#include "CMenu.h"
|
||||||
|
@ -32,6 +25,8 @@
|
||||||
#include "CDataPack.h"
|
#include "CDataPack.h"
|
||||||
#include "textparse.h"
|
#include "textparse.h"
|
||||||
#include "CvarManager.h"
|
#include "CvarManager.h"
|
||||||
|
#include "CLibrarySys.h"
|
||||||
|
#include "CFileSystem.h"
|
||||||
|
|
||||||
plugin_info_t Plugin_info =
|
plugin_info_t Plugin_info =
|
||||||
{
|
{
|
||||||
|
@ -143,6 +138,8 @@ int FF_InconsistentFile = -1;
|
||||||
int FF_ClientAuthorized = -1;
|
int FF_ClientAuthorized = -1;
|
||||||
int FF_ChangeLevel = -1;
|
int FF_ChangeLevel = -1;
|
||||||
|
|
||||||
|
IFileSystem* g_FileSystem;
|
||||||
|
|
||||||
bool ColoredMenus(String & ModName)
|
bool ColoredMenus(String & ModName)
|
||||||
{
|
{
|
||||||
const char * pModNames[] = { "cstrike", "czero", "dmc", "dod", "tfc", "valve" };
|
const char * pModNames[] = { "cstrike", "czero", "dmc", "dod", "tfc", "valve" };
|
||||||
|
@ -1494,6 +1491,8 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
||||||
|
|
||||||
g_CvarManager.CreateCvarHook();
|
g_CvarManager.CreateCvarHook();
|
||||||
|
|
||||||
|
GET_IFACE<IFileSystem>("filesystem_stdio", g_FileSystem, FILESYSTEM_INTERFACE_VERSION);
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,30 +43,6 @@ ModuleCallReason g_ModuleCallReason;
|
||||||
|
|
||||||
extern const char* no_function; // stupid work around
|
extern const char* no_function; // stupid work around
|
||||||
|
|
||||||
bool DirExists(const char *dir)
|
|
||||||
{
|
|
||||||
#if defined WIN32 || defined _WIN32
|
|
||||||
DWORD attr = GetFileAttributes(dir);
|
|
||||||
|
|
||||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (attr & FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
#else
|
|
||||||
struct stat s;
|
|
||||||
|
|
||||||
if (stat(dir, &s) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (S_ISDIR(s.st_mode))
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_error(int code, const char* fmt, ...)
|
void report_error(int code, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
|
|
@ -57,7 +57,6 @@ class Debugger;
|
||||||
Debugger *DisableDebugHandler(AMX *amx);
|
Debugger *DisableDebugHandler(AMX *amx);
|
||||||
void EnableDebugHandler(AMX *amx, Debugger *pd);
|
void EnableDebugHandler(AMX *amx, Debugger *pd);
|
||||||
|
|
||||||
bool DirExists(const char *dir);
|
|
||||||
const char* GetFileName(AMX *amx);
|
const char* GetFileName(AMX *amx);
|
||||||
|
|
||||||
inline cell FloatToCell(float input)
|
inline cell FloatToCell(float input)
|
||||||
|
|
|
@ -256,6 +256,7 @@
|
||||||
<ClCompile Include="..\CFlagManager.cpp" />
|
<ClCompile Include="..\CFlagManager.cpp" />
|
||||||
<ClCompile Include="..\CForward.cpp" />
|
<ClCompile Include="..\CForward.cpp" />
|
||||||
<ClCompile Include="..\CLang.cpp" />
|
<ClCompile Include="..\CLang.cpp" />
|
||||||
|
<ClCompile Include="..\CLibrarySys.cpp" />
|
||||||
<ClCompile Include="..\CLogEvent.cpp" />
|
<ClCompile Include="..\CLogEvent.cpp" />
|
||||||
<ClCompile Include="..\CMenu.cpp" />
|
<ClCompile Include="..\CMenu.cpp" />
|
||||||
<ClCompile Include="..\CMisc.cpp" />
|
<ClCompile Include="..\CMisc.cpp" />
|
||||||
|
@ -334,9 +335,11 @@
|
||||||
<ClInclude Include="..\CDataPack.h" />
|
<ClInclude Include="..\CDataPack.h" />
|
||||||
<ClInclude Include="..\CEvent.h" />
|
<ClInclude Include="..\CEvent.h" />
|
||||||
<ClInclude Include="..\CFile.h" />
|
<ClInclude Include="..\CFile.h" />
|
||||||
|
<ClInclude Include="..\CFileSystem.h" />
|
||||||
<ClInclude Include="..\CFlagManager.h" />
|
<ClInclude Include="..\CFlagManager.h" />
|
||||||
<ClInclude Include="..\CForward.h" />
|
<ClInclude Include="..\CForward.h" />
|
||||||
<ClInclude Include="..\CLang.h" />
|
<ClInclude Include="..\CLang.h" />
|
||||||
|
<ClInclude Include="..\CLibrarySys.h" />
|
||||||
<ClInclude Include="..\CList.h" />
|
<ClInclude Include="..\CList.h" />
|
||||||
<ClInclude Include="..\CLogEvent.h" />
|
<ClInclude Include="..\CLogEvent.h" />
|
||||||
<ClInclude Include="..\CMenu.h" />
|
<ClInclude Include="..\CMenu.h" />
|
||||||
|
|
|
@ -277,6 +277,9 @@
|
||||||
<Filter>Third Party\Hashing\hashers</Filter>
|
<Filter>Third Party\Hashing\hashers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\CPlugin.cpp">
|
<ClCompile Include="..\CPlugin.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\CLibrarySys.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -475,6 +478,12 @@
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\third_party\hashing\hashers\sha256.h">
|
<ClInclude Include="..\..\third_party\hashing\hashers\sha256.h">
|
||||||
<Filter>Third Party\Hashing\hashers</Filter>
|
<Filter>Third Party\Hashing\hashers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\CFileSystem.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\CLibrarySys.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -176,6 +176,16 @@ char *get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
|
||||||
return buffer[id];
|
return buffer[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *get_amxstring_null(AMX *amx, cell amx_addr, int id, int& len)
|
||||||
|
{
|
||||||
|
if (get_amxaddr(amx, amx_addr) == g_plugins.findPluginFast(amx)->getNullStringOfs())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_amxstring(amx, amx_addr, id, len);
|
||||||
|
}
|
||||||
|
|
||||||
void copy_amxmemory(cell* dest, cell* src, int len)
|
void copy_amxmemory(cell* dest, cell* src, int len)
|
||||||
{
|
{
|
||||||
while (len--)
|
while (len--)
|
||||||
|
|
|
@ -1895,8 +1895,10 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
|
||||||
if (size > INT_MAX)
|
if (size > INT_MAX)
|
||||||
error(105); /* overflow, exceeding capacity */
|
error(105); /* overflow, exceeding capacity */
|
||||||
#endif
|
#endif
|
||||||
|
#if 0 /* We don't actually care */
|
||||||
if (ispublic)
|
if (ispublic)
|
||||||
error(56,name); /* arrays cannot be public */
|
error(56,name); /* arrays cannot be public */
|
||||||
|
#endif
|
||||||
dim[numdim++]=(int)size;
|
dim[numdim++]=(int)size;
|
||||||
} /* while */
|
} /* while */
|
||||||
/* if this variable is never used (which can be detected only in the
|
/* if this variable is never used (which can be detected only in the
|
||||||
|
@ -1936,7 +1938,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
|
||||||
sym->usage|=uDEFINE;
|
sym->usage|=uDEFINE;
|
||||||
} /* if */
|
} /* if */
|
||||||
if (ispublic)
|
if (ispublic)
|
||||||
sym->usage|=uPUBLIC;
|
sym->usage|=uPUBLIC|uREAD;
|
||||||
if (fconst)
|
if (fconst)
|
||||||
sym->usage|=uCONST;
|
sym->usage|=uCONST;
|
||||||
if (fstock)
|
if (fstock)
|
||||||
|
|
|
@ -619,7 +619,7 @@ SC_FUNC int assemble(FILE *fout,FILE *fin)
|
||||||
assert(sym->vclass==sGLOBAL);
|
assert(sym->vclass==sGLOBAL);
|
||||||
mainaddr=sym->addr;
|
mainaddr=sym->addr;
|
||||||
} /* if */
|
} /* if */
|
||||||
} else if (sym->ident==iVARIABLE) {
|
} else if (sym->ident==iVARIABLE || sym->ident == iARRAY || sym->ident == iREFARRAY) {
|
||||||
if ((sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0)
|
if ((sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0)
|
||||||
match=++numpubvars;
|
match=++numpubvars;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
@ -794,7 +794,8 @@ SC_FUNC int assemble(FILE *fout,FILE *fin)
|
||||||
/* write the public variables table */
|
/* write the public variables table */
|
||||||
count=0;
|
count=0;
|
||||||
for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
|
for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
|
||||||
if (sym->ident==iVARIABLE && (sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0) {
|
if ((sym->ident==iVARIABLE || sym->ident==iARRAY || sym->ident==iREFARRAY)
|
||||||
|
&& (sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0) {
|
||||||
assert((sym->usage & uDEFINE)!=0);
|
assert((sym->usage & uDEFINE)!=0);
|
||||||
assert(sym->vclass==sGLOBAL);
|
assert(sym->vclass==sGLOBAL);
|
||||||
func.address=sym->addr;
|
func.address=sym->addr;
|
||||||
|
|
|
@ -39,7 +39,15 @@
|
||||||
*/
|
*/
|
||||||
#define MAX_PLAYERS 32 /* Maximum number of players AMX Mod X supports */
|
#define MAX_PLAYERS 32 /* Maximum number of players AMX Mod X supports */
|
||||||
|
|
||||||
public stock const MaxClients; /* Maximum number of players the server supports */
|
/**
|
||||||
|
* Maximum number of players the server supports
|
||||||
|
*/
|
||||||
|
public stock const MaxClients;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass this into certain functions to act as a C++ NULL
|
||||||
|
*/
|
||||||
|
public stock const NULL_STRING[1];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum buffer size required to store a clients name.
|
* The maximum buffer size required to store a clients name.
|
||||||
|
|
|
@ -12,140 +12,36 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#if defined _file_included
|
#if defined _file_included
|
||||||
#endinput
|
#endinput
|
||||||
#endif
|
#endif
|
||||||
#define _file_included
|
#define _file_included
|
||||||
|
|
||||||
/* Reads content from directory.
|
/**
|
||||||
* Returns index of next element or 0 when end of dir. is reached. */
|
* @note All paths in AMX Mod X natives are relative to the mod folder
|
||||||
native read_dir(const dirname[],pos,output[],len,&outlen);
|
* unless otherwise noted.
|
||||||
|
*
|
||||||
/* Reads line from file. Returns index of next line or 0 when end of file is reached. */
|
* Most functions in AMX Mod X (at least, ones that deal with direct
|
||||||
native read_file(const file[],line,text[],len,&txtlen);
|
* file manipulation) will support an alternate path specification.
|
||||||
|
|
||||||
/* Writes text to file. Function returns 0 on failure.
|
|
||||||
* When line is set to -1, the text is added at the end of file. */
|
|
||||||
native write_file(const file[],const text[],line = -1);
|
|
||||||
|
|
||||||
/* Deletes file. Function returns 1 on success, 0 on failure. */
|
|
||||||
native delete_file(const file[]);
|
|
||||||
|
|
||||||
/* Checks for file. If file exists function returns 1, in other case 0. */
|
|
||||||
native file_exists(const file[]);
|
|
||||||
|
|
||||||
/* renames a file. returns 0 on failure, 1 on success.
|
|
||||||
* if relative true, rename_file will act like other natives which
|
|
||||||
* use the moddir as a base directory. otherwise, the current directory is
|
|
||||||
* undefined (but assumed to be hlds).
|
|
||||||
*/
|
*/
|
||||||
native rename_file(const oldname[], const newname[], relative=0);
|
|
||||||
|
|
||||||
/* Checks if a directory exists */
|
|
||||||
native dir_exists(const dir[]);
|
|
||||||
|
|
||||||
/* Returns a file size in bytes if flag is set to 0.
|
|
||||||
* When flag is set to 1 returns number of lines in the file,
|
|
||||||
* and when flags is 2, function returns 1 if the file ends
|
|
||||||
* with line feed. If file doesn't exist returns -1. */
|
|
||||||
native file_size(const file[], flag=0);
|
|
||||||
|
|
||||||
#define SEEK_SET 0
|
|
||||||
#define SEEK_CUR 1
|
|
||||||
#define SEEK_END 2
|
|
||||||
|
|
||||||
//Open a file, returns a handle or 0 on failure
|
|
||||||
native fopen(const filename[],const mode[]);
|
|
||||||
|
|
||||||
//Closes a file handle
|
|
||||||
native fclose(file);
|
|
||||||
|
|
||||||
#define BLOCK_INT 4
|
|
||||||
#define BLOCK_SHORT 2
|
|
||||||
#define BLOCK_CHAR 1
|
|
||||||
#define BLOCK_BYTE 1
|
|
||||||
|
|
||||||
//The following functions work as such:
|
|
||||||
// RAW - means the array you pass is a raw bytestream, for experts only
|
|
||||||
// BLOCK - means you are passing in an array where each element will be written
|
|
||||||
// NORMAL - means you are writing only one element
|
|
||||||
// RAW and BLOCK return the number of blocks acted upon successfully
|
|
||||||
// NORMAL returns 1 on success
|
|
||||||
|
|
||||||
native fread(file, &data, mode);
|
|
||||||
native fread_blocks(file, data[], blocks, mode);
|
|
||||||
native fread_raw(file, stream[], blocksize, blocks);
|
|
||||||
native fwrite(file, data, mode);
|
|
||||||
native fwrite_blocks(file, const data[], blocks, mode);
|
|
||||||
native fwrite_raw(file, const stream[], blocksize, mode);
|
|
||||||
|
|
||||||
//Returns 1 if the file is ended, 0 otherwise
|
|
||||||
native feof(file);
|
|
||||||
|
|
||||||
//Reads a line from a text file -- includes newline!
|
|
||||||
native fgets(file, buffer[], maxlength);
|
|
||||||
|
|
||||||
//Writes a line to a text file. Returns # of characters written.
|
|
||||||
native fputs(file, const text[]);
|
|
||||||
|
|
||||||
//Writes a line to the file
|
|
||||||
native fprintf(file, const fmt[], any:...);
|
|
||||||
|
|
||||||
//Sets the current position in a file (see SEEK_ values above)
|
|
||||||
native fseek(file, position, start);
|
|
||||||
|
|
||||||
//Returns the current position in a file
|
|
||||||
native ftell(file);
|
|
||||||
|
|
||||||
//These are straight from the C standard.
|
|
||||||
native fgetc(file);
|
|
||||||
native fputc(file, data);
|
|
||||||
native fungetc(file, data);
|
|
||||||
|
|
||||||
//Return the size of a file
|
|
||||||
native filesize(const filename[], any:...);
|
|
||||||
|
|
||||||
//Attempts to remove a directory.
|
|
||||||
//Note that you cannot remove a directory that has files on most
|
|
||||||
// operating systems.
|
|
||||||
native rmdir(const path[]);
|
|
||||||
|
|
||||||
/* Returns 0 on success, like the POSIX specification */
|
|
||||||
native mkdir(const dirname[]);
|
|
||||||
|
|
||||||
|
|
||||||
//Delete a file (delete_file macro)
|
|
||||||
native unlink(const filename[]);
|
|
||||||
|
|
||||||
//Returns a handle to a directory
|
|
||||||
native open_dir(dir[], firstfile[], length);
|
|
||||||
native next_file(dirh, buffer[], length);
|
|
||||||
native close_dir(dirh);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a file using the LoadFileForMe engine function.
|
* Maximum path length.
|
||||||
*
|
|
||||||
* The data is truncated if there is not enough space. No null-terminator
|
|
||||||
* is applied; the data is the raw contents of the file.
|
|
||||||
*
|
|
||||||
* @param file File to load (may be a file from the GCF).
|
|
||||||
* @param buffer Buffer to store file contents.
|
|
||||||
* @param maxlength Maximum size of the file buffer.
|
|
||||||
* @param length Variable to store the file length. This may return
|
|
||||||
* a number larger than the buffer size.
|
|
||||||
* @return -1 if the file could not be loaded. Otherwise,
|
|
||||||
* the number of cells actually written to the buffer
|
|
||||||
* are returned.
|
|
||||||
*/
|
*/
|
||||||
native LoadFileForMe(const file[], buffer[], maxlength, &length=0);
|
#define PLATFORM_MAX_PATH 256
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes a buffered output stream.
|
* File inode types for use with open_dir() and next_file().
|
||||||
*
|
|
||||||
* @param file File handle, or 0 for all open streams.
|
|
||||||
* @return 0 on success, -1 on failure.
|
|
||||||
*/
|
*/
|
||||||
native fflush(file);
|
enum FileType
|
||||||
|
{
|
||||||
|
FileType_Unknown, /* Unknown file type (device/socket) */
|
||||||
|
FileType_Directory, /* File is a directory */
|
||||||
|
FileType_File, /* File is a file */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File time modes for use with GetFileTime().
|
||||||
|
*/
|
||||||
enum FileTimeType
|
enum FileTimeType
|
||||||
{
|
{
|
||||||
FileTime_LastAccess, /* Last access (not available on FAT) */
|
FileTime_LastAccess, /* Last access (not available on FAT) */
|
||||||
|
@ -153,11 +49,618 @@ enum FileTimeType
|
||||||
FileTime_LastChange, /* Last modification */
|
FileTime_LastChange, /* Last modification */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File position modes for use with fseek().
|
||||||
|
*/
|
||||||
|
#define SEEK_SET 0 /* Seek from start */
|
||||||
|
#define SEEK_CUR 1 /* Seek from current position */
|
||||||
|
#define SEEK_END 2 /* Seek from end position */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for use with file_size() flag parameter.
|
||||||
|
*/
|
||||||
|
#define FSOPT_BYTES_COUNT 0 /* Returns the file size in number of bytes */
|
||||||
|
#define FSOPT_LINES_COUNT 1 /* Returns how many lines there are in this file */
|
||||||
|
#define FSOPT_END_WITH_LF 2 /* Returns whether the last line is '\n' */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data block modes for use with fread*() and fwrite*().
|
||||||
|
*/
|
||||||
|
#define BLOCK_INT 4
|
||||||
|
#define BLOCK_SHORT 2
|
||||||
|
#define BLOCK_CHAR 1
|
||||||
|
#define BLOCK_BYTE 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File permissions flags for use with mkdir() and SetFilePermissions().
|
||||||
|
*/
|
||||||
|
#define FPERM_U_READ 0x0100 /* User can read. */
|
||||||
|
#define FPERM_U_WRITE 0x0080 /* User can write. */
|
||||||
|
#define FPERM_U_EXEC 0x0040 /* User can exec. */
|
||||||
|
#define FPERM_U_RWX FPERM_U_READ | FPERM_U_WRITE | FPERM_U_EXEC
|
||||||
|
|
||||||
|
#define FPERM_G_READ 0x0020 /* Group can read. */
|
||||||
|
#define FPERM_G_WRITE 0x0010 /* Group can write. */
|
||||||
|
#define FPERM_G_EXEC 0x0008 /* Group can exec. */
|
||||||
|
#define FPERM_G_RWX FPERM_G_READ | FPERM_G_WRITE | FPERM_G_EXEC
|
||||||
|
|
||||||
|
#define FPERM_O_READ 0x0004 /* Anyone can read. */
|
||||||
|
#define FPERM_O_WRITE 0x0002 /* Anyone can write. */
|
||||||
|
#define FPERM_O_EXEC 0x0001 /* Anyone can exec. */
|
||||||
|
#define FPERM_O_RWX FPERM_O_READ | FPERM_O_WRITE | FPERM_O_EXEC
|
||||||
|
|
||||||
|
#define FPERM_DIR_DEFAULT FPERM_U_RWX | FPERM_G_RWX | FPERM_O_RWX /* rwx r-x r-x (0755) */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads content from directory
|
||||||
|
*
|
||||||
|
* @note This native is expensive. Consider the use of open_dir(), next_file() and close_dir() instead.
|
||||||
|
* @note Both the '.' and '..' automatic directory entries will be retrieved for Windows and Linux.
|
||||||
|
*
|
||||||
|
* @param dirname Path to open
|
||||||
|
* @param pos Index the element
|
||||||
|
* @param output String buffer to hold content
|
||||||
|
* @param len Maximum size of string buffer
|
||||||
|
* @param outlen Number of characters written to the buffer
|
||||||
|
*
|
||||||
|
* @return Returns index of next element, otherwiwe 0 when end of dir is reached
|
||||||
|
*/
|
||||||
|
native read_dir(const dirname[], pos, output[], len, &outlen = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads line from file.
|
||||||
|
*
|
||||||
|
* @note This native is expensive. Consider the use of new file natives (fopen(), fgets(), etc.)
|
||||||
|
* if purpose is to read several lines of a file.
|
||||||
|
*
|
||||||
|
* @param file Path to open
|
||||||
|
* @param line Index of the line, starting to 0
|
||||||
|
* @param text String buffer to hold line read
|
||||||
|
* @param len Maximum size of string buffer
|
||||||
|
* @param txtlen Number of characters written to the buffer
|
||||||
|
*
|
||||||
|
* @return Returns index of next line, otherwise 0 when end of file is reached
|
||||||
|
* @error Unable to read the file
|
||||||
|
*/
|
||||||
|
native read_file(const file[], line, text[], len, &txtlen = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes text to file.
|
||||||
|
*
|
||||||
|
* @note This native is expensive. Consider the use of new file natives (fopen(), fputs(), etc.)
|
||||||
|
* if purpose is to write several lines of a file.
|
||||||
|
*
|
||||||
|
* @param file Path to open
|
||||||
|
* @param text String to write to
|
||||||
|
* @param line Index of the line, starting to 0
|
||||||
|
* If < 0, content will be appended
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
* @error Unable to write [temporary] file
|
||||||
|
*/
|
||||||
|
native write_file(const file[], const text[], line = -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a file.
|
||||||
|
*
|
||||||
|
* @param file Path of the file to delete
|
||||||
|
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||||
|
* This can be used to delete files existing in the Valve
|
||||||
|
* search path, rather than solely files existing directly
|
||||||
|
* in the gamedir.
|
||||||
|
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||||
|
*
|
||||||
|
* @return 1 on success, 0 on failure or if file not immediately removed.
|
||||||
|
*/
|
||||||
|
native delete_file(const file[], bool:use_valve_fs = false, const valve_path_id[] = "GAMECONFIG");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a file exists.
|
||||||
|
*
|
||||||
|
* @param file Path to the file
|
||||||
|
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||||
|
* This can be used to find files existing in any of
|
||||||
|
* the Valve search paths, rather than solely files
|
||||||
|
* existing directly in the gamedir.
|
||||||
|
*
|
||||||
|
* @return 1 if the file exists, 0 otherwise
|
||||||
|
*/
|
||||||
|
native file_exists(const file[], bool:use_valve_fs = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames a file.
|
||||||
|
*
|
||||||
|
* @param oldname New path to the file
|
||||||
|
* @param newname Path to the existing file
|
||||||
|
* @param relative If true, native will act like other natives which
|
||||||
|
* use the moddir as a base directory. Otherwise, the
|
||||||
|
* current directory is undefined (but assumed to be hlds).
|
||||||
|
*
|
||||||
|
* @return 1 on success, 0 otherwise
|
||||||
|
*/
|
||||||
|
native rename_file(const oldname[], const newname[], relative = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a directory exists.
|
||||||
|
*
|
||||||
|
* @param dir Path to the directory
|
||||||
|
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||||
|
* This can be used to find files existing in any of
|
||||||
|
* the Valve search paths, rather than solely files
|
||||||
|
* existing directly in the gamedir.
|
||||||
|
*
|
||||||
|
* @return 1 if the directory exists, 0 otherwise
|
||||||
|
*/
|
||||||
|
native dir_exists(const dir[], bool:use_valve_fs = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file size in bytes.
|
||||||
|
*
|
||||||
|
* @param file Path to the file
|
||||||
|
* @param flag Flag options, see FSOPT_* constants
|
||||||
|
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||||
|
* This can be used to find files existing in any of
|
||||||
|
* the Valve search paths, rather than solely files
|
||||||
|
* existing directly in the gamedir.
|
||||||
|
* If used, flag option is ignored.
|
||||||
|
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths
|
||||||
|
*
|
||||||
|
* @return If flag is FSOPT_BYTES_COUNT or use_valve_fs to true, the file size in bytes
|
||||||
|
* If flag is FSOPT_LINES_COUNT, the number of lines in the file
|
||||||
|
* If flag is FSOPT_END_WITH_LF, 1 is returned if file ends with line feed
|
||||||
|
* If file doesn't exist, -1
|
||||||
|
*/
|
||||||
|
native file_size(const file[], flag = FSOPT_BYTES_COUNT, bool:use_valve_fs = false, const valve_path_id[] = "GAME");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens or creates a file, returning a file handle on success. File handles
|
||||||
|
* should be closed with fclose().
|
||||||
|
*
|
||||||
|
* @note The open mode may be one of the following strings:
|
||||||
|
* "r": Open an existing file for reading.
|
||||||
|
* "w": Create a file for writing, or truncate (delete the contents of) an
|
||||||
|
* existing file and then open it for writing.
|
||||||
|
* "a": Create a file for writing, or open an existing file such that writes
|
||||||
|
* will be appended to the end.
|
||||||
|
* "r+": Open an existing file for both reading and writing.
|
||||||
|
* "w+": Create a file for reading and writing, or truncate an existing file
|
||||||
|
* and then open it for reading and writing.
|
||||||
|
* "a+": Create a file for both reading and writing, or open an existing file
|
||||||
|
* such that writes will be appended to the end.
|
||||||
|
*
|
||||||
|
* @note The open mode may also contain an additional character after "r", "w", or "a",
|
||||||
|
* but before any "+" sign. This character may be "b" (indicating binary mode) or
|
||||||
|
* "t" (indicating text mode). By default, "text" mode is implied. On Linux and
|
||||||
|
* Mac, this has no distinction from binary mode. On Windows, it causes the '\n'
|
||||||
|
* character (0xA) to be written as "\r\n" (0xD, 0xA).
|
||||||
|
*
|
||||||
|
* Example: "rb" opens a binary file for writing; "at" opens a text file for
|
||||||
|
* appending.
|
||||||
|
*
|
||||||
|
* @note Registered paths ID are (in priority order) :
|
||||||
|
* GAME All paths related to current mod, including fallback
|
||||||
|
* Depending settings, it includes: <gamedir>_lv/_addon/_<language>/_hd
|
||||||
|
* and <gamedir> itself
|
||||||
|
* GAMECONFIG The default writable directory (<gamedir>)
|
||||||
|
* GAMEDOWNLOAD The download directory (<gamedir>_download)
|
||||||
|
* GAME_FALLBACK All paths related to fallback game, same as GAME
|
||||||
|
* DEFAULTGAME All paths related to the default game which is "valve", same as GAME
|
||||||
|
* BASE The base path where server is installed
|
||||||
|
*
|
||||||
|
* Note that some paths are non-writable. It includes all <gamedir>_* (expect _download)
|
||||||
|
* and DEFAULTGAME. Any file inside a non-writable path will be ignored if you try to open
|
||||||
|
* it in writing mode.
|
||||||
|
*
|
||||||
|
* @param filename File to open
|
||||||
|
* @param mode Open mode
|
||||||
|
* @param use_valve_fs If true, the Valve file system will be used instead
|
||||||
|
* This can be used to finred files existing in valve
|
||||||
|
* search paths, rather than solely files existing directly
|
||||||
|
* in the gamedir.
|
||||||
|
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths
|
||||||
|
*
|
||||||
|
* @return A file handle, or null if the file could not be opened.
|
||||||
|
*/
|
||||||
|
native fopen(const filename[], const mode[], bool:use_valve_fs = false, const valve_path_id[] = "GAME");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes a file handle.
|
||||||
|
*
|
||||||
|
* @param file File handle
|
||||||
|
*/
|
||||||
|
native fclose(file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single binary data from a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Variable to store item read
|
||||||
|
* @param mode Size of each element, in bytes, to be read
|
||||||
|
* See BLOCK_* constants
|
||||||
|
*
|
||||||
|
* @return Number of elements read
|
||||||
|
*/
|
||||||
|
native fread(file, &any:data, mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads binary data from a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Array to store each item read
|
||||||
|
* @param blocks Number of items to read into the array
|
||||||
|
* @param mode Size of each element, in bytes, to be read
|
||||||
|
* Valid sizes are 1, 2, or 4. See BLOCK_* constants.
|
||||||
|
*
|
||||||
|
* @return Number of elements read
|
||||||
|
*/
|
||||||
|
native fread_blocks(file, any:data[], blocks, mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads raw binary data from a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param stream Array to store each item read
|
||||||
|
* @param blocksize Number of items to read into the array
|
||||||
|
* @param blocks Size of each element, in bytes. The data is read directly.
|
||||||
|
* That is, in 1 or 2-byte mode, the lower byte(s) in
|
||||||
|
* each cell are used directly, rather than performing
|
||||||
|
* any casts from a 4-byte number to a smaller number.
|
||||||
|
*
|
||||||
|
* @return Number of elements read
|
||||||
|
*/
|
||||||
|
native fread_raw(file, any:stream[], blocksize, blocks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a single binary data to a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Item to write
|
||||||
|
* @param mode Size of each item in the array in bytes
|
||||||
|
* Valid sizes are 1, 2, or 4. See BLOCK_* constants
|
||||||
|
*
|
||||||
|
* @return Number of elements written
|
||||||
|
*/
|
||||||
|
native fwrite(file, any:data, mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes binary data to a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Array of items to write
|
||||||
|
* @param blocks Number of items in the array
|
||||||
|
* @param mode Size of each item in the array in bytes
|
||||||
|
* Valid sizes are 1, 2, or 4. See BLOCK_* constants
|
||||||
|
*
|
||||||
|
* @return Number of elements written
|
||||||
|
*/
|
||||||
|
native fwrite_blocks(file, const any:data[], blocks, mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes raw binary data to a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file.
|
||||||
|
* @param stream Array of items to write. The data is written directly.
|
||||||
|
* That is, in 1 or 2-byte mode, the lower byte(s) in
|
||||||
|
* each cell are used directly, rather than performing
|
||||||
|
* any casts from a 4-byte number to a smaller number.
|
||||||
|
* @param blocks Size of each item in the array in bytes.
|
||||||
|
* @param mode Number of items in the array.
|
||||||
|
*
|
||||||
|
* @return Number of elements written
|
||||||
|
*/
|
||||||
|
native fwrite_raw(file, const any:stream[], blocks, mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the end of file has been reached.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
*
|
||||||
|
* @return 1 if end of file has been reached, 0 otherwise.
|
||||||
|
*/
|
||||||
|
native feof(file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a line from a text file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file.
|
||||||
|
* @param buffer String buffer to hold the line
|
||||||
|
* @param maxlength Maximum size of string buffer
|
||||||
|
*
|
||||||
|
* @return Total number of characters written on success, 0 otherwise
|
||||||
|
*/
|
||||||
|
native fgets(file, buffer[], maxlength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a line of text to a text file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param text String to write
|
||||||
|
* @param null_term True to append NULL terminator, false otherwise
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
native fputs(file, const text[], bool:null_term = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a line of formatted text to a text file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param format Formatting rules
|
||||||
|
* @param ... Variable number of format parameters
|
||||||
|
*
|
||||||
|
* @return Total number of characters written on success, 0 otherwise
|
||||||
|
*/
|
||||||
|
native fprintf(file, const fmt[], any:...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file position indicator.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param position Position relative to what is specified in whence
|
||||||
|
* @param start SEEK_ constant value of where to see from
|
||||||
|
*
|
||||||
|
* @return 0 on success, a non-zero value otherwise
|
||||||
|
*/
|
||||||
|
native fseek(file, position, start);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets current position in the file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
*
|
||||||
|
* @return Value for the file position indicator
|
||||||
|
*/
|
||||||
|
native ftell(file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets character from file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
*
|
||||||
|
* @return Character read on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
native fgetc(file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes character to file
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Character to put
|
||||||
|
*
|
||||||
|
* @return Character written on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
native fputc(file, data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ungets character from file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Character to unget
|
||||||
|
*
|
||||||
|
* @return On success, the character put back is returned, -1 otherwise
|
||||||
|
*/
|
||||||
|
native fungetc(file, data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes a buffered output stream.
|
||||||
|
*
|
||||||
|
* @param file File handle, or 0 for all open streams
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
native fflush(file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the formatted file size in bytes.
|
||||||
|
*
|
||||||
|
* @param filename Path to the file
|
||||||
|
* @param ... Variable number of format parameters
|
||||||
|
*
|
||||||
|
* @return File size in bytes, otherwise -1 if file not found
|
||||||
|
*/
|
||||||
|
native filesize(const filename[], any:...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a directory.
|
||||||
|
*
|
||||||
|
* @note On most Operating Systems you cannot remove a directory which has files inside it.
|
||||||
|
*
|
||||||
|
* @param path Path to the directory
|
||||||
|
*
|
||||||
|
* @return 1 on success, 0 otherwise
|
||||||
|
*/
|
||||||
|
native rmdir(const path[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a directory.
|
||||||
|
*
|
||||||
|
* @param path Path to create
|
||||||
|
* @param mode Permissions (default is o=rx,g=rx,u=rwx). Note that folders must have
|
||||||
|
* the execute bit set on Linux. On Windows, the mode is ignored.
|
||||||
|
* @param use_valve_fs If true, the Valve file system will be used instead
|
||||||
|
* This can be used to create folders in the game's
|
||||||
|
* Valve search paths, rather than directly in the gamedir.
|
||||||
|
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for default
|
||||||
|
* In this case, mode is ignored
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
native mkdir(const dirname[], mode = FPERM_DIR_DEFAULT, bool:use_valve_fs = false, const valve_path_id[] = "GAMECONFIG");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a file (delete_file macro)
|
||||||
|
*
|
||||||
|
* @param filename Path of the file to delete
|
||||||
|
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||||
|
* This can be used to delete files existing in the Valve
|
||||||
|
* search path, rather than solely files existing directly
|
||||||
|
* in the gamedir.
|
||||||
|
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths
|
||||||
|
*
|
||||||
|
* @return 1 on success, 0 on failure or if file not immediately removed
|
||||||
|
*/
|
||||||
|
native unlink(const filename[], bool:use_valve_fs = false, const valve_path_id[] = "GAMECONFIG");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a directory/folder for contents enumeration.
|
||||||
|
*
|
||||||
|
* @note Directories are closed with close_dir().
|
||||||
|
*
|
||||||
|
* @param dir Path to open.
|
||||||
|
* @param firstfile String buffer to hold first file name
|
||||||
|
* @param length Maximum size of the string buffer
|
||||||
|
* @param type Optional variable to store the file type
|
||||||
|
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||||
|
* This can be used to find files existing in any of
|
||||||
|
* the Valve search paths, rather than solely files
|
||||||
|
* existing directly in the gamedir.
|
||||||
|
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||||
|
*
|
||||||
|
* @return Handle to the directory, 0 otherwise
|
||||||
|
*/
|
||||||
|
native open_dir(dir[], firstfile[], length, &FileType:type = FileType_Unknown, bool:use_valve_fs = false, const valve_path_id[] = "GAME");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the next directory entry as a local filename.
|
||||||
|
*
|
||||||
|
* @note Contents of buffers are undefined when returning false.
|
||||||
|
* @note Both the '.' and '..' automatic directory entries will be retrieved for Windows and Linux.
|
||||||
|
*
|
||||||
|
* @param dirh Handle to a directory
|
||||||
|
* @param buffer String buffer to hold directory name
|
||||||
|
* @param length Maximum size of string buffer
|
||||||
|
* @param type Optional variable to store the file type. FileType_* constants
|
||||||
|
*
|
||||||
|
* @return 1 on success, 0 if there are no more files to read.
|
||||||
|
*/
|
||||||
|
native next_file(dirh, buffer[], length, &FileType:type = FileType_Unknown);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the directory.
|
||||||
|
*
|
||||||
|
* @param dirh Handle to a directory
|
||||||
|
*/
|
||||||
|
native close_dir(dirh);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a file using the LoadFileForMe engine function.
|
||||||
|
*
|
||||||
|
* The data is truncated if there is not enough space. No null-terminator
|
||||||
|
* is applied; the data is the raw contents of the file.
|
||||||
|
*
|
||||||
|
* @param file File to load (may be a file from the GCF)
|
||||||
|
* @param buffer Buffer to store file contents
|
||||||
|
* @param maxlength Maximum size of the file buffer
|
||||||
|
* @param length Variable to store the file length. This may return
|
||||||
|
* a number larger than the buffer size
|
||||||
|
* @return -1 if the file could not be loaded. Otherwise,
|
||||||
|
* the number of cells actually written to the buffer
|
||||||
|
* are returned.
|
||||||
|
*/
|
||||||
|
native LoadFileForMe(const file[], buffer[], maxlength, &length = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a file timestamp as a unix timestamp.
|
* Returns a file timestamp as a unix timestamp.
|
||||||
*
|
*
|
||||||
* @param file File name.
|
* @param file File name
|
||||||
* @param tmode Time mode. See FileTime_* constants.
|
* @param tmode Time mode, see FileTime_* constants
|
||||||
* @return Returns a file timestamp as a unix timestamp.
|
*
|
||||||
|
* @return Returns a file timestamp as a unix timestamp
|
||||||
*/
|
*/
|
||||||
native GetFileTime( const file[], FileTimeType:tmode );
|
native GetFileTime(const file[], FileTimeType:tmode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes a file or directories permissions.
|
||||||
|
*
|
||||||
|
* @param path Path to the file
|
||||||
|
* @param mode Permissions to set, see FPERM_* constants
|
||||||
|
*
|
||||||
|
* @return True on success, false otherwise
|
||||||
|
*/
|
||||||
|
native bool:SetFilePermissions(const path[], mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single int8 (byte) from a file. The returned value is sign-
|
||||||
|
* extended to an int32.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Variable to store the data read
|
||||||
|
*
|
||||||
|
* @return True on success, false on failure
|
||||||
|
*/
|
||||||
|
native bool:FileReadInt8(file, &any:data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single uint8 (unsigned byte) from a file. The returned value is
|
||||||
|
* zero-extended to an int32.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Variable to store the data read
|
||||||
|
*
|
||||||
|
* @return True on success, false on failure
|
||||||
|
*/
|
||||||
|
native bool:FileReadUint8(file, &any:data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single int16 (short) from a file. The value is sign-extended to
|
||||||
|
* an int32.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Variable to store the data read
|
||||||
|
*
|
||||||
|
* @return True on success, false on failure
|
||||||
|
*/
|
||||||
|
native bool:FileReadInt16(file, &any:data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single unt16 (unsigned short) from a file. The value is zero-
|
||||||
|
* extended to an int32.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Variable to store the data read
|
||||||
|
*
|
||||||
|
* @return True on success, false on failure
|
||||||
|
*/
|
||||||
|
native bool:FileReadUint16(file, &any:data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a single int32 (int/cell) from a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Variable to store the data read
|
||||||
|
*
|
||||||
|
* @return True on success, false on failure
|
||||||
|
*/
|
||||||
|
native bool:FileReadInt32(file, &any:data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a single int8 (byte) to a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Data to write (truncated to an int8)
|
||||||
|
*
|
||||||
|
* @return True on success, false on failure
|
||||||
|
*/
|
||||||
|
native bool:FileWriteInt8(file, any:data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a single int16 (short) to a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Data to write (truncated to an int16)
|
||||||
|
*
|
||||||
|
* @return True on success, false on failure
|
||||||
|
*/
|
||||||
|
native bool:FileWriteInt16(file, any:data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a single int32 (int/cell) to a file.
|
||||||
|
*
|
||||||
|
* @param file Handle to the file
|
||||||
|
* @param data Data to write
|
||||||
|
*
|
||||||
|
* @return True on success, false on failure
|
||||||
|
*/
|
||||||
|
native bool:FileWriteInt32(file, any:data);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user