diff --git a/amxmodx/binlog.cpp b/amxmodx/binlog.cpp new file mode 100644 index 00000000..39143443 --- /dev/null +++ b/amxmodx/binlog.cpp @@ -0,0 +1,125 @@ +#include "amxmodx.h" +#include "binlog.h" + +#if defined BINLOG_ENABLED + +BinLog g_BinLog; + +bool BinLog::Open() +{ + const char *data = get_localinfo("amxmodx_datadir", "addons/amxmodx/data"); + char path[255]; + build_pathname_r(path, sizeof(path)-1, "%s/binlogs", data); + + if (!DirExists(path)) + { + mkdir(path +#if defined __linux__ + , 0755 +#endif + ); + if (!DirExists(path)) + return false; + } + + char file[255]; + build_pathname_r(file, sizeof(file)-1, "%s/binlogs/lastlog", data); + + unsigned int lastcntr = 0; + FILE *lastlog = fopen(file, "rb"); + if (lastlog) + { + if (fread(&lastcntr, sizeof(int), 1, lastlog) != 1) + lastcntr = 0; + fclose(lastlog); + } + lastlog = fopen(file, "wb"); + if (lastlog) + { + lastcntr++; + fwrite(&lastcntr, sizeof(int), 1, lastlog); + fclose(lastlog); + } + build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr); + m_logfile.assign(file); + build_pathname_r(file, sizeof(file)-1, "%s/binlogs/bindb%04d.bdb", data, lastcntr); + m_dbfile.assign(file); + + return true; +} + +void BinLog::Close() +{ + //dummy function - logs are not kept open +} + +void BinLog::CacheAllPlugins() +{ + FILE *fp = fopen(m_dbfile.c_str(), "wb"); + if (!fp) + return; + + unsigned int magic = BINDB_MAGIC; + unsigned short vers = BINDB_VERSION; + + fwrite(&magic, sizeof(unsigned int), 1, fp); + fwrite(&vers, sizeof(unsigned short), 1, fp); + + int num = g_plugins.getPluginsNum(); + fwrite(&num, sizeof(int), 1, fp); + + CPluginMngr::CPlugin *pl; + char c; + unsigned char len; + for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter) + { + pl = &(*iter); + if (pl->isValid()) + c = 1; + else + c = 0; + fwrite(&c, sizeof(char), 1, fp); + len = (char)strlen(pl->getName()); + fwrite(&len, sizeof(char), 1, fp); + len++; + fwrite(pl->getName(), sizeof(char), len, fp); + int objcount; + AMX *amx = pl->getAMX(); + amx_NumNatives(amx, &objcount); + char name[34]; + for (int i=0; i + * ] + * Format of bindb: + * int32_t magic + * int16_t version + * int16_t num plugins + * [ + * str[int8_t] filename + * int8_t valid/loaded? + * int16_t num natives + * [ + * str[int8_t] native name + * ] + * int16_t num publics + * [ + * str[int8_t] public name + * ] + */ + +enum BinLogOp +{ + BinLog_Start=0, + BinLog_End, + BinLog_NativeCall, // + BinLog_CallPubFunc, // + BinLog_SetLine, // + BinLog_Registered, // +}; + +class BinLog +{ +public: + bool Open(); + void Close(); + void CacheAllPlugins(); + void WriteOp(BinLogOp op, ...); +private: + String m_dbfile; + String m_logfile; +}; + +#endif //BINLOG_ENABLED + +extern BinLog g_BinLog; + +#endif //_INCLUDE_BINLOG_H diff --git a/amxmodx/file.cpp b/amxmodx/file.cpp index ddd53f23..8e285880 100755 --- a/amxmodx/file.cpp +++ b/amxmodx/file.cpp @@ -307,27 +307,7 @@ static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */ char *sFile = get_amxstring(amx, params[1], 0, iLen); char *file = build_pathname("%s", sFile); -#if defined WIN32 || defined _WIN32 - DWORD attr = GetFileAttributes(file); - - if (attr == INVALID_FILE_ATTRIBUTES) - return 0; - - if (attr & FILE_ATTRIBUTE_DIRECTORY) - return 1; - - return 0; -#else - struct stat s; - - if (stat(file, &s) != 0) - return 0; - - if (S_ISDIR(s.st_mode)) - return 1; - - return 0; -#endif + return DirExists(file) ? 1 : 0; } static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */ diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp index bed0e69c..d2a405cd 100755 --- a/amxmodx/meta_api.cpp +++ b/amxmodx/meta_api.cpp @@ -39,6 +39,7 @@ #include "fakemeta.h" #include "newmenus.h" #include "natives.h" +#include "binlog.h" plugin_info_t Plugin_info = { @@ -298,6 +299,13 @@ int C_Spawn(edict_t *pent) // Set server flags memset(g_players[0].flags, -1, sizeof(g_players[0].flags)); +#if defined BINLOG_ENABLED + if (!g_BinLog.Open()) + { + LOG_ERROR(PLID, "Binary log failed to open."); + } +#endif + // ###### Load AMX scripts g_plugins.loadPluginsFromFile(get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini")); g_plugins.Finalize(); @@ -317,6 +325,10 @@ int C_Spawn(edict_t *pent) FF_ClientAuthorized = registerForward("client_authorized", ET_IGNORE, FP_CELL, FP_DONE); FF_ChangeLevel = registerForward("server_changelevel", ET_STOP, FP_STRING, FP_DONE); +#if defined BINLOG_ENABLED + g_BinLog.CacheAllPlugins(); +#endif + modules_callPluginsLoaded(); // ###### Call precache forward function diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index 197da96c..d21c0182 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -57,6 +57,30 @@ ModuleCallReason g_ModuleCallReason; 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, char* fmt, ...) { va_list argptr; diff --git a/amxmodx/modules.h b/amxmodx/modules.h index 4019bc34..42596d96 100755 --- a/amxmodx/modules.h +++ b/amxmodx/modules.h @@ -78,6 +78,8 @@ class Debugger; Debugger *DisableDebugHandler(AMX *amx); void EnableDebugHandler(AMX *amx, Debugger *pd); +bool DirExists(const char *dir); + const char* GetFileName(AMX *amx); #endif // __MODULES_H__