AES: StatsX CStrike при заходе на сервер при прописи /top15 пишет только одного игрока в списке.

Статус
В этой теме нельзя размещать новые ответы.
Сообщения
4
Реакции
0
Ошибка
AES: StatsX CStrike при заходе на сервер при прописи /top15 пишет только одного игрока в списке.
ОС
Linux
Amx Mod X
amxx version
AMX Mod X 1.9.0.5249 (http://www.amxmodx.org)
Authors:
        David "BAILOPAN" Anderson, Pavol "PM OnoTo" Marko
        Felix "SniperBeamer" Geyer, Jonny "Got His Gun" Bergstrom
        Lukasz "SidLuke" Wlasinski, Christian "Basic-Master" Hammacher
        Borja "faluco" Ferrer, Scott "DS" Ehlert
Compiled: Jun 19 2019 13:31:53
Built from: https://github.com/alliedmodders/amxmodx/commit/6cecb34
Build ID: 5249:6cecb34
Core mode: JIT+ASM32
C++
Билд
version
Protocol version 48
Exe version 1.1.2.7/Stdio (cstrike)
ReHLDS version: 3.7.0.685-dev-myarena
Build date: 15:07:00 Aug 26 2019 (1962)
Build from: https://github.com/dreamstalker/rehlds/commit/5b68568
C++
ReGamedll
game version
ReGameDLL version: 5.11.0.400-dev
Build date: 17:19:28 Sep 10 2019
Build from: https://github.com/s1lentq/ReGameDLL_CS/commit/a2a6997
C++
Версия Metamod
meta version
Metamod-r v1.3.0.128, API (5:13)
Metamod-r build: 17:47:54 Aug 24 2018
Metamod-r from: https://github.com/theAsmodai/metamod-r/commit/0cf2f70
C++
Список метамодулей
meta list
Currently loaded plugins:
      description      stat pend  file                       vers             src  load  unload
 [ 1] Reunion          RUN   -    reunion_mm_i386.so         v0.1.75          ini  Start Never
 [ 2] VoiceTranscoder  RUN   -    VoiceTranscoder.so         v2017RC3         ini  ANY   ANY  
 [ 3] ReAuthCheck      RUN   -    reauthcheck_mm_i386.so     v0.1.6           ini  Start Never
 [ 4] AMX Mod X        RUN   -    amxmodx_mm_i386.so         v1.9.0.5249      ini  Start ANY  
 [ 5] WHBlocker        RUN   -    whblocker_mm_i386.so       v1.5.696         ini  Chlvl ANY  
 [ 6] ReSemiclip       RUN   -    resemiclip_mm_i386.so      v2.3.9           ini  Chlvl ANY  
 [ 7] Rechecker        RUN   -    rechecker_mm_i386.so       v2.5             ini  Chlvl ANY  
 [ 8] ReSRDetector     RUN   -    resrdetector_mm_i386.so    v0.1.0           ini  Chlvl ANY  
 [ 9] hackdetector     RUN   -    hackdetector_amxx_i386.so  v0.15.328.lite   pl4  ANY   ANY  
 [10] MySQL            RUN   -    mysql_amxx_i386.so         v1.9.0.5249      pl4  ANY   ANY  
 [11] SQLite           RUN   -    sqlite_amxx_i386.so        v1.9.0.5249      pl4  ANY   ANY  
 [12] Fun              RUN   -    fun_amxx_i386.so           v1.9.0.5249      pl4  ANY   ANY  
 [13] Engine           RUN   -    engine_amxx_i386.so        v1.9.0.5249      pl4  ANY   ANY  
 [14] FakeMeta         RUN   -    fakemeta_amxx_i386.so      v1.9.0.5249      pl4  ANY   ANY  
 [15] CStrike          RUN   -    cstrike_amxx_i386.so       v1.9.0.5249      pl4  ANY   ANY  
 [16] CSX              RUN   -    csx_amxx_i386.so           v1.9.0.5249      pl4  ANY   ANY  
 [17] Ham Sandwich     RUN   -    hamsandwich_amxx_i386.so   v1.9.0.5249      pl4  ANY   ANY  
 [18] Orpheu           RUN   -    orpheu_amxx_i386.so        v2.6.3           pl4  ANY   ANY  
 [19] okapi            RUN   -    okapi_amxx_i386.so         v1.0             pl4  ANY   ANY  
 [20] ReAPI            RUN   -    reapi_amxx_i386.so         v5.10.0.188-dev  pl4  ANY   Never
20 plugins, 20 running
C++
Список плагинов
amx_plugins
Currently loaded plugins:
       name                    version     author            file             status   
 [  1] admin_loader            0.3.5       kanagava          admin_loader.am  running  
 [  2] FreshBans               1.3.8b      kanagava          fresh_bans.amxx  running  
 [  3] [182] Admin Full Slot   17.10.30    Sanlerus          admin_fullslot.  running  
 [  4] HackDetector            0.15.lite   Lev @ AGHL.RU De  hackdetector.am  running  
 [  5] AIM detector            0.9.4b      kanagava          aim_detector.am  running  
 [  6] Block Name Spam         0.1         s1lent            block_change_ni  running  
 [  7] ADmins-Restore          1.0         Fedcomp           admin-restore.a  running  
 [  8] Don't say IPs           0.1         JGHG              dontsayips.amxx  running  
 [  9] Block grande info       1.0         author            GRENI.amxx       running  
 [ 10] Block HudTextArgs       1.0         ConnorMcLeod      hudTextArgsBloc  running  
 [ 11] Admin Commands          1.8.1.3746  AMXX Dev Team     admincmd.amxx    running  
 [ 12] Admin Votes             1.8.2       AMXX Dev Team     adminvote.amxx   running  
 [ 13] Commands Menu           1.8.1.3746  AMXX Dev Team     cmdmenu.amxx     running  
 [ 14] Info. Messages          1.8.1.3746  AMXX Dev Team     imessage.amxx    running  
 [ 15] Maps Menu               1.8.1.3746  AMXX Dev Team     mapsmenu.amxx    running  
 [ 16] CS Misc. Stats          1.8.1.3746  AMXX Dev Team     miscstats.amxx   running  
 [ 17] Players Menu            1.8.1.3746  AMXX Dev Team     plmenu.amxx      running  
 [ 18] Restrict Weapons        1.8.1.3746  AMXX Dev Team     restmenu.amxx    running  
 [ 19] CSStatsX SQL            0.7.4+2     serfreeman1337    csstatsx_sql.am  running  
 [ 20] Menus Front-End         1.8.1.3746  AMXX Dev Team     menufront.amxx   running  
 [ 21] Admin Gag               1.2                           gagmenu.amxx     running  
 [ 22] mute menu               1.0         cheap_suit        mutemenu.amxx    running  
 [ 23] Bad Camper              1.4 MODED   Brad Jones        bad_camper_mode  running  
 [ 24] Night VIPs              Private     Private           night_vips.amxx  running  
 [ 25] [SWE] Vip               3.1         IIPU3PAK          swe_vip_31.amxx  running  
 [ 26] Demo Recorder           2.4.0       F@nt0M            demo_recorder.a  running  
 [ 27] Afk Control             0.5.1       neygomon          afk_control.amx  running  
 [ 28] Ping Checker            26.0.1 RC1  h1k3              ping_checker.am  running  
 [ 29] MapChooser RBS          15.07.15    SKAJIbnEJIb & UF  mapchooser_rbs.  running  
 [ 30] Reset_Score             1.0         miRror            resetscore.amxx  running  
 [ 31] Parachute               15.01.06    KRoT@L/JTP10181   parachute_rbs.a  running  
 [ 32] Lite AwpLimit           1.09        neygomon          awp.amxx         running  
 [ 33] Adverts                 1.9.0.5249  pUzzlik           adverts_message  running  
 [ 34] Admin Check             1.51        OneEyed           admin_check.amx  running  
 [ 35] Lite Translit           2.5.7b/10   neygomon          lite_translit.a  running  
 [ 36] Yet Another Voteban     1.52        AndrewZ/noskill   yet_another_vot  running  
 [ 37] Kill Assist RBS         15.07.24    Digi & SKAJIbnEJ  killassist_rbs.  running  
 [ 38] Killa HP                1.0         jas0n             killa_hp.amxx    running  
 [ 39] Admin ESP               1.5b_mini   KoST              admin_esp_mini.  running  
 [ 40] [182] Team Balancer     17.10.30    Sanlerus          team_balancer.a  running  
 [ 41] Map Spawns Editor       1.0.16      iG_os             map_spawns_edit  running  
 [ 42] PsychoStats Plugin      1.1         Stormtrooper      ps_heatmaps.amx  running  
 [ 43] RE C4 Timer [ON]        1.0         AcE               re_c4_timer.amx  running  
 [ 44] [ReAPI] No Team Flash   0.0.2       Vaqtincha         no_team_flash.a  running  
 [ 45] Advanced Experience Sy  0.5.9 [REA  serfreeman1337/s  aes_main.amxx    running  
 [ 46] AES: CStrike Addon      0.5.9 [REA  serfreeman1337/s  aes_exp_cstrike  running  
 [ 47] AES: Informer           0.5.9 [REA  serfreeman1337/s  aes_informer.am  running  
 [ 48] AES: StatsX             0.5.9 [REA  serfreeman1337/s  aes_statsx_cstr  running  
48 plugins, 48 running
C++
Автор плагина
serfreeman1337
Версия плагина
0.5+1
Исходный код
/*
*	AES: StatsX						v. 0.5+1
*	by serfreeman1337		https://github.com/serfreeman1337
*/

#include <amxmodx>
#include <csx>

#if AMXX_VERSION_NUM < 183
	#include <colorchat>
	
	#define print_team_default DontChange
	#define print_team_grey Grey
	#define print_team_red Red
	#define print_team_blue Blue
	
	#define MAX_PLAYERS 32
	#define MAX_NAME_LENGTH 32
	
	#define client_disconnected client_disconnect
#endif

#define AES			// расскомментируйте для поддержки AES (https://github.com/serfreeman1337/aes)
#define CSSTATSX_SQL		// расскомментируйте для поддержки CSstatsX SQL (https://github.com/serfreeman1337/csstatsx-sql)

#if defined AES
	#include <aes_v>
	
	native Float:aes_get_exp_for_stats_f(stats[8],stats2[4])
#endif

#if defined CSSTATSX_SQL
	#include <csstatsx_sql>
	#include <time>
#endif

#define PLUGIN "AES: StatsX"
#define VERSION "0.5+1"
#define AUTHOR "serfreeman1337"

/* - CVARS - */
enum _:cvars {
	CVAR_MOTD_DESC,
	CVAR_CHAT_DESC,
	CVAR_SESTATS_DESC,
	CVAR_SKILL,
	CVAR_MOTD_SKILL_FMT
}

new cvar[cvars]

/* - RANDOM STUFF */

// User stats parms id
#define STATS_KILLS             0
#define STATS_DEATHS            1
#define STATS_HS                2
#define STATS_TKS               3
#define STATS_SHOTS             4
#define STATS_HITS              5
#define STATS_DAMAGE            6

#define MAX_TOP			10

/* - SKILL - */

new const g_skill_letters[][] = {
	"L-",
	"L",
	"L+",
	"M-",
	"M",
	"M+",
	"H-",
	"H",
	"H+",
	"P-",
	"P",
	"P+",
	"G"
}

new const g_skill_class[][] = {
	"Lm",
	"L",
	"Lp",
	"Mm",
	"M",
	"Mp",
	"Hm",
	"H",
	"Hp",
	"Pm",
	"P",
	"Pp",
	"G"
}

// Global player flags.
new const BODY_PART[8][] =
{
	"WHOLEBODY", 
	"AES_HEAD", 
	"AES_CHEST", 
	"AES_STOMACH", 
	"AES_LARM", 
	"AES_RARM", 
	"AES_LLEG", 
	"AES_RLEG"
}

new Float:g_skill_opt[sizeof g_skill_letters]

#define BUFF_LEN 1535

new theBuffer[BUFF_LEN + 1] = 0

#define MENU_LEN 512

#define STATS_MENU_ACTION	0
#define STATS_MENU_PAGE		1
#define STATS_MENU_PERPAGE	7
new g_MenuStatus[MAX_PLAYERS + 1][STATS_MENU_PERPAGE + 2]

public SayStatsMe           = 0 // displays user's stats and rank
public SayRankStats         = 0 // displays user's rank stats
public SayRank              = 0 // displays user's rank
public SayTop15             = 0 // displays first 15 players
public SayStatsAll          = 0 // displays all players stats and rank
public SayHot	= 0	// displays top from current players
#if defined CSSTATSX_SQL
public SaySeStats	= 0 // displays players match history
#endif

#if defined AES
	new aes_track_mode
#endif

public plugin_precache()
{
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	/*
	// Отображение /top15 и /rank
	// ВАЖНО! Motd окно не может показывать больше 1534-х символов, а сообщение в чат больше 192-х.
	// Если что то отображается криво или не полностью, то нужно уменьшить количество пунктов. (Топ не показывает больше 10-ти игроков)
	//   * - Ранг
	//   a - Ник (Only /top15)
	//   b - Убийста
	//   c - Смерти
	//   d - Попаданий
	//   e - Выстрелов
	//   f - В голову
	//   g - Точность
	//   h - Эффективность
	//   i - Скилл
	//   j - Звание Army Ranks
	//   k - K:D
	//   l - HS:K
	//   m - HS %
	//   n - онлайн время
	*/
	
	cvar[CVAR_MOTD_DESC] = register_cvar("aes_statsx_top","*abcfi")
	cvar[CVAR_CHAT_DESC] = register_cvar("aes_statsx_rank","bci")
	
	//
	// o - изменение скилла
	// p - дата сессии
	// q - карта
	//
	cvar[CVAR_SESTATS_DESC] = register_cvar("aes_statsx_sestats","poqnbckfl")
	
	// Настройка скилла. Значения схожи со значениями эффективности.
	// Значения: L- L L+ M- M M+ H- H H+ P- P P+ G
	cvar[CVAR_SKILL] = register_cvar("aes_statsx_skill","60.0 75.0 85.0 100.0 115.0 130.0 140.0 150.0 165.0 180.0 195.0 210.0")
	
	/*
	* Как выводить скилл в motd
	*	0 - html (картинка с буквой + скилл)
	*	1 - буква (скилл)
	*	2 - буква
	*	3 - скилл
	*/
	cvar[CVAR_MOTD_SKILL_FMT] = register_cvar("aes_statsx_motd_skill","0")
	
	register_dictionary("statsx.txt")
	register_dictionary("statsx_aes.txt")
	
	#if defined CSSTATSX_SQL
		register_dictionary("time.txt")
	#endif
}

public plugin_init()
{
	register_clcmd("say","Say_Catch")
	register_clcmd("say_team","Say_Catch")
	
	register_menucmd(register_menuid("Stats Menu"), 1023, "actionStatsMenu")
}

#if AMXX_VERSION_NUM < 183
	public plugin_cfg()
#else
	public OnAutoConfigsBuffered()
#endif
{
	new levelString[512],stPos,ePos,rawPoint[20],cnt
	get_pcvar_string(cvar[CVAR_SKILL],levelString,charsmax(levelString))
	
	// парсер значений для скилла
	do {
		ePos = strfind(levelString[stPos]," ")
		
		formatex(rawPoint,ePos,levelString[stPos])
		g_skill_opt[cnt] = str_to_float(rawPoint)
		
		stPos += ePos + 1
		
		cnt++
		
		// narkoman wole suka
		if(cnt > sizeof g_skill_letters - 1)
			break
	} while (ePos != -1)
	
	new addStast[] = "amx_statscfg add ^"%s^" %s"

	server_cmd(addStast, "ST_SAY_STATSME", "SayStatsMe")
	server_cmd(addStast, "ST_SAY_RANKSTATS", "SayRankStats")
	server_cmd(addStast, "ST_SAY_RANK", "SayRank")
	server_cmd(addStast, "ST_SAY_TOP15", "SayTop15")
	server_cmd(addStast, "ST_SAY_STATS", "SayStatsAll")
	server_cmd(addStast, "AES_SAY_HOT", "SayHot")
	
	#if defined CSSTATSX_SQL 
		server_cmd(addStast, "CSXSQL_SESTATS_CFG", "SaySeStats")
	#endif
	
	#if defined AES
		aes_track_mode = get_cvar_num("aes_track_mode")
	#endif
}

#if defined CSSTATSX_SQL
//
// Команда /sestats
//
public SeStats_Show(id,player_id)
{
	if(!SaySeStats)
	{
		client_print_color(id,print_team_red,"%L %L",id,"STATS_TAG", id,"DISABLED_MSG")
		
		return PLUGIN_HANDLED
	}
	
	new plr_db,sestats_data[2]
	
	sestats_data[0] = id
	sestats_data[1] = player_id
	
	plr_db = get_user_stats_id(player_id)
	
	if(!plr_db|| !get_sestats_thread_sql(plr_db,"SeStats_ShowHandler",sestats_data,sizeof sestats_data,10))
	{
		client_print_color(id,print_team_red,"%L %L",id,"STATS_TAG", id,"AES_STATS_INFO2")
		
		return PLUGIN_HANDLED
	}
	
	return PLUGIN_HANDLED
}

public SeStats_ShowHandler(CSXSQL_SESTATS:sestats_array,sestats_data[])
{
	new id = sestats_data[0]
	new player_id = sestats_data[1]
	
	if(!is_user_connected(id) || !is_user_connected(player_id))
	{
		get_sestats_free(sestats_array)
		return PLUGIN_HANDLED
	}
	
	new len,title[64]
	
	// заголовок
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"AES_META")
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"AES_STYLE")
		
	if(id == player_id)
	{
		formatex(title,charsmax(title),"%L %L",
			id,"YOURS",
			id,"CSXSQL_SETITLE"
		)
			
	}
	else
	{
		new name[MAX_NAME_LENGTH]
		get_user_name(player_id,name,charsmax(name))
		
		formatex(title,charsmax(title),"%L %s",
			id,"CSXSQL_SETITLE",
			name
		)
	}
	
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"CSXSQL_SEHTML",title)
	
	// таблица со статистикой
	new row_str[512],cell_str[MAX_NAME_LENGTH * 3],row_len
	new desc_str[10],desc_char[4],bool:odd
	
	get_pcvar_string(cvar[CVAR_SESTATS_DESC],desc_str,charsmax(desc_str))
	trim(desc_str)
	
	new desc_length = strlen(desc_str)
	
	len += parse_top_desc_header(id,theBuffer,BUFF_LEN,len,false,desc_str)
	
	new stats[8],bh[8]
	
	for(new i,length = get_sestats_read_count(sestats_array) ; i < length ; i++)
	{
		get_sestats_read_stats(sestats_array,i,stats,bh)
		
		for(new desc_index ; desc_index < desc_length ; desc_index++)
		{
			cell_str[0] = 0
			desc_char[0] = desc_str[desc_index]
			
			switch(desc_char[0])
			{
				// время
				case 'p':
				{
					new stime = get_sestats_read_stime(sestats_array,i)
					format_time(cell_str,charsmax(cell_str),"%m/%d/%Y - %H:%M:%S",stime)
				}
				// изменение скилла
				case 'o':
				{
					new Float:skill = get_sestats_read_skill(sestats_array,i)
					
					formatex(cell_str,charsmax(cell_str),"%s%.2f",
						skill > 0.0 ? "+" : "",
						skill
					)
				}
				// карта
				case 'q':
				{
					get_sestats_read_map(sestats_array,i,cell_str,charsmax(cell_str))
				}
				// убийства
				case 'b':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_KILLS])
				}
				// смерти
				case 'c':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_DEATHS])
				}
				// попадания
				case 'd':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_HITS])
				}
				// выстрелы
				case 'e':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_SHOTS])
				}
				// хедшоты
				case 'f':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_HS])
				}
				// точнсть
				case 'g':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						accuracy(stats)
					)
				}
				// эффективность
				case 'h':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						effec(stats)
					)
				}
				// K:D
				case 'k':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f",
						kd_ratio(stats)
					)
				}
				// HS:K
				case 'l':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f",
						hsk_ratio(stats)
					)
				}
				// HS effec
				case 'm':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						effec_hs(stats)
					)
				}
				// время в игре
				case 'n':
				{
					new ot = get_sestats_read_online(sestats_array,i)
					func_format_ot(ot,cell_str,charsmax(cell_str),id)
				}
				default: continue
			}
			
			// выводим отформатированные данные
			row_len += formatex(row_str[row_len],charsmax(row_str)-row_len,"%L",id,"AES_BODY_CELL",cell_str)
		}
		row_len = 0
		
		row_len = len
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"%L",id,"AES_BODY_ROW",odd ? " id=b" : " id=q",row_str)
		
		if(len >= BUFF_LEN)
		{
			theBuffer[row_len] = 0
			break
		}
		
		row_len = 0
		
		odd ^= true
	}
	
	get_sestats_free(sestats_array)
	
	formatex(title,charsmax(title),"%L",id,"CSXSQL_SETITLE")
	show_motd(id,theBuffer,title)
	
	return PLUGIN_HANDLED
}
#endif

//
// Команда /hot
//
public ShowCurrentTop(id)
{
	if(!SayHot)
	{
		client_print_color(id,print_team_red,"%L %L",id,"STATS_TAG", id,"DISABLED_MSG")
		
		return PLUGIN_HANDLED
	}
	
	new players[MAX_PLAYERS],pnum
	get_players(players,pnum)
	
	new current_top[MAX_PLAYERS][2]
	
	for(new i,stats[8],bh[8] ; i < pnum ; i++)
	{
		current_top[i][0] = players[i]
		
		#if !defined CSSTATSX_SQL
			current_top[i][1] = get_user_stats(players[i],stats,bh)
		#else
			current_top[i][1] = get_user_stats_sql(players[i],stats,bh)
		#endif
	}
	
	SortCustom2D(current_top,sizeof current_top,"Sort_CurrentTop")
	
	new len,title[64]
	formatex(title,charsmax(title),"%L",id,"AES_HOT_PLAYERS")
	
	// заголовок
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"AES_META")
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"AES_STYLE")
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"AES_TOP_BODY",id,"AES_HOT_PLAYERS")
	
	// таблица со статистикой
	new row_str[512],cell_str[MAX_NAME_LENGTH * 3],row_len
	new desc_str[10],desc_char[4],bool:odd
	
	get_pcvar_string(cvar[CVAR_MOTD_DESC],desc_str,charsmax(desc_str))
	trim(desc_str)
	
	// TODO: AES RANKS
	replace(desc_str,charsmax(desc_str),"j","")
	
	new desc_length = strlen(desc_str)
	new skill_out = get_pcvar_num(cvar[CVAR_MOTD_SKILL_FMT])
	
	len += parse_top_desc_header(id,theBuffer,BUFF_LEN,len,false,desc_str)
	
	for(new i,stats[8],bh[8],player_id ,name[MAX_NAME_LENGTH] ; i < sizeof current_top ; i++)
	{
		player_id = current_top[i][0]
		
		if(!player_id)
		{
			continue
		}
		
		get_user_name(player_id,name,charsmax(name))
		
		#if !defined CSSTATSX_SQL
			get_user_stats(player_id,stats,bh)
		#else
			get_user_stats_sql(player_id,stats,bh)
		#endif
		
		for(new desc_index ; desc_index < desc_length ; desc_index++)
		{
			cell_str[0] = 0
			desc_char[0] = desc_str[desc_index]
			
			switch(desc_char[0]){
				// ранк
				case '*':
				{
					formatex(cell_str,charsmax(cell_str),"%d",current_top[i][1])
				}
				// ник
				case 'a':
				{
				
					formatex(cell_str,charsmax(cell_str),"%s",name)
					
					replace_all(cell_str,charsmax(cell_str),"<","&lt")
					replace_all(cell_str,charsmax(cell_str),">","&gt")
				}
				// убийства
				case 'b':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_KILLS])
				}
				// смерти
				case 'c':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_DEATHS])
				}
				// попадания
				case 'd':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_HITS])
				}
				// выстрелы
				case 'e':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_SHOTS])
				}
				// хедшоты
				case 'f':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats[STATS_HS])
				}
				// точнсть
				case 'g':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						accuracy(stats)
					)
				}
				// эффективность
				case 'h':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						effec(stats)
					)
				}
				
				// скилл
				case 'i':{
					new Float:skill ,skill_id
					
					#if defined CSSTATSX_SQL
						// используем скилл из csstatsx sql (ELO)
						get_user_skill(player_id,skill)
					#else
						// используем K:D для скилла
						skill = effec(stats)
					#endif
					
					skill_id =  aes_statsx_get_skill_id(skill)
					
					switch(skill_out)
					{
						// html
						case 0:
						{
							formatex(cell_str,charsmax(cell_str),"%L",
								id,
								"AES_SKILL_FMT",
								
								
								g_skill_class[skill_id],
								skill
							)
						}
						// буква (скилл)
						case 1:
						{
							formatex(cell_str,charsmax(cell_str),"%s (%.2f)",
								g_skill_letters[skill_id],
								skill
							)
						}
						// буква
						case 2:
						{
							formatex(cell_str,charsmax(cell_str),"%s",
								g_skill_letters[skill_id]
							)
						}
						// скилл
						case 3:
						{
							formatex(cell_str,charsmax(cell_str),"%.2f",
								skill
							)
						}
					}
					
					
					
					
				}
				#if defined AES
				// опыт и ранг
				case 'j':
				{
					// TODO: AES RANKS
					formatex(cell_str,charsmax(cell_str),"lyl")
				}
				#endif
				// K:D
				case 'k':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f",
						kd_ratio(stats)
					)
				}
				// HS:K
				case 'l':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f",
						hsk_ratio(stats)
					)
				}
				// HS effec
				case 'm':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						effec_hs(stats)
					)
				}
				#if defined CSSTATSX_SQL
				// время в игре
				case 'n':
				{
					new ot = get_user_gametime(player_id)
					func_format_ot(ot,cell_str,charsmax(cell_str),id)
				}
				#endif
				default: continue
			}
			
			// выводим отформатированные данные
			row_len += formatex(row_str[row_len],charsmax(row_str)-row_len,"%L",id,"AES_BODY_CELL",cell_str)
		}
		
		row_len = len
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"%L",id,"AES_BODY_ROW",odd ? " id=b" : " id=q",row_str)
		
		if(len >= BUFF_LEN)
		{
			theBuffer[row_len] = 0
		}
		
		row_len = 0
		odd ^= true
	}
	
	show_motd(id,theBuffer,title)
	
	return PLUGIN_HANDLED
}

public Sort_CurrentTop(const elem1[], const elem2[])
{
	if(elem1[1] < elem2[1])
	{
		return -1
	}
	else if(elem1[1] > elem2[1])
	{
		return 1
	}
	
	return 0
}

// Ловим сообщения чата
public Say_Catch(id){
	new msg[191]
	read_args(msg,190)
	
	trim(msg)
	remove_quotes(msg)

	if(msg[0] == '/'){
		if(strcmp(msg[1],"rank",true) == 0)
		{
			return RankSay(id)
		}
		if(strcmp(msg[1],"hot",true) == 0 || strcmp(msg[1],"topnow",true) == 0)
		{
			return ShowCurrentTop(id)
		}
		if(containi(msg[1],"top") == 0)
		{
			replace(msg,190,"/top","")
			
			return SayTop(id,str_to_num(msg))
		}
		if(strcmp(msg[1],"rankstats",true) == 0)
		{
			return RankStatsSay(id,id)
		}
		
		if(strcmp(msg[1],"statsme",true) == 0)
		{
			return StatsMeSay(id,id)
		}
		
		if(strcmp(msg[1],"stats",true) == 0)
		{
			arrayset(g_MenuStatus[id], 0, sizeof g_MenuStatus[])
			return ShowStatsMenu(id,0)
		}
		#if defined CSSTATSX_SQL
		if(strcmp(msg[1],"sestats",true) == 0 || strcmp(msg[1],"history",true) == 0)
		{
			return SeStats_Show(id,id)
		}
		#endif
	}
	
	return PLUGIN_CONTINUE
}

//
// Команда /rank
//
public RankSay(id){
	// команда /rank выключена
	if(!SayRank)
	{
		client_print_color(id,print_team_red,"%L %L",id,"STATS_TAG", id,"DISABLED_MSG")
		
		return PLUGIN_HANDLED
	}
	
	new message[191],len,rank,stats_num,stats[8],bh[8]
	
	len += formatex(message[len],charsmax(message)- len,"%L ",id,"STATS_TAG")
	
	#if defined CSSTATSX_SQL
		rank = get_user_stats_sql(id,stats,bh)
		stats_num = get_statsnum_sql()
	#else
		rank = get_user_stats(id,stats,bh)
		stats_num = get_statsnum()
	#endif
	
	if(rank > 0)
	{
		len += formatex(message[len],charsmax(message) - len,"%L ",id,"AES_YOUR_RANK_IS",rank,stats_num)
		len += parse_rank_desc(id,message[len],charsmax(message)-len,stats)
	}
	else
	{
		len += formatex(message[len],charsmax(message) - len,"%L ",id,"AES_STATS_INFO2")
	}
	
	client_print_color(id,print_team_default,message)
	
	return PLUGIN_HANDLED
}

//
// Формирование сообщения /rank
//
parse_rank_desc(id,msg[],maxlen,stats[8]){
	new cnt,theChar[4],len
	
	new desc_str[10]
	get_pcvar_string(cvar[CVAR_CHAT_DESC],desc_str,charsmax(desc_str))
	
	// Проверяем всё флаги
	for(new i,length = strlen(desc_str) ; i < length ; ++i){
		theChar[0] = desc_str[i]	// фз почему напрямую не рабатает
		
		// если это первое значение, то рисуем в начале скобку, иначе запятую с пробелом
		if(cnt != length)
			len += formatex(msg[len],maxlen - len,cnt <= 0 ? "(" : ", ")
		
		// добавляем в сообщение информацию в соотв. с флагами
		switch(theChar[0]){
			 // убийства
			case 'b':
			{
				len += formatex(msg[len],maxlen - len,"%L ^3%d^1",id,"KILLS",stats[0])
			}
			 // смерти
			case 'c':
			{
				len += formatex(msg[len],maxlen - len,"%L ^3%d^1",id,"DEATHS",stats[1])
			}
			 // попадания
			case 'd':
			{
				len += formatex(msg[len],maxlen - len,"%L ^3%d^1",id,"HITS",stats[5])
			}
			// выстрелы
			case 'e':
			{ 
				len += formatex(msg[len],maxlen - len,"%L ^3%d^1",id,"SHOTS",stats[4])
			}
			// хедшоты
			case 'f':
			{
				len += formatex(msg[len],maxlen - len,"%L ^3%d^1",id,"STATS_HS",stats[2])
			}
			// точность
			case 'g':
			{
				len += formatex(msg[len],maxlen - len,"%L ^3%.2f%%^1",id,"ACC",accuracy(stats))
			}
			// эффективность
			case 'h':
			{ 
				len += formatex(msg[len],maxlen - len,"%L ^3%.2f%%^1",id,"EFF",effec(stats))
			}
			// скилл
			case 'i':
			{
				new Float:skill,skill_id
				
				#if defined CSSTATSX_SQL
					get_user_skill(id,skill)
				#else
					skill = effec(stats)
				#endif
				
				skill_id = aes_statsx_get_skill_id(skill)
				
				len += formatex(msg[len],maxlen - len,"%L ^3%s^1 (%.2f)",id,"STATS_SKILL",
					g_skill_letters[skill_id],
					skill
				)
				
			}
			#if defined AES
			case 'j':{ // ранг и опыт
				new Float:player_exp = aes_get_player_exp(id)
				
				if(player_exp == -1.0)// без ранга
				{
					len += formatex(msg[len],maxlen - len,"%L ^4---^1",id,"STATS_RANK")
				}
				else
				{
					new level_str[AES_MAX_LEVEL_LENGTH ]
					new player_level = aes_get_player_level(id)
					aes_get_level_name(player_level,level_str,charsmax(level_str),id)
					
					len += formatex(msg[len],maxlen - len,"%L ^3%L^1",id,"STATS_RANK",id,"AES_RANK",
						level_str,player_exp
					)
				}
			}
			#endif
			// K:D
			case 'k':
			{
				len += formatex(msg[len],maxlen - len,"%L ^3%.2f^1",
					id,"AES_KS",
					kd_ratio(stats)
				)
			}
			// HS:K
			case 'l':
			{
				len += formatex(msg[len],maxlen - len,"%L ^3%.2f^1",
					id,"AES_HSK",
					hsk_ratio(stats)
				)
			}
			// HS effec
			case 'm':
			{
				len += formatex(msg[len],maxlen - len,"%L ^3%.2f^1%%",
					id,"AES_HSP",
					effec_hs(stats)
				)
			}
			#if defined CSSTATSX_SQL
			// время в игре
			case 'n':
			{
				new ot = get_user_gametime(id)
				
				len += formatex(msg[len],maxlen - len,"%L: ^3",id,"AES_TIME")
				len += func_format_ot(ot,msg[len],maxlen - len,id)
				len += formatex(msg[len],maxlen - len,"^1")
			}
			#endif
		}
		
		theChar[0] = 0
		cnt ++
	}
	
	// завершаем всё сообщение скобкой, если была подстановка параметров
	if(cnt)
	{
		len += formatex(msg[len],maxlen - len,")")
	}
	
	return len
}

#if defined CSSTATSX_SQL
func_format_ot(ot,string[],len,idLang = LANG_SERVER)
{
	new d,h,m,s
	
	d = (ot / SECONDS_IN_DAY)
	ot -= (d * SECONDS_IN_DAY)
	h = (ot / SECONDS_IN_HOUR)
	ot -= (h * SECONDS_IN_HOUR)
	m = (ot / SECONDS_IN_MINUTE)
	ot -= (m * SECONDS_IN_MINUTE)
	s = ot
	
	if(d)
	{
		return formatex(string,len,"%L",idLang,"AES_STATS_DESC1",d,h,m)
	}
	else if(h)
	{
		return formatex(string,len,"%L",idLang,"AES_STATS_DESC2",h,m)
	}
	else if(m)
	{
		return formatex(string,len,"%L",idLang,"AES_STATS_DESC3",m)
	}
		
	return formatex(string,len,"%L",idLang,"AES_STATS_DESC4",s)
}
#endif
//
// Формирование окна /rankstats
// 	id - кому показывать
// 	player_id - кого показывать
//
public RankStatsSay(id,player_id){
	// Команда /rankstats выключена
	if(!SayRankStats)
	{
		client_print_color(id,print_team_default,"%L %L",id,"STATS_TAG", id,"DISABLED_MSG")
		
		return PLUGIN_HANDLED
	}
	
	if(!is_user_connected(player_id))
	{
		client_print_color(id,print_team_default,"%L %L",id,"STATS_TAG",id,"AES_STATS_INFO2")
		
		return PLUGIN_HANDLED
	}
	
	new len,motd_title[MAX_NAME_LENGTH]
	new name[MAX_NAME_LENGTH],rank,stats[8],bh[8],stats_num,Float:skill,skill_id,skill_str[64]
	
	#if defined CSSTATSX_SQL
		new stats3[STATS3_END]
		get_user_stats3_sql(player_id,stats3)
	#endif
	
	theBuffer[0] = 0
	
	formatex(motd_title,charsmax(motd_title),"%L",id,"RANKSTATS_TITLE")
	
	len += formatex(theBuffer[len],BUFF_LEN-len,"%L",id,"AES_META")
	len += formatex(theBuffer[len],BUFF_LEN-len,"%L",id,"AES_STYLE")
	
	#if defined CSSTATSX_SQL
		rank = get_user_stats_sql(player_id,stats,bh)
		stats_num = get_statsnum_sql()
		get_user_skill(player_id,skill)
	#else
		rank = get_user_stats(player_id,stats,bh)
		stats_num = get_statsnum()
		skill = effec(stats)
	#endif
	
	skill_id = aes_statsx_get_skill_id(skill)
	
	
	if(id == player_id)
	{
		formatex(name,charsmax(name),"%L",id,"AES_YOU")
	}
	else
	{
		get_user_name(player_id,name,charsmax(name))
	}
	
	switch(get_pcvar_num(cvar[CVAR_MOTD_SKILL_FMT]))
	{
		// html
		case 0:
		{
			formatex(skill_str,charsmax(skill_str),"%L",
				id,
				"AES_SKILL_FMT",
				
				g_skill_class[skill_id],
				skill
			)
		}
		// буква (скилл)
		case 1:
		{
			formatex(skill_str,charsmax(skill_str),"%s (%.2f)",
				g_skill_letters[skill_id],
				skill
			)
		}
		// буква
		case 2:
		{
			formatex(skill_str,charsmax(skill_str),"%s",
				g_skill_letters[skill_id]
			)
		}
		// скилл
		case 3:
		{
			formatex(skill_str,charsmax(skill_str),"%.2f",
				skill
			)
		}
	}
	
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<table cellspacing=10 cellpadding=0><tr>")
	
	new bool:is_wstats = false
	
	#if defined CSSTATSX_SQL
		is_wstats = (get_user_wstats_sql(player_id,0,stats,bh) == -1) ? false : true
	#endif
	
	//
	// Общая статистика
	//
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<td valign=top width=%d%% class=q><table cellspacing=0><tr><th colspan=2>",
		is_wstats ? 40 : 50
	)
	
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"%L",
		id,"AES_RANKSTATS_TSTATS",
		name,rank,stats_num
	)
	
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=q><td>%L<td>%d (%L %d (%.2f%%))",id,"AES_KILLS",stats[STATS_KILLS],id,"AES_HS",stats[STATS_HS],effec_hs(stats))
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=b><td>%L<td>%d (%L %.2f)",id,"AES_DEATHS",stats[STATS_DEATHS],id,"AES_KS",kd_ratio(stats))
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=q><td>%L<td>%d",id,"AES_HITS",stats[STATS_HITS])
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=b><td>%L<td>%d",id,"AES_SHOTS",stats[STATS_SHOTS])
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=q><td>%L<td>%d",id,"AES_DMG",stats[STATS_DAMAGE])
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=b><td>%L<td>%.2f%%",id,"AES_ACC",accuracy(stats))
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=q><td>%L<td>%.2f%%",id,"AES_EFF",effec(stats))
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=b><td>%L<td>%s",id,"AES_SKILL",skill_str)
	
	#if !defined CSSTATSX_SQL
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=q><td height=18px><td>")
	#else
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=q><td>%L<td>",id,"AES_TIME")
		len += func_format_ot(
			get_user_gametime(player_id),
			theBuffer[len],charsmax(theBuffer)-len,
			id
		)
		
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=b><td>%L<td>%d",id,"CSXSQL_JOINS",stats3[STATS3_CONNECT])
		
		/*
		new from = get_systime() - get_user_lastjoin_sql(player_id)
		new from_str[40]
		get_time_length(id,from,timeunit_seconds,from_str,charsmax(from_str))
		
		len += formatex(theBuffer[len],charsmax(theBuffer)-len," (%L. %s %L)",
			id,"LAST",
			from_str,
			id,"AGO"
		)
		*/
		
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=q><td>%L<td>%d (%L, %L)",id,"CSXSQL_ROUNDS",
			(stats3[STATS3_ROUNDT] + stats3[STATS3_ROUNDCT]),
			id,"CSXSQL_AS_T",stats3[STATS3_ROUNDT],
			id,"CSXSQL_AS_CT",stats3[STATS3_ROUNDCT]
		)
		
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=b><td>%L<td>%d (%L, %L)",id,"CSXSQL_WINS",
			(stats3[STATS3_WINT] + stats3[STATS3_WINCT]),
			id,"CSXSQL_AS_T",stats3[STATS3_WINT],
			id,"CSXSQL_AS_CT",stats3[STATS3_WINCT]
		)
		
		new firstjoin = get_user_firstjoin_sql(player_id)
		
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=q><td>%L<td>",id,"CSXSQL_FIRSTJOIN")
		
		if(firstjoin > 0)
		{
			len += format_time(theBuffer[len],charsmax(theBuffer)-len,"%m/%d/%Y - %H:%M:%S",firstjoin)
		}
		else
		{
			len += formatex(theBuffer[len],charsmax(theBuffer)-len,"-")
		}
	#endif
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"</td></tr></table></td>")
	
	#if !defined CSSTATSX_SQL
		//
		// Статистика по попаданиям
		//
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<td valign=top width=50%% class=q><table cellspacing=0><tr><th colspan=2>")
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"%L",id,"AES_RANKSTATS_THITS")
			
		new theSwitcher
			
		for (new i = 1; i < 8; i++)
		{
			len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=%s><td>%L<td>%d",
				theSwitcher ? "b" : "q",
				id,BODY_PART[i],bh[i]
			)
				
			theSwitcher = theSwitcher ? false : true
		}
		
		
		// mne tak nadoel etot kod :(
		for(new i = 0 ; i < 2; ++i){
			len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=%s><td height=18px><td>",theSwitcher ? "b" : "q")
				
			theSwitcher = theSwitcher ? false : true
		}
		
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"</td>")
	#else
		// статистика по оружию выключена
		if(!is_wstats)
		{
			//
			// Статистика по попаданиям
			//
			len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<td valign=top width=50%% class=q><table cellspacing=0><tr><th colspan=2>")
			len += formatex(theBuffer[len],charsmax(theBuffer)-len,"%L",id,"AES_RANKSTATS_THITS")
				
			new theSwitcher
				
			for (new i = 1; i < 8; i++)
			{
				len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=%s><td>%L<td>%d",
					theSwitcher ? "b" : "q",
					id,BODY_PART[i],bh[i]
				)
					
				theSwitcher = theSwitcher ? false : true
			}
			
			
			// mne tak nadoel etot kod :(
			for(new i = 0 ; i < 5; ++i){
				len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=%s><td height=18px><td>",theSwitcher ? "b" : "q")
					
				theSwitcher = theSwitcher ? false : true
			}
			
			len += formatex(theBuffer[len],charsmax(theBuffer)-len,"</td>")
		}
		else
		{
			//
			// Статистика по используемому оружию
			//
			len += formatex(theBuffer[len],BUFF_LEN-len,"<td valign=top width=60%% class=q><table cellspacing=0 width=100%%><tr><th>%L<th>%L<th>%L<th>%L<th>%L<th>%L<th>%L",
				id,"AES_WEAPON",
				id,"AES_KILLS",
				id,"AES_DEATHS",
				id,"AES_HITS",
				id,"AES_SHOTS",
				id,"AES_DMG",
				id,"AES_ACC"
			)
				
			new bool:odd
			new wpn_stats[9],Array:wpn_stats_array = ArrayCreate(sizeof wpn_stats)
				
			for (new wpnId = 1,max_w = xmod_get_maxweapons_sql() ; wpnId < max_w ; wpnId++)
			{
				if (get_user_wstats_sql(player_id, wpnId, stats,bh))
				{
					wpn_stats[0] = stats[0]
					wpn_stats[1] = stats[1]
					wpn_stats[2] = stats[2]
					wpn_stats[3] = stats[3]
					wpn_stats[4] = stats[4]
					wpn_stats[5] = stats[5]
					wpn_stats[6] = stats[6]
					wpn_stats[7] = stats[7]
					wpn_stats[8] = wpnId
					
					ArrayPushArray(wpn_stats_array,wpn_stats)
				}
			}
			
			// сортируем по кол-ву убийств
			ArraySort(wpn_stats_array,"Sort_WeaponStats")
			
			for(new lena,i,wpnId,wpnName[MAX_NAME_LENGTH],length = ArraySize(wpn_stats_array) ; i < length && charsmax(theBuffer)-len > 0; i++)
			{
				ArrayGetArray(wpn_stats_array,i,wpn_stats)
				
				wpnId = wpn_stats[8]
				stats[0] = wpn_stats[0]
				stats[1] = wpn_stats[1]
				stats[2] = wpn_stats[2]
				stats[3] = wpn_stats[3]
				stats[4] = wpn_stats[4]
				stats[5] = wpn_stats[5]
				stats[6] = wpn_stats[6]
				stats[7] = wpn_stats[7]
				
				xmod_get_wpnname(wpnId,wpnName,charsmax(wpnName))
				
				lena = len
					
				len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=%s><td>%s<td>%d<td>%d<td>%d<td>%d<td>%d<td>%0.1f%%",
					odd ? "b" : "q",
					wpnName,
					stats[STATS_KILLS],
					stats[STATS_DEATHS],
					stats[STATS_HITS],
					stats[STATS_SHOTS],
					stats[STATS_DAMAGE],
					accuracy(stats)
				)
				
				// LENA FIX
				if(len >= BUFF_LEN)
				{
					len = lena
					theBuffer[len] = 0
					
					break
				}
						
				odd ^= true
			}
			
			ArrayDestroy(wpn_stats_array)
		}
	#endif
	
	show_motd(id,theBuffer,motd_title)
	
	return PLUGIN_HANDLED
}

#if defined CSSTATSX_SQL
	public Sort_WeaponStats(Array:array, item1, item2)
	{
		new wpn_stats1[9],wpn_stats2[9]
		ArrayGetArray(array,item1,wpn_stats1)
		ArrayGetArray(array,item2,wpn_stats2)
		
		if(wpn_stats1[0] > wpn_stats2[0])
		{
			return -1
		}
		else if(wpn_stats1[0] < wpn_stats2[0])
		{
			return 1
		}
		
		return 0
	}
#endif


//
// Личная статистка за карту
// 
// id - кому показывать
// stId - кого показывать
public StatsMeSay(id,player_id){
	if(!SayStatsMe){
		client_print_color(id,0,"%L %L",id,"STATS_TAG", id,"DISABLED_MSG")
		
		return PLUGIN_HANDLED
	}
	
	new len,stats[8],bh[8],motd_title[64]
	
	formatex(motd_title,charsmax(motd_title),"%L",id,"STATS_TITLE")
	
	if(id != player_id){
		new name[32]
		get_user_name(player_id,name,charsmax(name))
	}
	
	theBuffer[0] = 0
	
	get_user_wstats(player_id,0,stats,bh)
	
	len += formatex(theBuffer[len],BUFF_LEN-len,"%L%L",id,"AES_META",id,"AES_STYLE")
	len += formatex(theBuffer[len],BUFF_LEN-len,"%L",id,"AES_STATS_BODY")
	
	len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<table cellspacing=10 cellpadding=0><tr>")
	
	len += formatex(theBuffer[len],BUFF_LEN-len,"<td valign=top width=20%% class=q><table cellspacing=0 width=100%%><tr><th colspan=2>%L<tr><td>%L<td>%d<tr class=b><td>%L<td>%d<tr><td>%L<td>%d<tr class=b><td>%L<td>%d<tr><td>%L<td>%d<tr class=b><td>%L<td>%d<tr><td>%L<td>%0.2f%%<tr class=b><td>%L<td>%0.2f%%</table>",
		id,"AES_STATS_HEADER1",
		id,"AES_KILLS",stats[STATS_KILLS],
		id,"AES_HS",stats[STATS_HS],
		id,"AES_DEATHS",stats[STATS_DEATHS],
		id,"AES_HITS",stats[STATS_HITS],
		id,"AES_SHOTS",stats[STATS_SHOTS],
		id,"AES_DMG",stats[STATS_DAMAGE],
		id,"AES_ACC",accuracy(stats),
		id,"AES_EFF",effec(stats))
		
	len += formatex(theBuffer[len],BUFF_LEN-len,"<td valign=top width=80%% class=q><table cellspacing=0 width=100%%><tr><th>%L<th>%L<th>%L<th>%L<th>%L<th>%L<th>%L",
		id,"AES_WEAPON",
		id,"AES_KILLS",
		id,"AES_DEATHS",
		id,"AES_HITS",
		id,"AES_SHOTS",
		id,"AES_DMG",
		id,"AES_ACC"
	)
		
	new bool:odd
		
	for (new wpnName[32],wpnId = 1 ; wpnId < xmod_get_maxweapons() && charsmax(theBuffer)-len > 0 ; wpnId++)
	{
		if (get_user_wstats(player_id, wpnId, stats,bh))
		{
			xmod_get_wpnname(wpnId,wpnName,charsmax(wpnName))
			
			len += formatex(theBuffer[len],charsmax(theBuffer)-len,"<tr id=%s><td>%s<td>%d<td>%d<td>%d<td>%d<td>%d<td>%0.1f%%",
				odd ? "b" : "q",
				wpnName,
				stats[STATS_KILLS],
				stats[STATS_DEATHS],
				stats[STATS_HITS],
				stats[STATS_SHOTS],
				stats[STATS_DAMAGE],
				accuracy(stats)
			)
				
			odd ^= true
		}
	}
		
	show_motd(id,theBuffer,motd_title)
	
	return PLUGIN_HANDLED
}

// Формирование окна /top
// В Pos указывается с какой позиции рисовать
public SayTop(id,Pos)
{
	if(!SayTop15){
		client_print_color(id,0,"%L %L",id,"STATS_TAG", id,"DISABLED_MSG")
		
		return PLUGIN_HANDLED
	}
	
	if(Pos == 15 || Pos <= 0)
		Pos = 10
		
	#if defined CSSTATSX_SQL
		if(!get_stats_sql_thread(id,Pos,MAX_TOP,"SayTopHandler"))
		{
			client_print_color(id,print_team_red,"%L %L",id,"STATS_TAG",id,"AES_STATS_INFO1")
		}
	#else
		SayTopHandler(id,Pos)
	#endif
	
	return PLUGIN_HANDLED
}

enum _:stats_former_array
{
	STATSF_NAME[MAX_NAME_LENGTH],
	STATSF_AUTHID[30],
	STATSF_DATA[8],
	STATSF_DATA2[4],
	STATSF_BH[8],
	STATSF_RANK
	
	#if defined CSSTATSX_SQL
	,STATSF_OT
	#endif
}

//
// Сбор статистики
//
public SayTopHandler(id,Pos)
{
	new Array:stats_array = ArrayCreate(stats_former_array)
	new stats_info[stats_former_array],last_rank
	
	#if defined CSSTATSX_SQL
		new size = min(get_statsnum_sql(),Pos)
	#else
		new size = min(get_statsnum(),Pos)
	#endif
	
	#if defined AES
		new Array:authids_array = ArrayCreate(sizeof stats_info[STATSF_AUTHID])
	#endif
	
	new rank,stats[8],stats2[4],bh[8],name[MAX_NAME_LENGTH],authid[30]
	
	for(new i = size - MAX_TOP < 0 ? 0 : size - MAX_TOP; i < size ; i++){
		#if defined CSSTATSX_SQL
			rank = get_stats_sql(i,stats,bh,name,charsmax(name),authid,charsmax(authid))
			get_stats2_sql(i,stats2)
			get_stats_gametime(i,stats_info[STATSF_OT])
		#else
			rank = get_stats(i,stats,bh,name,charsmax(name),authid,charsmax(authid))
			get_stats2(i,stats2)
		#endif
		
		if(!rank)
			rank = last_rank
			
		for(new i ; i < 8 ; i++)
		{
			stats_info[STATSF_DATA][i] = stats[i]
			stats_info[STATSF_BH][i] = bh[i]
		}
		
		for(new i ; i < 4 ; i++)
		{
			stats_info[STATSF_DATA2][i] = stats2[i]
		}
		
		copy(stats_info[STATSF_NAME],
			charsmax(stats_info[STATSF_NAME]),
			name
		)
		
		copy(stats_info[STATSF_AUTHID],
			charsmax(stats_info[STATSF_AUTHID]),
			authid
		)
		
		last_rank = rank
		stats_info[STATSF_RANK] = rank
		
		// формируем статистику
		ArrayPushArray(stats_array,stats_info)
		
		#if defined AES
			ArrayPushString(authids_array,authid)
		#endif
	}
	
	new stats_data[2]
	
	stats_data[0] = _:stats_array
	
	#if defined AES
		stats_data[1] = _:authids_array
		
		if(!ArraySize(authids_array) || !aes_find_stats_thread(id,authids_array,"SayTopFormer",stats_data,sizeof stats_data))
		{
			new Array:empty_aes_stats = ArrayCreate()
			SayTopFormer(id,empty_aes_stats,stats_data)
		}
	#else
		SayTopFormer(id,stats_data)
	#endif
}

aes_statsx_get_skill_id(Float:skill)
{	
	for(new i ; i < sizeof g_skill_opt ; i++)
	{
		if(skill < g_skill_opt[i])
		{
			return i
		}
	}
	
	return (sizeof g_skill_opt - 1)
}

#if defined AES
	Float:aes_search_exp_in_stats(Array:aes_stats_array,stats_size,name[],authid[],&level)
	{
		for(new i,aes_stats[aes_stats_struct] ; i < stats_size ; i++)
		{
			ArrayGetArray(aes_stats_array,i,aes_stats)
			level = aes_stats[AES_S_LEVEL]
			
			switch(aes_track_mode)
			{
				case 0:
				{
					if(strcmp(aes_stats[AES_S_NAME],name,1) == 0)
					{
						return aes_stats[AES_S_EXP]
					}
				}
				case 1:
				{
					if(strcmp(aes_stats[AES_S_STEAMID],authid,1) == 0)
					{
						return aes_stats[AES_S_EXP]
					}
				}
				case 2:
				{
					if(strcmp(aes_stats[AES_S_IP],authid,1) == 0)
					{
						return aes_stats[AES_S_EXP]
					}
				}
			}
			
		}
		
		return -1.0
	}
#endif

#if !defined AES
public SayTopFormer(id,stats_data[])
#else
public SayTopFormer(id,Array:aes_stats_array,stats_data[])
#endif
{
	theBuffer[0] = 0
	
	new Array:stats_array = Array:stats_data[0]
	
	new len,title[64]
	formatex(title,charsmax(title),"%L",id,"AES_PLAYER_TOP")
	
	// заголовок
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"AES_META")
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"AES_STYLE")
	len += formatex(theBuffer[len],BUFF_LEN - len,"%L",id,"AES_TOP_BODY",id,"AES_PLAYER_TOP")
	
	// таблица со статистикой
	new stats_info[stats_former_array],row_str[512],cell_str[MAX_NAME_LENGTH * 3],row_len
	new desc_str[10],desc_char[4],bool:odd
	
	get_pcvar_string(cvar[CVAR_MOTD_DESC],desc_str,charsmax(desc_str))
	trim(desc_str)
	
	new desc_length = strlen(desc_str)
	new skill_out = get_pcvar_num(cvar[CVAR_MOTD_SKILL_FMT])
	
	len += parse_top_desc_header(id,theBuffer,BUFF_LEN,len,false,desc_str)
	
	#if defined AES
		new aes_stats_size = ArraySize(aes_stats_array)
		new aes_last_iter
	#endif
	
	for(new stats_index,length = ArraySize(stats_array);stats_index < length; stats_index ++){
		ArrayGetArray(stats_array,stats_index,stats_info)
		
		for(new desc_index ; desc_index < desc_length ; desc_index++)
		{
			cell_str[0] = 0
			desc_char[0] = desc_str[desc_index]
			
			switch(desc_char[0]){
				// ранк
				case '*':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats_info[STATSF_RANK])
				}
				// ник
				case 'a':
				{
					formatex(cell_str,charsmax(cell_str),"%s",stats_info[STATSF_NAME])
					
					replace_all(cell_str,charsmax(cell_str),"<","&lt")
					replace_all(cell_str,charsmax(cell_str),">","&gt")
				}
				// убийства
				case 'b':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats_info[STATSF_DATA][STATS_KILLS])
				}
				// смерти
				case 'c':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats_info[STATSF_DATA][STATS_DEATHS])
				}
				// попадания
				case 'd':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats_info[STATSF_DATA][STATS_HITS])
				}
				// выстрелы
				case 'e':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats_info[STATSF_DATA][STATS_SHOTS])
				}
				// хедшоты
				case 'f':
				{
					formatex(cell_str,charsmax(cell_str),"%d",stats_info[STATSF_DATA][STATS_HS])
				}
				// точнсть
				case 'g':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						accuracy(stats_info[STATSF_DATA])
					)
				}
				// эффективность
				case 'h':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						effec(stats_info[STATSF_DATA])
					)
				}
				
				// скилл
				case 'i':{
					new Float:skill ,skill_id
					
					#if defined CSSTATSX_SQL
						// используем скилл из csstatsx sql (ELO)
						get_skill(stats_info[STATSF_RANK] - 1,skill)
					#else
						// используем K:D для скилла
						skill = effec(stats_info[STATSF_DATA])
					#endif
					
					skill_id =  aes_statsx_get_skill_id(skill)
					
					switch(skill_out)
					{
						// html
						case 0:
						{
							formatex(cell_str,charsmax(cell_str),"%L",
								id,
								"AES_SKILL_FMT",
								
								
								g_skill_class[skill_id],
								skill
							)
						}
						// буква (скилл)
						case 1:
						{
							formatex(cell_str,charsmax(cell_str),"%s (%.2f)",
								g_skill_letters[skill_id],
								skill
							)
						}
						// буква
						case 2:
						{
							formatex(cell_str,charsmax(cell_str),"%s",
								g_skill_letters[skill_id]
							)
						}
						// скилл
						case 3:
						{
							formatex(cell_str,charsmax(cell_str),"%.2f",
								skill
							)
						}
					}
					
					
					
					
				}
				#if defined AES
				// опыт и ранг
				case 'j':
				{
					new level = 0
					new Float:exp = -1.0
					
					if(aes_stats_size)
						exp = aes_search_exp_in_stats(aes_stats_array,aes_stats_size,stats_info[STATSF_NAME],stats_info[STATSF_AUTHID],level)
					
					// не нашли стату aes для этого игрока
					if(exp == -1.0)
					{
						// расчитываем на основе статы cstrike
						new stats[8],stats2[4]
						
						// кек
						for(new i ; i < 8 ; i++)
						{
							stats[i] = stats_info[STATSF_DATA][i]
						}
						
						for(new i ; i < 4 ; i++)
						{
							stats2[i] = stats_info[STATSF_DATA2][i]
						}
						
						new Float:exp = aes_get_exp_for_stats_f(stats,stats2)
						
						if(exp != -1.0)
						{
							new level = aes_get_exp_level(exp)
							
							new level_str[AES_MAX_LEVEL_LENGTH]
							aes_get_level_name(level,level_str,charsmax(level_str),id)
							
							formatex(cell_str,charsmax(cell_str),"%L",
								id,"AES_RANK",
								level_str,
								exp + 0.005
							)
						}
						else // расчет по стате выключен
						{
							formatex(cell_str,charsmax(cell_str),"-")
						}
					}
					else
					{
						new level_str[AES_MAX_LEVEL_LENGTH]
						aes_get_level_name(level,level_str,charsmax(level_str),id)
						
						formatex(cell_str,charsmax(cell_str),"%L",
							id,"AES_RANK",
							level_str,
							exp + 0.005
						)
						
						aes_last_iter ++
					}
				}
				#endif
				// K:D
				case 'k':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f",
						kd_ratio(stats_info[STATSF_DATA])
					)
				}
				// HS:K
				case 'l':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f",
						hsk_ratio(stats_info[STATSF_DATA])
					)
				}
				// HS effec
				case 'm':
				{
					formatex(cell_str,charsmax(cell_str),"%.2f%%",
						effec_hs(stats_info[STATSF_DATA])
					)
				}
				#if defined CSSTATSX_SQL
				// время в игре
				case 'n':
				{
					new ot = stats_info[STATSF_OT]
					func_format_ot(ot,cell_str,charsmax(cell_str),id)
				}
				#endif
				default: continue
			}
			
			// выводим отформатированные данные
			row_len += formatex(row_str[row_len],charsmax(row_str)-row_len,"%L",id,"AES_BODY_CELL",cell_str)
		}
		
		row_len = 0
		
		len += formatex(theBuffer[len],charsmax(theBuffer)-len,"%L",id,"AES_BODY_ROW",odd ? " id=b" : " id=q",row_str)
		odd ^= true
	}
	
	ArrayDestroy(stats_array)
	
	#if defined AES
		ArrayDestroy(Array:stats_data[1])
		ArrayDestroy(aes_stats_array)
	#endif
	
	show_motd(id,theBuffer,title)
}

// Stats formulas
Float:accuracy(izStats[])
{
	if (!izStats[STATS_SHOTS])
		return (0.0)
	
	return (100.0 * float(izStats[STATS_HITS]) / float(izStats[STATS_SHOTS]))
}

Float:effec(izStats[])
{
	if (!izStats[STATS_KILLS])
		return (0.0)
	
	return (100.0 * float(izStats[STATS_KILLS]) / float(izStats[STATS_KILLS] + izStats[STATS_DEATHS]))
}

Float:effec_hs(stats[])
{
	if (!stats[STATS_KILLS])
		return float(stats[STATS_HS])
	
	return (100.0 * float(stats[STATS_HS]) / float(stats[STATS_KILLS] + stats[STATS_HS]))
}

Float:kd_ratio(stats[])
{
	if(!stats[STATS_DEATHS])
	{
		return float(stats[STATS_KILLS])
	}
	
	return float(stats[STATS_KILLS]) / float(stats[STATS_DEATHS])
}

Float:hsk_ratio(stats[])
{
	if(!stats[STATS_KILLS])
	{
		return float(stats[STATS_HS])
	}
	
	return float(stats[STATS_HS]) / float(stats[STATS_KILLS])
}


// Формируем заголовок таблицы для топа игроков
parse_top_desc_header(id,buff[],maxlen,len,bool:isAstats,desc_str[]){
	new tmp[256],len2,theChar[4],lCnt
	
	lCnt = isAstats != true ? strlen(desc_str) : 0//strlen(aStatsDescCap)
	
	for(new i ; i < lCnt ; ++i){
		theChar[0] = isAstats != true ? desc_str[i] : desc_str[i]//aStatsDescCap[i]
		
		switch(theChar[0]){
			case '*':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_POS")
			}
			case 'a':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_PLAYER")
			}
			case 'b':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_KILLS")
			}
			case 'c':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_DEATHS")
			}
			case 'd':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_HITS")
			}
			case 'e':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_SHOTS")
			}
			case 'f':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_HS")
			}
			case 'g':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_ACC")
			}
			case 'h':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_EFF")
			}
			case 'i':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_SKILL")
			}
			#if !defined NO_AES
			case 'j':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_ARMYRANKS")
			}
			#endif
			case 'k':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_KS")
			}
			case 'l':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_HSK")
			}
			case 'm':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_HSP")
			}
			#if defined CSSTATSX_SQL
			case 'n':{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"AES_TIME")
			}
			case 'p':
			{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"CSXSQL_DATE")
			}
			case 'o':
			{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"CSXSQL_SKILLCHANGE")
			}
			case 'q':
			{
				len2 += formatex(tmp[len2],charsmax(tmp)-len2,"%L",id,"AES_HEADER_CELL","",id,"CSXSQL_MAP")
			}
			#endif
		}
		
		theChar[0] = 0
	}
	
	return formatex(buff[len],maxlen-len,"%L",id,"AES_TOP_HEADER_ROW",tmp)
}

// формирование меню для просмотра статистики игроков
public ShowStatsMenu(id,page){
	if(!SayStatsAll){
		client_print_color(id,0,"%L %L",id,"STATS_TAG", id,"DISABLED_MSG")
		
		return PLUGIN_HANDLED
	}
	
	new menuKeys,menuText[512],menuLen
	new tName[42],players[32],pCount
	
	get_players(players, pCount)
	
	new maxPages = ((pCount - 1) / STATS_MENU_PERPAGE) + 1 // находим макс. кол-во страниц
	
	// отображаем с начала, если такой страницы не существует
	if(page > maxPages)
		page = 0

	// начальный индекс игрока согласно странице
	new usrIndex = (STATS_MENU_PERPAGE * page)
	
	menuLen += formatex(menuText[menuLen],MENU_LEN - 1 - menuLen,"%L %L\R\y%d/%d^n",
		id,"MENU_TAG",id,"MENU_TITLE",page + 1,maxPages)
	
	// добавляем игроков в меню
	while(usrIndex < pCount){
		get_user_name(players[usrIndex],tName, charsmax(tName))
		menuKeys |= (1 << usrIndex % STATS_MENU_PERPAGE)
		
		menuLen += formatex(menuText[menuLen],MENU_LEN - 1 - menuLen,"^n\r%d.\w %s",
			(usrIndex % STATS_MENU_PERPAGE) + 1,tName)
			
		g_MenuStatus[id][(usrIndex % STATS_MENU_PERPAGE) + 2] = players[usrIndex]
		
		usrIndex ++
		
		// перываем заполнение
		// если данная страница уже заполнена
		if(!(usrIndex % STATS_MENU_PERPAGE))
			break
	}
	
	// вариант просмотра статистики
	
	switch(g_MenuStatus[id][STATS_MENU_ACTION])
	{
		case 0:menuLen += formatex(menuText[menuLen],MENU_LEN - 1 - menuLen,"^n^n\r%d.\w %L",8,id,"MENU_RANK")
		case 1: menuLen += formatex(menuText[menuLen],MENU_LEN - 1 - menuLen,"^n^n\r%d.\w %L",8,id,"MENU_STATS")
		#if defined CSSTATSX_SQL
		case 2: menuLen += formatex(menuText[menuLen],MENU_LEN - 1 - menuLen,"^n^n\r%d.\w %L",8,id,"CSXSQL_SETITLE")
		#endif
	
	}
	
	menuKeys |= MENU_KEY_8
	
	if(!(usrIndex % STATS_MENU_PERPAGE)){
		menuLen += formatex(menuText[menuLen],MENU_LEN - 1 - menuLen,"^n^n\r%d.\w %L",9,id,"MORE")
		menuKeys |= MENU_KEY_9
	}
	
	if((STATS_MENU_PERPAGE * page)){
		menuLen += formatex(menuText[menuLen],MENU_LEN - 1 - menuLen,"^n^n\r%d.\w %L",0,id,"BACK")
		menuKeys |= MENU_KEY_0
	}else{
		menuLen += formatex(menuText[menuLen],MENU_LEN - 1 - menuLen,"^n^n\r%d.\w %L",0,id,"EXIT")
		menuKeys |= MENU_KEY_0
	}
			
	
	show_menu(id,menuKeys,menuText,-1,"Stats Menu")
	
	return PLUGIN_HANDLED
}

public actionStatsMenu(id,key){
	switch(key){
		case 0..(STATS_MENU_PERPAGE - 1):{
			new selected_player = g_MenuStatus[id][key + 2]
			
			if(!is_user_connected(selected_player)){
				ShowStatsMenu(id,g_MenuStatus[id][STATS_MENU_PAGE])
				
				return PLUGIN_HANDLED
			}
			
			switch(g_MenuStatus[id][STATS_MENU_ACTION])
			{
				case 0: RankStatsSay(id,selected_player)
				case 1: StatsMeSay(id,selected_player)
				#if defined CSSTATSX_SQL
				case 2: SeStats_Show(id,selected_player)
				#endif
			}
			
			ShowStatsMenu(id,g_MenuStatus[id][STATS_MENU_PAGE])
		}
		case 7:{
			g_MenuStatus[id][STATS_MENU_ACTION] ++
			#if defined CSSTATSX_SQL
			if(g_MenuStatus[id][STATS_MENU_ACTION] > 2)
				g_MenuStatus[id][STATS_MENU_ACTION] = 0
			#else
			if(g_MenuStatus[id][STATS_MENU_ACTION] > 1)
				g_MenuStatus[id][STATS_MENU_ACTION] = 0
			#endif
			
			ShowStatsMenu(id,g_MenuStatus[id][STATS_MENU_PAGE])
		}
		case 8:{
			g_MenuStatus[id][STATS_MENU_PAGE] ++
			ShowStatsMenu(id,g_MenuStatus[id][STATS_MENU_PAGE])
		}
		case 9:{
			if(g_MenuStatus[id][STATS_MENU_PAGE]){
				g_MenuStatus[id][1] --
				ShowStatsMenu(id,g_MenuStatus[id][STATS_MENU_PAGE])
			}
		}
	}
	
	return PLUGIN_HANDLED
}
C++
При заходе на сервер при прописи /top15 пишет только одного игрока в списке, если кто то подключается то он заносится в список. После перезахода на сервер происходит обнуление игроков, но в бд все нормально, игроки есть около 60, а в игре показывает только себя.
 
В этой теме было размещено решение! Перейти к решению.

Вложения

Сообщения
1,536
Реакции
2,327
Помог
39 раз(а)
qweasdzxc, смотрите в CSstatsX, как у вас заданы настройки сохранения статистика игрока
 
Сообщения
4
Реакции
0
Tranquillity,
// This file was auto-generated by AMX Mod X (v1.9.0.5249)
// Cvars for plugin "CSStatsX SQL" by "serfreeman1337" (csstatsx_sql.amxx, v0.7.4+2)


// Plugin version
// Do not edit this cvar
// -
// Default: "0.7.4+2"
csstatsx_sql "0.7.4+2"

// MySQL host
// -
// Default: "localhost"
csstats_sql_host "secret"

// MySQL user
// -
// Default: "root"
csstats_sql_user "secret"

// MySQL user password
// -
// Default: ""
csstats_sql_pass "secret"

// DB Name
// -
// Default: "amxx"
csstats_sql_db "secret"

// Table name
// -
// Default: "csstats"
csstats_sql_table "csstats"

// Database type
// mysql - MySQL
// sqlite - SQLite
// -
// Default: "mysql"
csstats_sql_type "mysql"

// Auto create tables
// 0 - don't send create table query
// 1 - send create table query on map load
// -
// Default: "1"
csstats_sql_create_db "1"

// How to update player stats in db
// -2 - on death and disconnect
// -1 - on round end and disconnect
// 0 - on disconnect
// higher than 0 - every n seconds and disconnect
// -
// Default: "-1"
csstats_sql_update "-1"

// Enable own forwards for client_death, client_damage
// 0 - disable
// 1 - enable. required if you want replace csx module
// -
// Default: "0"
csstats_sql_forwards "0"

// How to rank player
// 0 - kills- deaths - tk
// 1 - kills
// 2 - kills + hs
// 3 - skill
// 4 - online time
// -
// Default: "0"
csstats_sql_rankformula "0"

// Skill formula
// 0 - The ELO Method
// -
// Default: "0"
csstats_sql_skillformula "0"

// Enable weapon stats (/rankstats)
// 0 - disable
// 1 - enable
// This will create new table csstats_weapons in your database
// NOTE: table will be created only if you set cvar csstats_sql_create_db to 1
// -
// Default: "0"
csstats_sql_weapons "0"

// Enable player session stats (/sestats)
// 0 - disable
// 1 - enable
// NOTE: you need to import csstats_maps.sql
// Check install instructions
// -
// Default: "0"
csstats_sql_maps "0"

// Number of inactive days after which player's stats will be retested. (prune function)
// -
// Default: "0"
csstats_sql_autoclear "150"

// Cache option
// -1 - enabled
// 0 - disabled
// NOTE: Doesn't work with csstats_sql_update -2 or 0
// -
// Default: "-1"
csstats_sql_cachetime "0"

// Full stats reset in specified day of month
// -
// Default: "0"
csstats_sql_autoclear_day ""

// Minimum damage to count assist
// 0 - disable this feature
// -
// Default: "50"
csstats_sql_assisthp "50"
 
Сообщения
1,375
Реакции
2,409
Помог
58 раз(а)
Кол-во игроков отражает переменная statsnum в плагине csstatsx_sql.sma
Можно пройтись поиском по коду, и посмотреть, где она упоиминается. Как я вижу, она:
1) Выставляется в актуальное значение при загрузке игрока, уже имеющегося в БД (т.е. когда такой игрок зашёл)
2) Увеличивается на 1 единицу когда новый игрок пишется в БД
3) Ну и собственно используется в нативах, один из которых как раз участвует в формировании топа.

Отсюда и баг. Когда карта сменилась/сервер перезапустился, то пока не зайдёт уже имеющийся в БД игрок, актуального значения плагин не знает, и потому выводит только одного игрока (+ вновь зашедшие новички).

Как лечить? Можно для запроса инициализации таблицы (SQL_INITDB) добавить выборку кол-ва записей.
Попробуйте приложенный исходник. Квар csstats_sql_create_db должен быть равен 1.

serfreeman1337
 

Вложения

Последнее редактирование:
Сообщения
4
Реакции
0
BlackSignature, вылезла ошибка при компилировании:

//// csstatsx_sql.sma
//
// D:\ForCS 1.6\Server\cstrike\addons\amxmodx\scripting\csstatsx_sql.sma(3152) :
error 088: number of arguments does not match definition
//
// 1 Error.
// Could not locate output file D:\ForCS 1.6\Server\cstrike\addons\amxmodx\scrip
ting\compiled\csstatsx_sql.amx (compile failed).
//
 
Сообщения
1,375
Реакции
2,409
Помог
58 раз(а)
qweasdzxc, перезалил исходник, попробуйте
 
Сообщения
4
Реакции
0
BlackSignature, спасибо тебе за помощь! около 3 дней матался с этой проблемой , попроси скриптера csstatsx_sql перезалить исходник а то люди так и будут искать решение и не все найдут!
 
Статус
В этой теме нельзя размещать новые ответы.

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу