#include <amxmodx>
#include <fakemeta>
#include <json>
#define PLUGIN "Autoprecache Sound Models"
#define VERSION "1.1"
#define AUTHOR "MayroN & ArKaNeMaN"
/**
* amxmodx/configs/plugins/...:
* /AutoprecacheSoundModels.ini:
* models/custom/v_ak47.mdl
* models/custom/v_m4a1.mdl
* ...
* /AutoprecacheSoundModels.json:
* [
* "models/custom/v_ak47.mdl",
* "models/custom/v_m4a1.mdl"
* ...
* ]
*
* Читаются сразу и оба файла и массив list_models_v. Всё опционально.
* Если вариант с массивом не нужен - удалите или закомментируйте весь массив.
*/
new const CONFIG_INI_FILE[] = "AutoprecacheSoundModels.ini";
new const CONFIG_JSON_FILE[] = "AutoprecacheSoundModels.json";
new const list_models_v[][] = {
"models/custom/v_ak47.mdl",
"models/custom/v_m4a1.mdl",
"models/custom/v_awp.mdl",
"models/custom/v_deagle.mdl",
}
public plugin_precache(){
register_plugin(PLUGIN, VERSION, AUTHOR);
#if defined list_models_v
for(new i = 0; i < sizeof list_models_v; i++) {
UTIL_PrecacheSoundsFromModel(list_models_v[i]);
}
#endif
if (file_exists(GetConfigPath(CONFIG_JSON_FILE))) {
PrecacheFromJson(GetConfigPath(CONFIG_JSON_FILE));
}
if (file_exists(GetConfigPath(CONFIG_INI_FILE))) {
PrecacheFromIni(GetConfigPath(CONFIG_INI_FILE));
}
}
PrecacheFromJson(const filePath[]) {
new JSON:configJson = json_parse(filePath, true, true);
if (configJson == Invalid_JSON) {
log_amx("[ERROR] JSON syntax error in '%s'.", filePath);
return;
}
if (!json_is_array(configJson)) {
log_amx("[ERROR] '%s' must contains a json array.", filePath);
json_free(configJson);
return;
}
for (new i = 0, ii = json_array_get_count(configJson); i < ii; ++i) {
new modelPath[PLATFORM_MAX_PATH];
json_array_get_string(configJson, i, modelPath, charsmax(modelPath));
if (modelPath[0] == EOS) {
continue;
}
if (!file_exists(modelPath)) {
log_amx("[ERROR] Model '%s' not found. File '%s', item #%d.", modelPath, filePath, i);
continue;
}
UTIL_PrecacheSoundsFromModel(modelPath);
}
json_free(configJson);
}
PrecacheFromIni(const filePath[]) {
new fileHandle = fopen(filePath, "rt");
if (!fileHandle) {
return;
}
new modelPath[PLATFORM_MAX_PATH];
new lineIndex = 1;
while (!feof(fileHandle)) {
fgets(fileHandle, modelPath, charsmax(modelPath));
if (modelPath[0] == '#' || modelPath[0] == EOS) {
continue;
}
if (!file_exists(modelPath)) {
log_amx("[ERROR] Model '%s' not found. File '%s', line #%d.", modelPath, filePath, lineIndex);
continue;
}
UTIL_PrecacheSoundsFromModel(modelPath);
++lineIndex;
}
fclose(fileHandle);
}
stock UTIL_PrecacheSoundsFromModel(const szModelPath[]) {
new iFile = fopen(szModelPath, "rt");
if (!iFile) {
return;
}
new szSoundPath[PLATFORM_MAX_PATH];
new iNumSeq, iSeqIndex;
new iEvent, iNumEvents, iEventIndex;
fseek(iFile, 164, SEEK_SET);
fread(iFile, iNumSeq, BLOCK_INT);
fread(iFile, iSeqIndex, BLOCK_INT);
for (new k, i = 0; i < iNumSeq; i++) {
fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET);
fread(iFile, iNumEvents, BLOCK_INT);
fread(iFile, iEventIndex, BLOCK_INT);
fseek(iFile, iEventIndex + 176 * i, SEEK_SET);
for (k = 0; k < iNumEvents; k++) {
fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET);
fread(iFile, iEvent, BLOCK_INT);
fseek(iFile, 4, SEEK_CUR);
if (iEvent != 5004) {
continue;
}
fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR);
if (szSoundPath[0] != EOS) {
strtolower(szSoundPath);
engfunc(EngFunc_PrecacheSound, szSoundPath);
}
}
}
fclose(iFile);
}
GetConfigPath(const path[]) {
new configPath[PLATFORM_MAX_PATH];
get_localinfo("amxx_configsdir", configPath, charsmax(configPath));
formatex(configPath, charsmax(configPath), "%s/plugins/%s", configPath, path);
return configPath;
}