Вопросы

Вступление: Приветствую, я захотел полностью переделать свой скрипт, не знаю как это у меня получится но не суть.

 

Вопрос: Как сделать запрос в базу, и как придать переменной resultat форму пароля? То есть, контекст такой: Игрок вводит пароль, в базу dbHandle отправляется запрос на получение из таблицы users строки password у определенного id - Если resultat = 1 (правильный пароль), тогда игрока запускает. Если же другой, шлет его и выдает ShowLogin() на перепроверку пароля. 

 

Недоделка: 

Спойлер

case DLG_LOG:
{
    if (response)
    {
        static const fmt_query[] = "SELECT `password` FROM `users` WHERE `name` = '%s'";
        new query[sizeof(fmt_query)+(-2+MAX_PLAYER_NAME)];
        format(query, sizeof(query), fmt_query, player_info[playerid][PASSWORD]);
        mysql_tquery(dbHandle, query, "i", playerid);
        new resultat;
        return 1;
        
        if(resultat == 1)
        {
            SCM(playerid, COLOR_WHITE, "Пароль верный!");
            SpawnPlayer(playerid);
        }
        else
        {
            SCM(playerid, COLOR_RED, "Не верный!");
            ShowLogin(playerid);
        }
    }
    else
    {
        SCM(playerid, COLOR_WHITE, "{ff0000}[SERVER]{FFFFFF}:{FFFFFF} (/q).");
        SPD(playerid, -10" "" "" """);
        return Kick(playerid);
    }
}

Я надеюсь все правильно изложил как хотел..

 

Поделиться сообщением


Ссылка на сообщение

7 ответов на этот вопрос

  • 0

@VDOVA Ответ от ии:

Ваш первый шаг - это выполнить запрос к базе данных, чтобы получить пароль от пользователя. Вот пример как можно это сделать на Pawn (язык, используемый в SA-MP):

new id = GetPlayerId(playerid); // получаем id игрока
new password[50]; // переменная для хранения пароля из базы данных
format(query, sizeof(query), "SELECT password FROM users WHERE id = %d", id); // собираем запрос к базе данных для получения пароля
mysql_function_query(dbHandle, query); // отправляем запрос к базе данных

forward OnPlayerGetPassword(playerid, result, password); // ожидаем ответа от базы данных

 

Затем, после выполнения запроса, вам нужно обработать результат и сравнить введенный игроком и полученный из базы данных пароль. Вот пример, как это можно сделать:

Спойлер

public OnPlayerGetPassword(playerid, result, password[])
{
    if (result) // если запрос успешен
    {
        if (!strcmp(password, GetPlayerPassword(playerid))) // сравниваем введенный пароль с тем, что хранится в базе данных
        {
            // Пароль верный, запускаем игрока
            // Добавьте здесь код для запуска игрока
        }
        else
        {
            // Пароль неверный, отправляем игрока на повторное введение пароля
            ShowLogin(playerid); // замените это на вашу функцию отображения формы ввода пароля
        }
    }
    else
    {
        // Обработка ошибки запроса
    }
}

 

Обратите внимание, что в этом примере используется функция `GetPlayerPassword(playerid)`, которая должна быть вашей собственной функцией для получения введенного игроком пароля. Вы должны также иметь свою собственную функцию `ShowLogin(playerid)`, которая будет отображать форму ввода пароля.

 

Не забудьте подставить в примеры свои собственные функции и добавить обработку ошибок, чтобы ваш код был полностью функциональным.

Отредактировано пользователем Cawfee

Заметка от Cawfee , создано

3.2. Код необходимо брать в тег "Код", а код более 10 строк – еще и в "Спойлер". Как это сделать рассказано в разделе "FAQ".

Устное предупреждение.

Поделиться сообщением


Ссылка на сообщение
  • 0
case DLG_LOG: {
    if(response) {
        static const fmt_query[] = "SELECT `password` FROM `users` WHERE `name` = '%s'";

        new query[sizeof(fmt_query)+(-2+MAX_PLAYER_NAME)], 
            Cache:resultat,
            tmp_password[32];

        format(query, sizeof(query), fmt_query, player_info[playerid][PASSWORD]);
        resultat = mysql_query(dbHandle, query, true);

        cache_get_value_name_int(0"password", tmp_password); //функция под MySQL R40+
        cache_delete(resultat);

        if(!strcmp(inputtext, tmp_password, true)) {
            SCM(playerid, COLOR_WHITE, "Пароль верный!");
            return SpawnPlayer(playerid);
        }
        else {
            SCM(playerid, COLOR_RED, "Не верный!");
            return ShowLogin(playerid);
        }
    }
    else {
        SCM(playerid, COLOR_WHITE, "{ff0000}[SERVER]{FFFFFF}:{FFFFFF} (/q).");
        SPD(playerid, -10" "" "" """);
        return Kick(playerid);
    }
}

 

Поделиться сообщением


Ссылка на сообщение
  • 0

@VDOVA Если я не ошибаюсь, то mysql_tquery передаёт результат в указанный callback, а для работы с кэшем сразу после запроса надо использовать mysql_query:

Спойлер

 


case DLG_LOG:
{
    if (response)
    {
        static const fmt_query[] = "SELECT `password` FROM `users` WHERE `name` = '%s' LIMIT 1";
        // К запросам, где надо получить всего лишь 1 ответ лучше использовать LIMIT 1
        // В противном случае запрос будет исследовать ВСЮ таблицу, даже если и нашёл 1 результат
        // Черезвато выской задержкой в работе с БД при обширной базой аккаунтов
        new query[sizeof(fmt_query)+(-2+MAX_PLAYER_NAME)];
        format(query, sizeof(query), fmt_query, player_info[playerid][PASSWORD]);
        // Я думаю вместо player_info[playerid][PASSWORD] даолжна быть переменная с ником игрока)
        // mysql_tquery(dbHandle, query, "i", playerid);
        new Cache:check_pass = mysql_query(dbHandle, query, true); // Создаём запрос в БД
        new db_password[sizeof(player_info[playerid][PASSWORD])]; // Создаём переменную под пароль из БД
        cache_get_field_content(0"password", db_password, dbHandle);
        // Получаем значение "password" из 0-й строки результата запроса к БД dbHandle в переменную db_password
        cache_delete(check_pass); // Удаляем кэш за ненадобностью
        new resultat = !strcmp(inputtext, db_password);
        // Сравнием пароль из БД и введённый в диалог. strcmp возвращаем отбратный ответ, то есть при схожести строк вернёт FALSE
//        return 1;
        // К чему тут был return? Он же блокирует весь код ниже
        
        if(resultat) // Если resultat любое число, кроме нуля оно и так вернёт true
        {
            SCM(playerid, COLOR_WHITE, "Пароль верный!");
            SpawnPlayer(playerid);
        }
        else
        {
            SCM(playerid, COLOR_RED, "Не верный!");
            ShowLogin(playerid);
        }
    }
    else
    {
        // SCM(playerid, COLOR_WHITE, "{ff0000}[SERVER]{FFFFFF}:{FFFFFF} (/q).");
        // Зачем 2 раза устанавливать белый цвет?
        SCM(playerid, COLOR_WHITE, "{ff0000}[SERVER]{FFFFFF}: (/q).");
        SPD(playerid, -10" "" "" """);
        return Kick(playerid);
    }
}

Если же использовать mysql_tquery и callback под него, то код будет так:

Спойлер

case DLG_LOG:
{
    if (response)
    {
        static const fmt_query[] = "SELECT `password` FROM `users` WHERE `name` = '%s' LIMIT 1";
        new query[sizeof(fmt_query)+(-2+MAX_PLAYER_NAME)];
        format(query, sizeof(query), fmt_query, player_info[playerid][PASSWORD]);
        // Я думаю вместо player_info[playerid][PASSWORD] даолжна быть переменная с ником игрока)
        mysql_tquery(dbHandle, query, "CheckPassCallBack""i", playerid); // Создаём запрос в БД с ответом в CheckPassCallBack
    }
    else
    {
        SCM(playerid, COLOR_WHITE, "{ff0000}[SERVER]{FFFFFF}: (/q).");
        SPD(playerid, -10" "" "" """);
        return Kick(playerid);
    }
}
forward CheckPassCallBack(playerid);
public CheckPassCallBack(playerid) {
    new db_password[sizeof(player_info[playerid][PASSWORD])];
    cache_get_field_content(0"password", db_password, dbHandle);
    new resultat = !strcmp(inputtext, db_password);
    if(resultat) SCM(playerid, COLOR_WHITE, "Пароль верный!"), SpawnPlayer(playerid);
    else SCM(playerid, COLOR_RED, "Не верный!"), ShowLogin(playerid);
}

 

 

Отредактировано пользователем Sleash

Поделиться сообщением


Ссылка на сообщение
  • 0

@Sleash 

 

388:  new db_password[sizeof(player_info[playerid][PASSWORD]);

 

C:\Users\Åâãåíèÿ\Desktop\Ðåçåðà\gamemodes\project.pwn(388) : error 001: expected token: "]", but found "-identifier-"
C:\Users\Åâãåíèÿ\Desktop\Ðåçåðà\gamemodes\project.pwn(388) : warning 215: expression has no effect
C:\Users\Åâãåíèÿ\Desktop\Ðåçåðà\gamemodes\project.pwn(388) : error 001: expected token: ";", but found "]"
C:\Users\Åâãåíèÿ\Desktop\Ðåçåðà\gamemodes\project.pwn(388) : error 029: invalid expression, assumed zero
C:\Users\Åâãåíèÿ\Desktop\Ðåçåðà\gamemodes\project.pwn(388) : fatal error 107: too many error messages on one line

Поделиться сообщением


Ссылка на сообщение
  • 0
new db_password[64];

Учитывая мои проблемности с получением размера элемента из Enum, проще задать постоянную длину пароля.

Поделиться сообщением


Ссылка на сообщение
  • 0

@Sleash Вообще не помогает, можем как то связатся что бы ты лично просмотрел ошибки и помог? Сейчас я ухожу на тренировку. Так что если сможешь, оставь свои контакты, вк, дс, не важно. Я сижу уже 3-4 день над одной проблемой... Будет очень грустно если я ее не решу.

Поделиться сообщением


Ссылка на сообщение
  • 0

@VDOVA 
1) Мы можем поговорить в личных сообщениях через мессенджер форума
2) Если же Вы хотите ВК, то ссылка на мой профиль есть на странице моего форумного аккаунта

Поделиться сообщением


Ссылка на сообщение
Эта тема закрыта для публикации ответов.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

  • Похожий контент

    • От MrNARTI
      всем привет появилась ошибка со входам в автосалон, ерроров нету но при попытки входа показывает что есть транспорт загруженный хотя его нету. Но когда ввожу /car показывает что есть хотя повторяюсь его нет.
       
      код
       
      команда /саr
       
       
       
      если понадобится что то еще скинуть то скажите я скину.
    • От MrNARTI
      всем привет можете пожалуйста подсказать с командой от анти слива /aban
       
      чтобы банило и администратора который использовал эту кмд и адм которого указал в айди.