Allied Modders en español
[API] Settings System - Versión para impresión

+- Allied Modders en español (https://amxmodx-es.com)
+-- Foro: AMX Mod X - Scripting (https://amxmodx-es.com/Forum-AMX-Mod-X-Scripting)
+--- Foro: Aportes (https://amxmodx-es.com/Forum-Aportes)
+--- Tema: [API] Settings System (/Thread-API-Settings-System)



[API] Settings System - SVC - 27/07/2020

API: SETTINGS SYSTEM

Buenas noches, hacia mucho tiempo que no pasaba por aqui.
Queria compartir con ustedes esta API que diseñe hacia unas semanas ya.

• ¿EN QUE CONSISTE?

Basicamente esta API nos permite interactuar con archivos de configuracion de una manera mas sencilla.

Los "archivos de configuracion" son aquellos utilizados por la mayoria de los MODs para customizar sus modos de juego de manera "exterior", sin necesidad de re-compilar el MOD (en conclusion = archivos INI, aunque puede ser usado con cualquier archivo permitido).

No esta demas decir que la idea de esta API esta fundamentada en base a esto: Settings API (load/save data to INI files). Sin embargo la manera en como lo hace es muy diferente, optando por cargar los archivos en memoria, en lugar de leerlos cada vez que se requiere cargar un dato (para mayor informacion, leer el codigo fuente).

• ¿COMO SE UTILIZA?

Actualmente cuenta con 7 natives, las cuales son las siguientes:

Código PHP:
/*
==================================================
native: settings_open_file()

usage: opens a file

params:
    - szFileName[]: name of file that will be open
    
return: int
    - -1: file can't be open (the reason will be shown)
    - 0+: file's id (it is not the same that fopen() returns)
==================================================
*/
native settings_open_file(const szFileName[]);

/*
==================================================
native: settings_load_bool()

usage: loads a value (bool) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - &bValueOut: variable to store result (bool-type)
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_bool(const iFileId, const szSection[], const szKey[], &bool:bValueOut);

/*
==================================================
native: settings_load_int()

usage: loads a value (int) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - &iValueOut: variable to store result (int-type)
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_int(const iFileId, const szSection[], const szKey[], &iValueOut);

/*
==================================================
native: settings_load_float()

usage: loads a value (float) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - &fValueOut: variable to store result (float-type)
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_float(const iFileId, const szSection[], const szKey[], &Float:fValueOut);

/*
==================================================
native: settings_load_string()

usage: loads a value (string) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - szValueOut: buffer to store result
    - iValueOut: max buffer's length
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_string(const iFileId, const szSection[], const szKey[], szValueOut[], const iValueOutLen);

/*
==================================================
native: settings_load_darray()

usage: loads a value (dyn-array) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - &aValueOut: dyn-array to store result (dynamic array)
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_darray(const iFileId, const iDynamicArrayType, const szKey[], const szSection[], &Array:aValueOut);

/*
==================================================
native: settings_close()

usage: closes a file

params:
    - iFileId: the file-id
    
return: bool
    - true: file has been closed successfully
    - false: file can't be closed (the reason will be shown)
==================================================
*/
native bool:settings_close_file(const iFileId); 


Creo que las mismas son auto-explicables.
De igual manera, cualquier duda no teman en postearla.

• CODIGO

Código PHP:
/*===============================================================================================
 SETTINGS API SYSTEM
===============================================================================================*/

#include <AMXMODX>
#include <AMXMISC>

/*========================================
 MISC
========================================*/

#define IS_IN_RANGE(%1,%2,%3) (%2 <= %1 <= %3)

new const bool:KEEP_LOOPING true;

/*============================================
 SETTINGS
============================================*/

#define FILES_COUNT() g_iFilesCount
#define SECTIONS_COUNT() g_CurrentFileData[em_iFileSectionsCount]
#define KEYS_COUNT(%1) %1[em_iSectionKeysCount]

#define IS_FILE_CLOSED() g_CurrentFileData[em_bFileClosed]

#define IS_FILE_LOADED(%1) TrieKeyExists(g_tFilesFastList, %1)
#define SECTION_EXISTS(%1) TrieKeyExists(g_CurrentFileData[em_tFileSectionsFastList], %1)
#define KEY_EXISTS(%1,%2) TrieKeyExists(%1[em_tSectionKeysFastList], %2)

#define GET_FILE_ID(%1,%2) TrieGetCell(g_tFilesFastList, %1, %2)
#define GET_SECTION_ID(%1,%2) TrieGetCell(g_CurrentFileData[em_tFileSectionsFastList], %1, %2)
#define GET_KEY_ID(%1,%2,%3) TrieGetCell(%1[em_tSectionKeysFastList], %2, %3)

#define ALLOCATE_FILES_LIST() g_aFilesList = ArrayCreate(file_s)
#define ALLOCATE_FILES_FAST_LIT() g_tFilesFastList = TrieCreate()

#define ALLOCATE_SECTIONS_LIST() g_CurrentFileData[em_aFileSectionsList] = ArrayCreate(section_s)
#define ALLOCATE_SECTION_FAST_LIST() g_CurrentFileData[em_tFileSectionsFastList] = TrieCreate()

#define ALLOCATE_KEYS_LIST(%1) %1[em_aSectionKeysList] = ArrayCreate(key_s)
#define ALLOCATE_KEYS_FAST_LIST(%1) %1[em_tSectionKeysFastList] = TrieCreate()
#define ALLOCATE_KEY_VALUES(%1) %1[em_tKeyValues] = TrieCreate()

#define ADD_FILE_TO_LIST() ArrayPushArray(g_aFilesList, g_CurrentFileData)
#define ADD_FILE_TO_FAST_LIST(%1) TrieSetCell(g_tFilesFastList, %1, FILES_COUNT()++)

#define ADD_SECTION_TO_LIST(%1) ArrayPushArray(g_CurrentFileData[em_aFileSectionsList], %1)
#define ADD_SECTION_TO_FAST_LIST(%1) TrieSetCell(g_CurrentFileData[em_tFileSectionsFastList], %1, SECTIONS_COUNT()++)

#define ADD_KEY_TO_LIST(%1,%2) ArrayPushArray(%1[em_aSectionKeysList], %2)
#define ADD_KEY_TO_FAST_LIST(%1,%2,%3) TrieSetCell(%1[em_tSectionKeysFastList], %2, %3)
#define ADD_KEY_VALUE(%1,%2) TrieSetString(%1[em_tKeyValues], %2, g_szValue)

#define LOAD_FILE_DATA(%1) ArrayGetArray(g_aFilesList, %1, g_CurrentFileData)
#define LOAD_SECTION_DATA(%1,%2) ArrayGetArray(g_CurrentFileData[em_aFileSectionsList], %1, %2)
#define LOAD_KEY_DATA(%1,%2,%3) ArrayGetArray(%1[em_aSectionKeysList], %2, %3)
#define LOAD_KEY_VALUE(%1,%2) TrieGetString(%1[em_tKeyValues], %2, g_szValue, charsmax(g_szValue))

#define UPDATE_FILE_DATA(%1) ArraySetArray(g_aFilesList, %1, g_CurrentFileData)

#define CLEAR_FILES_DATA() ArrayDestroy(g_aFilesList)
#define CLEAR_FILES_FAST_DATA() TrieDestroy(g_tFilesFastList)

#define CLEAR_FILE_DATA(%1) ArrayDestroy(g_CurrentFileData[em_aFileSectionsList])
#define CLEAR_FILE_FAST_DATA(%1) TrieDestroy(g_CurrentFileData[em_tFileSectionsFastList])

#define CLEAR_SECTION_DATA(%1) ArrayDestroy(%1[em_aSectionKeysList])
#define CLEAR_SECTION_FAST_DATA(%1) TrieDestroy(%1[em_tSectionKeysFastList])

#define CLEAR_KEY_DATA(%1) TrieDestroy(%1[em_tKeyValues])

#define CLOSE_FILE() g_CurrentFileData[em_bFileClosed] = true
#define REOPEN_FILE() g_CurrentFileData[em_bFileClosed] = false

#define MAX_FILE_NAME_LEN 40

#define MAX_SECTION_NAME_LEN 20

#define MAX_KEY_NAME_LEN 30
#define MAX_KEY_VALUE_LEN 256

#define MAX_LINE_LEN MAX_KEY_VALUE_LEN + MAX_KEY_NAME_LEN

// this will close (free) all files data
// keep in mind that when you used this
// you will need to RE-ALLOCATE files data again
// I mean:
// ALLOCATE_FILES_LIST()
// ALLOCATE_FILES_FAST_LIT()
const CLOSE_ALL_FILES = -(1<<30);

enum file_s
{
 
bool:em_bFileClosed,
 
em_iFileSectionsCount,
 
em_szFileName[MAX_FILE_NAME_LEN],
 Array:
em_aFileSectionsList,
 
Trie:em_tFileSectionsFastList // same of above, but for sections ids (fast-lookup)
};

enum section_s
{
 
em_iSectionKeysCount,
 
em_szSectionName[MAX_SECTION_NAME_LEN],
 Array:
em_aSectionKeysList,
 
Trie:em_tSectionKeysFastList // same as the sections uses, but for keys
};

enum key_s
{
 
em_szKeyName[MAX_KEY_NAME_LEN],
 
Trie:em_tKeyValues // values are stored in a hash-map for fast-lookup searchs
};

// value-types for LoadFileValue()
enum _:ValueTypes
{
 
VALUE_TYPE_BOOL 0,
 
VALUE_TYPE_INT,
 
VALUE_TYPE_FLOAT,
 
 
// "DARR" stands for dynamic array
 // the same as used on ArrayCreate native
 
VALUE_TYPE_DARR_BOOL// array of bools
 
VALUE_TYPE_DARR_INT// array of ints
 
VALUE_TYPE_DARR_FLOAT// array of floats
 
VALUE_TYPE_DARR_STRING // array of strings
};

new 
g_iFilesCount;
new 
g_iCurrentFile;

new 
g_szLine[MAX_LINE_LEN];
new 
g_szValue[MAX_KEY_VALUE_LEN];

new 
g_CurrentFileData[file_s];

new Array:
g_aFilesList;

new 
Trie:g_tFilesFastList// same as above, but for files ids (fast lookup)

/*=======================================
 API
=======================================*/

#define MAX_FUNCTION_NAME 30

/*============================
 EXPORTED NATIVES
============================*/

#define MAX_NATIVE_NAME 30

enum exported_native_s
{
 
em_szNativeName[MAX_NATIVE_NAME],
 
em_szNativeFunc[MAX_FUNCTION_NAME],
 
em_iNativeParams
};

enum _:NativesList
{
 
/* SETTINGS API NATIVES */
 
NATIVE_OPEN_FILE 0,
 
NATIVE_LOAD_BOOL,
 
NATIVE_LOAD_INT,
 
NATIVE_LOAD_FLOAT,
 
NATIVE_LOAD_STRING,
 
NATIVE_LOAD_DARRAY,
 
NATIVE_CLOSE_FILE
};

new const 
c_ExportedNatives[NativesList][exported_native_s] =
{
 
/* SETTINGS API NATIVES */
 
"settings_open_file""API_OpenFile"1, },
 { 
"settings_load_bool""API_LoadBool"4, },
 { 
"settings_load_int""API_LoadInt"4, },
 { 
"settings_load_float""API_LoadFloat"4, },
 { 
"settings_load_string""API_LoadString"5, },
 { 
"settings_load_darray""API_LoadDynamicArray"5, },
 { 
"settings_close_file""API_CloseFile"1, }
};

/*===============================================================================
 API
===============================================================================*/

/*====================================================
 EXPORTED NATIVES
====================================================*/

public bool:API_CloseFile(const iPluginId, const iParams)
{
 new 
iExpected c_ExportedNatives[NATIVE_CLOSE_FILE][em_iNativeParams];
 if (
iParams != iExpected)
 {
 
log_amx("API_CloseFile(): invalid params-count (expected: %d | got: %d)"iExpectediParams);
 return 
false;
 }
 
 new 
iFileId get_param(1);
 if (!
IS_IN_RANGE(iFileId0FILES_COUNT() - 1))
 {
 
log_amx("API_CloseFile(): invalid file-id (%d)"iFileId);
 return 
false;
 }
 
 
CloseFile(iFileId);
 return 
true;
}

public 
bool:API_LoadDynamicArray(const iPluginId, const iParams)
{
 new 
iExpected c_ExportedNatives[NATIVE_LOAD_DARRAY][em_iNativeParams];
 if (
iParams != iExpected)
 {
 
log_amx("API_LoadDynamicArray(): invalid params-count (expected: %d | got: %d)"iExpectediParams);
 return 
false;
 }
 
 new 
iId get_param(1);
 if (!
IS_IN_RANGE(iId0FILES_COUNT() - 1))
 {
 
log_amx("API_LoadDynamicArray(): invalid file-id (%d)"iId);
 return 
false;
 }
 
 new 
iType get_param(2);
 if (!
IS_IN_RANGE(iTypeVALUE_TYPE_DARR_BOOLVALUE_TYPE_DARR_STRING))
 {
 
log_amx("API_LoadDynamicArray(): invalid darray-type (%d)"iType);
 return 
false;
 }
 
 new 
szSection[MAX_SECTION_NAME_LEN];
 
get_string(3szSectioncharsmax(szSection));
 if (!
szSection[0] || strlen(szSection) <= 1)
 {
 
log_amx("API_LoadDynamicArray(): invalid section-name (^"%s^")"szSection);
 return 
false;
 }
 
 new 
szKey[MAX_SECTION_NAME_LEN];
 
get_string(4szKeycharsmax(szKey));
 if (!
szKey[0] || strlen(szKey) <= 1)
 {
 
log_amx("API_LoadDynamicArray(): invalid key-name (^"%s^")"szKey);
 return 
false;
 }
 
 new Array:
aValueOut = Array:get_param_byref(5); 
 if (
aValueOut == Invalid_Array)
 {
 
log_amx("API_LoadDynamicArray(): invalid array-handle (%d)"aValueOut);
 return 
false;
 }
 
 if (
LoadFileValue(iIdiTypeszSectionszKeyaValueOut))
 return 
true;
 return 
true;
}

public 
bool:API_LoadString(const iPluginId, const iParams)
{
 new 
iExpected c_ExportedNatives[NATIVE_LOAD_STRING][em_iNativeParams];
 if (
iParams != iExpected)
 {
 
log_amx("API_LoadString(): invalid params-count (expected: %d | got: %d)"iExpectediParams);
 return 
false;
 }
 
 new 
iId get_param(1);
 if (!
IS_IN_RANGE(iId0FILES_COUNT() - 1))
 {
 
log_amx("API_LoadString(): invalid file-id (%d)"iId);
 return 
false;
 }
 
 new 
szSection[MAX_SECTION_NAME_LEN];
 
get_string(2szSectioncharsmax(szSection));
 if (!
szSection[0] || strlen(szSection) <= 1)
 {
 
log_amx("API_LoadString(): invalid section-name (^"%s^")"szSection);
 return 
false;
 }
 
 new 
szKey[MAX_SECTION_NAME_LEN];
 
get_string(3szKeycharsmax(szKey));
 if (!
szKey[0] || strlen(szKey) <= 1)
 {
 
log_amx("API_LoadString(): invalid key-name (^"%s^")"szKey);
 return 
false;
 }
 
 new 
iLenOut get_param(5);
 
 
// single-strings are handle on a different way
 
if (LoadFileValueString(iIdszSectionszKey))
 {
 
set_string(4g_szValueiLenOut);
 return 
true;
 }
 return 
false;
}

public 
bool:API_LoadFloat(const iPluginId, const iParams)
{
 new 
iExpected c_ExportedNatives[NATIVE_LOAD_FLOAT][em_iNativeParams];
 if (
iParams != iExpected)
 {
 
log_amx("API_LoadInt(): invalid params-count (expected: %d | got: %d)"iExpectediParams);
 return 
false;
 }
 
 new 
iId get_param(1);
 if (!
IS_IN_RANGE(iId0FILES_COUNT() - 1))
 {
 
log_amx("API_LoadFloat(): invalid file-id (%d)"iId);
 return 
false;
 }
 
 new 
szSection[MAX_SECTION_NAME_LEN];
 
get_string(2szSectioncharsmax(szSection));
 if (!
szSection[0] || strlen(szSection) <= 1)
 {
 
log_amx("API_LoadFloat(): invalid section-name (^"%s^")"szSection);
 return 
false;
 }
 
 new 
szKey[MAX_SECTION_NAME_LEN];
 
get_string(3szKeycharsmax(szKey));
 if (!
szKey[0] || strlen(szKey) <= 1)
 {
 
log_amx("API_LoadFloat(): invalid key-name (^"%s^")"szKey);
 return 
false;
 }
 
 new 
Float:fValueOut;
 if (
LoadFileValue(iIdVALUE_TYPE_FLOATszSectionszKeyfValueOut))
 {
 
set_float_byref(4fValueOut);
 return 
true;
 }
 return 
false;
}

public 
bool:API_LoadInt(const iPluginId, const iParams)
{
 new 
iExpected c_ExportedNatives[NATIVE_LOAD_INT][em_iNativeParams];
 if (
iParams != iExpected)
 {
 
log_amx("API_LoadInt(): invalid params-count (expected: %d | got: %d)"iExpectediParams);
 return 
false;
 }
 
 new 
iId get_param(1);
 if (!
IS_IN_RANGE(iId0FILES_COUNT() - 1))
 {
 
log_amx("API_LoadInt(): invalid file-id (%d)"iId);
 return 
false;
 }
 
 new 
szSection[MAX_SECTION_NAME_LEN];
 
get_string(2szSectioncharsmax(szSection));
 if (!
szSection[0] || strlen(szSection) <= 1)
 {
 
log_amx("API_LoadInt(): invalid section-name (^"%s^")"szSection);
 return 
false;
 }
 
 new 
szKey[MAX_SECTION_NAME_LEN];
 
get_string(3szKeycharsmax(szKey));
 if (!
szKey[0] || strlen(szKey) <= 1)
 {
 
log_amx("API_LoadInt(): invalid key-name (^"%s^")"szKey);
 return 
false;
 }
 
 new 
iValueOut;
 if (
LoadFileValue(iIdVALUE_TYPE_INTszSectionszKeyiValueOut))
 {
 
set_param_byref(4iValueOut);
 return 
true;
 }
 return 
false;
}

public 
bool:API_LoadBool(const iPluginId, const iParams)
{
 new 
iExpected c_ExportedNatives[NATIVE_LOAD_BOOL][em_iNativeParams];
 if (
iParams != iExpected)
 {
 
log_amx("API_LoadBool(): invalid params-count (expected: %d | got: %d)"iExpectediParams);
 return 
false;
 }
 
 new 
iId get_param(1);
 if (!
IS_IN_RANGE(iId0FILES_COUNT() - 1))
 {
 
log_amx("API_LoadBool(): invalid file-id (%d)"iId);
 return 
false;
 }
 
 new 
szSection[MAX_SECTION_NAME_LEN];
 
get_string(2szSectioncharsmax(szSection));
 if (!
szSection[0] || strlen(szSection) <= 1)
 {
 
log_amx("API_LoadBool(): invalid section-name (^"%s^")"szSection);
 return 
false;
 }
 
 new 
szKey[MAX_SECTION_NAME_LEN];
 
get_string(3szKeycharsmax(szKey));
 if (!
szKey[0] || strlen(szKey) <= 1)
 {
 
log_amx("API_LoadBool(): invalid key-name (^"%s^")"szKey);
 return 
false;
 }
 
 new 
bool:bValueOut;
 if (
LoadFileValue(iIdVALUE_TYPE_BOOLszSectionszKeybValueOut))
 {
 
set_param_byref(4bValueOut);
 return 
true;
 }
 return 
false;
}

public 
API_OpenFile(const iPluginId, const iParams)
{
 new 
iExpected c_ExportedNatives[NATIVE_OPEN_FILE][em_iNativeParams];
 if (
iParams != iExpected)
 {
 
log_amx("API_OpenFile(): invalid params-count (expected: %d | got: %d)"iExpectediParams);
 return -
1;
 }
 
 new 
szFile[MAX_FILE_NAME_LEN];
 
get_string(1szFilecharsmax(szFile));
 
 return 
OpenFile(szFile);
}

/*================================================================================
 MAIN
================================================================================*/

SetFailState(const szMessage[], any:...)
{
 static 
szText[128];
 
 if (
numargs() == 1)
 
copy(szTextcharsmax(szText), szMessage);
 else
 
vformat(szTextcharsmax(szText), szMessage2);
 
set_fail_state(szText);
}

/*============================================
 SETTINGS
============================================*/

/*
==================================================
CloseFile()

==================================================
*/
CloseFile(const iFileId)
{
 
// close all files?
 
if (iFileId == CLOSE_ALL_FILES)
 {
 new 
SectionData[section_s];
 new 
KeyData[key_s];
 
 for (new 
iFileiFile FILES_COUNT(); iFile++)
 {
 
LOAD_FILE_DATA(iFile);
 
 for (new 
iSectioniSection SECTIONS_COUNT(); iSection++)
 {
 
LOAD_SECTION_DATA(iSectionSectionData);
 
 for (new 
iKeyiKey KEYS_COUNT(SectionData); iKey++)
 {
 
LOAD_KEY_DATA(SectionDataiKeyKeyData);
 
CLEAR_KEY_DATA(KeyData);
 }
 
 
CLEAR_SECTION_DATA(SectionData);
 
CLEAR_SECTION_FAST_DATA(SectionData);
 }
 
 
CLEAR_FILE_DATA();
 
CLEAR_FILE_FAST_DATA();
 }
 
 
CLEAR_FILES_DATA();
 
CLEAR_FILES_FAST_DATA();
 return;
 }
 
 
LoadFileData(iFileId);
 
 
CLOSE_FILE();
 
UPDATE_FILE_DATA(iFileId);
 
 
g_iCurrentFile = -1;
}

/*
==================================================
IsFileClosed()

==================================================
*/
bool:IsFileClosed(const iFileId)
{
 
LoadFileData(iFileId);
 
 if (
IS_FILE_CLOSED())
 return 
true;
 return 
false;
}

/*
==================================================
ReOpenFile()

==================================================
*/
ReOpenFile(const iFileId)
{
 
LoadFileData(iFileId);
 
 
REOPEN_FILE();
 
UPDATE_FILE_DATA(iFileId);
}

/*
==================================================
CanReOpenFile()

==================================================
*/
bool:CanReOpenFile(const iFileId)
{
 if (
iFileId == -|| !IsFileClosed(iFileId))
 return 
false;
 return 
true;
}

/*
==================================================
ParseValueToArray()

==================================================
*/
ParseValueToArray(const iDynamicArrayType, &Array:aValueOut)
{
 static 
szValue[20];
 
 while (
g_szValue[0] != 0)
 {
 
strtok(g_szValueszValuecharsmax(szValue), g_szValuecharsmax(g_szValue), ',');
 
trim(g_szValue);
 
trim(szValue);
 
 switch(
iDynamicArrayType)
 {
 case 
VALUE_TYPE_DARR_BOOLArrayPushCell(aValueOutbool:equal(szValue"true"));
 case 
VALUE_TYPE_DARR_INTArrayPushCell(aValueOutstr_to_num(szValue));
 case 
VALUE_TYPE_DARR_FLOATArrayPushCell(aValueOutstr_to_float(szValue));
 case 
VALUE_TYPE_DARR_STRINGArrayPushString(aValueOutszValue);
 }
 }
}

/*
==================================================
GetKeyId()

==================================================
*/
GetKeyId(const szKeyName[], const iAssociatedSection)
{
 new 
iId = -1;
 
 new 
SectionData[section_s];
 {
 
LOAD_SECTION_DATA(iAssociatedSectionSectionData);
 }
 
 
GET_KEY_ID(SectionDataszKeyNameiId);
 return 
iId;
}

/*
==================================================
GetSectionId()

==================================================
*/
GetSectionId(const szSectionName[])
{
 new 
iId = -1;
 
GET_SECTION_ID(szSectionNameiId);
 return 
iId;
}

/*
==================================================
LoadFileData()

==================================================
*/
LoadFileData(const iFileId)
{
 if (
g_iCurrentFile != iFileId)
 {
 
LOAD_FILE_DATA(iFileId);
 
 
g_iCurrentFile iFileId;
 }
}

/*
==================================================
LoadFileValueString()

==================================================
*/
bool:LoadFileValueString(const iFileId, const szSectionName[], const szKeyName[])
{
 
// file closed?
 
if (IsFileClosed(iFileId))
 {
 
log_amx("LoadFileValueString(): file already closed (you need to open it again)");
 return 
false;
 }
 
 
LoadFileData(iFileId);
 
 new 
iSectionId GetSectionId(szSectionName); // get section's id
 
if (iSectionId == -1// section doesn't exists
 
{
 
log_amx("LoadFileValueString(): section ^"%s^" doesn't exists"szSectionName);
 return 
false;
 }
 
 new 
iKeyId GetKeyId(szKeyNameiSectionId); // get key's id
 
if (iKeyId == -1// key doesn't exists
 
{
 
log_amx("LoadFileValueString(): key ^"%s^" doesn't belong to ^"%s^" section"szKeyNameszSectionName);
 return 
false;
 }
 
 new 
SectionData[section_s];
 
LOAD_SECTION_DATA(iSectionIdSectionData);
 
 new 
KeyData[key_s];
 
LOAD_KEY_DATA(SectionDataiKeyIdKeyData);
 
 
LOAD_KEY_VALUE(KeyDataszKeyName);
 return 
true;
}

/*
==================================================
LoadFileValue()

==================================================
*/
bool:LoadFileValue(const iFileId, const iValueType, const szSectionName[], const szKeyName[], &any:ValueOut)
{
 
// file closed?
 
if (IsFileClosed(iFileId))
 {
 
log_amx("LoadFileValue(): file already closed (you need to open it again)");
 return 
false;
 }
 
 
// invalid value-type? (see ValueTypes enum)
 
if (!IS_IN_RANGE(iValueTypeVALUE_TYPE_BOOLVALUE_TYPE_DARR_STRING))
 {
 
SetFailState("LoadFileValue(): invalid value-type (%d)"iValueType);
 return 
false;
 }
 
 
LoadFileData(iFileId);
 
 new 
iSectionId GetSectionId(szSectionName); // get section's id
 
if (iSectionId == -1// section doesn't exists
 
{
 
log_amx("LoadFileValue(): section ^"%s^" doesn't exists"szSectionName);
 return 
false;
 }
 
 new 
iKeyId GetKeyId(szKeyNameiSectionId); // get key's id
 
if (iKeyId == -1// key doesn't exists on section
 
{
 
log_amx("LoadFileValue(): key ^"%s^" doesn't belong to ^"%s^" section"szKeyNameszSectionName);
 return 
false;
 }
 
 new 
SectionData[section_s];
 
LOAD_SECTION_DATA(iSectionIdSectionData);
 
 new 
KeyData[key_s];
 
LOAD_KEY_DATA(SectionDataiKeyIdKeyData);
 
 
LOAD_KEY_VALUE(KeyDataszKeyName);
 
 switch (
iValueType)
 {
 case 
VALUE_TYPE_BOOLValueOut bool:equal(g_szValue"true");
 case 
VALUE_TYPE_INTValueOut str_to_num(g_szValue);
 case 
VALUE_TYPE_FLOATValueOut str_to_float(g_szValue);
 case 
VALUE_TYPE_DARR_BOOL..VALUE_TYPE_DARR_STRINGParseValueToArray(iValueTypeValueOut);
 }
 return 
true;
}

/*
==================================================
IsKeyLine()

==================================================
*/
bool:IsKeyLine()
{
 return 
bool:(contain(g_szLine"=") != -1);
}

/*
==================================================
IsSectionLine()

==================================================
*/
bool:IsSectionLine()
{
 new 
iPos contain(g_szLine"]");
 return 
bool:(g_szLine[0] == '[' && iPos != -1);
}

/*
==================================================
IsCommentLine()

==================================================
*/
bool:IsCommentLine()
{
 return 
bool:(g_szLine[0] == ';' || equal(g_szLine"//"2));
}

/*
==================================================
ReadFileLine()

==================================================
*/
bool:ReadFileLine(const iFile)
{
 if (!
iFile)
 {
 
SetFailState("ReadFileLine(): invalid file (%d)"iFile);
 return 
false;
 }
 
 if (
feof(iFile))
 return 
false;
 
 
fgets(iFileg_szLinecharsmax(g_szLine));
 
replace(g_szLinecharsmax(g_szLine), "^n""");
 return 
true;
}

/*
==================================================
LoadFile()

==================================================
*/
bool:LoadFile(const iFile)
{
 
arrayset(g_CurrentFileData0file_s);
 
 
// allocate file's sections lists (normal & fast-lookup)
 
ALLOCATE_SECTIONS_LIST();
 
ALLOCATE_SECTION_FAST_LIST();
 
 new 
SectionData[section_s];
 new 
KeyData[key_s];
 
 static 
szKey[MAX_KEY_NAME_LEN];
 
 new 
bool:bSaveSection// are inside a section? then need to be saved
 
 // only used for search the "]" character
 // this is the section's name-end character
 
new iPos;
 
 
// read next line
 
while (KEEP_LOOPING)
 {
 
// we have reach file's end
 
if (!ReadFileLine(iFile))
 {
 
// check for some section to be saved
 
if (bSaveSection)
 {
 
// save section
 
ADD_SECTION_TO_LIST(SectionData);
 
ADD_SECTION_TO_FAST_LIST(SectionData[em_szSectionName]);
 
 
bSaveSection false;
 }
 break;
 }
 
 
// comment line?
 
if (IsCommentLine())
 continue;
 
 
// section line?
 
if (IsSectionLine())
 {
 
// check for some section to be saved
 
if (bSaveSection)
 {
 
// save section
 
ADD_SECTION_TO_LIST(SectionData);
 
ADD_SECTION_TO_FAST_LIST(SectionData[em_szSectionName]);
 
 
bSaveSection false;
 }
 
 
// clear previous section data
 
arrayset(SectionData0section_s);
 
 
iPos contain(g_szLine"]"); // find "]" character
 
 // check if section name-lenght is greather than size assigned to it
 
if (iPos MAX_SECTION_NAME_LEN)
 {
 
// copy only the assigned size
 
copy(SectionData[em_szSectionName], MAX_SECTION_NAME_LEN 1g_szLine[1]);
 }
 else
 {
 
// copy full-name, but ignore the "]" character
 
copy(SectionData[em_szSectionName], iPos 1g_szLine[1]);
 }
 
 
// check if a section with same name has been registered previously
 
if (SECTION_EXISTS(SectionData[em_szSectionName]))
 {
 
SetFailState("LoadFile(): there can't be two sections with the same name (section named ^"%s^" already exists)"SectionData[em_szSectionName]);
 return 
false;
 }
 
 
// allocate section's keys lists (normal & fast-lookup)
 
ALLOCATE_KEYS_LIST(SectionData);
 
ALLOCATE_KEYS_FAST_LIST(SectionData);
 
 
bSaveSection true;
 }
 else if (
IsKeyLine())
 {
 
// clear previous
 
arrayset(KeyData0key_s);
 
 
strtok(g_szLineszKeycharsmax(szKey), g_szValuecharsmax(g_szValue), '=');
 
trim(szKey);
 
trim(g_szValue);
 
 if (
KEY_EXISTS(SectionDataszKey))
 {
 
SetFailState("LoadFile(): there can't be two keys equals on a section");
 return 
false;
 }
 
 
copy(KeyData[em_szKeyName], MAX_KEY_NAME_LEN 1szKey);
 
 
// allocate key's values
 
ALLOCATE_KEY_VALUES(KeyData);
 
 
// save key-value
 
ADD_KEY_VALUE(KeyDataszKey);
 
 
// save key
 
ADD_KEY_TO_LIST(SectionDataKeyData);
 
ADD_KEY_TO_FAST_LIST(SectionDataszKeySectionData[em_iSectionKeysCount]++);
 }
 }
 
fclose(iFile);
 return 
true;
}

/*
==================================================
OpenFile()

==================================================
*/
OpenFile(const szFileName[])
{
 
// add space for base-address: "addons/amxmodx/configs"
 
new szPath[MAX_FILE_NAME_LEN 25];
 
get_configsdir(szPathcharsmax(szPath));
 
format(szPathcharsmax(szPath), "%s/%s"szPathszFileName);
 
 if (!
file_exists(szPath))
 {
 
log_amx("OpenFile(): file ^"%s^" doesn't exists"szPath);
 return -
1;
 }
 
 
// check if file was previously loaded
 
if (IS_FILE_LOADED(szFileName))
 {
 new 
iFileId = -1;
 
GET_FILE_ID(szFileNameiFileId);
 
 
// can re-open file?
 
if (CanReOpenFile(iFileId))
 {
 
// do it, and return it's id
 
ReOpenFile(iFileId);
 return 
iFileId;
 }
 
 
// file is attempt to be opened twice
 
log_amx("OpenFile:() file ^"%s^" already loaded"szPath);
 return -
1;
 }
 
 new 
iFile fopen(szPath"rt");
 if (!
iFile)
 {
 
log_amx("OpenFile(): can't read file ^"%s^""szPath);
 return -
1;
 }
 
 
// go to load file's data
 
if (LoadFile(iFile))
 {
 
// file loaded successfully, so add it to the both: normal & fast-lookup lists
 
ADD_FILE_TO_LIST();
 
ADD_FILE_TO_FAST_LIST(szFileName);
 return 
FILES_COUNT() - 1;
 }
 return -
1// should never reach here
}

/*=========================================================================================
 AMXX FORWARDS
=========================================================================================*/

/*
==================================================
plugin_end()

==================================================
*/
public plugin_end()
{
 
CloseFile(CLOSE_ALL_FILES);
}

/*
==================================================
plugin_precache()

==================================================
*/
public plugin_precache()
{
 
ALLOCATE_FILES_LIST();
 
ALLOCATE_FILES_FAST_LIT();
}

/*
==================================================
plugin_natives()

==================================================
*/
public plugin_natives()
{
 new 
szNative[MAX_NATIVE_NAME];
 new 
szFunc[MAX_FUNCTION_NAME];
 
 for (new 
isizeof c_ExportedNativesi++)
 {
 
copy(szNativecharsmax(szNative), c_ExportedNatives[i][em_szNativeName]);
 
copy(szFunccharsmax(szFunc), c_ExportedNatives[i][em_szNativeFunc]);
 
 if (
szNative[0] && szFunc[0])
 
register_native(szNativeszFunc);
 }


• CREDITOS

Principalmente los creditos van para MeRcyLeZZ debido a lo anteriormente mencionado, sin contar porciones de codigo de su Zombie Plague Mod

No duden en postear cualquier inconveniente que presenten.
Adios.



RE: [API] Settings System - Hinami - 27/07/2020

buen aporte, aunque quizá deberías dejar unos ejemplos para la gente que no sepa demasiado y desee usar el api.


RE: [API] Settings System - SVC - 28/07/2020

(27/07/2020, 11:35 PM)Hypnotize escribió: buen aporte, aunque quizá deberías dejar unos ejemplos para la gente que no sepa demasiado y desee usar el api.


TEST:

- test.ini:

Código PHP:
los comentarios pueden ser añadidos tanto utilizando el caracter ";"
// como tambien dos barras invertidas '//'

[TEST SECTION 1]
INT KEY 30
BOOL KEY 
true
FLOAT KEY 
35.0

[TEST SECTION 2]
STRING KEY Hi World

[TEST SECTION 3]
INT-ARRAY = 12345,
FLOAT-ARRAY = 10.09.08.07.0
BOOL
-ARRAY = truefalsefalsetruetruetruefalse
STRING
-ARRAY = string1string2string3string4string5 

- test_config.sma:

Código PHP:
#include    AMXMODX
#include    AMXMISC
#include    SETTINGS_API

new const config_file[] = "test.ini";

public 
plugin_precache()
{
    new 
iFile settings_open_file(config_file// file's path = addons/amxmodx/configs/test.ini
    
    
if (iFile == -1)
    {
        
set_fail_state("there was an error open file ^"%s^""config_file);
        return;
    }
    
    new 
iIntValue;
    if (!
settings_load_int(iFile"TEST SECTION 1""INT KEY"iIntValue))
        
log_amx("can't load value for ^"iIntValue^"");
    else
        
log_amx("iIntValue = %d"iIntValue);
    
    new 
bool:bBoolValue;
    if (!
settings_load_bool(iFile"TEST SECTION 1""BOOL KEY"bBoolValue))
        
log_amx("can't load value for ^"bBoolValue^"");
    else
        
log_amx("bBoolValue = %s"bBoolValue "true" "false");
    
    new 
Float:fFloatValue
    
if (!settings_load_float(iFile"TEST SECTION 1""FLOAT KEY"fFloatValue))
        
log_amx("can't load value for ^"fFloatValue^"");
    else
        
log_amx("fFloatValue = %.4f"fFloatValue);
    
    new 
szStringValue[10];
    if (!
settings_load_string(iFile"TEST SECTION 2""STRING KEY"szStringValuecharsmax(szStringValue)))
        
log_amx("can't load value for ^"szStringValue^"");
    else
        
log_amx("szStringValue = %s"szStringValue);
    
    new Array:
aIntsArray ArrayCreate();
    if (!
settings_load_darray(iFileVALUE_TYPE_DARR_INT"TEST SECTION 3""INT-ARRAY"aIntsArray))
        
log_amx("can't lod value for ^"aIntsArray^"");
    else
    {
        new 
iSize ArraySize(aIntsArray);
        
log_amx("elements = %d"iSize);
        
        for (new 
iiSizei++)
            
log_amx("value #%d = %d"i+1ArrayGetCell(aIntsArrayi));
    }
    
    new Array:
aFloatsArray ArrayCreate();
    if (!
settings_load_darray(iFileVALUE_TYPE_DARR_FLOAT"TEST SECTION 3""FLOAT-ARRAY"aFloatsArray))
        
log_amx("can't lod value for ^"aFloatsArray^"");
    else
    {
        new 
iSize ArraySize(aFloatsArray);
        
log_amx("elements = %d"iSize);
        
        for (new 
iiSizei++)
            
log_amx("value #%.4f = %d"i+1ArrayGetCell(aFloatsArrayi));
    }
    
    new Array:
aBoolsArray ArrayCreate();
    if (!
settings_load_darray(iFileVALUE_TYPE_DARR_BOOL"TEST SECTION 3""BOOL-ARRAY"aBoolsArray))
        
log_amx("can't lod value for ^"aBoolsArray^"");
    else
    {
        new 
iSize ArraySize(aBoolsArray);
        
log_amx("elements = %d"iSize);
        
        for (new 
iiSizei++)
            
log_amx("value #%d = %s"i+1ArrayGetCell(aBoolsArrayi) ? "true" "false");
    }
    
    new Array:
aStringsArray ArrayCreate(10);
    if (!
settings_load_darray(iFileVALUE_TYPE_DARR_STRING"TEST SECTION 3""STRING-ARRAY"aStringsArray))
        
log_amx("can't lod value for ^"aStringsArray^"");
    else
    {
        new 
iSize ArraySize(aStringsArray);
        
log_amx("elements = %d"iSize);
        
        new 
szBuff[10];
        for (new 
iiSizei++)
        {
            
ArrayGetString(aStringsArrayiszBuffcharsmax(szBuff));
            
log_amx("value #%d = %s"i+1,  szBuff);
        }
    }
    
    
// bad key case (key doesn't exists on section)
    
new iBadKeyValue;
    if (!
settings_load_int(iFile"TEST SECTION 1""INT KEY BAD"iBadKeyValue))
        
log_amx("can't load value for ^"iBadKeyValue^"");
    else
        
log_amx("iBadKeyValue; = %d"iBadKeyValue);
    
    
// bad section case (section doesn't exists on file)
    
new iBadSectionValue;
    if (!
settings_load_int(iFile"TEST SECTION 4""INT KEY"iBadSectionValue))
        
log_amx("can't load value for ^"iBadSectionValue^"");
    else
        
log_amx("iBadSectionValue; = %d"iBadSectionValue);
    
    
settings_close_file(iFile);


GAMEPLAY:

- gameplay.ini:

Código PHP:
[ROUND]
INFINITE true

[MONEY]
ON GAME-START 5000
ON KILL 
500
ON PLANT
-BOMB 750

[MESSAGES]
CONNECT Welcome to my server :

- gameplay_config.sma:

Código PHP:
#include    AMXMODX
#include    AMXMISC
#include    SETTINGS_API

new const config_file[] = "gameplay.ini";

new 
bool:g_bInfiniteRound;

new 
g_iMoneyOnGameStart;
new 
g_iMoneyOnKill;
new 
g_iMoneyOnPlantBomb;

new 
g_szWelcomeMsg[30];

public 
plugin_precache()
{
    new 
iFile settings_open_file(config_file)
    
    if (
iFile == -1)
    {
        
set_fail_state("there was an error open file ^"%s^""config_file);
        return;
    }
    
    if (!
settings_load_bool(iFile"ROUND""INFINITE"g_bInfiniteRound))
        
log_amx("can't load value for ^"g_bInfiniteRound^"");
    else
        
log_amx("infinitie round is %s"g_bInfiniteRound "enabled" "diseabled");
    
    if (!
settings_load_int(iFile"MONEY""ON GAME-START"g_iMoneyOnGameStart))
        
log_amx("can't load value for ^"g_iMoneyOnGameStart^"");
    else
        
log_amx("money at game-start: %d"g_iMoneyOnGameStart);
    
    if (!
settings_load_int(iFile"MONEY""ON KILL"g_iMoneyOnKill))
        
log_amx("can't load value for ^"g_iMoneyOnKill^"");
    else
        
log_amx("money per each kill: %d"g_iMoneyOnKill);
    
    if (!
settings_load_int(iFile"MONEY""ON PLANT-BOMB"g_iMoneyOnPlantBomb))
        
log_amx("can't load value for ^"g_iMoneyOnPlantBomb^"");
    else
        
log_amx("money when plant bomb: %d"g_iMoneyOnPlantBomb);
    
    if (!
settings_load_string(iFile"MESSAGES""CONNECT"g_szWelcomeMsgcharsmax(g_szWelcomeMsg)))
        
log_amx("can't load value for ^"g_szWelcomeMsg^"");
    else
        
log_amx("message when somebody connects: %s"g_szWelcomeMsg);
    
    
settings_close_file(iFile);


Y el qué no podia faltar (solo mostrare algunos ejemplos):

ZOMBIEPLAGUE:


- zombieplague.ini:

Código PHP:
; -----------------------------------------
Zombie Plague 4.3 Fix5 Customization File
; -----------------------------------------
Any changes you make here will be
automatically loaded at map start

NoteNo error parsing is done for this.
Make sure you don't mistype anything.

[Access Flags]
ENABLE/DISABLE MOD = l
ADMIN MENU = d
START MODE INFECTION = d
START MODE NEMESIS = d
START MODE SURVIVOR = d
START MODE SWARM = d
START MODE MULTI = d
START MODE PLAGUE = d
MAKE ZOMBIE = d
MAKE HUMAN = d
MAKE NEMESIS = d
MAKE SURVIVOR = d
RESPAWN PLAYERS = d
ADMIN MODELS = d

[Player Models] (randomly chosen if more than one)
HUMAN = arctic , guerilla , leet , terror , gign , gsg9 , sas , urban
NEMESIS = zombie_source
SURVIVOR = leet , sas
ADMIN ZOMBIE = zombie_source
ADMIN HUMAN = vip

; If you don'
t want people using altered player modelsenable the following.
Bounds Check (model's geometry must fit in the same bbox)
; 2 = CRC Check (file on client must exactly match server'
s file)
FORCE CONSISTENCY 0

By default, zombie models are class specificYou can edit them separately in your zp_zombieclasses.ini
; If, howeveryou want all zombies to use the same models regardless of class, you can enable this
setting and add your global zombie models to the "ZOMBIE" line.
SAME MODELS FOR ALL 0
ZOMBIE 
zombie_source

[Weapon Models]
V_KNIFE HUMAN models/v_knife.mdl
V_KNIFE NEMESIS 
models/zombie_plague/v_knife_zombie.mdl
V_WEAPON SURVIVOR 
models/v_m249.mdl
GRENADE INFECT 
models/zombie_plague/v_grenade_infect.mdl
GRENADE FIRE 
models/zombie_plague/v_grenade_fire.mdl
GRENADE FROST 
models/zombie_plague/v_grenade_frost.mdl
GRENADE FLARE 
models/zombie_plague/v_grenade_flare.mdl
V_KNIFE ADMIN HUMAN 
models/v_knife.mdl
V_KNIFE ADMIN ZOMBIE 
models/zombie_plague/v_knife_zombie.mdl

[Grenade Sprites]
TRAIL sprites/laserbeam.spr
RING 
sprites/shockwave.spr
FIRE 
sprites/flame.spr
SMOKE 
sprites/black_smoke3.spr
GLASS 
models/glassgibs.mdl

[Sounds] (randomly chosen if more than one)
WIN ZOMBIES ambience/the_horror1.wav ambience/the_horror3.wav ambience/the_horror4.wav
WIN HUMANS 
zombie_plague/win_humans1.wav zombie_plague/win_humans2.wav
WIN NO ONE 
ambience/3dmstart.wav
ZOMBIE INFECT 
zombie_plague/zombie_infec1.wav zombie_plague/zombie_infec2.wav zombie_plague/zombie_infec3.wav scientist/c1a0_sci_catscream.wav scientist/scream01.wav
ZOMBIE PAIN 
zombie_plague/zombie_pain1.wav zombie_plague/zombie_pain2.wav zombie_plague/zombie_pain3.wav zombie_plague/zombie_pain4.wav zombie_plague/zombie_pain5.wav
NEMESIS PAIN 
zombie_plague/nemesis_pain1.wav zombie_plague/nemesis_pain2.wav zombie_plague/nemesis_pain3.wav
ZOMBIE 
DIE = zombie_plague/zombie_die1.wav zombie_plague/zombie_die2.wav zombie_plague/zombie_die3.wav zombie_plague/zombie_die4.wav zombie_plague/zombie_die5.wav
ZOMBIE FALL 
zombie_plague/zombie_fall1.wav
ZOMBIE MISS SLASH 
weapons/knife_slash1.wav weapons/knife_slash2.wav
ZOMBIE MISS WALL 
weapons/knife_hitwall1.wav
ZOMBIE HIT NORMAL 
weapons/knife_hit1.wav weapons/knife_hit2.wav weapons/knife_hit3.wav weapons/knife_hit4.wav
ZOMBIE HIT STAB 
weapons/knife_stab.wav
ZOMBIE IDLE 
nihilanth/nil_now_die.wav nihilanth/nil_slaves.wav nihilanth/nil_alone.wav zombie_plague/zombie_brains1.wav zombie_plague/zombie_brains2.wav
ZOMBIE IDLE LAST 
nihilanth/nil_thelast.wav
ZOMBIE MADNESS 
zombie_plague/zombie_madness1.wav
ROUND NEMESIS 
zombie_plague/nemesis1.wav zombie_plague/nemesis2.wav
ROUND SURVIVOR 
zombie_plague/survivor1.wav zombie_plague/survivor2.wav
ROUND SWARM 
ambience/the_horror2.wav
ROUND MULTI 
ambience/the_horror2.wav
ROUND PLAGUE 
zombie_plague/nemesis1.wav zombie_plague/survivor1.wav
GRENADE INFECT EXPLODE 
zombie_plague/grenade_infect.wav
GRENADE INFECT PLAYER 
scientist/scream20.wav scientist/scream22.wav scientist/scream05.wav
GRENADE FIRE EXPLODE 
zombie_plague/grenade_explode.wav
GRENADE FIRE PLAYER 
zombie_plague/zombie_burn3.wav zombie_plague/zombie_burn4.wav zombie_plague/zombie_burn5.wav zombie_plague/zombie_burn6.wav zombie_plague/zombie_burn7.wav
GRENADE FROST EXPLODE 
warcraft3/frostnova.wav
GRENADE FROST PLAYER 
warcraft3/impalehit.wav
GRENADE FROST 
BREAK = warcraft3/impalelaunch1.wav
GRENADE FLARE 
items/nvg_on.wav
ANTIDOTE 
items/smallmedkit1.wav
THUNDER 
zombie_plague/thunder1.wav zombie_plague/thunder2.wav

[Ambience Sounds] (randomly chosen if more than one) (only .wav and .mp3 formats supported) (duration is in seconds)
INFECTION ENABLE 0
INFECTION SOUNDS 
zombie_plague/ambience.wav
INFECTION DURATIONS 
17
NEMESIS ENABLE 
0
NEMESIS SOUNDS 
zombie_plague/ambience.wav
NEMESIS DURATIONS 
17
SURVIVOR ENABLE 
0
SURVIVOR SOUNDS 
zombie_plague/ambience.wav
SURVIVOR DURATIONS 
17
SWARM ENABLE 
0
SWARM SOUNDS 
zombie_plague/ambience.wav
SWARM DURATIONS 
17
PLAGUE ENABLE 
0
PLAGUE SOUNDS 
zombie_plague/ambience.wav
PLAGUE DURATIONS 
17

[Buy Menu Weapons]
PRIMARY weapon_galil weapon_famas weapon_m4a1 weapon_ak47 weapon_sg552 weapon_aug weapon_scout weapon_m3 weapon_xm1014 weapon_tmp weapon_mac10 weapon_ump45 weapon_mp5navy weapon_p90
SECONDARY 
weapon_glock18 weapon_usp weapon_p228 weapon_deagle weapon_fiveseven weapon_elite
ADDITIONAL ITEMS 
weapon_hegrenade weapon_flashbang weapon_smokegrenade

[Extra ItemsWeapons and their costs]
NAMES Napalm Nade Frost Nade Flare AWP Magnum Sniper M249 Para Machinegun SG550 Auto-Sniper G3SG1 Auto-Sniper
ITEMS 
weapon_hegrenade weapon_flashbang weapon_smokegrenade weapon_awp weapon_m249 weapon_sg550 weapon_g3sg1
COSTS 
10 12 12

[Hard Coded Items Costs]
NIGHT VISION 15
ANTIDOTE 
15
ZOMBIE MADNESS 
17
INFECTION BOMB 
20

[Weather Effects]
RAIN 0
SNOW 
0
FOG 
0
FOG DENSITY 
0.0018
FOG COLOR 
128 128 128

[Custom Skies] (randomly chosen if more than one)
ENABLE 1
SKY NAMES 
space

[Lightning Lights Cycle]
LIGHTS ijklmnonmlkjihgfedcb klmlkjihgfedcbaabcdedcb bcdefedcijklmlkjihgfedcb

[Zombie Decals] (for bloodstains/footsteps)
DECALS 99 107 108 184 185 186 187 188 189

[Knockback Power for Weapons] (use -1.0 to disable knockback power for the weapon)
P228 2.4
SCOUT 
6.5
XM1014 
8.0
MAC10 
2.3
AUG 
5.0
ELITE 
2.4
FIVESEVEN 
2.0
UMP45 
2.4
SG550 
5.3
GALIL 
5.5
FAMAS 
5.5
USP 
2.2
GLOCK18 
2.0
AWP 
10.0
MP5NAVY 
2.5
M249 
5.2
M3 
8.0
M4A1 
5.0
TMP 
2.4
G3SG1 
6.5
DEAGLE 
5.3
SG552 
5.0
AK47 
6.0
P90 
2.0

[Objective Entities] (and anything that would affect gameplay that needs to be removed)
CLASSNAMES func_bomb_target info_bomb_target info_vip_start func_vip_safetyzone func_escapezone hostage_entity monster_scientist func_hostage_rescue info_hostage_rescue env_fog env_rain env_snow item_longjump func_vehicle func_buyzone

[SVC_BAD Prevention] (if you experience *manySVC_BAD kicks, try one of the following)
AIncrease the delay between model changes here (in 0.1 increments until the kicks are gone)
MODELCHANGE DELAY 0.2
B. If you still get recurring kicks, try enabling this setting: (experimental!)
HANDLE MODELS ON SEPARATE ENT 0

; If you want your models to have accurate hitboxes, try enabling this.
Notemake sure your models don't have messed up hitboxes, otherwise
; this setting might cause your server insane cpu usage and lag!
SET MODELINDEX OFFSET = 0 

- zp_config.sma:

Código PHP:
#include    AMXMODX
#include    AMXMISC
#include    SETTINGS_API

new const config_file[] = "zombieplague.ini";

new 
g_iEnableRain;
new 
g_iEnableSnow;
new 
g_iEnableFog;

new 
g_iEnableCustomSkies;

new 
g_szFogDensity[10];
new 
g_szFogColor[13];

new Array:
g_aSkiesNamesList;
new Array:
g_aZombieDecalsList;
new Array:
g_aObjectiveEntsList;

public 
plugin_precache()
{
    
g_aZombieDecalsList ArrayCreate();
    
g_aSkiesNamesList ArrayCreate(10);
    
g_aObjectiveEntsList ArrayCreate(32);
    
    new 
iFile settings_open_file(config_file)
    
    if (
iFile == -1)
    {
        
set_fail_state("there was an error open file ^"%s^""config_file);
        return;
    }
    
    if (
settings_load_int(iFile"Weather Effects""RAIN"g_iEnableRain))
        
log_amx("ZP: rain enabled");
    
    if (
settings_load_int(iFile"Weather Effects""SNOW"g_iEnableSnow))
        
log_amx("ZP: snow enabled");
    
    if (
settings_load_int(iFile"Weather Effects""FOG"g_iEnableFog))
    {
        
log_amx("ZP: fog enabled");
        
        
settings_load_string(iFile"Weather Effects""FOG DENSITY"g_szFogDensitycharsmax(g_szFogDensity));
        
settings_load_string(iFile"Weather Effects""FOG COLOR"g_szFogColorcharsmax(g_szFogColor));
    }
    
    if (
settings_load_int(iFile"Custom Skies""ENABLE"g_iEnableCustomSkies))
    {
        
log_amx("ZP: custom skies enabled");
        
        
settings_load_darray(iFileVALUE_TYPE_DARR_STRING"Custom Skies""NAMES"g_aSkiesNamesList);
    }
    
    
settings_load_darray(iFileVALUE_TYPE_DARR_INT"Zombie Decals""DECALS"g_aZombieDecalsList);
    
    
settings_load_darray(iFileVALUE_TYPE_DARR_STRING"Objective Entities""CLASSNAMES"g_aObjectiveEntsList);
    
    
settings_close_file(iFile);


SETTINGS_API.inc:

Código PHP:
/*===============================================================================================
                                        SETTINGS API SYSTEM
===============================================================================================*/

#if defined        SETTINGS_API_INC
    #endinput
#endif
#define        SETTINGS_API_INC

// value-types for iDynamicArrayType (settings_load_darray)
enum _:ValueTypes
{
    
VALUE_TYPE_DARR_BOOL 3// array of bools
    
VALUE_TYPE_DARR_INT// array of ints
    
VALUE_TYPE_DARR_FLOAT// array of floats
    
VALUE_TYPE_DARR_STRING // array of strings
};

/*
==================================================
native: settings_open_file()

usage: opens a file

params:
    - szFileName[]: name of file that will be open
    
return: int
    - -1: file can't be open (the reason will be shown)
    - 0+: file's id (it is not the same that fopen() returns)
==================================================
*/
native settings_open_file(const szFileName[]);

/*
==================================================
native: settings_load_bool()

usage: loads a value (bool) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - &bValueOut: variable to store result (bool-type)
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_bool(const iFileId, const szSection[], const szKey[], &bool:bValueOut);

/*
==================================================
native: settings_load_int()

usage: loads a value (int) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - &iValueOut: variable to store result (int-type)
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_int(const iFileId, const szSection[], const szKey[], &iValueOut);

/*
==================================================
native: settings_load_float()

usage: loads a value (float) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - &fValueOut: variable to store result (float-type)
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_float(const iFileId, const szSection[], const szKey[], &Float:fValueOut);

/*
==================================================
native: settings_load_string()

usage: loads a value (string) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - szValueOut: buffer to store result
    - iValueOut: max buffer's length
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_string(const iFileId, const szSection[], const szKey[], szValueOut[], const iValueOutLen);

/*
==================================================
native: settings_load_darray()

usage: loads a value (dyn-array) from a file

params:
    - iFileId: the file-id
    - szSectionName[]: the section where value is located
    - szKey[]: the key that holds the value
    - &aValueOut: dyn-array to store result (dynamic array)
    
return: bool
    - true: value has been loaded successfully
    - false: value can't be loaded (the reason will be shown)
==================================================
*/
native bool:settings_load_darray(const iFileId, const iDynamicArrayType, const szKey[], const szSection[], &Array:aValueOut);

/*
==================================================
native: settings_close()

usage: closes a file

params:
    - iFileId: the file-id
    
return: bool
    - true: file has been closed successfully
    - false: file can't be closed (the reason will be shown)
==================================================
*/
native bool:settings_close_file(const iFileId);