Page 1 of 2

[MySQl] CSGO Agents [VERSION: 2.3]

Posted: 23 Jul 2021, 19:30
by lexz
Descriere: Un meniu de unde iti poti alege modele pe playeri (pentru fiecare echipa) cu salvare MySQl, preview MOTD si un document .cfg in fisierul config de unde se face configurarea. Pluginul nu este open source si este inca in versiunea beta! Daca feedbackul este bun ii voi face update-uri si optimizari, iar cand va fi gata ii voi posta si sursa. De asemenea este si licentiat pe mysql.

ULTIMA VERSIUNE ESTE IN ULTIMUL POST, POTI FOLOSI ACEST LINK CA REFERINTA, DAR FA UPDATE-UL DIN POSTUL FACUT MAI JOS.
Descarcare: Link! [VERSION 2.1]

ULTIMA VERSIUNE IN ULTIMUL POST

Nume: CSGO Agents
Versiune: 2.3
Servere care folosesc pluginul: Click
Imagini:
https://imgur.com/nieaxaC
https://imgur.com/lSiwRUq
https://imgur.com/DAkBiuo
https://imgur.com/aguvunn

Code: Select all

Changelog:

Version 1.0:
	- Lansarea initiala.

Version 2.0:
	- Imbunatatire cod si schimbat pe alocuri.
	- Scos numarul maxim de modele.
	- Adaugat un semn ( [#] ) in dreptul modelului selectat.
	- Adaugata comanda in chat: "/agents".
	- Acum poti selecta modele chiar daca nu esti la echipa de care apartine modelul.
	- Acum pluginul se inregistreaza corect in amx_plugins.
	- Daca nu sunt modele in fisierul config, pluginul afiseaza un mesaj in meniuri.
	- Rezolvat bug care pica serverul atunci cand nu erau modele in config.
	- Rezolvat bug scriere fisier config cand nu exista.
	- Rezolvat bug selectare model VIP.
	- Adaugate 3 functii noi in config:
		-> PREVIEW_MENU: 1/0 (default: 1) (ACTIVARE/DEZACTIVARE PREVIEW MENU)
		-> MODELS_COUNTER: 1/0 (default 1) (ACTIVARE/DEZACTIVARE MODEL COUNTER DIN MENIUL PRINCIPAL)
		-> VIP_FLAG: flag (default: t) (FLAGUL VIP PENTRU MODELELE VIP)
	
Version 2.1
	- Adaugat suport pentru modelele care au fisier "T.mdl".
	
Version 2.2
	- Schimbat api-ul pentru schimbarea modelelor
		
	Thanks to: Shadows Adi.
Instalare:
1. Fisierul cs_player_models_api.amxx il puneti in addons/amxmodx/plugins
2. Fisierul csgo_agents.amxx il puneti in addons/amxmodx/plugins
3. Intrati in fisierul addons/amxmodx/configs/plugins.ini si adaugati la urma:

Code: Select all

cs_player_models_api.amxx
csgo_agents.amxx
4. Alti pasi necesari....

Cvar-uri (se adauga in fisierul amxmodx\configs\amxx.cfg):
Fara cvar-uri

Comenzi publice (se tasteaza in joc prin apasarea tastei Y):
- Chat: /agents - afiseaza meniul
- Console: amx_agents- afiseaza meniul

Module necesare (se sterge ; din fata modulului de mai jos; acestea le gasiti in fisierul amxmodx\configs\modules.ini):
- Nu trebuie precizate, acestea se activeaza singure cand sunt folosite

Model fisier config:

Code: Select all

#Skinul pentru echipa Terrorist si Counter-Strike trebuie puse la sectiunea respectiva
#Model: "Nume Skin", "Nume model (fara .mdl)", "Nume fisier preview (cu .html)", "ONLY VIP (1/0)" 
#In cazul in care nu doriti preview la skin scrieti in ghilimelele unde ar trebui sa fie numele fisierului "NOPREVIEW" 
#Skinurile fiecarui player se salveaza pe SteamID.


[SETTINGS]

PREVIEW_MENU = 1 #Meniul pentru preview (0/1)
MODELS_COUNTER = 1  #Textul din meniu care arata cate modele sunt
VIP_FLAG = t #Flag-ul VIP


[MYSQL CONNECTION]

SQL_HOSTNAME = hostname
SQL_USERNAME = username
SQL_PASSWORD = password
SQL_DATABASE = database_name


[Terrorist]
"ISIS Killer" "isis" "NOPREVIEW" "0"
"aLQaeda Terrorist" "alqaeda" "alqaeda.html" "0"
"Crazy Assassin" "crazy_assassin" "crazy_assassin.html" "0"
"Prestige Murderer" "prestige_murderer" "prestige_murderer.html" "1"

[Counter-Strike]
"FBI Agent" "fbi" "NOPREVIEW" "0"
"SIAS Anti-Tero" "sias" "sias.html" "0"
"SWAT C4 Defuser" "c4_defuser" "c4_defuser.html" "0"
"Prestige Sergeant" "prestige_sergeant" "prestige_sergeant.html" "1"


Re: [MySQl] CSGO Agents

Posted: 23 Jul 2021, 22:47
by Shadows Adi
Nu merge link-ul de descarcare.

Re: [MySQl] CSGO Agents

Posted: 23 Jul 2021, 23:30
by kidd0x
Shadows Adi wrote:
23 Jul 2021, 22:47
Nu merge link-ul de descarcare.
https://www98.zippyshare.com/v/9P2vd681/file.html

Re: [MySQl] CSGO Agents

Posted: 24 Jul 2021, 12:10
by Alexandru P.
Cum poti sa dai feedback daca:
L 07/24/2021 - 12:03:47: [AMXX] Plugin ("csgo_agents.amxx") is setting itself as failed.
L 07/24/2021 - 12:03:47: [AMXX] Plugin says: The server is not licensed.
L 07/24/2021 - 12:03:47: [AMXX] Run time error 1 (plugin "csgo_agents.amxx") - forced exit

Re: [MySQl] CSGO Agents

Posted: 24 Jul 2021, 19:59
by lexz
EDIT: Intampin cateva probleme la host si pluginul ingreuneaza schimbarea hartii. Cand isi va reveni hostul voi reposta link.

edit2: link cu o baza de date provizorie: ---

Re: [MySQl] CSGO Agents

Posted: 26 Jul 2021, 02:10
by lexz
Update la versiunea 2.0! :D:D

Re: [MySQl] CSGO Agents - UPDATE [VERSION: 2.0]

Posted: 26 Jul 2021, 02:24
by kraier
Super tare, am sa-l incerc! :*

Re: [MySQl] CSGO Agents - UPDATE [VERSION: 2.0]

Posted: 26 Jul 2021, 11:11
by Alexandru P.
Nu functioneaza link-ul de descarcare

Re: [MySQl] CSGO Agents - UPDATE [VERSION: 2.0]

Posted: 26 Jul 2021, 12:36
by lexz
Link adaugat. Nu inteleg de ce mi se tot sterge de pe mediafire, dar e up acum.

Re: [MySQl] CSGO Agents - UPDATE [VERSION: 2.1]

Posted: 08 Aug 2021, 23:27
by lexz
Update.

Code: Select all

Version 2.1
	- Adaugat suport pentru modelele care au fisier "T.mdl".

Re: [MySQl] CSGO Agents - UPDATE [VERSION: 2.1]

Posted: 22 Dec 2021, 05:44
by lexz
cod sursa

Code: Select all

COD SCOS, VERSIUNE VECHE, VERIFICA POSTUL DE MAI JOS

Re: [MySQl] CSGO Agents - UPDATE [VERSION: 2.1]

Posted: 22 Dec 2021, 11:29
by Shadows Adi
lexz wrote:
22 Dec 2021, 05:44
cod sursa

Code: Select all

#include <amxmodx>
#include <amxmisc>
#include <sqlx>
#include <hamsandwich>
#include <cs_player_models_api>

#define PLUGIN "CSGO Agents"
#define VERSION "2.1"
#define AUTHOR "lexzor"

#define MAX_SKINS 100
#define NON_USED_SKIN 300

#pragma semicolon 1
#pragma compress 1

///////
//SQL//
///////
;
new const SQL_HOSTNAME[]				=				"SQL_HOSTNAME";
new const SQL_USERNAME[]				=				"SQL_USERNAME";
new const SQL_PASSWORD[]				=				"SQL_PASSWORD";
new const SQL_DATABASE[]				=				"SQL_DATABASE";
new const PREVIEW_MENU[]				=				"PREVIEW_MENU";
new const MODELS_COUNTER[]				=				"MODELS_COUNTER";
new const VIP_FLAG[]					=				"VIP_FLAG";
new const g_szTable[] = "CSGO_Agents_Players_Data";
new Handle:g_SqlTuple;
new g_Error[512];
new const g_szPluginName[] = "CSGO AGENTS";

//////////
//CONFIG//
//////////
new const g_szFileName[] = "csgo_agents.cfg";
new const g_szMOTDFolder[] = "csgo_agents_motd";
new g_szFile[124];
new const g_szFileInfo[][] =
{
	"#Skinul pentru echipa Terrorist si Counter-Strike trebuie puse la sectiunea respectiva.^n",
	"#Model: ^"Nume Skin^", ^"Nume model (fara .mdl)^", ^"Nume fisier preview (cu .html)^", ^"ONLY VIP (1/0)^"^n",
	"#In cazul in care nu doriti preview la skin scrieti in ghilimelele unde ar trebui sa fie numele fisierului ^"NOPREVIEW^".^n",
	"#Skinurile fiecarui player se salveaza pe SteamID.^n^n^n",
	"[MYSQL CONNECTION]^n^n",
	"SQL_HOSTNAME = ^n",
	"SQL_USERNAME = ^n",
	"SQL_PASSWORD = ^n",
	"SQL_DATABASE = ^n^n^n",
	"[SETTINGS]^n^n",
	"PREVIEW_MENU = 1 #Meniul pentru preview (0/1)^n",
	"MODELS_COUNTER = 1  #Textul din meniu care arata cate modele sunt.^n",
	"VIP_FLAG = t #Flag-ul VIP.^n^n^n",
	"[Terrorist]^n^n^n",
	"[Counter-Strike]^n^n^n"
};

////////
//ENUM//
////////
enum _:SQLDATA
{
	MYSQL_HOST[32],
	MYSQL_USER[32],
	MYSQL_PASS[48],
	MYSQL_DB[32],
}

enum _:TEROR
{
	szTModelName[64],
	szTModelLocation[64],
	szTModelPreview[64],
	szTSkin[64],
	iTVIPOnly,
	iTID
}

enum _:COUNTER_TERO
{
	szCTModelName[64],
	szCTModelLocation[64],
	szCTModelPreview[64],
	szCTSkin[25],
	iCTVIPOnly,
	iCTID
}

enum _:PREFERENCES
{
	MENU_PREVIEW,
	COUNTER_MODELS,
	FLAG_VIP[26]
}

enum
{ 
	SQL_DATA = 1,
	SETTINGS = 2,
	TERRORISTS = 3,
	COUNTER_TERRORISTS = 4
}

enum _:TEAMS
{
	T,
	CT
}

//////////
//PLUGIN//
//////////
new const g_szTag [] = "^4[CSGO Agents]^1";
new g_TSkin[MAX_SKINS][TEROR];
new g_CTSkin[MAX_SKINS][COUNTER_TERO];
new g_iCounterTotalSkins;
new g_iTerorristTotalSkins;
new g_iPlayerSkin[MAX_PLAYERS + 1][TEAMS];
new g_szAuthID[MAX_PLAYERS + 1][MAX_AUTHID_LENGTH];
new g_szSQlData[SQLDATA];
new g_iSettings[PREFERENCES];

public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR);

	register_cvar("csgo_agents_wf", VERSION, FCVAR_SERVER|FCVAR_EXTDLL|FCVAR_UNLOGGED|FCVAR_SPONLY);

	register_clcmd("say", "say_hook");
	register_clcmd("say_team", "say_hook");
	register_clcmd("amx_agents", "agents_menu", _, "Open CSGO Agents menu");
	RegisterHam(Ham_Spawn, "player", "player_spawn_post", 1);
}

public plugin_precache()
{
	new szFileDirector[64], iFilePointer;
	
	get_configsdir(szFileDirector, charsmax(szFileDirector));
	formatex(g_szFile, charsmax(g_szFile), "%s/%s", szFileDirector, g_szFileName);
	
	new iFile = file_exists(g_szFile);

	if(!iFile)
	{
		iFilePointer = fopen(g_szFile, "w");
		new szFileData[512];
				
		for(new i; i < sizeof(g_szFileInfo); i++)
		{
			formatex(szFileData, charsmax(szFileData), "%s", g_szFileInfo[i]);
			fputs(iFilePointer, szFileData);
		}

		fclose(iFilePointer);

		server_print(" ");
		server_print("-----------------------------------------");
		server_print("[CSGO AGENTS] Config file has been created succesfully!");
		server_print("[CSGO AGENTS] First of all config the plugin in ^"csgo_agents.cfg^"");
		server_print("-----------------------------------------");
		server_print(" ");
		
		set_fail_state("Complete SQL informations.");
	}

	if (iFile)
	{
		new szData[512];
		new szString[124];
		new szValue[124];
		new szParseData[4][64];
		new iSection;
		new szCfgDir[32];
		new i = 0;
		new z = 0;

		iFilePointer = fopen(g_szFile, "rt");

		while(!feof(iFilePointer)) 
		{
			fgets(iFilePointer, szData, charsmax(szData));
			trim(szData);
			
			if(szData[0] == '#' || szData[0] == EOS || szData[0] == ';')
				continue;
				
			if(szData[0] == '[')
				iSection += 1;
			
			switch(iSection)
			{
				case SQL_DATA:
				{
					if (szData[0] != '[')
					{
						strtok2(szData, szString, charsmax(szString), szValue, charsmax(szValue), '=', TRIM_INNER);
						
						if(szValue[0] == EOS || !szValue[0])
						{
							set_fail_state("You must complete SQL data in configuration file!");
						}
							
						if(equal(szString, SQL_HOSTNAME))
						{
							copy(g_szSQlData[MYSQL_HOST], charsmax(g_szSQlData[MYSQL_HOST]), szValue);				
						}
						
						if(equal(szString, SQL_USERNAME))
						{
							copy(g_szSQlData[MYSQL_USER], charsmax(g_szSQlData[MYSQL_USER]), szValue);
						}
						
						if(equal(szString, SQL_PASSWORD))
						{
							copy(g_szSQlData[MYSQL_PASS], charsmax(g_szSQlData[MYSQL_PASS]), szValue);
						}
						
						if(equal(szString, SQL_DATABASE))
						{
							copy(g_szSQlData[MYSQL_DB], charsmax(g_szSQlData[MYSQL_DB]), szValue);
						}
					}
				}

				case SETTINGS:
				{
					if(szData[0] != '[')
					{
						strtok2(szData, szString, charsmax(szString), szValue, charsmax(szValue), '=', TRIM_INNER);
						
						if(szValue[0] == EOS || !szValue[0])
							continue;
						
						if(equal(szString, PREVIEW_MENU))
						{
							g_iSettings[MENU_PREVIEW] = str_to_num(szValue); 
						}

						if(equal(szString, MODELS_COUNTER))
						{
							g_iSettings[COUNTER_MODELS] = str_to_num(szValue);
						}

						if(equal(szString, VIP_FLAG))
						{
							copy(g_iSettings[FLAG_VIP], charsmax(g_iSettings[FLAG_VIP]), szValue);
						}
					}
				}

				case TERRORISTS:
				{
					if(szData[0] != '[')
					{	
						++i;
						parse(szData, szParseData[0], charsmax(szParseData[]), szParseData[1], charsmax(szParseData[]),  szParseData[2], charsmax(szParseData[]), szParseData[3], charsmax(szParseData[]));

						copy(g_TSkin[i-1][szTModelName], charsmax(g_TSkin[][szTModelName]), szParseData[0]);

						formatex(g_TSkin[i-1][szTModelPreview], charsmax(g_TSkin[][szTModelPreview]), "%s/%s/%s", szCfgDir, g_szMOTDFolder, szParseData[2]);
						formatex(g_TSkin[i-1][szTModelLocation], charsmax(g_TSkin[][szTModelLocation]), "models/player/%s/%s", szParseData[1], szParseData[1]);

						g_TSkin[i-1][iTVIPOnly] = str_to_num(szParseData[3]);

						if(g_TSkin[i-1][szTModelLocation][0] != EOS || g_TSkin[i-1][szTModelLocation][0])
							precache_player_model(g_TSkin[i-1][szTModelLocation]);
			
						replace_all(g_TSkin[i-1][szTModelLocation], charsmax(g_TSkin[][szTModelLocation]), "/", " ");
						parse(g_TSkin[i-1][szTModelLocation], szParseData[0], charsmax(szParseData), szParseData[1], charsmax(szParseData), g_TSkin[i-1][szTSkin], charsmax(g_TSkin[][szTSkin]));

						g_TSkin[i-1][iTID] = i-1;

						++g_iTerorristTotalSkins;
					}
				}

				case COUNTER_TERRORISTS:
				{
					if(szData[0] != '[')
					{	
						++z;
						parse(szData, szParseData[0], charsmax(szParseData[]), szParseData[1], charsmax(szParseData[]),  szParseData[2], charsmax(szParseData[]), szParseData[3], charsmax(szParseData[]));

						copy(g_CTSkin[z-1][szCTModelName], charsmax(g_CTSkin[][szCTModelName]), szParseData[0]);

						formatex(g_CTSkin[z-1][szCTModelPreview], charsmax(g_CTSkin[][szCTModelPreview]), "%s/%s/%s", szCfgDir, g_szMOTDFolder, szParseData[2]);
						formatex(g_CTSkin[z-1][szCTModelLocation], charsmax(g_CTSkin[][szCTModelLocation]), "models/player/%s/%s", szParseData[1], szParseData[1]);

						g_CTSkin[z-1][iCTVIPOnly] = str_to_num(szParseData[3]);

						if(g_CTSkin[z-1][szCTModelLocation][0] != EOS || g_CTSkin[z-1][szCTModelLocation][0])
							precache_player_model(g_CTSkin[z-1][szCTModelLocation]);

						replace_all(g_CTSkin[z-1][szCTModelLocation], charsmax(g_CTSkin[][szCTModelLocation]), "/", " ");
						parse(g_CTSkin[z-1][szCTModelLocation], szParseData[0], charsmax(szParseData[]), szParseData[0], charsmax(szParseData[]), g_CTSkin[z-1][szCTSkin], charsmax(g_CTSkin[][szCTSkin]));

						g_CTSkin[z-1][iCTID] = z-1;

						++g_iCounterTotalSkins;
					}
				}
			}
		}
	}

	fclose(iFilePointer);

	MySql_Init();
}

public plugin_end()
{
	SQL_FreeHandle(g_SqlTuple);
}

public MySql_Init()
{
	g_SqlTuple = SQL_MakeDbTuple(g_szSQlData[MYSQL_HOST], g_szSQlData[MYSQL_USER],g_szSQlData[MYSQL_PASS], g_szSQlData[MYSQL_DB]);
	   
	new ErrorCode,Handle:SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,g_Error,charsmax(g_Error));
	   
	if(SqlConnection == Empty_Handle)
	{
		set_fail_state(g_Error);
	}
	
	new Handle:Queries;
	new szQuery[1024];
	
	formatex(szQuery, charsmax(szQuery), "CREATE TABLE IF NOT EXISTS %s ( `id` INT(11) NOT NULL AUTO_INCREMENT , `name` VARCHAR(33) NOT NULL , `steamid` VARCHAR(65) NOT NULL , `last_ct_agent` INT(4) NOT NULL , `last_t_agent` INT(4) NOT NULL , PRIMARY KEY (`id`))", g_szTable);
	Queries = SQL_PrepareQuery(SqlConnection, szQuery);

	if(!SQL_Execute(Queries))
	{
		SQL_QueryError(Queries,g_Error,charsmax(g_Error));
		set_fail_state(g_Error);
	}		
	
	server_print("[%s] SQL Connection to server database has been realized succesfully!", g_szPluginName);
	
	SQL_FreeHandle(Queries);
	SQL_FreeHandle(SqlConnection);
}  
/////////////////////////////////////////////// SQL ///////////////////////////////////////////////
public client_authorized(id)
{
	get_user_authid(id, g_szAuthID[id], charsmax(g_szAuthID[]));
}

public client_putinserver(id)
{
	new szQuery[512];
	new szData[1];
	g_iPlayerSkin[id][T] = NON_USED_SKIN;
	g_iPlayerSkin[id][CT] = NON_USED_SKIN;
	szData[0] = id;
	formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s` WHERE `steamid` = '%s'", g_szTable, g_szAuthID[id]);
	SQL_ThreadQuery(g_SqlTuple, "CheckData", szQuery, szData, 1);
}

#if AMXX_VERSION_NUM < 183
public client_disconnect(id)
#else
public client_disconnected(id)
#endif
{
	g_iPlayerSkin[id][T] = 0;
	g_iPlayerSkin[id][CT] = 0;
}

public CheckData(FailState, Handle:Query, szError[], ErrorCode, szData[], iSize)
{
	if(FailState || ErrorCode)
	{
		server_print(" ");
		server_print("[%s] SQL ERROR: %s", g_szPluginName, szError);
		server_print(" ");
	}

	if(SQL_NumResults(Query) > 0)
	{
		new id = szData[0];
		g_iPlayerSkin[id][T] = SQL_ReadResult(Query, 4);
		g_iPlayerSkin[id][CT] = SQL_ReadResult(Query, 3);
	}
}
/////////////////////////////////////////////// SAY HOOK ///////////////////////////////////////////////
public say_hook(id)
{
	new szArg[192];

	read_args(szArg, charsmax(szArg));
	remove_quotes(szArg);

	if(equal(szArg, "/agents"))
	{
		agents_menu(id);
	}

	return PLUGIN_CONTINUE;
}
/////////////////////////////////////////////// MENU ///////////////////////////////////////////////
public agents_menu(id)
{
	new iMenu = menu_create("\r[CSGO Agents]\y Menu", "agents_menu_handler");

	menu_additem(iMenu, "Terrorist Agents");
	menu_additem(iMenu, "Counter-Terrorists Agents");

	if(g_iSettings[MENU_PREVIEW] != 0)
	{
		menu_additem(iMenu, "Preview skins");
	}

	if(g_iSettings[COUNTER_MODELS] != 0)
	{
		new skinCounter[36];

		menu_addblank2(iMenu);

		if(g_iCounterTotalSkins != 0 && g_iTerorristTotalSkins != 0)
		{
			formatex(skinCounter, charsmax(skinCounter), "\dTerrorists Agents: %i", g_iTerorristTotalSkins);
			menu_addtext2(iMenu, skinCounter);

			formatex(skinCounter, charsmax(skinCounter), "\dCounter-Terrorists Agents: %i", g_iCounterTotalSkins);
			menu_addtext2(iMenu, skinCounter);

			formatex(skinCounter, charsmax(skinCounter), "\dTotal Agents: %i", g_iCounterTotalSkins + g_iTerorristTotalSkins);
			menu_addtext2(iMenu, skinCounter);
		}
		else
		{
			formatex(skinCounter, charsmax(skinCounter), "\dThere are no skins.");
			menu_addtext2(iMenu, skinCounter);
		}
	}

	menu_setprop(iMenu, MPROP_EXIT, MEXIT_ALL);
	menu_display(id, iMenu, 0);
}

public agents_menu_handler(id, menu, item)
{
	if (item == MENU_EXIT)
	{
		menu_destroy(menu);
	}

	switch(item)
	{
		case 0: terrorists_menu(id);
		case 1: counter_terrorists_menu(id);
		case 2: preview_menu(id);
	}
}

terrorists_menu(id)
{
	new iMenu = menu_create("\r[CSGO Agents]\y Terrorists Agents", "terrorists_agents_menu_handler");
	new szMenuItem[4][45];

	if(g_iTerorristTotalSkins > 0)
	{
		formatex(szMenuItem[0], charsmax(szMenuItem[]), "Default Skin - \y [%s]", g_iPlayerSkin[id][T] == NON_USED_SKIN ? "ON" : "OFF");
		menu_additem(iMenu, szMenuItem[0]);

		for (new i; i < g_iTerorristTotalSkins; i++)
		{
			if(g_TSkin[i][iTVIPOnly] == 0)
			{
				if(g_TSkin[i][iTID] == g_iPlayerSkin[id][T])
				{
					formatex(szMenuItem[1], charsmax(szMenuItem[]), "%s \r[#]", g_TSkin[i][szTModelName]);
					menu_additem(iMenu, szMenuItem[1]);
				}
				else
				{
					menu_additem(iMenu, g_TSkin[i][szTModelName]);
				}
			}
			else 
			{
				if(g_TSkin[i][iTID] == g_iPlayerSkin[id][T])
				{
					formatex(szMenuItem[2], charsmax(szMenuItem[]), "%s - \y[VIP] \r[#]", g_TSkin[i][szTModelName]);
					menu_additem(iMenu, szMenuItem[2]);
				}
				else
				{
					formatex(szMenuItem[3], charsmax(szMenuItem[]), "%s - \y[VIP]", g_TSkin[i][szTModelName]);
					menu_additem(iMenu, szMenuItem[3]);
				}	
			}
		}
	}
	else 
	{
		formatex(szMenuItem[0], charsmax(szMenuItem[]), "\dThere are no models to choose from.");
		menu_addtext2(iMenu, szMenuItem[0]);
	}

	menu_setprop(iMenu, MPROP_EXIT, MEXIT_ALL);
	menu_display(id, iMenu, 0);
}

public terrorists_agents_menu_handler(id, menu, item)
{
	if (item == MENU_EXIT)
	{
		menu_destroy(menu);
	}

	if(item > g_iTerorristTotalSkins || item < 0)
	{
		return PLUGIN_HANDLED;
	}

	if(item == 0)
	{
		if(is_user_alive(id))
		{
			cs_reset_player_model(id);
			client_print_color(id, print_team_default, "%s You choose^4 Default Skin^1!", g_szTag);
		}
		else 
		{
			client_print_color(id, print_team_default, "%s You will be respawned with^4 Default Skin^1!", g_szTag);
		}

		g_iPlayerSkin[id][T] = NON_USED_SKIN;
		save_data_sql(id);
		return PLUGIN_HANDLED;
	}

	item -= 1;

	if(g_TSkin[item][iTVIPOnly] != 0 && !(get_user_flags(id) & read_flags(g_iSettings[FLAG_VIP])))
	{
		client_print_color(id, print_team_default, "%s You can't choose this skin because you are not a ^4VIP^1!", g_szTag);
		return PLUGIN_HANDLED;
	}
			
	if(is_user_alive(id))
	{
		if(get_user_team(id) == 1)
			cs_set_player_model(id, g_TSkin[item][szTSkin]);

		client_print_color(id, print_team_default, "%s You choose^4 %s^1 Agent!", g_szTag, g_TSkin[item][szTModelName]);
	}
	else 
	{
		client_print_color(id, print_team_default, "%s You will be respawned with^4 %s^1 Agent Model!", g_szTag, g_TSkin[item][szTModelName]);
	}

	g_iPlayerSkin[id][T] = item;
	save_data_sql(id);
	return PLUGIN_CONTINUE;
}

counter_terrorists_menu(id)
{
	new iMenu = menu_create("\r[CSGO Agents]\y Counter-Terrorists Agents", "counter_terrorists_agents_menu_handler");
	new szMenuItem[4][45];
	
	if(g_iCounterTotalSkins > 0)
	{
		formatex(szMenuItem[0], charsmax(szMenuItem[]), "Default Skin - \y [%s]", g_iPlayerSkin[id][CT] == NON_USED_SKIN ? "ON" : "OFF");
		menu_additem(iMenu, szMenuItem[0]);

		for (new i; i < g_iCounterTotalSkins; i++)
		{
			if(g_CTSkin[i][iCTVIPOnly] == 0)
			{
				if(g_CTSkin[i][iCTID] == g_iPlayerSkin[id][CT])
				{
					formatex(szMenuItem[1], charsmax(szMenuItem[]), "%s \r[#]", g_CTSkin[i][szCTModelName]);
					menu_additem(iMenu, szMenuItem[1]);
				}
				else
				{
					menu_additem(iMenu, g_CTSkin[i][szCTModelName]);
				}
			}
			else 
			{
				if(g_CTSkin[i][iCTID] == g_iPlayerSkin[id][CT])
				{
					formatex(szMenuItem[2], charsmax(szMenuItem[]), "%s - \y[VIP] \r[#]", g_CTSkin[i][szCTModelName]);
					menu_additem(iMenu, szMenuItem[2]);
				}
				else
				{
					formatex(szMenuItem[3], charsmax(szMenuItem[]), "%s - \y[VIP]", g_CTSkin[i][szCTModelName]);
					menu_additem(iMenu, szMenuItem[3]);
				}	
			}
		}
	}
	else 
	{
		formatex(szMenuItem[0], charsmax(szMenuItem[]), "\dThere are no models to choose from.");
		menu_addtext2(iMenu, szMenuItem[0]);
	}

	menu_setprop(iMenu, MPROP_EXIT, MEXIT_ALL);
	menu_display(id, iMenu, 0);
}

public counter_terrorists_agents_menu_handler(id, menu, item)
{
	if (item == MENU_EXIT)
	{
		menu_destroy(menu);
	}

	if(item == 0)
	{
		if(is_user_alive(id))
		{
			cs_reset_player_model(id);

			client_print_color(id, print_team_default, "%s You choose^4 Default Skin^1!", g_szTag);
		}
		else 
		{
			client_print_color(id, print_team_default, "%s You will be respawned with^4 Default Skin^1!", g_szTag);
		}

		g_iPlayerSkin[id][CT] = NON_USED_SKIN;
		save_data_sql(id);
		return PLUGIN_HANDLED;
	}

	if(item > g_iCounterTotalSkins || item < 0)
	{
		return PLUGIN_HANDLED;
	}

	item -= 1;

	if(g_CTSkin[item][iCTVIPOnly] != 0 && !(get_user_flags(id) & read_flags(g_iSettings[FLAG_VIP])))
	{
		client_print_color(id, print_team_default, "%s You can't choose this skin because you are not a ^4VIP^1!", g_szTag);
		return PLUGIN_HANDLED;
	}
	
	if(is_user_alive(id))
	{
		if(get_user_team(id) == 2)
			cs_set_player_model(id, g_CTSkin[item][szCTSkin]);

		client_print_color(id, print_team_default, "%s You choose^4 %s^1 Agent!", g_szTag, g_CTSkin[item][szCTModelName]);
	}
	else
	{
		client_print_color(id, print_team_default, "%s You will be respawned with^4 %s^1 Agent Model!", g_szTag, g_CTSkin[item][szCTModelName]);
	}

	g_iPlayerSkin[id][CT] = item;
	save_data_sql(id);
	return PLUGIN_CONTINUE;
}

preview_menu(id)
{
	new iMenu = menu_create("\r[CSGO Agents]\y Preview Menu", "preview_menu_handler");

	menu_additem(iMenu, "Terrorist Agents");
	menu_additem(iMenu, "Counter-Terrorists Agents");

	menu_setprop(iMenu, MPROP_EXIT, MEXIT_ALL);
	menu_display(id, iMenu, 0);
}

public preview_menu_handler(id, menu, item)
{
	if (item == MENU_EXIT)
	{
		menu_destroy(menu);
	}

	switch(item)
	{
		case 0: preview_terrorist_agents(id);
		case 1: preview_counter_terrorist_agents(id);
	}
}

public preview_terrorist_agents(id)
{
	new iMenu = menu_create("\r[CSGO Agents]\y Terrorists Agents", "terrorists_preview_menu_handler");
	new szMsg[45];

	if(g_iTerorristTotalSkins > 0)
	{
		for (new i; i < g_iTerorristTotalSkins; i++)
		{
				menu_additem(iMenu, g_TSkin[i][szTModelName]);
		}
	}
	else 
	{
		formatex(szMsg, charsmax(szMsg), "\dThere are no models to see preview of.");
		menu_addtext2(iMenu, szMsg);
	}

	menu_setprop(iMenu, MPROP_EXIT, MEXIT_ALL);
	menu_display(id, iMenu, 0);
}

public terrorists_preview_menu_handler(id, menu, item)
{
	if (item == MENU_EXIT)
	{
		menu_destroy(menu);
	}

	if(contain(g_TSkin[item][szTModelPreview], "NOPREVIEW") != -1)
	{
		client_print_color(id, print_team_default, "%s Agent ^4%s^1 does not have a preview!", g_szTag, g_TSkin[item][szTModelName]);
		return PLUGIN_HANDLED;
	}

	show_motd(id, g_CTSkin[item][szCTModelPreview]);

	preview_terrorist_agents(id);

	return PLUGIN_CONTINUE;
}

public preview_counter_terrorist_agents(id)
{
	new iMenu = menu_create("\r[CSGO Agents]\y Counter-Terrorists Agents", "counter_terrorists_preview_menu_handler");
	new szMsg[45];

	if(g_iCounterTotalSkins > 0)
	{
		for (new i; i < g_iCounterTotalSkins; i++)
		{
				menu_additem(iMenu, g_CTSkin[i][szCTModelName]);	
		}
	}
	else 
	{
		formatex(szMsg, charsmax(szMsg), "\dThere are no models to see preview of.");
		menu_addtext2(iMenu, szMsg);
	}

	menu_setprop(iMenu, MPROP_EXIT, MEXIT_ALL);
	menu_display(id, iMenu, 0);
}

public counter_terrorists_preview_menu_handler(id, menu, item)
{
	if (item == MENU_EXIT)
	{
		menu_destroy(menu);
	}
	
	if(contain(g_CTSkin[item][szCTModelPreview], "NOPREVIEW") != -1)
	{
		client_print_color(id, print_team_default, "%s Agent ^4%s^1 does not have a preview!", g_szTag, g_CTSkin[item][szCTModelName]);
		return PLUGIN_HANDLED;
	}

	show_motd(id, g_CTSkin[item][szCTModelPreview]);

	preview_counter_terrorist_agents(id);

	return PLUGIN_CONTINUE;
}

public player_spawn_post(id)
{
	if(is_user_alive(id))
	{
		cs_reset_player_model(id);

		if((get_user_team(id) == 1 && g_iPlayerSkin[id][T] == NON_USED_SKIN) || (get_user_team(id) == 2 && g_iPlayerSkin[id][CT] == NON_USED_SKIN))
		{
			return PLUGIN_HANDLED;
		}

		switch(get_user_team(id))
		{
			case 1:
			{
				new iSkin = g_iPlayerSkin[id][T];
				cs_set_player_model(id, g_TSkin[iSkin][szCTSkin]);
			}

			case 2:
			{
				new iSkin = g_iPlayerSkin[id][CT];
				cs_set_player_model(id, g_CTSkin[iSkin][szCTSkin]);
			}
		}
	}

	return PLUGIN_CONTINUE;
}

public FreeHandle(FailState, Handle:Query, szError[], ErrorCode, szData[], iSize)
{
	if(FailState || ErrorCode)
	{
		server_print(" ");
		server_print("[%s] SQL ERROR: %s", szError, g_szPluginName);
		server_print(" ");
	}
	
	SQL_FreeHandle(Query);
}

public save_data_sql(id)
{
	new szQuery[512];
	new szData[1];
	szData[0] = id;
	formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s` WHERE `steamid` = '%s'", g_szTable, g_szAuthID[id]);
	SQL_ThreadQuery(g_SqlTuple, "SaveData", szQuery, szData, 1);
}

public SaveData(FailState, Handle:Query, szError[], ErrorCode, szData[], iSize)
{
	if(FailState || ErrorCode)
	{
		server_print(" ");
		server_print("[%s] SQL ERROR: %s", szError, g_szPluginName);
		server_print(" ");
	}

	new szQuery[512];
	new id = szData[0];

	if(SQL_NumResults(Query) < 1)
	{
		new szName[MAX_NAME_LENGTH];
		get_user_name(id, szName, charsmax(szName));
		formatex(szQuery, charsmax(szQuery), "INSERT INTO `%s` (`name`,`steamid`,`last_ct_agent`,`last_t_agent`) VALUES ('%s','%s','%i','%i')",
		g_szTable, szName, g_szAuthID[id], g_iPlayerSkin[id][CT], g_iPlayerSkin[id][T]);
		SQL_ThreadQuery(g_SqlTuple, "FreeHandle", szQuery);
	}
	else 
	{
		formatex(szQuery, charsmax(szQuery), "UPDATE `%s` SET `last_ct_agent`='%i', `last_t_agent`='%i' WHERE `steamid` = '%s'", g_szTable, g_iPlayerSkin[id][CT], g_iPlayerSkin[id][T], g_szAuthID[id]);
		SQL_ThreadQuery(g_SqlTuple, "FreeHandle", szQuery);
	}
}

precache_player_model(const szModel[], &id = 0)
{
    new model[128];
    formatex(model, charsmax(model), "%sT.mdl", szModel);

    if(file_exists(model))
        id = precache_generic(model);

    static const extension[] = "T.mdl";
    #pragma unused extension

    copy(model[strlen(model) - charsmax(extension)], charsmax(model), ".mdl");
    return precache_model(model);
}
Linia 331: Nu are sens de ce ai pus ca cheie primara coloana 'ID' pentru ca se incrementeaza automat. Poti pune steamid-ul sau numele drept cheie primara.

In meniuri de ce folosesti o variabila care poata stoca pana la 4 * 45 de celule? Poti folosi doar 45 de celule pentru a construi meniurile, pentru ca odata ce folosesti menu_additem() dupa formatarea itemului din meniu, acesta intra intr-un spatiu rezervat alocat automat in care asteapta sa fie afisat.

Iar construirea meniurilor poate fi optimizata:

Code: Select all

terrorists_menu(id)
{
	new iMenu = menu_create("\r[CSGO Agents]\y Terrorists Agents", "terrorists_agents_menu_handler");
	new szMenuItem[128], szTemp[64], bool:bIsSelected, bool:bForVIP;

	if(g_iTerorristTotalSkins > 0)
	{
		formatex(szMenuItem, charsmax(szMenuItem), "Default Skin - \y [%s]", g_iPlayerSkin[id][T] == NON_USED_SKIN ? "ON" : "OFF");
		menu_additem(iMenu, szMenuItem);

		for (new i; i < g_iTerorristTotalSkins; i++)
		{
			bIsSelected = g_TSkin[i][iTID] == g_iPlayerSkin[id][T] ? true : false;
			bForVIP = g_TSkin[i][iTVIPOnly] == 1 ? true : false;
			formatex(szTemp, charsmax(szTemp), "%s", g_TSkin[i][szTModelName]);

			formatex(szMenuItem, charsmax(szMenuItem), "%s %s %s", szTemp, bForVIP ? "- \y[VIP]" : "" , bIsSelected ? "\r[#]" : "");
			menu_additem(iMenu, !bIsSelected ? szTemp : szMenuItem);
		}
	}
	else 
	{
		formatex(szMenuItem, charsmax(szMenuItem), "\dThere are no models to choose from.");
		menu_addtext2(iMenu, szMenuItem);
	}

	menu_setprop(iMenu, MPROP_EXIT, MEXIT_ALL);
	menu_display(id, iMenu);
}
Si mai sunt multe optimizari care pot fi facute, dar per total bravo.