Написание плагинов

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980

Вложения

  • shop_top100.sp
    3.5 КБ · Просмотры: 29

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
Лол, в панели нету страничек???
Тогда почему просто не перевести панель в меню и максимальное количество выводимых игроков вынести в конвар?
Сообщения автоматически склеены:

пару фиксов, таких как:
- на ласт страничек была возможность переключится на следущую, которая была пустой по факту
- отображение названия (ТОП100 богачей) было статичным, сделал его в зависимости от количества в конваре.

- добавил конвар на изменение количества выводимых игроков (файл конфига по пути cfg/shop/shop_top.cfg) sm_shop_top_max
-
максимум 500 игроков на вывод (больше нету смысла, но кому нада, то меняйте 500 на нужное число максимального лимита)

С меню была плохая идея, признаю (оно адекватно не делает пустые места, панель тащит)
46924
46925
 

Вложения

  • shop_topX.sp
    3.9 КБ · Просмотры: 19
  • shop_topX.smx
    8.3 КБ · Просмотры: 13
Последнее редактирование:

khakiev

Участник
Сообщения
9
Реакции
1
01/2019 - 19:56:42: [SM] Native "GetClientHealth" reported: Client index 0 is invalid
L 10/01/2019 - 19:56:42: [SM] Displaying call stack trace for plugin "KillHP.smx":
L 10/01/2019 - 19:56:42: [SM] [0] Line 34, KillHP.sp::hookPlayerDie()
Спамит в консоли беспредельно, что мне с этим делать?
 

Puwok

Участник
Сообщения
37
Реакции
4
Приветствую.

Суть проблемы:
Иногда бывает когда игрок присоединится к серверу вызывается функция OnClientDisconnect() и когда выходит опять же вызывается она. Так вот при первом вызове в g_iAuth[iClient] приходит пустое значение.

Подскажите как сделать проверку: Если g_iAuth[iClient] == null то return;

Верху плагина
C-подобный:
char g_iAuth[MAXPLAYERS + 1][32];
GetClientAuthId(iClient, AuthId_Steam2, g_iAuth[iClient], 32);

OnClientDisconnect()
C-подобный:
if(Мега проверка)
{
    LogToFile(ERR, "Словили пустой iAuth");
    return;
}
// Выполняем код[B]э[/B]
char szQuery[1024]; и т.д
LogToFile(LOG, "%s quit, iTime: %i", g_iAuth[iClient], g_iGame);
 

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
Приветствую.

Суть проблемы:
Иногда бывает когда игрок присоединится к серверу вызывается функция OnClientDisconnect() и когда выходит опять же вызывается она. Так вот при первом вызове в g_iAuth[iClient] приходит пустое значение.

Подскажите как сделать проверку: Если g_iAuth[iClient] == null то return;

Верху плагина
C-подобный:
char g_iAuth[MAXPLAYERS + 1][32];
GetClientAuthId(iClient, AuthId_Steam2, g_iAuth[iClient], 32);

OnClientDisconnect()
C-подобный:
if(Мега проверка)
{
    LogToFile(ERR, "Словили пустой iAuth");
    return;
}
// Выполняем код[B]э[/B]
char szQuery[1024]; и т.д
LogToFile(LOG, "%s quit, iTime: %i", g_iAuth[iClient], g_iGame);


C++:
if( !g_iAuth[client][0] ) return;

// Проверяем заполнена ли ячейка в строке [0]
// Если в ней есть что-то, то возвратит true, если нет то false
// Выше указано, что если стока не пустая (конкретно первый символ, пробел это тоже считается как символ), то return
 

DeeperSpy

Гений, миллиардер, плейбой, филантроп, майнкрафтер
Сообщения
588
Реакции
362
Приветствую.

Суть проблемы:
Иногда бывает когда игрок присоединится к серверу вызывается функция OnClientDisconnect() и когда выходит опять же вызывается она. Так вот при первом вызове в g_iAuth[iClient] приходит пустое значение.

Подскажите как сделать проверку: Если g_iAuth[iClient] == null то return;

Верху плагина
C-подобный:
char g_iAuth[MAXPLAYERS + 1][32];
GetClientAuthId(iClient, AuthId_Steam2, g_iAuth[iClient], 32);

OnClientDisconnect()
C-подобный:
if(Мега проверка)
{
    LogToFile(ERR, "Словили пустой iAuth");
    return;
}
// Выполняем код[B]э[/B]
char szQuery[1024]; и т.д
LogToFile(LOG, "%s quit, iTime: %i", g_iAuth[iClient], g_iGame);
g_iAuth[iClient] == 0
 

Puwok

Участник
Сообщения
37
Реакции
4
C++:
if( !g_iAuth[client][0] ) return;

// Проверяем заполнена ли ячейка в строке [0]
// Если в ней есть что-то, то возвратит true, если нет то false
// Выше указано, что если стока не пустая (конкретно первый символ, пробел это тоже считается как символ), то return

Лайком поддержал.

Заходил я на сервер где то час назад. Вот щяс плагин поправил по твоему методу, сделал sm plugins reload

Логи чистые.

Зашёл на сервер, сразу лог выскочил.

debug_SP:
L 10/01/2019 - 20:59:11: [StatsPlayers.smx] Словили пустой iAuth

Вышел:

StatsPlayers:
L 10/01/2019 - 20:59:22: [StatsPlayers.smx] STEAM_1:1:451171923 quit, iTime: 8

зашёл опять, всё нормально debug_sp не выскочил. Я так понял после перезагрузки плагина, и если я зайду то g_iAuth будет null у меня

Надо искать в плагине где собака зарыта.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
C-подобный:
SetPanelCurrentKey(panel, 10);
хм, и в КСГО эта кнопка видна и с ней можно взаимодействовать (в КСГО в меню на одну кнопку в меню меньше, чем в других играх)?
Для чего ты убрал iMax = SQL_GetRowCount(hndl);? Нужно было добавить отдельную переменную для квара, а эта у меня используется для того, чтобы не было пустых строк в меню, если игроков в списке меньше, чем 100.
Вот поставили у тебя в плагине значение квару равное 500, а игроков в списке штук 5 и будет у тебя 49 страниц без игроков.
C-подобный:
public GetTop100(Handle:owner, Handle:hndl, const String:error[], any:serial)
{
    ...
    iPos[client] = 1;    // сразу отправляем на вторую страницу?
    ...
}
C-подобный:
public FunctionDisplay(client, String:buffer[], maxlength)
{
    char buff[30];
    Format(buff, sizeof(buff), "ТОП%i богачей", iMax);
    strcopy(buffer, maxlength, buff);
}
а почему не просто
C-подобный:
public FunctionDisplay(client, String:buffer[], maxlength)
{
    FormatEx(buffer, 30, "ТОП%i богачей", iMax);
}
?
C-подобный:
if(iMax > 500) iMax = 500;
Вообще границы значений квара нужно было задавать при его создании вот так:
C-подобный:
(cvar = CreateConVar("sm_shop_top_max", "41", _, _, true, _, true, 500.0)).AddChangeHook(ChangeCvar_Max);
Сообщения автоматически склеены:

Подскажите как сделать проверку: Если g_iAuth[iClient] == null то return;
Наш человек читает мануал, только в одном случае?
bool GetClientAuthId(int client, AuthIdType authType, char[] auth, int maxlen, bool validate)
Return Value
True on success, false otherwise.
вот этого по идее должно быть достаточно
А на счёт получения пустой строки тебе правильно Loco написал, вот так нужно проверять: if(!g_iAuth[iClient][0]) return;
Сообщения автоматически склеены:

Я так понял после перезагрузки плагина, и если я зайду то g_iAuth будет null у меня
А при срабатывании какого события ты пытаешься получить SteamId?
Сообщения автоматически склеены:

Как-то можно это пофиксить?
DHooks самой свежей версии?
Все файлы, необходимые для работы расширения DHooks, обновлены?
 
Последнее редактирование:

Puwok

Участник
Сообщения
37
Реакции
4
А при срабатывании какого события ты пытаешься получить SteamId?


C-подобный:
public void OnClientPostAdminCheck(int iClient)
{
    if (!IsFakeClient(iClient))
    {
        char szQuery[256], szAuth[32];
        GetClientAuthId(iClient, AuthId_Engine, szAuth, sizeof(szAuth), true);
        FormatEx(szQuery, sizeof(szQuery), "Мега запрос", szAuth);
        g_hDatabase.Query(SQL_Callback_SelectClient, szQuery, GetClientUserId(iClient));
    }
}

public void SQL_Callback_SelectClient(Database hDatabase, DBResultSet hResults, const char[] sError, any iUserID)
{
    if (sError[0])
    {
        LogError("SQL_Callback_SelectClient: %s", sError);
        return;
    }
   
    int iClient = GetClientOfUserId(iUserID);
   
    if (iClient)
    {
        char szQuery[1024], szName[MAX_NAME_LENGTH * 2 + 1], sClientIP[PLATFORM_MAX_PATH];

        g_hDatabase.Escape(szQuery, szName, sizeof(szName));

        GetClientName(iClient, szQuery, MAX_NAME_LENGTH);
        GetClientIP(iClient, sClientIP, sizeof(sClientIP));
       
       
        GetClientAuthId(iClient, AuthId_Steam2, g_iAuth[iClient], 32);

        ниже код пошёл на обновления данных игрока в [B]MySQL[/B] либо добавление.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
а для чего ты получаешь SteamId 2 раза?
да ещё и разных типов
у тебя же должен всегда использоваться только 1, т.к. и работа ведётся только с одной БД
получи один раз и храни пока игрок на сервере
при работе с БД используй сохранённый SteamId
 

Puwok

Участник
Сообщения
37
Реакции
4
а для чего ты получаешь SteamId 2 раза?
да ещё и разных типов
у тебя же должен всегда использоваться только 1, т.к. и работа ведётся только с одной БД
получи один раз и храни пока игрок на сервере
при работе с БД используй сохранённый SteamId

Спасибо за совет, исправил.

C-подобный:
public void OnClientPostAdminCheck(int iClient) {
    if (!IsFakeClient(iClient)) {
        char szQuery[256];
        GetClientAuthId(iClient, AuthId_Steam2, g_iAuth[iClient], 32, true);
        FormatEx(szQuery, sizeof(szQuery), "Мега запрос", g_iAuth[iClient]);
        g_hDatabase.Query(SQL_Callback_SelectClient, szQuery, GetClientUserId(iClient));
    }
}
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Puwok, вообще, для получения AuthId_Steam2 можно использовать OnClientAuthorized() (кстати, в описании говорится что если нужен статус админа, то лучше использовать OnClientPostAdminCheck вместо OnClientAuthorized)
Called when a client receives an auth ID. The state of a client's authorization as an admin is not guaranteed here. Use OnClientPostAdminCheck() if you need a client's admin status.

This is called by bots, but the ID will be "BOT".
Вот как-то так:
C-подобный:
char sSId[MAXPLAYERS+1][24];

public void OnClientAuthorized(int client, const char[] auth)
{
    sSId[client][0] = 0;
    if(!IsFakeClient(client))
    {
        char szQuery[256];
        FormatEx(sSId[client], sizeof(sSId[client][]), auth);
        FormatEx(szQuery, sizeof(szQuery), "Мега запрос", auth);
        g_hDatabase.Query(SQL_Callback_SelectClient, szQuery, GetClientUserId(client));
    }
}

public void SQL_Callback_SelectClient(Database hDatabase, DBResultSet hResults, const char[] sError, any client)
{
    if(sError[0])
    {
        LogError("SQL_Callback_SelectClient: %s", sError);
        return;
    }

    if((client = GetClientOfUserId(client)))
    {
        char szQuery[1024],
            // ну как бы для чего нам строка длиннее максимальной длины имени?
            // Да и размер символьного массива округляется компилятором в большую сторону до числа кратного 4 или 8, не помню точно
            szName[MAX_NAME_LENGTH],
            // IP длиннее 15 символов это IP с портом, да и то это 21 символ всего, а не 256, как ты прописал
            IP[16];

        g_hDatabase.Escape(szQuery, szName, sizeof(szName));    // а где берётся значение szQuery?

        GetClientName(client, szQuery, sizeof(szQuery));
        GetClientIP(client, IP, sizeof(IP));
//        а дальше используем сохранённый sSId[client]
 
Последнее редактирование:

Allen

love society
Сообщения
352
Реакции
274
Спасибо за совет, исправил.

C-подобный:
public void OnClientPostAdminCheck(int iClient) {
    if (!IsFakeClient(iClient)) {
        char szQuery[256];
        GetClientAuthId(iClient, AuthId_Steam2, g_iAuth[iClient], 32, true);
        FormatEx(szQuery, sizeof(szQuery), "Мега запрос", g_iAuth[iClient]);
        g_hDatabase.Query(SQL_Callback_SelectClient, szQuery, GetClientUserId(iClient));
    }
}
Совет, вместо FormatEx лучше использовать Database.Format(). Database.Format · dbi · SourceMod Scripting API Reference
 

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
Почему команда дублируется от лица игрока несколько раз?
Это "несколько раз" == количеству заходов на сервер, то-есть если зашёл 5 раз на сервер, то тригерится 5 раз на одну команду.
47096
 

Вложения

  • fakerank_personal.sp
    5.2 КБ · Просмотры: 8

vitek37politov

Участник
Сообщения
49
Реакции
1
Нужен плагин для css OB, чтобы пишешь в чат !vk и вылезало окно с группой сервера, и так же для веб морды статистики level_ranks !st .
И еще замена стандартного сообщения {name} join is terrorist force с поддержкой morecolors
 
Последнее редактирование:

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
а почему ты сделал так:
C-подобный:
public void FRS_Overload()
{
    OnPluginStart();
}
?
Что бы при загрузке ядра, все его модули отослали данные игроков. А почему они в OnPluginsStart(), это из-за того, что бы модуль можно было подгрузить посреди карты и не было с ним траблов

Команда показывается только когда я напишу !cfr
Триггернится столько же раз, сколько я перезашёл на сервер
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Loco, попробуй такой вариант (немного почистил и оптимизировал код)
 

Вложения

  • fakerank_personal.sp
    5 КБ · Просмотры: 5
Сверху Снизу