here is my version (works with both sqlite and mysql, configuration in amxmodx/configs/sql.cfg):
PHP Code:
#include <amxmodx>
#include <hamsandwich>
#include <sqlx>
enum ELevelDefinition{
ELD_name[32],
ELD_kills
}
new const g_levels[][ELevelDefinition] ={
{"Newbie", 0},
{"Veteran",9},
{"Pro",6},
{"Semi-Pro",3}
}
new g_sort[sizeof g_levels]
#define _GenerateUserId() (_pg_last_userid = (_pg_last_userid+1)%0xffffff)
new _pg_last_userid
#define _Set(%1,%2) %1|=1<<%2
#define _UnSet(%1,%2) %1&=~(1<<%2)
#define _Is(%1,%2) (%1&1<<%2)
new _in_server, _authed, _loaded
new g_max_players
new g_p_kills[33]
new g_p_level[33]
new g_p_local_userid[33]
new Trie:gt_chat
new Handle:g_sql_tuple
new g_sql_ready
public plugin_init(){
register_plugin("SQL Rank Mod", "1.0", "Sylwester")
g_max_players = get_maxplayers()
RegisterHam(Ham_Killed, "player", "Player_KilledPost", 1)
register_message(get_user_msgid("SayText"), "msg_SayText")
for(new i,j ; i<sizeof g_levels; j=++i){
while(--j>=0 && g_levels[g_sort[j]][ELD_kills] > g_levels[i][ELD_kills]){
g_sort[j+1] = g_sort[j]
}
g_sort[j+1] = i
}
gt_chat = TrieCreate()
TrieSetCell(gt_chat, "#Cstrike_Chat_All", 1)
TrieSetCell(gt_chat, "#Cstrike_Chat_AllDead", 2)
TrieSetCell(gt_chat, "#Cstrike_Chat_T", 3)
TrieSetCell(gt_chat, "#Cstrike_Chat_T_Dead", 4)
TrieSetCell(gt_chat, "#Cstrike_Chat_CT", 5)
TrieSetCell(gt_chat, "#Cstrike_Chat_CT_Dead", 6)
TrieSetCell(gt_chat, "#Cstrike_Chat_Spec", 7)
TrieSetCell(gt_chat, "#Cstrike_Chat_AllSpec", 8)
set_task(0.2, "sql_init")
}
public sql_init(){
g_sql_tuple = SQL_MakeStdTuple()
new type[15]
get_cvar_string("amx_sql_type", type, sizeof(type)-1)
SQL_SetAffinity(type)
new cache[] = "CREATE TABLE IF NOT EXISTS `kills_counter` (`authid` VARCHAR(35) PRIMARY KEY, `kills` INTEGER);"
SQL_ThreadQuery(g_sql_tuple, "qh_create_table", cache)
}
public qh_create_table(FailState,Handle:Query,Error[],Errcode,Data[],DataSize){
if(FailState){
log_amx("SQL Error (qh_create_table): %s", Error)
set_task(10.0, "sql_init")
return
}
g_sql_ready = true
for(new id=1; id<=g_max_players; id++)
if(_Is(_in_server, id) && _Is(_authed, id))
Player_Load(id)
}
public client_connect(id){
g_p_local_userid[id] = _GenerateUserId()
_UnSet(_authed, id)
}
public client_authorized(id){
if(is_user_bot(id) || is_user_hltv(id))
return
_Set(_authed, id)
if(_Is(_in_server, id))
Player_Load(id)
}
public client_putinserver(id){
g_p_level[id] = 0
g_p_kills[id] = 0
_Set(_in_server, id)
if(_Is(_authed, id))
Player_Load(id)
}
public client_disconnect(id){
Player_Save(id)
_UnSet(_authed, id)
_UnSet(_in_server, id)
_UnSet(_loaded, id)
}
public Player_KilledPost(victim, attacker){
if(victim==attacker || !(1<=attacker<=g_max_players))
return
g_p_kills[attacker]++
if(g_p_level[attacker]+1<sizeof(g_levels) && g_levels[g_sort[g_p_level[attacker]+1]][ELD_kills] <= g_p_kills[attacker])
g_p_level[attacker]++
}
public Player_Load(id){
if(!g_sql_ready)
return
new authid[36]
get_user_authid(id, authid, sizeof(authid)-1)
new cache[128]
formatex(cache, sizeof(cache)-1, "SELECT `kills` FROM `kills_counter` WHERE `authid`='%s';", authid)
new data[2]
data[0] = id
data[1] = g_p_local_userid[id]
SQL_ThreadQuery(g_sql_tuple, "qh_Player_Load", cache, data, 2)
}
public qh_Player_Load(FailState,Handle:Query,Error[],Errcode,Data[],DataSize){
new id = Data[0]
if(!_Is(_in_server, id) || g_p_local_userid[id] != Data[1])
return
if(FailState){
log_amx("SQL Error (qh_Player_Load): %s", Error)
set_task(10.0, "Player_Load", id)
return
}
_Set(_loaded, id)
if(!SQL_MoreResults(Query))
return
g_p_kills[id] = SQL_ReadResult(Query, 0)
new level
do{
level++
}while(level < sizeof(g_levels) && g_levels[g_sort[level]][ELD_kills] <= g_p_kills[id])
g_p_level[id] = level-1
}
public Player_Save(id){
if(!_Is(_loaded, id))
return
new authid[36]
get_user_authid(id, authid, sizeof(authid)-1)
new cache[128]
formatex(cache, sizeof(cache)-1, "REPLACE INTO `kills_counter` (`authid`,`kills`)VALUES('%s','%d');", authid, g_p_kills[id])
SQL_ThreadQuery(g_sql_tuple, "qh_Player_Save", cache)
}
public qh_Player_Save(FailState,Handle:Query,Error[],Errcode,Data[],DataSize){
if(FailState){
log_amx("SQL Error (qh_Player_Save): %s", Error)
return
}
}
public msg_SayText(msg_id, msg_dest, msg_ent){
static name[32], cache[256], pos, chat_id
get_msg_arg_string(2, cache, 255)
if(!TrieGetCell(gt_chat, cache, chat_id))
return PLUGIN_CONTINUE
new id = get_msg_arg_int(1)
get_user_name(id, name, 31)
switch(chat_id){
case 1: pos = formatex(cache, sizeof(cache)-1, "^1")
case 2: pos = formatex(cache, sizeof(cache)-1, "^1*DEAD* ")
case 3: pos = formatex(cache, sizeof(cache)-1, "^1(Terrorist) ")
case 4: pos = formatex(cache, sizeof(cache)-1, "^1*DEAD*(Terrorist) ")
case 5: pos = formatex(cache, sizeof(cache)-1, "^1(Counter-Terrorist) ")
case 6: pos = formatex(cache, sizeof(cache)-1, "^1*DEAD*(Counter-Terrorist) ")
case 7: pos = formatex(cache, sizeof(cache)-1, "^1(Spectator) ")
case 8: pos = formatex(cache, sizeof(cache)-1, "^1*SPEC* ")
}
pos += formatex(cache[pos], sizeof(cache)-1, "^4[%s] ^3%s^1: ", g_levels[g_sort[g_p_level[id]]][ELD_name], name)
get_msg_arg_string(4, cache[pos], sizeof(cache)-pos)
set_msg_arg_string(4, "")
cache[191] = 0
set_msg_arg_string(2, cache)
return PLUGIN_CONTINUE
}