// 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 // // NVault Module // #include #include "amxxapi.h" #include "NVault.h" #include #ifdef WIN32 #define MKDIR(p) mkdir(p) #else #define MKDIR(p) mkdir(p, 0755) #endif #if defined(__linux__) || defined(__APPLE__) #include #include #include #else #include #endif ke::Vector g_Vaults; Queue g_OldVaults; VaultMngr g_VaultMngr; #ifndef _WIN32 extern "C" void __cxa_pure_virtual(void) { } #endif static cell nvault_open(AMX *amx, cell *params) { int len, id=-1; char *name = MF_GetAmxString(amx, params[1], 0, &len); char path[255], file[255]; MF_BuildPathnameR(path, sizeof(path), "%s/vault", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data")); sprintf(file, "%s/%s.vault", path, name); for (size_t i=0; iGetFilename(), file) == 0) return i; } NVault *v = (NVault *)g_VaultMngr.OpenVault(file); if (v == NULL || !v->Open()) { delete v; return -1; } if (!g_OldVaults.empty()) { id = g_OldVaults.first(); g_OldVaults.pop(); } if (id != -1) { g_Vaults[id] = v; } else { g_Vaults.append(v); id = (int)g_Vaults.length()-1; } return id; } static cell nvault_touch(AMX *amx, cell *params) { unsigned int id = params[1]; if (id >= g_Vaults.length() || !g_Vaults.at(id)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); return 0; } NVault *pVault = g_Vaults.at(id); int len; char *key = MF_GetAmxString(amx, params[2], 0, &len); if (params[3] == -1) { pVault->Touch(key, time(NULL)); } else { pVault->Touch(key, static_cast(params[3])); } return 1; } static cell nvault_get(AMX *amx, cell *params) { unsigned int id = params[1]; if (id >= g_Vaults.length() || !g_Vaults.at(id)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); return 0; } NVault *pVault = g_Vaults.at(id); unsigned int numParams = (*params)/sizeof(cell); int len; char *key = MF_GetAmxString(amx, params[2], 0, &len); const char *val = pVault->GetValue(key); switch (numParams) { case 2: { return atoi(val); break; } case 3: { cell *fAddr = MF_GetAmxAddr(amx, params[3]); *fAddr = amx_ftoc((REAL)atof(val)); return 1; break; } case 4: { len = *(MF_GetAmxAddr(amx, params[4])); return MF_SetAmxString(amx, params[3], val, len); break; } } return 0; } static cell nvault_lookup(AMX *amx, cell *params) { unsigned int id = params[1]; if (id >= g_Vaults.length() || !g_Vaults.at(id)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); return 0; } NVault *pVault = g_Vaults.at(id); int len; time_t stamp; char *key = MF_GetAmxString(amx, params[2], 0, &len); char *buffer = new char[params[4]+1]; if (!pVault->GetValue(key, stamp, buffer, params[4])) { delete [] buffer; return 0; } MF_SetAmxString(amx, params[3], buffer, params[4]); cell *addr = MF_GetAmxAddr(amx, params[5]); addr[0] = (cell)stamp; delete [] buffer; return 1; } static cell nvault_set(AMX *amx, cell *params) { unsigned int id = params[1]; if (id >= g_Vaults.length() || !g_Vaults.at(id)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); return 0; } NVault *pVault = g_Vaults.at(id); int len; const char *key = MF_GetAmxString(amx, params[2], 0, &len); const char *val = MF_GetAmxString(amx, params[3], 1, &len); pVault->SetValue(key, val); return 1; } static cell nvault_pset(AMX *amx, cell *params) { unsigned int id = params[1]; if (id >= g_Vaults.length() || !g_Vaults.at(id)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); return 0; } NVault *pVault = g_Vaults.at(id); int len; const char *key = MF_GetAmxString(amx, params[2], 0, &len); const char *val = MF_GetAmxString(amx, params[3], 1, &len); pVault->SetValue(key, val, 0); return 1; } static cell nvault_close(AMX *amx, cell *params) { unsigned int id = params[1]; if (id >= g_Vaults.length() || !g_Vaults.at(id)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); return 0; } NVault *pVault = g_Vaults.at(id); pVault->Close(); delete pVault; g_Vaults[id] = NULL; g_OldVaults.push(id); return 1; } static cell AMX_NATIVE_CALL nvault_prune(AMX *amx, cell *params) { unsigned int id = params[1]; if (id >= g_Vaults.length() || !g_Vaults.at(id)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); return 0; } NVault *pVault = g_Vaults.at(id); time_t start = (time_t )params[2]; time_t end = (time_t )params[3]; return pVault->Prune(start, end); } static cell AMX_NATIVE_CALL nvault_remove(AMX *amx, cell *params) { unsigned int id = params[1]; if (id >= g_Vaults.length() || !g_Vaults.at(id)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); return 0; } NVault *pVault = g_Vaults.at(id); int len; const char *key = MF_GetAmxString(amx, params[2], 0, &len); pVault->Remove(key); return 1; } IVaultMngr *GetVaultMngr() { return static_cast(&g_VaultMngr); } void OnAmxxAttach() { //create the dir if it doesn't exist MKDIR(MF_BuildPathname("%s/vault", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data"))); MF_AddNatives(nVault_natives); MF_RegisterFunction((void *)GetVaultMngr, "GetVaultMngr"); } void OnPluginsUnloaded() { for (size_t i=0; i