/* AMXMODX script.
*
* (c) Copyright 2004, =NoNaMe= (denver@dataline.ru)
* This file is provided as is (no warranties).
*
*  = AntiMat System by NoNaMe v 0.98 optimized =
*
* Что уже было и есть сейчас:
*  0.98optJJ - (Версия от JohnJ) Позволил себе изменить некоторые вещи:
*			    - Заменяется не сам мат а всё сообщение (это даёт возможность
*				найти мат используя меньше вариантов в матлисте, да и анализ
				фразы более быстр)
*			    - Наказания, по-моему, в таком случае становятся не нужны, 
*				поэтому по умолчанию они все отключены
*			    - Теперь антимат может слапать не отнимая здоровья (c повреждением 0)
*			    - Исправлено сравнение с исключениями (например если матом 
*				в матлисте являются все слова, содержащие "e6", то исключением
*				будет "xle6" и т.п. (т.е. начинаются слова с разных позиций 
*				в строке)
*  1.00RC1-Изменения: - добавлен новый алгоритм поиска ругательств (подстановка
*                       пробелов, подмена букв)
*                     - добавлен cvar antimat_old <0:1> по умолчанию 0 для испо-
*                       льзования старого метода поиска матов (для слабых машин)
*                     - antimat_menu - добавлено меню для упращения настройки
*                       AntiMat-a
*  0.98 optimized - оптимизированная версия (текущая):
*                     - antimat_update теперь - обновление базы данных проводится
*                       вручную (авто убрано для снижения аппаратных затрат)
*                     - amx_matlist заменено на antimat_matlist и больше не пере-
*                       гружает базу
*                     - Добавлено предупреждение о включённой защите чистоты
*                       языка, за это отвечает cvar antimat_logo <0:1> по умолча-
*                       нию 0
*
*  0.96 -  Изменения: - добавлен antimat_say <1:0> (по умолчанию 1) - вкл/выкл
*                                команды say
*
*  0.95 -  Изменения: - добалены cvar-ы:
*                              - antimat_cor <1:0> (по умолчанию 1) - вкл/выкл
*                                наказания
*                              - antimat_ip <1:0> (по умолчанию 1) - вкл/выкл
*                                показ IP при конекте игрока
*                              - antimat_name <1:0> (по умолчанию 1) - вкл/выкл
*                                проверку имени игрока на плохие слова
*                     - больше не нужен стороний плагин one_name.amx, работает
*                       самостоятельно  
*
*  0.8  -  Изменения: - добавлена проверка имени игрока на ругань
*                     - Анонс входа игрока с показанием его IP - адреса
*
*  0.6  -  Изменения: - добавлен словарь исключение, база исключений обновляется
*                       без перезагрузки сервера
*                     - добавлен CVAR antimat_dmoney < money > - отнимает деньги
*                       за каждый мат у мёртвых
*
*  0.4  -  Изменения: - убран глюк с заеданием слэпа!
*                     - убран глюк с отниманием денег у мёртвых! теперь отнимает
*                       беспроблемно
*
*  0.3  -  Изменения: - добавлен штраф за ругательства
*                   - мёртвые тоже наказываются
*                   - antimat_slap < healths > - отимает за каждый мат
*                     здоровье ( по умолчанию 20 )
*                   - antimat_money < money > - отнимает деньги за мат,
*                     у мёртвых в четырёх кратном размере ( по умолчанию 500$ )
*
*  0.1  -  Первый релиз : - замена ругательств маской
*                         - возможность обновлять базу не перегружая плагин
*                           или сервер
*/

#include <amxmodx>
#include <amxmisc>
#include <cstrike>

#define MAX_WORDS 200

new PLUGIN[]="AHTuMAT"
new AUTHOR[]="=NoNaMe= | JohnJ"
new VERSION[]="0.98optJJ"

// Файлы: маты с их фильтрами и исключения
new mat_base[127] = "addons/amxmodx/configs/antimat_matlist.ini"
new iskl_base[127] = "addons/amxmodx/configs/antimat_iskluch.ini"

// переменные в которых хранятся маты, фильтры, исключения и их количество
new mat[MAX_WORDS][32]
new mask[MAX_WORDS][32]
new iskl[MAX_WORDS][32]
new num_words = 0
new num_iskl = 0
new iskl_flag = 0
new bool:dontcheck[33]

// сравнение с исключениями
comp_iskl( text[], pos )
{
  iskl_flag = 0
  new k,len,i,isk[32]
  for (k=0; k<=num_iskl; k++)
  {
    len=strlen(iskl[k])
    i=containi(text, iskl[k])
    isk=iskl[k]
    if ((i>=0) && (i<=pos) && (i+len>=pos))
    {
     iskl_flag = 1
    }
  }
}

// фильтр базара для команды say
public mat_filter(id)
{
  if (get_cvar_num("antimat_say")==1)
  {
   new said[128], my_money, pos
   new money = get_cvar_num("antimat_money")
   new dmoney = get_cvar_num("antimat_dmoney")
   new slap = get_cvar_num("antimat_slap")
   read_args(said,128)
   new name[32]
   get_user_name(id,name,31)

   for (new i=0; i<=num_words; i++)
   {
       pos = containi(said,mat[i])
       if (pos != -1)
       {
         comp_iskl(said, pos)
         if ( iskl_flag != 1)
         {
           replace(said, 128, said, mask[i])
           if (!is_user_alive(id))
           {
             if (get_cvar_num("antimat_cor")==1)
             {
               my_money = cs_get_user_money(id)
               if (my_money>=dmoney)
                 cs_set_user_money(id, (my_money-dmoney), 1)
               else
                 cs_set_user_money(id, 0, 1)
             }
             client_cmd(id,"say %s",said)
             return PLUGIN_HANDLED
           }
           else
           {
             if (get_cvar_num("antimat_cor")==1)
             {
               my_money = cs_get_user_money(id)
               if (my_money>=money)
                 cs_set_user_money(id, (my_money-money), 1)
               else
                 cs_set_user_money(id, 0, 1)
               if (slap>=0)
               {
                 user_slap(id, slap)
                 client_print(0,print_chat,"** %s 6bIJI oTCJIanaH 3a MaTbI!", name)
               }
             }
             client_cmd(id,"say %s",said)
             return PLUGIN_HANDLED
           }
         }
       }
   }
  }
  return PLUGIN_CONTINUE
}

// фильтр базара для команды say_team
public mat_filter_team(id)
{
   new said[128], my_money
   new money = get_cvar_num("antimat_money")
   new dmoney = get_cvar_num("antimat_dmoney")
   new slap = get_cvar_num("antimat_slap")
   read_args(said,128)
   new name[32]
   get_user_name(id,name,31)

   for (new i=0; i<=num_words; i++)
   {
       new pos = containi(said,mat[i])
       if (pos != -1)
       {
         comp_iskl(said, pos)
         if ( iskl_flag != 1)
         {
           replace(said, 128, said, mask[i])
           if (!is_user_alive(id))
           {
             if (get_cvar_num("antimat_cor")==1)
             {
               my_money = cs_get_user_money(id)
               if (my_money>=dmoney)
                 cs_set_user_money(id, (my_money-dmoney), 1)
               else
                 cs_set_user_money(id, 0, 1)
             }
             client_cmd(id,"say_team %s",said)
             return PLUGIN_HANDLED
           }
           else
           {
             if (get_cvar_num("antimat_cor")==1)
             {
               my_money = cs_get_user_money(id)
               if (my_money>=money)
                 cs_set_user_money(id, (my_money-money), 1)
               else
                 cs_set_user_money(id, 0, 1)
               if (slap!=0)
               {
                 user_slap(id, slap)
                 client_print(0,print_chat,"** %s 6bIJI oTCJIanaH 3a MaTbI!", name)
               }
             }
             client_cmd(id,"say_team %s",said)
             return PLUGIN_HANDLED
           }
         }
       }
   }
   return PLUGIN_CONTINUE
}

// Поиск по новому алгоритму (исключения невидоизменяются!!!)
public search_bad_words(text[])
{
//  new string_word[128]
  // Цикл по мату
//  for (new i=0; i<=num_words; i++)
//  {

//  }
}

// чтение файлов с занесением содержимого в переменные
// ( flag = 0 - читаем исключения, flag >0 - читаем маты с фильтрами )
read_list(filename[], flag)
{
    if (flag > 0)
    {
      // чтение матов и их фильтров
      num_words = 0
      if (file_exists(filename))
      {
        new readdata[64], len, pos = 0
        while (num_words < MAX_WORDS && read_file(filename,pos++,readdata,63,len))
        {
          parse(readdata, mat[num_words], 31, mask[num_words], 31)
          ++num_words
        }
      }
      else log_message("[AntiMat] He Mory Hau*Tu *I*au*JI Co CnucKoM MaToB")
    }
    else
    {
      // чтение слов исключений
      num_iskl = 0
      if (file_exists(filename))
      {
        new readdata[32], len, pos = 0
        while (num_iskl < MAX_WORDS && read_file(filename,pos++,readdata,32,len))
        {
          iskl[num_iskl] = readdata
          ++num_iskl
        }
      }
      else log_message("[AntiMat] He Mory Hau*Tu *I*au*JI Co CnucKoM ucKJII04eHuu*")
    }
    return PLUGIN_CONTINUE
}

// обновление базы
public antimat_update(id,level,cid)
{
    if (!cmd_access(id,level,cid,1))
        return PLUGIN_HANDLED
    read_list(mat_base, 1)
    read_list(iskl_base, 0)
    return PLUGIN_CONTINUE
}

// просмотр фильтруемых слов из консоли сервера
public antimat_matlist(id,level,cid)
{
    if (!cmd_access(id,level,cid,1))
        return PLUGIN_HANDLED
    console_print(id,"Mat/Filter Database^n%-32s %s","Mat","Filter")
    for(new a=0; a<num_words; ++a)
        console_print(id,"%-32s %s", mat[a], mask[a])
    console_print(id,"Total %d",num_words)
    
    console_print(id,"^n%s","Isklucheniay")
    for(new a=0; a<num_iskl; ++a)
        console_print(id,"%s ", iskl[a])
    return PLUGIN_HANDLED
}

public client_putinserver(id)
{
  if (get_cvar_num("antimat_logo")==1)
  {
    set_task(10.0,"dispLogo",id)
  }
  return PLUGIN_CONTINUE
}

public dispLogo(id)
{
  if (get_cvar_num("antimat_logo")==1)
  {
    new name[32], userip[16]
    get_user_name(id,name,31)
    get_user_ip(id,userip,15,1)
    set_hudmessage(140, 0, 0, 0.05, 0.40, 2, 0.1, 4.0, 0.02, 0.02, 2)
    show_hudmessage(id,"[AntiMat] npuBeT %s (%s)", name, userip)
    set_hudmessage(140, 0, 0, 0.05, 0.42, 2, 0.1, 4.0, 0.02, 0.02, 3)
    show_hudmessage(id,"[AntiMat] Ha cepBepe cTouT AHTuMaT")
    set_hudmessage(140, 0, 0, 0.05, 0.44, 2, 0.1, 4.0, 0.02, 0.02, 4)
    show_hudmessage(id,"[AntiMat] HeKoToPbIe MaTbI 3anpeLLjeHbI!")
  }
}

// Проверка имени на плохие слова
public client_connect(id)
{
  if (get_cvar_num("antimat_name")==1)
  {
    new name[32], userip[16]
    get_user_name(id,name,31)
    get_user_ip(id,userip,15,1)
    if (get_cvar_num("antimat_ip")==1)
      client_print(0,print_chat,"** %s (%s) npuKoHHeKTuJIC9! **", name, userip)
    for (new i=0; i<=num_words; i++)
    {
       new pos = containi(name,mat[i])
       if (pos != -1)
       {
         comp_iskl(name, pos)
         if ( iskl_flag != 1)
         {
           if (get_cvar_num("antimat_ip")==1)
             client_print(0,print_chat,"** %s (%s) 6bIJI oTKJII04eH! MaTepLLIuHHoe uM9! **", name, userip)
           client_cmd(id,"echo ** 3anpeLLjeHbI MaTbI B HuKax! **; disconnect")
           return PLUGIN_HANDLED
         }
       }
    }
  }
  return PLUGIN_CONTINUE
}

// запрет смены имени во время игры
public client_infochanged(id)
{
  if (get_cvar_num("antimat_name")==1)
  {
        if (dontcheck[id])
        {
                dontcheck[id] = false
        }
        else if (is_user_connected(id)){
                new newname[32], oldname[32]
                get_user_info(id, "name", newname,31)
                get_user_name(id,oldname,31)
        
                if (!equal(oldname,newname))
                {
                        dontcheck[id] = true
                        for (new i=0; i<=num_words; i++)
                        {
                          new pos = containi(newname,mat[i])
                          if (pos != -1)
                          {
                            comp_iskl(newname, pos)
                            if ( iskl_flag != 1)
                            {
                              client_cmd(id,"echo ** 3anpeLLjeHbI MaTbI B HuKax! **")
                              set_user_info(id,"name",oldname)
                              return PLUGIN_HANDLED
                            }
                          }
                        }
                }
        }
  }
  return PLUGIN_CONTINUE
}

// инициализация плагина и регистрация глобальных CVAR-ов и команд
public plugin_init()
{
    register_plugin(PLUGIN,VERSION,AUTHOR)
    register_clcmd("say","mat_filter")
    register_clcmd("say_team","mat_filter_team")
    register_concmd("antimat_matlist","antimat_matlist",ADMIN_LEVEL_A,"- show mat/filter file")
    register_concmd("antimat_update","antimat_update",ADMIN_LEVEL_A,"- update mat/filter file")
    register_cvar("antimat_money","0")
    register_cvar("antimat_dmoney","0")
    register_cvar("antimat_slap","-1")
    register_cvar("antimat_ip","1")
    register_cvar("antimat_cor","0")
    register_cvar("antimat_name","1")
    register_cvar("antimat_say","1")
    register_cvar("antimat_logo","0")
//    register_cvar("antimat_old","1")
    read_list(mat_base, 1)
    read_list(iskl_base, 0)
}