Правила форума Гаранты форума
Размещение рекламы AMX-X компилятор

Здравствуйте, гость Вход | Регистрация

Наши новости:

14-дек
24-апр
10-апр
11-апр

Проблема в скрипте

, задержка на проверку
Статус пользователя nepret
сообщение 6.10.2009, 2:59
Сообщение #1
Стаж: 14 лет

Сообщений: 25
Благодарностей: 3
Полезность: 92

Плагин: Namereg

Краткое описание: Плугин позволяет игроку самостоятельно регистрировать
свое имя, чтобы никто другой не мог им воспользоваться.
Идентификация пользователей происходит путем ввода пароля в консоли
Для административных целей так же ведется лог посещений сервера, где
записываются данные о последнем визите игрока на сервер.

Проблема:
Я предпологаю использовать данный плагин для War3FT MOD (2.3.1), в этой версии есть баг на кражу\удаление чужих акков, данный плагин в принципе защищает, НО, тут стоит долгая проверка на ник (как на вход с чужим ником, так и на смену ника) 2-3 секунды, если зайти на пустой сервер, то можно сразу же выбрать команду, выбрать рассу, сменить ник и выйти, то же самое и при смене ника... грубо говоря дюп на скорость.
Как уменьшить проверку ника до "нуля"?


Код
*/



#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <dbi>


#define MAX_PLAYERS 33

// Уровни доступа
#define REG_ACCESS ADMIN_ALL
#define CHPASSWD_ACCESS ADMIN_ALL
#define LOGIN_ACCESS ADMIN_ALL
#define HELP_ACCESS ADMIN_ALL

//Удаление устаревших записей (в секундах)

//Прочтите примечание ниже, если хотите использовать
//автоматическое удаление устаревших записей пользователей
//По умолчанию автоматическое удаление пользователей
//не разрешено

#define USER_DELETE_TIME 15552000 //6 месяцев

//Лог подключений
//По умолчанию чистится автоматически
#define LOG_DELETE_TIME 604800 //1 неделя

new const PLUGIN_NAME[] = "NameReg"
new const AUTHOR[] = "WEER"
new const VERSION[] = "0.3"

//Поля где хранятся пароли
new const PASSWORD_FIELD[] = "_pswd"

//Для временного хранения предыдущего пароля
//(Нужно если чел залогинился мертвым)
new const PASSWORD_FIELD2[] = "_pswd2"

//Заменять заблкокированные имена на..
new const NAME_BLOCKED[] = "[This name is blocked]"

//Если имя игрока зарегистирированно, а пароль не ввееден
// то заменять имя юзера на...
new const NAME_REGISTERED[] = "[This name is registered]"

//Параметры базы данных
new bool:SQL_CONNECTED = false

new const USER_TABLE[] = "nreg_users"
new const RESERVED_TABLE[] = "nreg_reserved"
new const BLOCKED_TABLE[] = "nreg_blocked"
new const EXCEPTIONS_TABLE[] = "nreg_exceptions"
new const LOG_TABLE[] = "nreg_log"

new Sql:sql
new Result:result

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////

public plugin_init()
    {
    register_plugin(PLUGIN_NAME, VERSION, AUTHOR)
    
    register_concmd("name_reg","consoleRegister",REG_ACCESS," <name> <pass1> <pass2> - Register a player name")
    register_concmd("name_passwd","consoleChpasswd",CHPASSWD_ACCESS," <name> <old_pass2> <new_pass1> <new_pass2> - Change password")
    register_concmd("login","consoleLogin",LOGIN_ACCESS," <name> <pass> - Login (for registered user)")
    register_concmd("logout","consoleLogout",LOGIN_ACCESS," - Logout (for registered user)")
    register_concmd("name_help","consoleHelp",LOGIN_ACCESS," - Displays User Registration help")
    
    set_task(1.0,"sqlInit")
    set_task(2.0,"deleteOldUser")
    
}


public plugin_modules()
    {
    require_module("engine")
    require_module("DBI")
    
}

public sqlInit()
    {
    new host[64],user[32],pass[32],db[32],error[128]
    get_cvar_string("amx_sql_host",host,63)
    get_cvar_string("amx_sql_user",user,31)
    get_cvar_string("amx_sql_pass",pass,31)
    get_cvar_string("amx_sql_db",db,31)
    
    sql = dbi_connect(host,user,pass,db,error,127)
    
    if (sql <= SQL_FAILED)
        {
        log_amx("Failed to connect to SQL")
        return PLUGIN_HANDLED
    }    
    
    log_amx("Name Registration System Online")
    SQL_CONNECTED = true
    return PLUGIN_HANDLED
}


//Удаляет старые данные из базы
public deleteOldUser()
    {
    if (!SQLconnected())
        return PLUGIN_HANDLED
    
    new timestamp = get_systime(0)
    new deletestamp = timestamp - USER_DELETE_TIME
    new deletestamp2 = timestamp - LOG_DELETE_TIME
    
    //Выяснение количества "просроченных" пользователей
    result = dbi_query(sql,"SELECT name FROM `%s` WHERE timestamp < '%i'",USER_TABLE,deletestamp)
    if(result == RESULT_FAILED)
        {
        log_amx("Database ERROR")
        dbi_free_result(result)
        return PLUGIN_HANDLED
    }
    if(result > RESULT_NONE)
        {
        new num_deleted_users = dbi_num_rows(result)
        log_amx("Found %d out of date users in database. These users dont login less then 6 month. Please remove this users manually.",num_deleted_users)
    }
    dbi_free_result(result)
    
    
    
    //Удаление юзеров - достаточно рискованно с учетом того
    //что время можно перевести случайно:)
    //Лучше вручную чистить
    
    //dbi_query(sql,"DELETE FROM `%s` WHERE timestamp < '%i'",USER_TABLE,deletestamp)
    
    //Удаление логов
    //Тут думаю лучше автоматически, так как ценность информации не сильно большая
    dbi_query(sql,"DELETE FROM `%s` WHERE timestamp < '%i'",LOG_TABLE,deletestamp2)
    
    return PLUGIN_HANDLED    
}




//Регистрация имени из консоли
public consoleRegister(id,level,cid)
    {
    if (read_argc() < 3)
        {
        client_print(id,print_console,"Usage: name_reg <name> <password1> <password2>")
        consoleNeed2Pass(id)
        return PLUGIN_HANDLED
    }
    
    if (!SQLconnected())
        return PLUGIN_HANDLED
    if (!cmd_access(id, level, cid, 3))
        return PLUGIN_HANDLED
    
    new name[32], pass[35], pass2[35]
    
    read_argv(1, name, 31)
    read_argv(2, pass, 34)
    read_argv(3, pass2, 34)
    if(equal(name,"") || equal(pass,"") || equal(pass2,"") )
        {
        client_print(id,print_console,"Usage: name_reg <name> <password1> <password2>")
        consoleNeed2Pass(id)
        return PLUGIN_HANDLED
    }
    
    if(equal(pass,pass2))
        {
        client_print(id,print_console,"Usage: name_reg <name> <password1> <password2>")
        consoleNeed2Pass(id)
        return PLUGIN_HANDLED
    }
    
    
    if(exception(name))
        {
        client_print(id,print_console,"This name is reserved for system")
        return PLUGIN_HANDLED
    }
    
    
    if(!validNameMsg(id, name))
        return PLUGIN_HANDLED
    if(!validPassMsg(id, pass))
        return PLUGIN_HANDLED
    if(!validPassMsg(id, pass2))
        return PLUGIN_HANDLED
    
    
    result = dbi_query(sql,"INSERT INTO %s(name, pass, pass2) values('%s','%s','%s')",USER_TABLE, name, pass, pass2)
    if( result == RESULT_FAILED )
        {
        log_amx("Database ERROR")
        client_print(id, print_console, "System error. Please try again later")
        dbi_free_result(result)
        return PLUGIN_HANDLED
    }    
    else
        {
        dbi_free_result(result)
        console_print(id, "***Name ^"%s^" succesfully registered", name)
        completeLogin(id, name, pass)
        return PLUGIN_HANDLED
        
        
    }
    return PLUGIN_HANDLED
}





//Смена пароля из консоли
public consoleChpasswd(id,level,cid)
    {
    if (read_argc() < 4)
        {
        client_print(id,print_console,"Usage: name_passwd <name> <old_pass2> <new_pass1> <new_pass2>")
        consoleNeed2Pass(id)
        return PLUGIN_HANDLED
    }
    
    if (!SQLconnected())
        return PLUGIN_HANDLED
    if (!cmd_access(id, level, cid, 3))
        return PLUGIN_HANDLED
    
    new name[32], old_pass2[35],new_pass[35],new_pass2[35]
    
    read_argv(1, name, 31)
    read_argv(2, old_pass2, 34)
    read_argv(3, new_pass, 34)
    read_argv(4, new_pass2, 34)
    
    if(equal(name,"") || equal(new_pass,"") || equal(new_pass2,"") )
        {
        client_print(id,print_console,"Usage: name_passwd <name> <old_pass2> <new_pass1> <new_pass2>")
        consoleNeed2Pass(id)
        return PLUGIN_HANDLED
    }
    
    if(equal(new_pass,new_pass2))
        {
        client_print(id,print_console,"Usage: name_passwd <name> <old_pass2> <new_pass1> <new_pass2>")
        consoleNeed2Pass(id)
        return PLUGIN_HANDLED
    }
    
    
    result = dbi_query(sql,"SELECT pass2 FROM `%s` WHERE name='%s'",USER_TABLE,name)
    if(result == RESULT_FAILED)
        {
        log_amx("Database ERROR")
        client_print(id, print_console, "System error. Please try again later")
        dbi_free_result(result)
        return PLUGIN_HANDLED
    }
    if (result == RESULT_OK)
        {
        if(dbi_nextrow(result)>0)
            {
            new old_pass2_real[35]
            dbi_field(result,1,old_pass2_real,35)
            dbi_free_result(result)
            if (equal(old_pass2_real,old_pass2))
                {
                result = dbi_query(sql,"UPDATE `%s` SET pass = '%s', pass2 = '%s' WHERE name = '%s'",USER_TABLE, new_pass, new_pass2, name)
                if(result == RESULT_FAILED)
                    {
                    log_amx("Database ERROR")
                    client_print(id, print_console, "System error. Password dont changed! Please try again later")
                    dbi_free_result(result)
                    return PLUGIN_HANDLED
                }                
                dbi_free_result(result)
                client_print(id,print_console,"Password update successfully!")                
                return PLUGIN_HANDLED
            }
            
        }
    }
    else
        {
        dbi_free_result(result)
        console_print(id, "Invalid user/password combination")
        return PLUGIN_HANDLED    
    }
    
    return PLUGIN_HANDLED
    
}


//Логин из консоли
public consoleLogin(id,level,cid)
    {
    
    if (!SQLconnected())
        return PLUGIN_HANDLED
    if (!cmd_access(id, level, cid, 3))
        return PLUGIN_HANDLED
    
    
    new name[32], pass[35]
    read_argv(1, name, 31)
    read_argv(2, pass, 34)
    
    if(!validPassMsg(id, pass))
        return PLUGIN_HANDLED
    
    if (!validName(name))
        {
        console_print(id, "Your name has been blocked. Please contact to admin!")
        return PLUGIN_HANDLED
    }
    
    switch(login(name,pass))
    {
        case 1:
        completeLogin(id, name, pass)
        case -1:
        console_print(id, "Invalid user/password combination")
        default:
        return PLUGIN_HANDLED        
    }
    return PLUGIN_HANDLED
}






//Логаут
public consoleLogout(id,level,cid)
    {
    if (!SQLconnected())
        return PLUGIN_HANDLED
    if (!cmd_access(id, level, cid, 1))
        return PLUGIN_HANDLED
    
    new name[32], pass[35]
    
    get_user_info(id, "name", name, 31)
    get_user_info(id, PASSWORD_FIELD, pass, 34)
    
    if(login(name,pass) > 0)
        {
        set_user_info (id, PASSWORD_FIELD, "")
        console_print(id,"Logout successful")
        return PLUGIN_HANDLED
    }
    else
        {
        console_print(id, "You are not logged in")
    }
    return PLUGIN_HANDLED
}





//Хелпы всякие разные
public consoleHelpMsg(id)
    {
    
    client_print(id,print_console,"This server support name registration system")
    client_print(id,print_console,"If you register your name, nobody exept you will be able to use it")
    client_print(id,print_console,"Console commands:")
    client_print(id,print_console,"name_reg <name> <password1> <password2> - name registration")
    client_print(id,print_console,"name_passwd <name> <old_psswd2> <new_psswd1> <new_psswd2> - change password")
    client_print(id,print_console,"login <name> <password1> - login ")
    client_print(id,print_console,"logout - logout")
    consoleNeed2Pass(id)
    
    return PLUGIN_CONTINUE
}

public consoleNeed2Pass(id)
    {
    
    client_print(id,print_console,"Two passwords (pin and puk code) need for security purpose")
    client_print(id,print_console,"<password1> (pin) - need to login")
    client_print(id,print_console,"This password you can save into your config file")
    client_print(id,print_console,"For example this line save password ^"qwert^":")
    client_print(id,print_console,"setinfo ^"%s^" ^"qwert^"",PASSWORD_FIELD)
    client_print(id,print_console,"<password2> (puk) - need to change password")
    client_print(id,print_console,"DONT SAVE PASSWORD2 INTO YOUR CONFIG FILE!!!^n")
    client_print(id,print_console,"Please use DIFFERENT <password1> and <password2>")
    
    
    return PLUGIN_CONTINUE
}

public consoleHelp(id,level,cid)
    {
    if (!SQLconnected())
        return PLUGIN_HANDLED
    if (!cmd_access(id, level, cid, 1))
        return PLUGIN_HANDLED
    consoleHelpMsg(id)
    return PLUGIN_HANDLED
}






//Отслеживает вход клинта на сервер
public client_putinserver(id)
    {
    if (!SQLconnected())
        return PLUGIN_HANDLED
    
    //Не проверять ботов, прокси и админов с иммунитетом
    if ( (is_user_bot(id)) || (access(id,ADMIN_IMMUNITY)) || is_user_hltv(id))
        return PLUGIN_CONTINUE
    
    new name[32], pass[35]
    
    get_user_info(id,"name", name, 31)
    get_user_info(id, PASSWORD_FIELD, pass, 34)
    
    new current_time[64]
    get_time("%H:%M - %d/%m/%Y",current_time,63)
    new player_ip[32]
    get_user_ip(id,player_ip,32,1)
    new servername[200]
    get_cvar_string("hostname",servername,100)
    new timestamp = get_systime(0)
    new mapname[32]
    get_mapname(mapname,31)
    
    //Запись в лог подключений
    result = dbi_query(sql,"INSERT INTO `%s` (name, last_time_login, last_ip_login, last_server,last_map, timestamp) values ('%s','%s','%s','%s','%s','%i')",LOG_TABLE, name,current_time, player_ip, servername,mapname, timestamp)
    if(result == RESULT_FAILED)
        {
        log_amx("Database ERROR")
        dbi_free_result(result)
        return PLUGIN_HANDLED
    }    
    dbi_free_result(result)
    
    
    //Проверяем не введен ли пароль заранее
    if(login(name, pass) > 0)
        {        
        //Обновляем данные в таблице пользователей
        result = dbi_query(sql,"UPDATE `%s` SET last_time_login = '%s', last_ip_login = '%s', last_server = '%s', last_map = '%s', timestamp = '%i' WHERE name = '%s'",USER_TABLE, current_time, player_ip, servername, mapname, timestamp, name)
        if(result == RESULT_FAILED)
            {
            log_amx("Database ERROR")
            dbi_free_result(result)
            return PLUGIN_HANDLED
        }        
        dbi_free_result(result)
    }
    else
        {
        new details[1]
        details[0] = id            
        set_task(2.0,"promptUser",450+id,details,2)
    }
    return PLUGIN_CONTINUE
}





//Определяет изменение имени
public client_infochanged(id)
    {        
    if (!SQLconnected())
        return PLUGIN_HANDLED
    
    //Не проверять ботов, прокси и админов с иммунитетом    
    if ( (is_user_bot(id)) || (access(id,ADMIN_IMMUNITY)) || is_user_hltv(id))
        return PLUGIN_CONTINUE
    
    new newName[32], oldName[32], pass[35]
    
    new details[1]
    details[0] = id
    
    get_user_name(id,oldName,31)
    get_user_info(id, "name", newName,31)
    get_user_info(id, PASSWORD_FIELD, pass, 34)
    
    //Смена карты - имя получить невозможно
    if (equali(oldName,"") || equali(newName,""))
        {
        return PLUGIN_CONTINUE
    }
    
    //Залогинился мертвым
    if (login(newName, pass) >0 )
        {        
        return PLUGIN_CONTINUE
    }
    
    //Если просто решил сменить имя
    if(!equali(oldName,newName))
        {
        set_user_info(id, PASSWORD_FIELD, "")
        set_user_info(id, PASSWORD_FIELD2, "")
        set_task(3.0,"promptUser",450+id,details,2)
        return PLUGIN_CONTINUE
    }    
    return PLUGIN_CONTINUE
}





//провреяет имя пользвоателя
public promptUser(details[])
    {
    
    new id = details[0]
    
    new name[32], pass[35]
    
    get_user_info(id,"name",name,31)
    get_user_info(id,PASSWORD_FIELD,pass,34)
    
    new pass_old[35]
    get_user_info(id,PASSWORD_FIELD2,pass_old,34)
    
    
    
    //Исключения
    if(exception(name))
        {
        return PLUGIN_HANDLED
    }
    
    //Ввел пароль вручную или из конфига
    if(login(name,pass) > 0)
        {
        return PLUGIN_HANDLED
    }
    
    
    
    // Залогинился мертвым - ждем до следюущего раунда
    if (login(name,pass_old) > 0 )
        return PLUGIN_HANDLED
    
    
    
    switch(validName(name))
    {
        case -1:
        {
            
            client_print(id, print_console, ">>This name is registered. Please enter your password")
            client_print(id, print_console, ">>Type ^"name_help^" for more details")
            client_print(id, print_chat,"*** Your name is registred on this server. Please enter your password.")
            client_cmd(id, "name ^"%s^"", NAME_REGISTERED)
        }
        case -2:
        {
            client_print(id, print_console, ">>Name is reserved for the admin")
            client_print(id, print_chat,"*** Your name has been blocked. Check your console")
            client_cmd(id, "name ^"%s^"", NAME_BLOCKED)
            
        }
        case -3:
        {
            client_print(id, print_console, ">>Name is blocked on this server")
            client_print(id, print_chat,"*** Your name has been blocked. Check your console")
            client_cmd(id, "name ^"%s^"", NAME_BLOCKED)
            
            
        }
        case -10:
        {
            client_print(id, print_console, ">>Invalid name characters: ^", ', \")
            client_print(id, print_chat,"*** Your name has been blocked. Check your console")
            client_cmd(id, "name ^"%s^"", NAME_BLOCKED)
            
        }
        default:
        {
            return PLUGIN_HANDLED
        }
        
    }
    return PLUGIN_HANDLED
}




//Завершение логина
public completeLogin(id, name[], pass[])
    {
    new pass_old[35], name_old[32]
    
    get_user_info(id,PASSWORD_FIELD,pass_old,34)
    get_user_info(id,"name",name_old,31)
    
    set_user_info (id, PASSWORD_FIELD2, pass_old)
    set_user_info (id, PASSWORD_FIELD, pass)
    client_cmd(id, "name ^"%s^"",name)
    
    //Считывание данных о времени    
    result = dbi_query(sql,"SELECT last_time_login,last_ip_login FROM `%s` WHERE name='%s'",USER_TABLE,name)
    
    if(result == RESULT_FAILED)
        {
        log_amx("Database ERROR")
        dbi_free_result(result)
        return PLUGIN_HANDLED
    }
    else
        {
        
        if(dbi_nextrow(result)>0)
            {
            new last_time[64], last_ip[32]
            dbi_field(result,1,last_time,64)
            dbi_field(result,2,last_ip,32)
            new servername2[200]
            get_cvar_string("hostname",servername2,100)
            client_cmd(id, "echo ^"***[%s] :: Welcome to the %s^"",name,servername2)
            client_print(id,print_chat,"*[%s] :: Login successfully", name)
            client_print(id,print_chat,"*[%s] :: Last login time: %s  ::  Last login ip: %s",name,last_time,last_ip)
        }
        dbi_free_result(result)
    }
    
    //Обновляем данные о времени
    new current_time[64]
    get_time("%H:%M - %d/%m/%Y",current_time,63)
    new player_ip[32]
    get_user_ip(id,player_ip,32,1)
    new servername[200]
    get_cvar_string("hostname",servername,100)
    new timestamp = get_systime(0)
    new mapname[32]
    get_mapname(mapname,31)
    
    result = dbi_query(sql,"UPDATE `%s` SET last_time_login = '%s', last_ip_login = '%s', last_server = '%s', last_map = '%s', timestamp = '%i' WHERE name = '%s'",USER_TABLE, current_time, player_ip, servername, mapname, timestamp, name)
    if(result == RESULT_FAILED)
        {
        log_amx("Database ERROR")
        dbi_free_result(result)
        return PLUGIN_HANDLED
    }    
    dbi_free_result(result)    
    
    return PLUGIN_HANDLED
}





//Проверяет имя/пароль в базе
public login(name[],pass[])
    {
    if(equal(pass,""))
        return -1
    
    if(equal(name,""))
        return -1
    
    
    result = dbi_query(sql,"SELECT * FROM `%s` WHERE name = '%s' and pass = '%s'", USER_TABLE, name, pass)
    if(result >= RESULT_OK)
        {
        dbi_free_result(result)
        return 1
        
        
    }
    dbi_free_result(result)
    return -1
}




//Проверка правильности паролей
public validPass(pass[])
    {
    trim(pass)
    if((containi (pass, "^"") >= 0) || (containi (pass, "'") >= 0) || (containi (pass, "\") >= 0))
        return false
    return true
}

public validPassMsg(id, pass[])
    {
    if(validPass(pass))
        return true
    console_print(id, "Invalid password characters: ^", ', \")
    return false
}




//Проверка правильности имени
public validName(name[])
    {
    
    trim(name)
    if((containi (name, "^"") >= 0) || (containi (name, "'") >= 0) || (containi (name, "\") >= 0) )
        {
        return -10
    }
    
    
    //Заблокированные слова (проверяется наличие слова в имени)
    result = dbi_query(sql,"SELECT name FROM %s", BLOCKED_TABLE)
    if(result >= RESULT_OK)
        {
        while( result && dbi_nextrow(result) > 0 )
            {
            new blockedName[32]
            dbi_result(result, "name", blockedName, 31)
            if(containi(name,blockedName) != -1)
                {
                dbi_free_result(result)
                if(!exception(name))
                    return -3
            }
        }
    }
    dbi_free_result(result)
    
    //Зарезервированные имена (проверяется точное совпадение имени)
    result = dbi_query(sql,"SELECT * FROM %s WHERE name like '%s'", RESERVED_TABLE, name)
    if(result >= RESULT_OK)
        {
        dbi_free_result(result)
        if(!exception(name))
            return -2
    }
    dbi_free_result(result)
    
    
    //Исключения (имя не изменяется, но зарегистрировать его нельзя)
    //проверяется точное совпадение
    result = dbi_query(sql,"SELECT * FROM %s WHERE name like '%s'", EXCEPTIONS_TABLE, name)
    if(result >= RESULT_OK)
        {
        dbi_free_result(result)
        return -4
    }
    dbi_free_result(result)
    
    //Наличие пользователя
    result = dbi_query(sql,"SELECT * FROM %s WHERE name like '%s'", USER_TABLE, name)
    if(result >= RESULT_OK)
        {
        dbi_free_result(result)
        if(!exception(name))
            return -1
    }
    dbi_free_result(result)
    
    return 1
}

public validNameMsg(id, name[])
    {
    switch(validName(name))
    {
        case 1:
        return true
        case -1:
        console_print(id, "Name already registered")
        case -2:
        console_print(id, "Name is reserved for the admin")
        case -3:
        console_print(id, "Name is blocked (possibly contains profanity)")
        case -4:
        console_print(id, "Name is reserved for the admin")
        case -10:
        console_print(id, "Invalid name characters: ^", ', \")
        default:
        console_print(id, "Invalid name")
    }
    return false
}




//Провера исключений
public exception(name[])
    {
    result = dbi_query(sql,"SELECT * FROM %s WHERE name like '%s'", EXCEPTIONS_TABLE, name)
    if(result >= RESULT_OK)
        {
        dbi_free_result(result)
        return 1
    }
    dbi_free_result(result)
    return 0
}




//Определяет наличие подключения к базе
public SQLconnected()
    {
    if (SQL_CONNECTED)
        return true
    //log_amx("Cannot connect to database")
    return false
}
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Empower
сообщение 18.11.2009, 20:20
Сообщение #2
Стаж: 15 лет

Сообщений: 298
Благодарностей: 945
Полезность: 0

CODE

#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <dbi>


#define MAX_PLAYERS 33

// Уровни доступа
#define REG_ACCESS ADMIN_ALL
#define CHPASSWD_ACCESS ADMIN_ALL
#define LOGIN_ACCESS ADMIN_ALL
#define HELP_ACCESS ADMIN_ALL

//Удаление устаревших записей (в секундах)

//Прочтите примечание ниже, если хотите использовать
//автоматическое удаление устаревших записей пользователей
//По умолчанию автоматическое удаление пользователей
//не разрешено

#define USER_DELETE_TIME 15552000 //6 месяцев

//Лог подключений
//По умолчанию чистится автоматически
#define LOG_DELETE_TIME 604800 //1 неделя

new const PLUGIN_NAME[] = "NameReg"
new const AUTHOR[] = "WEER"
new const VERSION[] = "0.3"

//Поля где хранятся пароли
new const PASSWORD_FIELD[] = "_pswd"

//Для временного хранения предыдущего пароля
//(Нужно если чел залогинился мертвым)
new const PASSWORD_FIELD2[] = "_pswd2"

//Заменять заблкокированные имена на..
new const NAME_BLOCKED[] = "[This name is blocked]"

//Если имя игрока зарегистирированно, а пароль не ввееден
// то заменять имя юзера на...
new const NAME_REGISTERED[] = "[This name is registered]"

//Параметры базы данных
new bool:SQL_CONNECTED = false

new const USER_TABLE[] = "nreg_users"
new const RESERVED_TABLE[] = "nreg_reserved"
new const BLOCKED_TABLE[] = "nreg_blocked"
new const EXCEPTIONS_TABLE[] = "nreg_exceptions"
new const LOG_TABLE[] = "nreg_log"

new Sql:sql
new Result:result

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////

public plugin_init()
{
register_plugin(PLUGIN_NAME, VERSION, AUTHOR)

register_concmd("name_reg","consoleRegister",REG_ACCESS," <name> <pass1> <pass2> - Register a player name")
register_concmd("name_passwd","consoleChpasswd",CHPASSWD_ACCESS," <name> <old_pass2> <new_pass1> <new_pass2> - Change password")
register_concmd("login","consoleLogin",LOGIN_ACCESS," <name> <pass> - Login (for registered user)")
register_concmd("logout","consoleLogout",LOGIN_ACCESS," - Logout (for registered user)")
register_concmd("name_help","consoleHelp",LOGIN_ACCESS," - Displays User Registration help")

set_task(1.0,"sqlInit")
set_task(2.0,"deleteOldUser")

}


public plugin_modules()
{
require_module("engine")
require_module("DBI")

}

public sqlInit()
{
new host[64],user[32],pass[32],db[32],error[128]
get_cvar_string("amx_sql_host",host,63)
get_cvar_string("amx_sql_user",user,31)
get_cvar_string("amx_sql_pass",pass,31)
get_cvar_string("amx_sql_db",db,31)

sql = dbi_connect(host,user,pass,db,error,127)

if (sql <= SQL_FAILED)
{
log_amx("Failed to connect to SQL")
return PLUGIN_HANDLED
}

log_amx("Name Registration System Online")
SQL_CONNECTED = true
return PLUGIN_HANDLED
}


//Удаляет старые данные из базы
public deleteOldUser()
{
if (!SQLconnected())
return PLUGIN_HANDLED

new timestamp = get_systime(0)
new deletestamp = timestamp - USER_DELETE_TIME
new deletestamp2 = timestamp - LOG_DELETE_TIME

//Выяснение количества "просроченных" пользователей
result = dbi_query(sql,"SELECT name FROM `%s` WHERE timestamp < '%i'",USER_TABLE,deletestamp)
if(result == RESULT_FAILED)
{
log_amx("Database ERROR")
dbi_free_result(result)
return PLUGIN_HANDLED
}
if(result > RESULT_NONE)
{
new num_deleted_users = dbi_num_rows(result)
log_amx("Found %d out of date users in database. These users dont login less then 6 month. Please remove this users manually.",num_deleted_users)
}
dbi_free_result(result)



//Удаление юзеров - достаточно рискованно с учетом того
//что время можно перевести случайно:)
//Лучше вручную чистить

//dbi_query(sql,"DELETE FROM `%s` WHERE timestamp < '%i'",USER_TABLE,deletestamp)

//Удаление логов
//Тут думаю лучше автоматически, так как ценность информации не сильно большая
dbi_query(sql,"DELETE FROM `%s` WHERE timestamp < '%i'",LOG_TABLE,deletestamp2)

return PLUGIN_HANDLED
}




//Регистрация имени из консоли
public consoleRegister(id,level,cid)
{
if (read_argc() < 3)
{
client_print(id,print_console,"Usage: name_reg <name> <password1> <password2>")
consoleNeed2Pass(id)
return PLUGIN_HANDLED
}

if (!SQLconnected())
return PLUGIN_HANDLED
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED

new name[32], pass[35], pass2[35]

read_argv(1, name, 31)
read_argv(2, pass, 34)
read_argv(3, pass2, 34)
if(equal(name,"") || equal(pass,"") || equal(pass2,"") )
{
client_print(id,print_console,"Usage: name_reg <name> <password1> <password2>")
consoleNeed2Pass(id)
return PLUGIN_HANDLED
}

if(equal(pass,pass2))
{
client_print(id,print_console,"Usage: name_reg <name> <password1> <password2>")
consoleNeed2Pass(id)
return PLUGIN_HANDLED
}


if(exception(name))
{
client_print(id,print_console,"This name is reserved for system")
return PLUGIN_HANDLED
}


if(!validNameMsg(id, name))
return PLUGIN_HANDLED
if(!validPassMsg(id, pass))
return PLUGIN_HANDLED
if(!validPassMsg(id, pass2))
return PLUGIN_HANDLED


result = dbi_query(sql,"INSERT INTO %s(name, pass, pass2) values('%s','%s','%s')",USER_TABLE, name, pass, pass2)
if( result == RESULT_FAILED )
{
log_amx("Database ERROR")
client_print(id, print_console, "System error. Please try again later")
dbi_free_result(result)
return PLUGIN_HANDLED
}
else
{
dbi_free_result(result)
console_print(id, "***Name ^"%s^" succesfully registered", name)
completeLogin(id, name, pass)
return PLUGIN_HANDLED


}
return PLUGIN_HANDLED
}





//Смена пароля из консоли
public consoleChpasswd(id,level,cid)
{
if (read_argc() < 4)
{
client_print(id,print_console,"Usage: name_passwd <name> <old_pass2> <new_pass1> <new_pass2>")
consoleNeed2Pass(id)
return PLUGIN_HANDLED
}

if (!SQLconnected())
return PLUGIN_HANDLED
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED

new name[32], old_pass2[35],new_pass[35],new_pass2[35]

read_argv(1, name, 31)
read_argv(2, old_pass2, 34)
read_argv(3, new_pass, 34)
read_argv(4, new_pass2, 34)

if(equal(name,"") || equal(new_pass,"") || equal(new_pass2,"") )
{
client_print(id,print_console,"Usage: name_passwd <name> <old_pass2> <new_pass1> <new_pass2>")
consoleNeed2Pass(id)
return PLUGIN_HANDLED
}

if(equal(new_pass,new_pass2))
{
client_print(id,print_console,"Usage: name_passwd <name> <old_pass2> <new_pass1> <new_pass2>")
consoleNeed2Pass(id)
return PLUGIN_HANDLED
}


result = dbi_query(sql,"SELECT pass2 FROM `%s` WHERE name='%s'",USER_TABLE,name)
if(result == RESULT_FAILED)
{
log_amx("Database ERROR")
client_print(id, print_console, "System error. Please try again later")
dbi_free_result(result)
return PLUGIN_HANDLED
}
if (result == RESULT_OK)
{
if(dbi_nextrow(result)>0)
{
new old_pass2_real[35]
dbi_field(result,1,old_pass2_real,35)
dbi_free_result(result)
if (equal(old_pass2_real,old_pass2))
{
result = dbi_query(sql,"UPDATE `%s` SET pass = '%s', pass2 = '%s' WHERE name = '%s'",USER_TABLE, new_pass, new_pass2, name)
if(result == RESULT_FAILED)
{
log_amx("Database ERROR")
client_print(id, print_console, "System error. Password dont changed! Please try again later")
dbi_free_result(result)
return PLUGIN_HANDLED
}
dbi_free_result(result)
client_print(id,print_console,"Password update successfully!")
return PLUGIN_HANDLED
}

}
}
else
{
dbi_free_result(result)
console_print(id, "Invalid user/password combination")
return PLUGIN_HANDLED
}

return PLUGIN_HANDLED

}


//Логин из консоли
public consoleLogin(id,level,cid)
{

if (!SQLconnected())
return PLUGIN_HANDLED
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED


new name[32], pass[35]
read_argv(1, name, 31)
read_argv(2, pass, 34)

if(!validPassMsg(id, pass))
return PLUGIN_HANDLED

if (!validName(name))
{
console_print(id, "Your name has been blocked. Please contact to admin!")
return PLUGIN_HANDLED
}

switch(login(name,pass))
{
case 1:
completeLogin(id, name, pass)
case -1:
console_print(id, "Invalid user/password combination")
default:
return PLUGIN_HANDLED
}
return PLUGIN_HANDLED
}






//Логаут
public consoleLogout(id,level,cid)
{
if (!SQLconnected())
return PLUGIN_HANDLED
if (!cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED

new name[32], pass[35]

get_user_info(id, "name", name, 31)
get_user_info(id, PASSWORD_FIELD, pass, 34)

if(login(name,pass) > 0)
{
set_user_info (id, PASSWORD_FIELD, "")
console_print(id,"Logout successful")
return PLUGIN_HANDLED
}
else
{
console_print(id, "You are not logged in")
}
return PLUGIN_HANDLED
}





//Хелпы всякие разные
public consoleHelpMsg(id)
{

client_print(id,print_console,"This server support name registration system")
client_print(id,print_console,"If you register your name, nobody exept you will be able to use it")
client_print(id,print_console,"Console commands:")
client_print(id,print_console,"name_reg <name> <password1> <password2> - name registration")
client_print(id,print_console,"name_passwd <name> <old_psswd2> <new_psswd1> <new_psswd2> - change password")
client_print(id,print_console,"login <name> <password1> - login ")
client_print(id,print_console,"logout - logout")
consoleNeed2Pass(id)

return PLUGIN_CONTINUE
}

public consoleNeed2Pass(id)
{

client_print(id,print_console,"Two passwords (pin and puk code) need for security purpose")
client_print(id,print_console,"<password1> (pin) - need to login")
client_print(id,print_console,"This password you can save into your config file")
client_print(id,print_console,"For example this line save password ^"qwert^":")
client_print(id,print_console,"setinfo ^"%s^" ^"qwert^"",PASSWORD_FIELD)
client_print(id,print_console,"<password2> (puk) - need to change password")
client_print(id,print_console,"DONT SAVE PASSWORD2 INTO YOUR CONFIG FILE!!!^n")
client_print(id,print_console,"Please use DIFFERENT <password1> and <password2>")


return PLUGIN_CONTINUE
}

public consoleHelp(id,level,cid)
{
if (!SQLconnected())
return PLUGIN_HANDLED
if (!cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED
consoleHelpMsg(id)
return PLUGIN_HANDLED
}






//Отслеживает вход клинта на сервер
//public client_putinserver(id)
public client_authorized(id)
{
if (!SQLconnected())
return PLUGIN_HANDLED

//Не проверять ботов, прокси и админов с иммунитетом
if ( (is_user_bot(id)) || (access(id,ADMIN_IMMUNITY)) || is_user_hltv(id))
return PLUGIN_CONTINUE

new name[32], pass[35]

get_user_info(id,"name", name, 31)
get_user_info(id, PASSWORD_FIELD, pass, 34)

new current_time[64]
get_time("%H:%M - %d/%m/%Y",current_time,63)
new player_ip[32]
get_user_ip(id,player_ip,32,1)
new servername[200]
get_cvar_string("hostname",servername,100)
new timestamp = get_systime(0)
new mapname[32]
get_mapname(mapname,31)

//Запись в лог подключений
result = dbi_query(sql,"INSERT INTO `%s` (name, last_time_login, last_ip_login, last_server,last_map, timestamp) values ('%s','%s','%s','%s','%s','%i')",LOG_TABLE, name,current_time, player_ip, servername,mapname, timestamp)
if(result == RESULT_FAILED)
{
log_amx("Database ERROR")
dbi_free_result(result)
return PLUGIN_HANDLED
}
dbi_free_result(result)


//Проверяем не введен ли пароль заранее
if(login(name, pass) > 0)
{
//Обновляем данные в таблице пользователей
result = dbi_query(sql,"UPDATE `%s` SET last_time_login = '%s', last_ip_login = '%s', last_server = '%s', last_map = '%s', timestamp = '%i' WHERE name = '%s'",USER_TABLE, current_time, player_ip, servername, mapname, timestamp, name)
if(result == RESULT_FAILED)
{
log_amx("Database ERROR")
dbi_free_result(result)
return PLUGIN_HANDLED
}
dbi_free_result(result)
}
else
{
new details[1]
details[0] = id
set_task(2.0,"promptUser",450+id,details,2)
}
return PLUGIN_CONTINUE
}





//Определяет изменение имени
public client_infochanged(id)
{
if (!SQLconnected())
return PLUGIN_HANDLED

//Не проверять ботов, прокси и админов с иммунитетом
if ( (is_user_bot(id)) || (access(id,ADMIN_IMMUNITY)) || is_user_hltv(id))
return PLUGIN_CONTINUE

new newName[32], oldName[32], pass[35]

new details[1]
details[0] = id

get_user_name(id,oldName,31)
get_user_info(id, "name", newName,31)
get_user_info(id, PASSWORD_FIELD, pass, 34)

//Смена карты - имя получить невозможно
if (equali(oldName,"") || equali(newName,""))
{
return PLUGIN_CONTINUE
}

//Залогинился мертвым
if (login(newName, pass) >0 )
{
return PLUGIN_CONTINUE
}

//Если просто решил сменить имя
if(!equali(oldName,newName))
{
set_user_info(id, PASSWORD_FIELD, "")
set_user_info(id, PASSWORD_FIELD2, "")
set_task(3.0,"promptUser",450+id,details,2)
return PLUGIN_CONTINUE
}
return PLUGIN_CONTINUE
}





//провреяет имя пользвоателя
public promptUser(details[])
{

new id = details[0]

new name[32], pass[35]

get_user_info(id,"name",name,31)
get_user_info(id,PASSWORD_FIELD,pass,34)

new pass_old[35]
get_user_info(id,PASSWORD_FIELD2,pass_old,34)



//Исключения
if(exception(name))
{
return PLUGIN_HANDLED
}

//Ввел пароль вручную или из конфига
if(login(name,pass) > 0)
{
return PLUGIN_HANDLED
}



// Залогинился мертвым - ждем до следюущего раунда
if (login(name,pass_old) > 0 )
return PLUGIN_HANDLED



switch(validName(name))
{
case -1:
{

client_print(id, print_console, ">>This name is registered. Please enter your password")
client_print(id, print_console, ">>Type ^"name_help^" for more details")
client_print(id, print_chat,"*** Your name is registred on this server. Please enter your password.")
client_cmd(id, "name ^"%s^"", NAME_REGISTERED)
}
case -2:
{
client_print(id, print_console, ">>Name is reserved for the admin")
client_print(id, print_chat,"*** Your name has been blocked. Check your console")
client_cmd(id, "name ^"%s^"", NAME_BLOCKED)

}
case -3:
{
client_print(id, print_console, ">>Name is blocked on this server")
client_print(id, print_chat,"*** Your name has been blocked. Check your console")
client_cmd(id, "name ^"%s^"", NAME_BLOCKED)


}
case -10:
{
client_print(id, print_console, ">>Invalid name characters: ^", ', \")
client_print(id, print_chat,"*** Your name has been blocked. Check your console")
client_cmd(id, "name ^"%s^"", NAME_BLOCKED)

}
default:
{
return PLUGIN_HANDLED
}

}
return PLUGIN_HANDLED
}




//Завершение логина
public completeLogin(id, name[], pass[])
{
new pass_old[35], name_old[32]

get_user_info(id,PASSWORD_FIELD,pass_old,34)
get_user_info(id,"name",name_old,31)

set_user_info (id, PASSWORD_FIELD2, pass_old)
set_user_info (id, PASSWORD_FIELD, pass)
client_cmd(id, "name ^"%s^"",name)

//Считывание данных о времени
result = dbi_query(sql,"SELECT last_time_login,last_ip_login FROM `%s` WHERE name='%s'",USER_TABLE,name)

if(result == RESULT_FAILED)
{
log_amx("Database ERROR")
dbi_free_result(result)
return PLUGIN_HANDLED
}
else
{

if(dbi_nextrow(result)>0)
{
new last_time[64], last_ip[32]
dbi_field(result,1,last_time,64)
dbi_field(result,2,last_ip,32)
new servername2[200]
get_cvar_string("hostname",servername2,100)
client_cmd(id, "echo ^"***[%s] :: Welcome to the %s^"",name,servername2)
client_print(id,print_chat,"*[%s] :: Login successfully", name)
client_print(id,print_chat,"*[%s] :: Last login time: %s :: Last login ip: %s",name,last_time,last_ip)
}
dbi_free_result(result)
}

//Обновляем данные о времени
new current_time[64]
get_time("%H:%M - %d/%m/%Y",current_time,63)
new player_ip[32]
get_user_ip(id,player_ip,32,1)
new servername[200]
get_cvar_string("hostname",servername,100)
new timestamp = get_systime(0)
new mapname[32]
get_mapname(mapname,31)

result = dbi_query(sql,"UPDATE `%s` SET last_time_login = '%s', last_ip_login = '%s', last_server = '%s', last_map = '%s', timestamp = '%i' WHERE name = '%s'",USER_TABLE, current_time, player_ip, servername, mapname, timestamp, name)
if(result == RESULT_FAILED)
{
log_amx("Database ERROR")
dbi_free_result(result)
return PLUGIN_HANDLED
}
dbi_free_result(result)

return PLUGIN_HANDLED
}





//Проверяет имя/пароль в базе
public login(name[],pass[])
{
if(equal(pass,""))
return -1

if(equal(name,""))
return -1


result = dbi_query(sql,"SELECT * FROM `%s` WHERE name = '%s' and pass = '%s'", USER_TABLE, name, pass)
if(result >= RESULT_OK)
{
dbi_free_result(result)
return 1


}
dbi_free_result(result)
return -1
}




//Проверка правильности паролей
public validPass(pass[])
{
trim(pass)
if((containi (pass, "^"") >= 0) || (containi (pass, "'") >= 0) || (containi (pass, "\") >= 0))
return false
return true
}

public validPassMsg(id, pass[])
{
if(validPass(pass))
return true
console_print(id, "Invalid password characters: ^", ', \")
return false
}




//Проверка правильности имени
public validName(name[])
{

trim(name)
if((containi (name, "^"") >= 0) || (containi (name, "'") >= 0) || (containi (name, "\") >= 0) )
{
return -10
}


//Заблокированные слова (проверяется наличие слова в имени)
result = dbi_query(sql,"SELECT name FROM %s", BLOCKED_TABLE)
if(result >= RESULT_OK)
{
while( result && dbi_nextrow(result) > 0 )
{
new blockedName[32]
dbi_result(result, "name", blockedName, 31)
if(containi(name,blockedName) != -1)
{
dbi_free_result(result)
if(!exception(name))
return -3
}
}
}
dbi_free_result(result)

//Зарезервированные имена (проверяется точное совпадение имени)
result = dbi_query(sql,"SELECT * FROM %s WHERE name like '%s'", RESERVED_TABLE, name)
if(result >= RESULT_OK)
{
dbi_free_result(result)
if(!exception(name))
return -2
}
dbi_free_result(result)


//Исключения (имя не изменяется, но зарегистрировать его нельзя)
//проверяется точное совпадение
result = dbi_query(sql,"SELECT * FROM %s WHERE name like '%s'", EXCEPTIONS_TABLE, name)
if(result >= RESULT_OK)
{
dbi_free_result(result)
return -4
}
dbi_free_result(result)

//Наличие пользователя
result = dbi_query(sql,"SELECT * FROM %s WHERE name like '%s'", USER_TABLE, name)
if(result >= RESULT_OK)
{
dbi_free_result(result)
if(!exception(name))
return -1
}
dbi_free_result(result)

return 1
}

public validNameMsg(id, name[])
{
switch(validName(name))
{
case 1:
return true
case -1:
console_print(id, "Name already registered")
case -2:
console_print(id, "Name is reserved for the admin")
case -3:
console_print(id, "Name is blocked (possibly contains profanity)")
case -4:
console_print(id, "Name is reserved for the admin")
case -10:
console_print(id, "Invalid name characters: ^", ', \")
default:
console_print(id, "Invalid name")
}
return false
}




//Провера исключений
public exception(name[])
{
result = dbi_query(sql,"SELECT * FROM %s WHERE name like '%s'", EXCEPTIONS_TABLE, name)
if(result >= RESULT_OK)
{
dbi_free_result(result)
return 1
}
dbi_free_result(result)
return 0
}




//Определяет наличие подключения к базе
public SQLconnected()
{
if (SQL_CONNECTED)
return true
//log_amx("Cannot connect to database")
return false
}
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
  Тема закрытаНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: