#include <amxmodx>
#include <amxmisc>
#include <sockets>
/* Dont change */
#define RECVBUF_LEN 4096
#define PENDBUF_LEN 1000
#define ANTIFLOOD_TIMERID 6998
#define IRC_CHECKSOCKID 6996
#define IRC_SENDNEXTID 6997
#define IRC_CHECKSOCKTIMER 0.3
#define VERSION "1.52"
//menu
#define MENU_SIZE 256
#define MENU_PLAYERS 7
///////////////////////
#define MAXIMUM 512
new irc_user[] = "nirc 0 * :reportcheater"; /* IRC USER */
/**************************************************************/
/**************************************************************/
/* Settings below should only be changed if you have problems */
/**************************************************************/
/**************************************************************/
/* Debug settings - Uncomment to enable */
/* debugging is only useful if the bot does not connect. */
//#define IRC_DEBUG /* Show warning's and errors. Useful for debugging connection problems */
//#define IRC_DEBUG2 /*Show all sent/recv'd data. This is _ALOT_. But might help debugging */
/* Various tweaks relating to connecting and antiflood */
/******* If it's not broken, don't change it! **********/
/* Experiment if the bot does not connect */
#define IRC_CONNWAIT 9000000
#define IRC_CONNDELAY 5.0
#define IRC_CONNSTAGE1TIMER 8.0
#define IRC_CONNSTAGE2TIMER 5.0
#define IRC_PERFORMTIMER 5.0
/* Antiflood */
#define IRC_SENDNEXTTIMER 0.8
#define ANTIFLOOD_SECONDS 5
#define ANTIFLOOD_BYTES 1500
#define ANTIFLOOD_LINES 4
/*Advertise*/
#define LISTEN_FREQ 10.0
/* Use (maxplayers*3) pendbufs (Min 20,Max 70)*/
#define PENDBUF_COUNT 30
////////////////////
new antiflood_lines,antiflood_bytes;
new irc_sock, irc_error;
new irc_recv[RECVBUF_LEN+1];
new irc_recvold[RECVBUF_LEN+1];
new irc_pend[PENDBUF_COUNT][PENDBUF_LEN+1];
new irc_nextpend;
new irc_nextsend;
new irc_connected;
new bool:nirc_morelines;
new irc_report_type1,irc_report_type2
new g_iMenuPosition
new g_iMenuPlayers[32]
new g_iMenuOption[32]
new g_iMenuSettings[32]
new irc_server
new irc_port
new irc_mynick
new irc_mychan
new irc_mypass
new irc_identify
new irc_ident
new irc_adv
new irc_adv_freq
new activator
new g_iMaxPlayers
new chan[32]
new listened,listening
new banfile[16]
new configfolder[256]
new output[MAXIMUM][32]
new k = 0
new path [64]
public plugin_init()
{
register_plugin("Report cheater",VERSION,"spHoTt!");
register_cvar("Report_Cheater", "1.52",FCVAR_SERVER)
register_dictionary("reportcheater.txt")
register_dictionary("common.txt")
register_clcmd("say_team", "handle_say")
register_clcmd("say", "handle_say")
register_clcmd ("amx_irc_unban", "unbancmd", ADMIN_KICK, "Unban players from reportcheater service")
irc_server = register_cvar("irc_server","")
irc_mynick = register_cvar("irc_mynick","")
irc_port = register_cvar("irc_port","")
irc_mychan = register_cvar("irc_mychan","")
irc_mypass = register_cvar("irc_mypass","")
irc_identify = register_cvar("irc_identify","0")
irc_ident = register_cvar("irc_ident","",FCVAR_PROTECTED&FCVAR_UNLOGGED)
activator = register_cvar("irc_from_hlds_say_activator","/jelentes")
irc_report_type1 = register_cvar("irc_report_type1","Wh")
irc_report_type2 = register_cvar("irc_report_type2","Aim/speedhack")
register_menucmd(register_menuid("\r[Soldiers] CsaloBejelentese:"),1023,"actionVoteMenu")
register_cvar("irc_clientport","0",FCVAR_PROTECTED&FCVAR_UNLOGGED)
irc_adv_freq = register_cvar ( "irc_adv_freq", "300.0" )
irc_adv = register_cvar("irc_adv","1")
if(get_pcvar_num(irc_adv))
set_task ( Float:30.0, "Advertise", 0 )
remove_task(IRC_CHECKSOCKID);
remove_task(IRC_SENDNEXTID);
register_cvar("nirc_ircsock","0",FCVAR_PROTECTED&FCVAR_UNLOGGED);
irc_sock=get_cvar_num("nirc_ircsock");
get_pcvar_string(irc_mychan,chan,charsmax(chan))
listening = register_cvar("irc_listening","0")
listened = register_cvar("irc_listened","0")
register_cvar("irc_listened_msg","")
if(get_pcvar_num(listening))
set_task ( LISTEN_FREQ, "listen", 0 )
banfile="rcban.ini"
get_configsdir (configfolder, charsmax(configfolder))
format (path, charsmax(path), "%s/%s", configfolder, banfile)
if(!file_exists(path))
{
new writestr[32]
format(writestr,charsmax(writestr),"ReportCheater banfile!!!")
write_file(path,writestr)
}
loadbanlist(0)
irc_nextpend=0;
irc_nextsend=0;
g_iMaxPlayers = get_maxplayers()
if(irc_sock==0)
{
irc_connected=0;
new i;
irc_recvold[0]='^x00';
irc_recv[0] ='^x00';
for(i=0;i<PENDBUF_COUNT;i++)
{
irc_pend[i][0]='^x00';
}
set_task(IRC_CONNDELAY,"irc_connect");
}
else
{
irc_connected=1;
set_task(IRC_CHECKSOCKTIMER,"irc_checksock",IRC_CHECKSOCKID,"",0,"b");
set_task(IRC_SENDNEXTTIMER,"irc_sendnext",IRC_SENDNEXTID,"",0,"b");
set_task(float(ANTIFLOOD_SECONDS),"antiflood_timer",ANTIFLOOD_TIMERID,"",0,"b");
}
}
public actionVoteMenu( id, key )
{
switch( key )
{
case 7:
{
++g_iMenuOption[id]
g_iMenuOption[id] %= 2
switch(g_iMenuOption[id]){
case 0: g_iMenuSettings[id] = 0
case 1: g_iMenuSettings[id] = 1
}
showVoteMenu( id, g_iMenuPosition )
}
case 8:
{
showVoteMenu( id, ++g_iMenuPosition )
}
case 9:
{
showVoteMenu( id, --g_iMenuPosition )
}
default:
{
new id_cheater = g_iMenuPlayers[g_iMenuPosition * MENU_PLAYERS + key]
if(is_user_admin(id)){
if ( g_iMenuSettings[id] ) {
banid(id,id_cheater,"id")
} else
{
unbanid(id,id_cheater,"id")
}
}
else if(!is_user_bot(id_cheater))
{
new authid_cheater[32]
new type[32]
new authid_reporter[32]
new name_cheater[32]
new finalmessage[301], len
new name_reporter[32]
get_user_authid(id_cheater,authid_cheater,charsmax(authid_cheater))
get_user_name(id_cheater,name_cheater,charsmax(name_cheater))
get_user_authid(id,authid_reporter,charsmax(authid_reporter))
get_user_name(id,name_reporter,charsmax(name_reporter))
len = format(finalmessage,300,"PRIVMSG %s : (%s)",chan,authid_reporter)
len += format(finalmessage[len],300-len,"%s",name_reporter)
if(g_iMenuSettings[id]){
get_pcvar_string(irc_report_type1,type,charsmax(type))
}
else
{
get_pcvar_string(irc_report_type2,type,charsmax(type))
}
len += format(finalmessage[len],300-len," %L^n",LANG_SERVER,"IRC_MSG",name_cheater,type,authid_cheater)
format(irc_pend[irc_nextpend],PENDBUF_LEN,"%s",finalmessage)
format(finalmessage,300,"%s %L^n",name_reporter,LANG_SERVER,"IRC_MSG",name_cheater,type,authid_cheater)
irc_incrpend()
sendadmins(finalmessage)
client_print(id,print_chat,"[ReportCheater] %L",LANG_PLAYER,"IRC_REQ2")
}
}
}
return PLUGIN_HANDLED
}
public showVoteMenu( id, pos )
{
if( pos < 0 ) return
new i, j
new szMenuBody[MENU_SIZE]
new iCurrKey = 0
new szUserName[32]
new iStart = pos * MENU_PLAYERS
new iNum
new type[32]
new m_back[16]
new m_exit[16]
new m_more[16]
format( m_back, charsmax(m_back),"%L",LANG_PLAYER,"BACK")
format( m_exit, charsmax(m_exit),"%L",LANG_PLAYER,"EXIT")
format( m_more, charsmax(m_more),"%L",LANG_PLAYER,"MORE")
get_players( g_iMenuPlayers, iNum )
if( iStart >= iNum )
iStart = pos = g_iMenuPosition = 0
new iLen = format( szMenuBody, MENU_SIZE-1, "\r[Soldiers] CsaloBejelentese:\R%d/%d^n\w^n", pos+1, (iNum / MENU_PLAYERS + ((iNum % MENU_PLAYERS) ? 1 : 0 )) )
new iEnd = iStart + MENU_PLAYERS
new iKeys = (1<<9|1<<7)
if( iEnd > iNum )
iEnd = iNum
for( i = iStart; i < iEnd; i++ )
{
j = g_iMenuPlayers[i]
get_user_name( j, szUserName, 32 )
if(( is_user_bot(j) || is_user_admin(j) || id==j ) )
{
iCurrKey++
iLen += format( szMenuBody[iLen], (MENU_SIZE-1-iLen), "\d%d. %s^n\w", iCurrKey, szUserName )
}
else
{
iKeys |= (1<<iCurrKey++)
iLen += format( szMenuBody[iLen], (MENU_SIZE-1-iLen), "%d. %s^n", iCurrKey, szUserName )
}
}
if(is_user_admin(id)){
if ( g_iMenuSettings[id] )
iLen += format( szMenuBody[iLen], (MENU_SIZE-1-iLen), "^n8. BAN^n" )
else
iLen += format( szMenuBody[iLen], (MENU_SIZE-1-iLen), "^n8. UNBAN^n" )
} else {
if(g_iMenuSettings[id]){
get_pcvar_string(irc_report_type1,type,charsmax(type))
}
else
{
get_pcvar_string(irc_report_type2,type,charsmax(type))
}
}
if( iEnd != iNum )
{
format( szMenuBody[iLen], (MENU_SIZE-1-iLen), "^n9. %s...^n0. %s",m_more, pos ? m_back : m_exit )
iKeys |= (1<<8)
}
else
format( szMenuBody[iLen], (MENU_SIZE-1-iLen), "^n0. %s", pos ? m_back : m_exit )
show_menu( id, iKeys, szMenuBody, -1 )
return
}
public handle_say(id)
{
if(irc_connected && !isuserbanned(id,"id"))
{
new msg[256]
new authid[32]
new activat[32]
get_pcvar_string(activator,activat,charsmax(activat))
g_iMenuPosition = 0
read_args(msg,charsmax(msg))
remove_quotes(msg)
if(strlen(msg) <= 0)
return PLUGIN_CONTINUE
new name[32]
get_user_name(id,name,charsmax(name))
if(containi(msg,"/admin") != -1)
{
new finalmessage[301]
replace(msg,charsmax(msg),"/admin","")
get_user_authid(id,authid,charsmax(authid))
format(irc_pend[irc_nextpend],PENDBUF_LEN,"PRIVMSG %s : %L: %s^n",chan,LANG_SERVER,"IRC_REQ",name, authid,msg)
format(finalmessage,300,"%L: %s",LANG_SERVER,"IRC_REQ",name,authid,msg)
irc_incrpend()
sendadmins(finalmessage)
client_print(id,print_chat,"[Soldiers CsaloBejelentese] %L",LANG_PLAYER,"IRC_REQ2")
return PLUGIN_HANDLED
}
else
{
if(containi(msg,activat) == -1)
return 0
else
{
replace(msg,1024,activat,"")
showVoteMenu( id, g_iMenuPosition = 0 )
return PLUGIN_HANDLED
}
}
}
return PLUGIN_CONTINUE;
}
public irc_conn1()
{
#if defined IRC_DEBUG
log_amx("[ReportCheater] irc_conn1() STAGE|SENDNICK")
#endif
new nick[32]
get_pcvar_string(irc_mynick,nick,charsmax(nick))
format(irc_pend[irc_nextpend],PENDBUF_LEN,"NICK %s^n",nick)
irc_incrpend()
set_task(IRC_CONNSTAGE2TIMER,"irc_conn2")
}
public irc_conn2()
{
#if defined IRC_DEBUG
log_amx("[ReportCheater] irc_conn2() STAGE|SENDUSER")
#endif
format(irc_pend[irc_nextpend],PENDBUF_LEN,"USER %s^n",irc_user)
irc_incrpend()
set_task(IRC_PERFORMTIMER,"irc_conn3")
}
public irc_conn3()
{
#if defined IRC_DEBUG
log_amx("[ReportCheater] irc_conn3() STAGE|JOINCHAN")
#endif
new pass[32]
new ident[128]
new nick[32]
get_pcvar_string(irc_mynick,nick,charsmax(nick))
get_pcvar_string(irc_mypass,pass,charsmax(pass))
get_pcvar_string(irc_ident,ident,charsmax(ident))
get_pcvar_string(irc_mychan,chan,charsmax(chan))
if(get_pcvar_num(irc_identify)){
format(irc_pend[irc_nextpend],PENDBUF_LEN,"%s^n",ident)
irc_incrpend()
format(irc_pend[irc_nextpend],PENDBUF_LEN,"MODE %s +x^n",nick)
irc_incrpend();
}
format(irc_pend[irc_nextpend],PENDBUF_LEN,"JOIN %s %s^n",chan,pass)
irc_incrpend();
irc_connected=1
}
/* Yes I am aware this is a bad\ugly way of doing this - but it does work, and doesent bring the server to its knees */
public irc_connect()
{
#if defined DEBUG
log_amx("[ReportCheater] connect() STAGE|CONNECTING");
#endif
new server[64]
get_pcvar_string(irc_server,server,charsmax(server))
irc_sock = socket_open(server, get_pcvar_num (irc_port),SOCKET_TCP,irc_error);
for(new i=0;i<PENDBUF_COUNT;i++)
{
irc_pend[i][0]='^x00';
}
if(irc_sock>0)
{
set_cvar_num("nirc_ircsock",irc_sock);
set_task(IRC_CHECKSOCKTIMER,"irc_checksock",IRC_CHECKSOCKID,"",0,"b");
set_task(IRC_SENDNEXTTIMER,"irc_sendnext",IRC_SENDNEXTID,"",0,"b");
set_task(float(ANTIFLOOD_SECONDS),"antiflood_timer",ANTIFLOOD_TIMERID,"",0,"b");
set_task(IRC_CONNSTAGE1TIMER,"irc_conn1");
}
else
{
#if defined IRC_DEBUG
log_amx("[Soldiers] CsaloBejelentese] ERROR|socket_open (%s:%d)",server,get_pcvar_num (irc_port));
#endif
set_task(50.0,"plugin_init");
//set_task(120.0,"irc_connect");
}
}
public irc_checksock()
{
if(nirc_morelines)
{
nirc_checkrecv();
}
else if(socket_change(irc_sock,1))
{
new l=strlen(irc_recvold);
socket_recv(irc_sock,irc_recvold[l],sizeof(irc_recvold)-2-l);
nirc_checkrecv();
}
}
nirc_checkrecv()
{
new l=strlen(irc_recvold),i,k;
for(i=0;i<l;i++)
{
if(irc_recvold[i]!='^n')
{
irc_recv[i]=irc_recvold[i];
}
else
{
(irc_recv[i-1]=='^r')?(irc_recv[i-1]='^x00'):(irc_recv[i]='^x00');
i++;
l=strlen(irc_recvold[i]);
k=0;
while((k<l)&&(i+k<RECVBUF_LEN-1))
{
irc_recvold[k] = irc_recvold[i+k];
k++;
}
irc_recvold[k] = '^x00';
nirc_morelines=false;
if(irc_parse()==-1)
{
socket_close(irc_sock);
remove_task(IRC_CHECKSOCKID);
remove_task(IRC_SENDNEXTID);
set_cvar_num("nirc_ircsock",0);
set_task(60.0,"irc_connect");
irc_connected=0;
#if defined DEBUG
log_amx("[Soldiers] CsaloBejelentese] ERROR... restart in 60 seconds...");
#endif
}
for(i=0;i<k;i++)
{
if(irc_recvold[i]=='^n')
{
nirc_morelines=true;
nirc_checkrecv();
i=k;
}
}
i=l;
}
}
}
public antiflood_timer()
{
antiflood_bytes = 0;
antiflood_lines = 0;
}
public irc_sendnext()
{
if(irc_pend[irc_nextsend][0]!='^x00')
{
new len = strlen(irc_pend[irc_nextsend]);
if(((len+antiflood_bytes)<ANTIFLOOD_BYTES)&&(antiflood_lines+1<ANTIFLOOD_LINES))
{
#if defined IRC_DEBUG2
log_amx("[Soldiers] CsaloBejelentese] SEND -> %s",irc_pend[irc_nextsend]);
#endif
socket_send(irc_sock,irc_pend[irc_nextsend],strlen(irc_pend[irc_nextsend]));
irc_pend[irc_nextsend][0]='^x00';
irc_nextsend++;
if(irc_nextsend==PENDBUF_COUNT)
{
irc_nextsend = 0;
}
antiflood_bytes+=len;
antiflood_lines++;
}
}
}
/* Yeah... I do things in strange ways... */
irc_parse()
{
#if defined IRC_DEBUG2
log_amx("[ReportCheater] RECV <- %s",irc_recv);
#endif
new i=0//,r=0;
new tmp[4];
if(equali(irc_recv, "ERROR", 5))
{
return -1;
}
if(equali(irc_recv,"PING",4))
{
format(irc_pend[irc_nextpend],PENDBUF_LEN,"PO%s^n",irc_recv[2]);
irc_incrpend();
return 1;
}
while((i<strlen(irc_recv))&&(irc_recv[i]!=' '))i++;
tmp[0]=irc_recv[i+1];
tmp[1]=irc_recv[i+2];
tmp[2]=irc_recv[i+3];
tmp[3]='^x00';
switch(str_to_num(tmp))
{
case 431,432,433:
{
new nick[32]
get_pcvar_string(irc_mynick,nick,charsmax(nick))
format(irc_pend[irc_nextpend],PENDBUF_LEN,"NICK %s-^n",nick);
irc_incrpend();
format(nick,sizeof(nick)-1,"%s-",nick);
#if defined IRC_DEBUG
log_amx("[ReportCheater] WARNING -|- USING ALT_NICK %s",nick);
#endif
}
case 451:
{
format(irc_pend[irc_nextpend],PENDBUF_LEN,"USER %s^n",irc_user);
irc_incrpend();
#if defined IRC_DEBUG
log_amx("[Soldiers] CsaloBejelentese] WARNING -|- RESEND USER");
#endif
}
case 404,442,461:
{
new pass[32]
get_pcvar_string(irc_mypass,pass,charsmax(pass))
get_pcvar_string(irc_mychan,chan,charsmax(chan))
format(irc_pend[irc_nextpend],PENDBUF_LEN,"JOIN %s %s^n",chan,pass);
irc_incrpend();
#if defined IRC_DEBUG
log_amx("[Soldiers] CsaloBejelentese] WARNING -|- REJOIN CHANNEL");
#endif
}
}
return 0;
}
irc_incrpend()
{
irc_nextpend++;
if(irc_nextpend==PENDBUF_COUNT)
{
irc_nextpend=0;
}
}
public sendadmins(msg[]){
for( new i = 1; i <= g_iMaxPlayers ; i++ )
{
if( is_user_admin(i) )
{
client_print(i, print_chat, "[Soldiers] CsaloBejelentese] %s",msg);
}
}
}
public Advertise ( )
{
if(get_pcvar_num(irc_adv)) {
client_print ( 0, print_chat, "%L",LANG_PLAYER,"IRC_ADVERT" )
set_task ( get_pcvar_float ( irc_adv_freq ), "Advertise", 0 )
}
}
public listen ()
{
if(get_pcvar_num(listened)) {
new msg[128]
get_cvar_string("irc_listened_msg",msg,charsmax(msg))
format(irc_pend[irc_nextpend],PENDBUF_LEN,"PRIVMSG %s :%s^n",chan,msg )
sendadmins(msg)
irc_incrpend();
set_pcvar_num(listened,0)
set_cvar_string("irc_listened_msg","")
}
if(get_pcvar_num(listening)) set_task ( LISTEN_FREQ, "listen", 0 )
}
public isuserbanned(g_id,authid_ch[32]){
new g_authid[32]
new i
if(g_id)
get_user_authid(g_id,g_authid,charsmax(g_authid))
else
g_authid=authid_ch
for(i=1;i<k;i++){
if(equal(g_authid,output[i])) return 1
}
return 0
}
public banid(g_id,id_cheater,authid_ch[32]){
if(g_id && isuserbanned(id_cheater,authid_ch)){
client_print(g_id,print_chat,"[ReportCheater] %L",LANG_PLAYER,"IRC_ALREADY_BANNED")
return 0
}
new authid_cheater[32]
if(!g_id){
authid_cheater=authid_ch
}
else
get_user_authid(id_cheater,authid_cheater,charsmax(authid_cheater))
new writestr[33]
format(writestr,charsmax(writestr),"%s",authid_cheater)
new nextline = 0
new rstr[33], fnum, b
while(read_file(path,fnum,rstr,32,b))
{
if(b <= 0)
{
nextline = fnum
break
}
fnum++
}
if(!nextline)
write_file(path,writestr)
else
write_file(path,writestr,nextline)
if(g_id){
client_print(g_id,print_chat,"[ReportCheater] %L",LANG_PLAYER,"IRC_ADDED")
loadbanlist(0)
}
return 1
}
public unbanid(g_id,id_cheater,authid_ch[32]){
if(!isuserbanned(id_cheater,authid_ch)){
if (g_id)client_print(g_id,print_chat,"[ReportCheater] %L",LANG_PLAYER,"IRC_NOTFOUND")
return 0
}
new removed=0,i
new authid_cheater[32]
if(!g_id){
authid_cheater=authid_ch
}
else
get_user_authid(id_cheater,authid_cheater,charsmax(authid_cheater))
if(file_exists ( path))
delete_file ( path )
new writestr[101]
format(writestr,100,"ReportCheater banfile!!!")
write_file(path,writestr)
i=1
while(i<k){
if(!equali(output[i],authid_cheater))
banid(0,0,output[i])
else
removed++
i++
}
if(removed){
if(g_id) client_print(g_id,print_chat,"[ReportCheater] %L",LANG_PLAYER,"IRC_REMOVED")
loadbanlist(removed)
return 1
}
return 0
}
public unbancmd(id)
{
new authid[32]
read_args(authid,32)
trim(authid)
remove_quotes(authid)
if(strlen(authid) <= 0){
client_print(id,print_console,"[ReportCheater] amx_irc_unban <steam_id>")
return PLUGIN_HANDLED
}
if(unbanid(0,0,authid))
client_print(id,print_console,"[ReportCheater] %L",LANG_PLAYER,"IRC_REMOVED")
else
client_print(id,print_console,"[ReportCheater] %L",LANG_PLAYER,"IRC_NOTFOUND")
return PLUGIN_HANDLED
}
public loadbanlist(removed){
new i
new file_handle = fopen (path, "rt+")
new file_text [256]
for(i=0;i<removed+k;i++){
output[i]=""
}
k = 0
while (!feof (file_handle) && k < MAXIMUM) {
fgets (file_handle, file_text, 255)
trim (file_text)
if(!equali(file_text,""))
{
copy (output [k], strlen (file_text), file_text)
}
k++
}
fclose (file_handle)
}