
/* 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=939
3
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 a
rm","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], sta
ts_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 h
it(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 h
it(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/de
aths          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],stat
s[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], mb
ody[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 distanc
e of %.2f meters.^nHe did %d damage to you with %d hit(s)^nand still has %dhp a
nd %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,kille
rs[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],sta
ts[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":"Hi
s", 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 func
tion 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,((inu
m/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] ? "Sh
ow 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 r 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 wher
e wonid=%d",wonid)
                                mysql_query(mysql,query)
                                if (mysql_nextrow(mysql) > 0) //si mysql nous r
envoie des données, on met r jour
                                {
                                        //par soucis d'optimisation, on récupcr
e ici les données, évitant nb_players requetes 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[playe
rs[i]],31)
                                        mysql_getfield(mysql,10,tempsstr,31)
                                        stats_frags[players[i]] = frags = strto
num(fragsstr) + stats[0]
                                        stats_morts[players[i]] = morts = strto
num(mortsstr) + stats[1]
                                        stats_hits[players[i]] = strtonum(hitss
tr) + stats[5]
                                        stats_shots[players[i]] = strtonum(shot
sstr) + stats[4]
                                        stats_headshots[players[i]] = strtonum(
headshotsstr) + stats[2]
                                        stats_temps[players[i]] = strtonum(temp
sstr)  //addition du temps r 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=sho
ts+%d, hits=hits+%d, ratio='%d', game_time=game_time+%d WHERE wonid=%d",name,st
ats[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 Upda
te: '%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écupcre 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_stat
s 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, da
te : %s, time : %d",name,stats[0],stats[1],stats[2],stats[4],stats[5],ratio,cti
me,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 stat
s : '%s'",merror)
        }
} 

public save_player_stats(tid,params[]) //permet de sauvegarder les stats d'un j
oueur 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écupcre 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",woni
d)
                mysql_query(mysql,query)
                if (mysql_nextrow(mysql) > 0) //si mysql nous renvoie des donné
es, on met r jour
                {
                        //par soucis d'optimisation, on récupcre ici les donnée
s, évitant nb_players requetes 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', frag
s=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 n
ot 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 p
ar le nb de frags - le nb de mort
                        //on récupcre 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 n
ot 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_SYS
PRIO_NORM,THREAD_QUEUE_LOCAL)
                if(!tid) server_print("[AMX] Stats MySQL error: could not creat
e 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 complete
d.")
        }
        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écupcre la valeu
r de amx_stats_mysql_min

        format(temp,9,"%f",get_gametime()) //on récupcre le tps de jeux pour vé
rifier la différence
        upload_time = strtonum(temp) - last_upload //on calcule la différence d
epuis 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,THRE
AD_QUEUE_LOCAL) 
        if(!tid) server_print("[AMX] Stats MySQL error: could not create the th
read !") 
}

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

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

        new query[1535]
        format(query,1535,"SELECT * FROM amx_stats ORDER BY 'ratio' DESC, 'head
shots' 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_QU
EUE_LOCAL) 
        if(!tid) server_print("[AMX] Stats MySQL error: could not create the th
read !") 
}

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",woni
d)
                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[3
2], 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/death
s        hits/shots/headshots^n")

        new query[1535]
        format(query,1535,"SELECT * FROM amx_stats ORDER BY 'ratio' DESC, 'head
shots' 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^n
Shots: %d^n^nYou played %d hour(s), %d minute(s) and %d seconde(s) on this serv
er ^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 distan
ce of %.2f meters",     name,wpn,float(killers[id][3]) * 0.0254 )
                client_print(id,print_chat,"* He did %d damage to you with %d h
it(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,b
uffor)
        } 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écupcre 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 th
e 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)?"ye
s":"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 loca
l stats")
        register_clcmd("say /top15","display_top15",0,"- display the first 15 p
layers")
        register_clcmd("say /statsme","disp_stats",0,"- display your stats")
        register_clcmd("say /stats","disp_pplstats",0,"- display the other stat
s")
        register_clcmd("say /rank","disp_rank",0,"- display your rank")
        register_clcmd("say /hp","display_killer",0,"- displays info. about you
r 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 st
ats 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,S
TS_FLAG5)       
        server_cmd("amx_addoption ^"Top15 at the end of map^" %d %d",STS_CHNL,S
TS_FLAG6)       
        server_cmd("amx_addoption ^"Show killer hp&ap^" %d %d",STS_CHNL,STS_FLA
G7)
        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 
} 
