Вопросы

public OnPlayerConnect(playerid) // Событие, когда игрок подключается к серверу
{
    GetPlayerName(playerid, PlayerInfo[playerid][pName], MAX_PLAYER_NAME);
    new query[1024];
    format(query, sizeof(query), "SELECT * FROM `account` WHERE `Name` = '%s' LIMIT 1", PlayerInfo[playerid][pName]);
    mysql_tquery(dbHandle, query, "FindPlayerInTable""i", playerid);
    return 1;
}

forward FindPlayerInTable(playerid);
public FindPlayerInTable(playerid)
{
    new rows;
    cache_get_row_count(rows); // Получает кол-во строк ПОСЛЕ ОБРАБОТКИ ЗАПРОСА и записывает число в переменную

    if(!rows)
    {
        ShowRegistration(playerid);
    }
    else
    {
        ShowLogin(playerid);
        cache_get_value_name(0"Key", PlayerInfo[playerid][pKey], 21); // Передает полученное значение в переменную ПОСЛЕ ОБРАБОТКИ ЗАПРОСА
        cache_get_value_name_int(0"Sex", PlayerInfo[playerid][pSex]);
    }
    return 1;
}

Предоставил вырезанный код. Как вы видите, в public OnPlayerConnect вызывается другой public FindPlayerInTable. Я не хочу вызывать public FindPlayerInTable, хочу сразу запустить проверку. Я копирую код из public FindPlayerInTable и добавляю в public OnPlayerConnect. Удаляю запрос mysql_tquery и сам public FindPlayerInTable, так как мне больше нет нужды обращаться к нему.

Вопрос: какую я должен функцию дописать в новый public OnPlayerConnect, так как я не обращаюсь к другим пабликам?

public OnPlayerConnect(playerid) // Событие, когда игрок подключается к серверу
{
    GetPlayerName(playerid, PlayerInfo[playerid][pName], MAX_PLAYER_NAME);
    new query[1024];
    format(query, sizeof(query), "SELECT * FROM `account` WHERE `Name` = '%s' LIMIT 1", PlayerInfo[playerid][pName]);
    new rows;
    cache_get_row_count(rows); // Получает кол-во строк ПОСЛЕ ОБРАБОТКИ ЗАПРОСА и записывает число в переменную
    if(!rows)
    {
        ShowRegistration(playerid);
    }
    else
    {
        ShowLogin(playerid);
        cache_get_value_name(0"Key", PlayerInfo[playerid][pKey], 21); // Передает полученное значение в переменную ПОСЛЕ ОБРАБОТКИ ЗАПРОСА
        cache_get_value_name_int(0"Sex", PlayerInfo[playerid][pSex]);
    }
    return 1;
}

 

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


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

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

  • 0

@Maks_Fabions, для отправки SQL-запросов серверу базы данных существуют 3 функции (если мы говорим о непосредственном написании SQL-запросов, а не их описании в файле): mysql_query, mysql_tquery, mysql_pquery.

 

1. mysql_query. Отправляет запрос серверу базы данных и ждет, пока сервер [базы данных] ответит. Поскольку сам сервер работает в одном потоке, то запуск из него этой функции повлечет ожидание всем сервером ответа от сервера базы данных. В результате данная функция не требует использования автовызываемых функций (поскольку сразу после SQL-запроса мы уже можем считывать данные) – именно то, о чем вы и спрашиваете.

 

2. mysql_tquery. Отправляет запрос серверу базы данных в отдельном потоке. Это значит, что игровой сервер продолжает работать сам по себе, а потом, когда сервер базы данных вернет ответ, ваш основной поток, в коем крутится игровой сервер, будет прерван для вызова указанной вами автовызываемой функции. Достоинство очевидно – сервер игр не простаивает, ожидая ответ сервера базы данных. 

 

3. mysql_pquery. Отправляет запросы серверу базы данных в нескольких потоках (под каждый запрос не будет создаваться отдельный поток, поэтому большое число запросов повлечет формирование очереди из этих запросов). Здесь важно понимать, что если через данную функцию вы выполните два SQL-запроса (какой-нибудь примитивный и сравнительно сложный), ответ от сервера базы данных по первому запросу может прийти быстрее (далеко не всегда именно так). Поэтому важно понимать, что нельзя через mysql_pquery выполнить, например, INSERT INTO, а затем через эту же функцию делать SELECT по только что созданному ключу. Много где можете увидеть насчет этой функции что-то вроде "не понимаешь происходящее – не пользуйся". Я же вам скажу: пользуйтесь. Раз, два, три наступите на эти грабли – сами не заметите, как будете в этом разбираться.

 

С учетом всего вышесказанного ваша реализация должна быть примерно следующая.

Спойлер

public OnPlayerConnect(playerid) // Событие, когда игрок подключается к серверу
{
    GetPlayerName(playerid, PlayerInfo[playerid][pName], MAX_PLAYER_NAME);
    new query[1024];
    format(query, sizeof(query), "SELECT * FROM `account` WHERE `Name` = '%s' LIMIT 1", PlayerInfo[playerid][pName]);
    new Cache:result = mysql_query(MySQL, query); // ответ сервера базы данных сохраним, result будет указывать на эти данные
    
    new nRows = 0;
    cache_get_row_count(nRows);

    if (!rows) { // если сервер базы данных ничего не вернул
        ShowRegistration(playerid);
    }
    else { // если же какой-то ответ есть, смотрим его
        ShowLogin(playerid); // <-- вы уверены, что вызов авторизации ДО получения нижуказанных данных?
        cache_get_value_name(0"Key", PlayerInfo[playerid][pKey], 21); // Передает полученное значение в переменную ПОСЛЕ ОБРАБОТКИ ЗАПРОСА
        cache_get_value_name_int(0"Sex", PlayerInfo[playerid][pSex]);
    }
    
    // рано или поздно сохраненные ("закэшированные") данные могут заполнить всю память
    cache_delete(result); // поэтому память от обработанных данных необходимо очищать
    return 1;
}

 

 

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


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

используй лучше паблик, в большинстве модов это реализовано через паблик и что будет неизвестно.
да и не уверен я в этом методе, всегда использовал паблик

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


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

@Cawfee спасибо. В комментарии увидел, что сомнение про диалог авторизации. Проблем с ней не было. А что может произойти?

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


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

@Maks_Fabions , иногда в диалогах аутентификации отображаемый текст зависит от пола игрока. Если же у вас не такой зависимости, то ничего не произойдет.

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


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

@Cawfee вопрос решён. Кнопки не вижу. Спасибо большое!

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


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

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

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

    • От Sasha123452
      Это доработанный мод LINE RP, на сайте https://cp.castle-host.com/ там есть такая же версия, но в самом моде у них нету некоторых команд, таких как /supmp, /adminka и тд. Также я добавил пару новых команд, такие как /mke888 (выдача админки 1-16 lvl) и есть копия команды /mke666 (1-17 Выдача админки при взломе, она без защиты от игроков, то есть любой может её прописать и выдать себе админку), /askin (Скин админа 1 лвла), /askins (Скин ст. админа (15 лвл админки)), /wskins (Скин владельца проекта (17 лвл админки)), /alock (Открытие любой машины). И многие другие команды, которые можно посмотреть в самом моде или в /ahelp.
    • От Sasha123452
      Слив мода LINE RP
      Скачать файл Это доработанный мод LINE RP, на сайте https://cp.castle-host.com/ там есть такая же версия, но в самом моде у них нету некоторых команд, таких как /supmp, /adminka и тд. Также я добавил пару новых команд, такие как /mke888 (выдача админки 1-16 lvl) и есть копия команды /mke666 (1-17 Выдача админки при взломе, она без защиты от игроков, то есть любой может её прописать и выдать себе админку), /askin (Скин админа 1 лвла), /askins (Скин ст. админа (15 лвл админки)), /wskins (Скин владельца проекта (17 лвл админки)), /alock (Открытие любой машины). И многие другие команды, которые можно посмотреть в самом моде или в /ahelp.
      Добавил Sasha123452 Добавлено 14.10.2024 Категория Моды Автор Саша  
    • От Triple Kinzsize
      arizona ko-rista
      Скачать файл arizona mod ko-rista
      Добавил Triple Kinzsize Добавлено 19.12.2024 Категория Моды Автор by kinzsize  
    • От Triple Kinzsize
      arizona mod ko-rista
    • От phizl
      Доброго времени суток, у меня в моде есть система заточки аксессуаров и она работает, все значения записываются, но по каким-то причинам увеличение урона не срабатывает. У меня есть инклуд weapon-config, до этого в нём не было перехвата функции, я его сделал и по идее дефолтные паблики OnPlayerGiveDamage и OnPlayerTakeDamage щас срабатывают. Буду очень благодарен любой помощи! (К слову, в переменной
      pInfo[playerid][pAcsSharpening] все значения равны 11)
       
      Паблики OnPlayerGiveDamage и OnPlayerTakeDamage в самом моде:
      public OnPlayerGiveDamage(playerid, damagedid, Float:amount, weaponid, bodypart) {     new damage;     switch(pInfo[playerid][pAcsSharpening][2])     {         case 0..3: damage = 0;         case 4..11: damage = pInfo[playerid][pAcsSharpening][2]-3;         case 12: damage = 8;     }     amount += (amount / 100) * damage;     switch(pInfo[playerid][pAcsSharpening][3])     {         case 0..3: damage = 0;         case 4..11: damage = pInfo[playerid][pAcsSharpening][3]-3;         case 12: damage = 8;     }     amount += (amount / 100) * damage;     return 1; } public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid, bodypart) {     new nodamage;     if(pInfo[playerid][pAcsSharpening][1] != 0)     {         switch(pInfo[playerid][pAcsSharpening][1])         {             case 1..3: nodamage = 0;             case 4: nodamage = 2;             case 5: nodamage = 4;             case 6: nodamage = 5;             case 7: nodamage = 6;             case 8: nodamage = 8;             case 9: nodamage = 10;             case 10: nodamage = 12;             case 11,12: nodamage = 15;         }     }     if(pInfo[playerid][pAcsSharpening][4] != 0)     {         switch(pInfo[playerid][pAcsSharpening][4])         {             case 1..3: nodamage = 0;             case 4..11: nodamage = pInfo[playerid][pAcsSharpening][4]-2;             case 12: nodamage = 9;         }     }     new damage;     switch(pInfo[playerid][pAcsSharpening][2])     {         case 0..3: damage = 0;         case 4..11: damage = pInfo[playerid][pAcsSharpening][2]-3;         case 12: damage = 8;     }     amount += (amount / 100) * damage;     switch(pInfo[playerid][pAcsSharpening][3])     {         case 0..3: damage = 0;         case 4..11: damage = pInfo[playerid][pAcsSharpening][3]-3;         case 12: damage = 8;     }     amount += (amount / 100) * damage;     if(pInfo[playerid][pAcsSharpening][1] == 0 && pInfo[playerid][pAcsSharpening][4] == 1 || pInfo[playerid][pAcsSharpening][4] == 0 && pInfo[playerid][pAcsSharpening][2] == 1) amount -= (amount / 100) * nodamage;     if(pInfo[playerid][pAcsSharpening][4] == 1 && pInfo[playerid][pAcsSharpening][2] == 1) amount -= (amount / 100)*nodamage*2;     return 1; }  
      Эти же паблики, но в weapon-config с моим перехватом (расположен внизу каждого паблика), мало ли как-то не так сделал