/* AMX Mod script. 
* 
* (c) Copyright 2003, AlexLG
* This file is provided as is (no warranties). 
* Thanks to OLO for stats.amx
* 
*/

/*
You must have MySQL module for AMX (MetaSmall) and also
the module for the multi-threading : http://djeyl.net/forum/viewtopic.php?t=9393
Here, there are the sql query to create the table :

CREATE TABLE amx_stats (
  id int(11) NOT NULL auto_increment,
  name text NOT NULL,
  frags int(11) NOT NULL default '0',
  deaths int(11) NOT NULL default '0',
  headshots int(11) NOT NULL default '0',
  shots int(11) NOT NULL default '0',
  hits int(11) NOT NULL default '0',
  ratio float NOT NULL default '0',
  date tinytext NOT NULL,
  game_time int(11) NOT NULL default '0',
  wonid int(11) NOT NULL default '0',
  UNIQUE KEY id (id)
) TYPE=MyISAM;



Notes : 
. check $moddir/addons/amx/mysql.cfg for MySQL access configuration 

*/ 

#include <amxmod> 
#include <amxmisc>
#include <mysql>
#include <csstats> 
#include <mthread>

//normal
#define STS_CHNL 	5

#define STS_FLAG2 2 //shows attackers
#define STS_FLAG3 3 //shows victims
#define STS_FLAG4 4 //shows killer
#define STS_FLAG5 5 //displays player stats at the end of map
#define STS_FLAG6 6 //displays top15 at the end of map
#define STS_FLAG7 7 //displays killer hp&ap to victim console and screen

// Say commands
#define STS_FLAG8 8 //displays information about user killer
#define STS_FLAG9 9 //displays players stats and rank
#define STS_FLAG10 10 //displays first 15. players
#define STS_FLAG11 11 //displays user position in rank
#define STS_FLAG12 12 //displays user stats

new killers[33][4]
new klist[33]
new buffor[2048]
new user_position[33]
new bool:user_state[33]
new user_players[33][32]
new body_part[8][] = {"whole body","head","chest","stomach","left arm","right arm","left leg","right leg"}
//fin

new mysql = 0
new mysql_test = 0
new upload_time, upload_min
new last_upload = 0
new temp[10]
new mhost[64], muser[32], mpass[32], mdb[32], merror[256]
new stats_date[32][32]
new stats_frags[32], stats_morts[32], stats_headshots[32], stats_shots[32], stats_hits[32], stats_temps[32]

new top15[2048]

//DEBUT stats normale (sans mysql)
get_attackers(id) {
	new name[32],wpn[32], stats[8],body[8],found=0
	new pos = copy(buffor,2047,"Attackers:^n")
	new amax = get_maxplayers()
	for(new a = 1; a <= amax; ++a){
		if(get_user_astats(id,a,stats,body,wpn,31)){
			found = 1
			if (stats[0])
				format(wpn,31," -- %s",wpn)
			else
				wpn[0] = 0
			get_user_name(a,name,31)
			pos += format(buffor[pos],2047-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[6],stats[5],wpn)
		}
	}
	return found
}

/* build list of victims */
get_victims(id) {
	new name[32],wpn[32], stats[8],body[8],found=0
	new pos = copy(buffor,2047,"Victims:^n")
	new amax = get_maxplayers()
	for(new a = 1; a <= amax; ++a){
		if(get_user_vstats(id,a,stats,body,wpn,31)){
			found = 1
			if (stats[1])
				format(wpn,31," -- %s",wpn)
			else
				wpn[0] = 0
			get_user_name(a,name,31)
			pos += format(buffor[pos],2047-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[6],stats[5],wpn)
		}
	}
	return found
}

/* build list of hita for AV List */
get_hits(id,killer) {
	new stats[8], body[8], pos = 0
	buffor[0] = 0
	get_user_astats(id,killer,stats,body)
	for(new a = 1; a < 8; ++a)
		if(body[a])
			pos += format(buffor[pos],2047-pos,"%s: %d^n",body_part[a],body[a])
}

/* get top 15 */
get_top15(){
	new stats[8], body[8], name[32]
	new pos = copy(buffor,2047,"#   nick                           kills/deaths          hits/shots/headshots^n")
	new imax = get_statsnum()
	if (imax > 15) imax = 15
	for(new a = 0; a < imax; ++a){
		get_stats(a,stats,body,name,31)
		pos += format(buffor[pos],2047-pos,"%2d.  %-28.27s    %d/%d                      %d/%d/%d^n",a+1,name,stats[0],stats[1],stats[5],stats[4],stats[2])
	}
}

/* build list of hits for say hp */
get_myhits(id,killed) {
	new name[32], stats[8], body[8], found = 0
	get_user_name(killed,name,31)
	new pos = format(buffor,2047,"* You hit %s in:",name)
	get_user_vstats(id,killed,stats,body)
	for(new a = 1; a < 8; ++a){
		if(body[a]){
			found = 1
			pos += format(buffor[pos],2047-pos," %s: %d ",body_part[a],body[a])
		}
	}
	return found
}

/* save hits and damage */
public damage_event(id) {
	if (killers[id][0]) {
		klist[id] = 0
		new mode = get_user_flags(0,STS_CHNL)
		if ( mode & (1<<STS_FLAG4) ){
			new name[32], stats[8], body[8], wpn[33], mstats[8], mbody[8]
			get_user_name(killers[id][0],name,31)
			get_user_astats(id,killers[id][0],stats,body,wpn,31)
			get_user_vstats(id,killers[id][0],mstats,mbody)
			set_hudmessage(220,80,0,0.05,0.15,0, 6.0, 12.0, 1.0, 2.0, 1)
			get_hits(id,killers[id][0])
			show_hudmessage(id,"%s killed you with %s^nfrom distance of %.2f meters.^nHe did %d damage to you with %d hit(s)^nand still has %dhp and %dap.^nYou did %d damage to him with %d hit(s).^nHe hits you in:^n%s",
					name,wpn,float(killers[id][3]) * 0.0254,	stats[6],stats[5],		killers[id][1],killers[id][2],
						mstats[6],mstats[5],buffor )
		}
		if ( (mode&(1<<STS_FLAG3)) &&get_victims(id)){
			set_hudmessage(0,80,220,0.55,0.60,0, 6.0, 12.0, 1.0, 2.0, 4)
			show_hudmessage(id,buffor)
		}
		if ( (mode&(1<<STS_FLAG2)) &&get_attackers(id)){
			set_hudmessage(220,80,0,0.55,0.35,0, 6.0, 12.0, 1.0, 2.0, 3)
			show_hudmessage(id,buffor)
		}
	}
}

/* save state at death */
public deathmsg_event() {
	new killer = read_data(1)
	new victim = read_data(2)
	if (killer != victim && killer)	{
		new vorigin[3], korigin[3]
		get_user_origin(victim,vorigin)
		get_user_origin(killer,korigin)
		killers[victim][0] = killer
		killers[victim][1] = get_user_health(killer)
		killers[victim][2] = get_user_armor(killer)
		killers[victim][3] = get_distance(vorigin,korigin)
		if ( get_user_flags(0,STS_CHNL) & (1<<STS_FLAG7) ){
			new name[32], kmsg[128]
			get_user_name(killer,name,31)
			format(kmsg,127,"%s still has %dhp and %dap",name,killers[victim][1],killers[victim][2])
			client_print(victim,print_console,kmsg)
			set_hudmessage(255,255,255,0.02,0.9,2, 1.5, 3.0, 0.02, 5.0, 1)
			show_hudmessage(victim,kmsg)
		}
	}
}

public resethud_event(id) {
	if(klist[id]){
		new mode = get_user_flags(0,STS_CHNL)
		if ((mode&(STS_FLAG3))&&get_victims(id)){
			set_hudmessage(0,80,220,0.55,0.60,0, 6.0, 12.0, 1.0, 2.0, 4)
			show_hudmessage(id,buffor)
		}
		if ((mode&(STS_FLAG2))&&get_attackers(id)){
			set_hudmessage(220,80,0,0.55,0.35,0, 6.0, 12.0, 1.0, 2.0, 3)
			show_hudmessage(id,buffor)
		}
	}
	killers[id][0] = 0
	klist[id] = 1
}

public display_stats(id,dest) {
	new name[32], stats[8], body[8]
	get_user_wstats(id,0,stats,body)
	new pos = format(buffor,2047,"Kills: %d^nDeaths: %d^nDamage: %d^nHits: %d^nShots: %d^n^n",
		stats[0],stats[1],stats[6],stats[5],stats[4])
	for(new a = 1; a < 31; ++a)	{
		if (get_user_wstats(id,a,stats,body)){
			get_weaponname(a,name,31)
			pos += format(buffor[pos],2047-pos,"%s shots: %d  hits: %d  damage: %d  kills: %d  deaths: %d^n",
				name[7],stats[4],stats[5],stats[6],stats[0],stats[1])
		}
	}
	get_user_name(id,name,31)
	show_motd(dest,buffor,name)
	return PLUGIN_CONTINUE
}

public display_rank(id,dest) {
	new name[32], stats[8], body[8]
	new rank_pos = get_user_stats(id,stats,body)
	new pos = format(buffor,2047,"Kills: %d^nDeaths: %d^nDamage: %d^nHits: %d^nShots: %d^n^n",
		stats[0],stats[1],stats[6],stats[5],stats[4])
	pos += format(buffor[pos],2047-pos,"Hits:^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n^n",
		body_part[1],body[1],body_part[2],body[2],body_part[3],body[3],	body_part[4],body[4],
		body_part[5],body[5],body_part[6],body[6],body_part[7],body[7])
	format(buffor[pos],2047-pos,"%s rank is %d of %d",(id==dest)?"Your":"His", rank_pos,get_statsnum())
	get_user_name(id,name,31)
	show_motd(dest,buffor,name)
	return PLUGIN_CONTINUE
}

	
public disp_pplstats(id){
	if ( !(get_user_flags(0,STS_CHNL) & (1<<STS_FLAG9)) ){
		client_print(id,print_chat,"* Server has disabled that option.")
		return PLUGIN_HANDLED
	}
	show_ppl_menu(id,user_position[id]=0)
	return PLUGIN_CONTINUE
}

public action_ppl_menu(id,key){
	switch(key){
	case 7: {
		user_state[id] = !user_state[id]
		show_ppl_menu(id,user_position[id])
	}
	case 8: show_ppl_menu(id,++user_position[id])
	case 9:	show_ppl_menu(id,--user_position[id])
	default:{
		new option = user_position[id] * 7 + key
		new index = user_players[id][option]
		if (is_user_connected(index)){
			if (user_state[id]) {
				if (mysql_test) {
					client_print(id,print_chat,"* This function is not developed in this version.")
				} else {
					display_rank(index,id)
				}
			} else {
				if (mysql_test) {
					display_statsmysql(index,id)
				} else {
					display_stats(index,id)
				}
			}
		}
		show_ppl_menu(id,user_position[id])
		}
	}
	return PLUGIN_HANDLED
}

show_ppl_menu(id,pos){
	if (pos < 0) return PLUGIN_HANDLED
	new menu_body[512], inum, start = pos * 7
	get_players(user_players[id],inum)
	if (start >= inum) start = pos = user_position[id] = 0
	new len = format(menu_body,511,"\yAMX Stats\R%d/%d^n\w^n",pos + 1,((inum/7)+((inum%7)?1:0)))
	new name[32], end = start + 7, keys = (1<<9)|(1<<7)
	if (end > inum) end = inum
	pos = 0
	for(new a = start; a < end; ++a){
		get_user_name(user_players[id][a],name,31)
		keys |= (1<<pos)
		len += format(menu_body[len],511-len,"%d. %s^n\w",++pos,name)
	}
	len += format(menu_body[len],511-len,"^n8. %s^n\w",user_state[id] ? "Show rank" : "Show stats" )
	if (end != inum){
		len += format(menu_body[len],511-len,"^n9. More...^n0. Back")
		keys |= (1<<8)
	}
	else {
		len += format(menu_body[len],511-len,"^n0. Back")
	}
	show_menu(id,keys,menu_body)
	return PLUGIN_HANDLED
}

public avmode(id,level,cid){
	if (!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED
	if (read_argc() < 2){
		new sflags[32]
		get_flags((get_user_flags(0,STS_CHNL)>>2),sflags,31)
		console_print(id,"^"amx_avlist_mode^" is ^"%s^"", sflags)
		return PLUGIN_HANDLED
	}
	new arg[32]
	read_argv(1,arg,31)
	remove_user_flags(0,0x1FFC,STS_CHNL)
	set_user_flags(0,(read_flags(arg)<<2),STS_CHNL)
	console_print(id,"^"amx_avlist_mode^" set to ^"%s^"", arg)
	return PLUGIN_HANDLED
}

//FIN STATS NORMALE


public save_stats() 
{ 

	if (mysql_test)  //si la connexion à la base est ok
	{
		new players[32], num, i
		get_players(players,num)

		for (i=0;i<num;++i)
		{
			if (!is_user_bot(players[i]) || get_cvar_num("amx_stats_bot")==1) 
			{

				new name[32], body[8], stats[8], wonid
				/*petit rappel : tableau stats :
				* 0 - kills
				* 1 - deaths
				* 2 - headshots
				* 3 - teamkilling
				* 4 - shots
				* 5 - hits
				* 6 - damage
				*/
	
				get_user_name(players[i],name,31)
				get_user_wstats(players[i],0,stats,body)
				wonid = get_user_wonid(players[i])
				
				//requetes mysql
				new query[1535]
				format(query,1535,"SELECT * FROM amx_stats where wonid=%d",wonid)
				mysql_query(mysql,query)
				if (mysql_nextrow(mysql) > 0) //si mysql nous renvoie des données, on met à jour
				{
					//par soucis d'optimisation, on récupère ici les données, évitant nb_players requêtes en plus
	
					new fragsstr[32], mortsstr[32], hitsstr[32], shotsstr[32], headshotsstr[32], tempsstr[32], frags, morts
					mysql_getfield(mysql,3,fragsstr,31)
					mysql_getfield(mysql,4,mortsstr,31)
					mysql_getfield(mysql,5,headshotsstr,31)
					mysql_getfield(mysql,6,shotsstr,31)
					mysql_getfield(mysql,7,hitsstr,31)
					mysql_getfield(mysql,9,stats_date[players[i]],31)
					mysql_getfield(mysql,10,tempsstr,31)
					stats_frags[players[i]] = frags = strtonum(fragsstr) + stats[0]
					stats_morts[players[i]] = morts = strtonum(mortsstr) + stats[1]
					stats_hits[players[i]] = strtonum(hitsstr) + stats[5]
					stats_shots[players[i]] = strtonum(shotsstr) + stats[4]
					stats_headshots[players[i]] = strtonum(headshotsstr) + stats[2]
					stats_temps[players[i]] = strtonum(tempsstr)  //addition du temps à rajouter
					new ratio = frags - morts  //on défini le ratio par le nb de frags - le nb de mort
				
					format(query,1535,"UPDATE amx_stats SET name='%s', frags=frags+%d, deaths=deaths+%d, headshots=headshots+%d, shots=shots+%d, hits=hits+%d, ratio='%d', game_time=game_time+%d WHERE wonid=%d",name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio,upload_time,wonid)
					if (mysql_query(mysql,query) > 0)
					{
						//c'est ok, on efface les stats
						server_print("[AMX] Player Update: '%s', frags : %d, deaths : %d, hs : %d, shots : %d, hits : %d, ratio : %d",name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio)
						reset_user_wstats(players[i])
					} else {
						//c pas bon
						mysql_error(mysql,merror,255) 
						server_print("[AMX] Stats MySQL error : could not save the stats of '%s' : '%s'",name,merror)
					}
				} else { //sinon, on crée l'entrée
					new ratio = stats[0] - stats[1]  //on défini le ratio par le nb de frags - le nb de mort
					//on récupère la date et l'heure
					new ctime[64], temps
					get_time("%d/%m/%Y - %H:%M:%S",ctime,63)
					temps = get_user_time(players[i])
		
					//par optimisation, on met ici la récupération des joueurs
					stats_frags[players[i]] = stats[0]
					stats_morts[players[i]] = stats[1]
					stats_hits[players[i]] = stats[5]
					stats_shots[players[i]] = stats[4]
					stats_headshots[players[i]] =stats[2]
					stats_temps[players[i]] = temps
	
					format(query,1535,"INSERT INTO amx_stats SET wonid='%d', name='%s', frags=%d, deaths=%d, headshots=%d, shots=%d, hits=%d, ratio='%d', date='%s', game_time=%d",wonid,name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio,ctime,temps)
					if (mysql_query(mysql,query) > 0)
					{
						//c'est ok, on efface les stats
						server_print("[AMX] New Player : '%s', frags : %d, deaths : %d, hs : %d, shots : %d, hits : %d, ratio : %d, date : %s, time : %d",name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio,ctime,temps)
						reset_user_wstats(players[i])
					} else {
						//c pas bon
						mysql_error(mysql,merror,255) 
						server_print("[AMX] Stats MySQL error : could not save the stats of '%s' : '%s'",name,merror)
					}
				}  //fin de présence dans table
			}  //fin du bot
		}  //fin du for
		server_print("[AMX] Stats MySQL : Stats saved")
		format(temp,9,"%f",get_gametime()) //on enregistre le temps de l'upload
		last_upload = strtonum(temp)
		recup_top15()
	} else {
		mysql_error(mysql,merror,255) 
		server_print("[AMX] Stats MySQL error : could not save the stats : '%s'",merror)
	}
} 

public save_player_stats(tid,params[]) //permet de sauvegarder les stats d'un joueur uniquement (fonction appellé lors de la déconnection du joueur)
{
	new id = params[0]
	new dernier_temps, temp_tps[10]

	if (!is_user_bot(id) || get_cvar_num("amx_stats_bot")==1) 
	{

		new name[32], body[8], stats[8], wonid
		
		get_user_name(id,name,31)
		get_user_wstats(id,0,stats,body)
		wonid = get_user_wonid(id)
		format(temp_tps,9,"%f",get_gametime()) //on récupère le tps de jeux pour vérifier la différence
		dernier_temps = strtonum(temp_tps) - last_upload		

		//requetes mysql
		new query[1535]
		format(query,1535,"SELECT * FROM amx_stats where wonid=%d",wonid)
		mysql_query(mysql,query)
		if (mysql_nextrow(mysql) > 0) //si mysql nous renvoie des données, on met à jour
		{
			//par soucis d'optimisation, on récupère ici les données, évitant nb_players requêtes en plus
			new fragsstr[32], mortsstr[32], frags, morts
			mysql_getfield(mysql,3,fragsstr,31)
			mysql_getfield(mysql,4,mortsstr,31)
			frags = strtonum(fragsstr) + stats[0]
			morts = strtonum(mortsstr) + stats[1]
			new ratio = frags - morts  //on défini le ratio par le nb de frags - le nb de mort
		
			format(query,1535,"UPDATE amx_stats SET name='%s', frags=frags+%d, deaths=deaths+%d, headshots=headshots+%d, shots=shots+%d, hits=hits+%d, ratio='%d', game_time=game_time+%d WHERE wonid=%d",name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio,dernier_temps,wonid)
			if (mysql_query(mysql,query) > 0)
			{
				//c'est ok, on efface les stats
				server_print("[AMX] Update Player : '%s', frags : %d, deaths : %d, hs : %d, shots : %d, hits : %d, ratio : %d, time : %d",name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio,dernier_temps)
				reset_user_wstats(id)
			} else {
				//c pas bon
				mysql_error(mysql,merror,255) 
				server_print("[AMX] Stats MySQL error : could not save the stats of '%s' : '%s'",name,merror)
			}
		} else { //sinon, on crée l'entrée
			new ratio = stats[0] - stats[1]  //on défini le ratio par le nb de frags - le nb de mort
			//on récupère la date et l'heure
			new ctime[64], temps
			get_time("%d/%m/%Y - %H:%M:%S",ctime,63)
			temps = get_user_time(id)
		
			format(query,1535,"INSERT INTO amx_stats SET wonid='%d', name='%s', frags=%d, deaths=%d, headshots=%d, shots=%d, hits=%d, ratio='%d', date='%s', game_time=%d",wonid,name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio,ctime,temps)
			if (mysql_query(mysql,query) > 0)
			{
				//c'est ok, on efface les stats
				server_print("[AMX] New Player : '%s', frags : %d, deaths : %d, hs : %d, shots : %d, hits : %d, ratio : %d, date : %s, time : %d",name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio,ctime,temps)
				reset_user_wstats(id)
			} else {
				//c pas bon
				mysql_error(mysql,merror,255) 
				server_print("[AMX] Stats MySQL error : could not save the stats of '%s' : '%s'",name,merror)
			}
		}  //fin de présence dans table
	} //fin bot
}

public client_disconnect(id)
{
	new params[1]
	params[0] = id
	if (mysql_test) {
		new tid = thread_run("save_player_stats",params,1,"",THREAD_SYSPRIO_NORM,THREAD_QUEUE_LOCAL)
		if(!tid) server_print("[AMX] Stats MySQL error: could not create the thread !") 
		new mess_disco = 0
		while (tid == thread_isvalid(tid))
		{
			if (mess_disco == 0)
			{
				client_print(id,print_chat,"[AMX] Stats MySQL : Please wait, your stats were be saved...")
				mess_disco = 1
			}
		}
		client_print(id,print_chat,"[AMX] Stats MySQL : Saving completed.")
	}
	return PLUGIN_CONTINUE
}

public save_stats_time()
{
	//on va tester ici l'upload time, evite de lancer un thread pour rien
	upload_min = get_cvar_num("amx_stats_mysql_min") //on récupère la valeur de amx_stats_mysql_min

	format(temp,9,"%f",get_gametime()) //on récupère le tps de jeux pour vérifier la différence
	upload_time = strtonum(temp) - last_upload //on calcule la différence depuis le dernier upload
	//server_print("[AMX] Stats MySQL : upload_time : '%d'",upload_time)
		
	if (upload_time > upload_min) 
     	{
		save_stats() 
	}
}

public save_stats_t()
{
	new tid = thread_run("save_stats_time","",0,"",THREAD_SYSPRIO_NORM,THREAD_QUEUE_LOCAL) 
	if(!tid) server_print("[AMX] Stats MySQL error: could not create the thread !") 
}

public save_stats_notime()
{
	new tid = thread_run("save_stats","",0,"",THREAD_SYSPRIO_NORM,THREAD_QUEUE_LOCAL) 
	if(!tid) server_print("[AMX] Stats MySQL error: could not create the thread !") 
}

public recup_top15()
{
	//sauvegarde du top15
	new pos = copy(top15,2047,"#   nick                         frags/deaths        hits/shots/headshots^n")

	new query[1535]
	format(query,1535,"SELECT * FROM amx_stats ORDER BY 'ratio' DESC, 'headshots' DESC")
	mysql_query(mysql,query)
	for(new a = 0; a < 15 && mysql_nextrow(mysql) > 0; ++a)
	{
		new name[32], fragsstr[32], mortsstr[32], hitsstr[32], shotsstr[32], headshotsstr[32]
		new frags, morts, hits, shots, headshots
		mysql_getfield(mysql,2,name,31)
		mysql_getfield(mysql,3,fragsstr,31)
		mysql_getfield(mysql,4,mortsstr,31)
		mysql_getfield(mysql,5,headshotsstr,31)
		mysql_getfield(mysql,6,shotsstr,31)
		mysql_getfield(mysql,7,hitsstr,31)
		frags = strtonum(fragsstr)
		morts = strtonum(mortsstr)
		hits = strtonum(hitsstr)
		shots = strtonum(shotsstr)
		headshots = strtonum(headshotsstr)
		pos += format(top15[pos],2047-pos,"%2d.  %-28.27s    %d/%d                      %d/%d/%d^n",a+1,name,frags,morts,hits,shots,headshots)
	}
}

public recup_stats_t()
{
	new tid = thread_run("recup_stats","",0,"",THREAD_SYSPRIO_LOW,THREAD_QUEUE_LOCAL) 
	if(!tid) server_print("[AMX] Stats MySQL error: could not create the thread !") 
}

public recup_stats() //recup stats pour récupérer les stats au début de la map
{
	//sauvegarde des stats de joueurs
	new i, plstats[32], numstats
	get_players(plstats,numstats)
	for (i=0;i<numstats;++i)
	{
		new name[32], wonid
		get_user_name(plstats[i],name,31)
		wonid = get_user_wonid(plstats[i])
		new query[1535]
		format(query,1535,"SELECT * FROM amx_stats WHERE wonid=%d",wonid)
		mysql_query(mysql,query)
		if (mysql_nextrow(mysql) > 0) //s'il y a des donnée, on stocke
		{
			new fragsstr[32], mortsstr[32], hitsstr[32], shotsstr[32], headshotsstr[32], tempsstr[32]
			mysql_getfield(mysql,3,fragsstr,31)
			mysql_getfield(mysql,4,mortsstr,31)
			mysql_getfield(mysql,5,headshotsstr,31)
			mysql_getfield(mysql,6,shotsstr,31)
			mysql_getfield(mysql,7,hitsstr,31)
			mysql_getfield(mysql,9,stats_date[plstats[i]],31)
			mysql_getfield(mysql,10,tempsstr,31)
			stats_frags[plstats[i]] = strtonum(fragsstr)
			stats_morts[plstats[i]] = strtonum(mortsstr)
			stats_hits[plstats[i]] = strtonum(hitsstr)
			stats_shots[plstats[i]] = strtonum(shotsstr)
			stats_headshots[plstats[i]] = strtonum(headshotsstr)
			stats_temps[plstats[i]] = strtonum(tempsstr)
		}
	}

	//sauvegarde du top15
	new pos = copy(top15,2047,"#   nick                         frags/deaths        hits/shots/headshots^n")

	new query[1535]
	format(query,1535,"SELECT * FROM amx_stats ORDER BY 'ratio' DESC, 'headshots' DESC")
	mysql_query(mysql,query)
	for(new a = 0; a < 15 && mysql_nextrow(mysql) > 0; ++a)
	{
		new name[32], fragsstr[32], mortsstr[32], hitsstr[32], shotsstr[32], headshotsstr[32]
		new frags, morts, hits, shots, headshots
		mysql_getfield(mysql,2,name,31)
		mysql_getfield(mysql,3,fragsstr,31)
		mysql_getfield(mysql,4,mortsstr,31)
		mysql_getfield(mysql,5,headshotsstr,31)
		mysql_getfield(mysql,6,shotsstr,31)
		mysql_getfield(mysql,7,hitsstr,31)
		frags = strtonum(fragsstr)
		morts = strtonum(mortsstr)
		hits = strtonum(hitsstr)
		shots = strtonum(shotsstr)
		headshots = strtonum(headshotsstr)
		pos += format(top15[pos],2047-pos,"%2d.  %-28.27s    %d/%d                      %d/%d/%d^n",a+1,name,frags,morts,hits,shots,headshots)
	}
}

public display_statsmysql(id,dest) 
{
	new tempstats[2048]
	new name[32]

	new heures = stats_temps[id] / 3600
	new minutes = (stats_temps[id] % 3600) / 60
	new secondes = stats_temps[id] % 60
	format(tempstats,2047,"Frags: %d^nDeaths: %d^nHeadshots: %d^nHits: %d^nShots: %d^n^nYou played %d hour(s), %d minute(s) and %d seconde(s) on this server ^nsince %s",
		stats_frags[id],stats_morts[id],stats_headshots[id],stats_shots[id],stats_hits[id],heures,minutes,secondes,stats_date[id])
	get_user_name(id,name,31)
	show_motd(dest,tempstats,name)
	return PLUGIN_CONTINUE
}

public display_top15(id)
{
	if ( !(get_user_flags(0,STS_CHNL) & (1<<STS_FLAG10)) ){
		client_print(id,print_chat,"* Server has disabled that option.")
		return PLUGIN_HANDLED
	}

	if (mysql_test) 
	{
		show_motd(id,top15,"Top 15")
	} else {
		get_top15()
		show_motd(id,buffor,"Top 15")
	}
	return PLUGIN_CONTINUE
}

public disp_stats(id)
{
	if ( !(get_user_flags(0,STS_CHNL) & (1<<STS_FLAG12)) ){
		client_print(id,print_chat,"* Server has disabled that option.")
		return PLUGIN_HANDLED
	}

	if (mysql_test) 
	{
		display_statsmysql(id, id)
	} else {
		display_stats(id,id)
	}
	return PLUGIN_CONTINUE
}

public display_killer(id) {
	if ( !(get_user_flags(0,STS_CHNL) & (1<<STS_FLAG8)) ){
		client_print(id,print_chat,"* Server has disabled that option.")
		return PLUGIN_HANDLED
	}
	if (killers[id][0]) {
		new name[32], stats[8], body[8], wpn[33], mstats[8], mbody[8]
		get_user_name(killers[id][0],name,31)
		get_user_astats(id,killers[id][0],stats,body,wpn,31)
		get_user_vstats(id,killers[id][0],mstats,mbody)
		client_print(id,print_chat,"* %s killed you with %s from distance of %.2f meters",	name,wpn,float(killers[id][3]) * 0.0254 )
		client_print(id,print_chat,"* He did %d damage to you with %d hit(s) and still had %dhp and %dap",
			stats[6],stats[5], killers[id][1],killers[id][2] )
		client_print(id,print_chat,"* You did %d damage to him with %d hit(s)",mstats[6],	mstats[5] )
		if (get_myhits(id,killers[id][0])) client_print(id,print_chat,buffor)
	} else {
		client_print(id,print_chat,"* You have no killer...")
	}
	return PLUGIN_CONTINUE
}

public disp_rank(id)
{
	if ( !(get_user_flags(0,STS_CHNL) & (1<<STS_FLAG11)) ){
		client_print(id,print_chat,"* Server has disabled that option.")
		return PLUGIN_HANDLED
	}

	if (mysql_test) 
	{
		client_print(id,print_chat,"* This function is not developed in this version.")
	} else {
		display_rank(id,id)
	}
	return PLUGIN_CONTINUE
}

public reset_stats()
{
	new players[32], num, i
	get_players(players,num)
	for (i=0;i<num;++i)
	{
		reset_user_wstats(players[i])
	}
}

public end_game()
{
	new mode = get_user_flags(0,STS_CHNL)
	if ( mode & (1<<STS_FLAG5) ){
		new players[32], inum
		get_players(players,inum)
		for(new i = 0; i < inum; ++i)
			display_stats(players[i],players[i])
	}	
	else if ( mode & (1<<STS_FLAG6) )	{
		new players[32], inum
		get_players(players,inum)
		for(new i = 0; i < inum; ++i)
			display_top15(players[i])
	}
}


public intermission_event()
{
	save_stats_t()
	set_task(1.0,"end_game")
}

public init_function()
{
	get_cvar_string("amx_mysql_host",mhost,64) 
	get_cvar_string("amx_mysql_user",muser,32) 
	get_cvar_string("amx_mysql_pass",mpass,32) 
	get_cvar_string("amx_mysql_db",mdb,32)
	mysql=mysql_connect(mhost,muser,mpass,mdb,merror,255)
	
	if (mysql > 0)
	{
		server_print("[AMX] Stats Mysql : Connection established to the database")
		mysql_test = 1
		recup_stats_t() //on récupère les stats des le début, sinon, il faut attendre le demarrage de l'upload
		register_event("RoundTime" ,"save_stats_t" ,"bc")
	} else {
		server_print("[AMX] Stats MySQL error : could not connect to the database : '%s'",merror)
		mysql_test = 0
	}

}

public debug_threads()
{
	new fname[17];
	new cnt,t,tid,r;

	thread_debug();

	server_print("");
	server_print("Thread stats from plugin :");
	server_print(" #  name             run");
	cnt=thread_count();	
	r=0;
	for(t=1;t<=cnt;t++)
	{
		tid = thread_search("",t);
		thread_getname(tid,fname,16);
		server_print("%3d %-16s %s",tid,fname,thread_isrunning(tid)?"yes":"no");
		if(thread_isrunning(tid))
		{
			r++;
		}
	}
	server_print("%d thread(s) (%d running, %d queued)",cnt,r,cnt-r);
	server_print("");

}

public plugin_init() 
{ 
	register_plugin("Stats Mysql WonId","0.7","AlexLG") 
	register_event("30","intermission_event","a")
	register_event("DeathMsg","deathmsg_event","a")
	register_event("ResetHUD","resethud_event","be")
	register_event("Damage","damage_event","b","2!0","3=0","4!0")
	register_clcmd("amx_savestats","save_stats_notime",ADMIN_LEVEL_A,"Save stats on MySQL manualy")
	register_clcmd("amx_resetstats","reset_stats",ADMIN_LEVEL_A,"Reset local stats")
	register_clcmd("say /top15","display_top15",0,"- display the first 15 players")
	register_clcmd("say /statsme","disp_stats",0,"- display your stats")
	register_clcmd("say /stats","disp_pplstats",0,"- display the other stats")
	register_clcmd("say /rank","disp_rank",0,"- display your rank")
	register_clcmd("say /hp","display_killer",0,"- displays info. about your killer")
	register_cvar("amx_mysql_host","127.0.0.1")
	register_cvar("amx_mysql_user","root")
	register_cvar("amx_mysql_pass","")
	register_cvar("amx_mysql_db","amx")
	register_cvar("amx_stats_mysql_min","120")
	register_cvar("amx_stats_bot","0")
	register_srvcmd("amx_avlist_mode","avmode",ADMIN_CFG,"<flags> - sets stats options")
	register_menucmd(register_menuid("\yStats AMX"),1023,"action_ppl_menu")
	server_cmd("amx_addoption ^"Show Attackers^" %d %d",STS_CHNL,STS_FLAG2)	
	server_cmd("amx_addoption ^"Show Victims^" %d %d",STS_CHNL,STS_FLAG3)	
	server_cmd("amx_addoption ^"Show killer^" %d %d",STS_CHNL,STS_FLAG4)
	server_cmd("amx_addoption ^"Stats at the end of map^" %d %d",STS_CHNL,STS_FLAG5)	
	server_cmd("amx_addoption ^"Top15 at the end of map^" %d %d",STS_CHNL,STS_FLAG6)	
	server_cmd("amx_addoption ^"Show killer hp&ap^" %d %d",STS_CHNL,STS_FLAG7)
	server_cmd("amx_addoption ^"Say /hp^" %d %d",STS_CHNL,STS_FLAG8)	
	server_cmd("amx_addoption ^"Say /stats^" %d %d",STS_CHNL,STS_FLAG9)	
	server_cmd("amx_addoption ^"Say /top15^" %d %d",STS_CHNL,STS_FLAG10)
	server_cmd("amx_addoption ^"Say /rank^" %d %d",STS_CHNL,STS_FLAG11)	
	server_cmd("amx_addoption ^"Say /statsme^" %d %d",STS_CHNL,STS_FLAG12)
	server_cmd("exec addons/amx/mysql.cfg")
	set_task(5.0,"init_function")
	return PLUGIN_CONTINUE 
} 

