[SourcePawn] Урок 15 - API (natives, forwards, functions)

Banana

Участник
Сообщения
892
Реакции
113
LogError, правда оно укажет именно на эту строку, удобно если их много, а текст ошибки один.
LogError просто делает запись в логи но не указывает строку.. дайте пример если у вас указывает.
--- Добавлено позже ---
@Banana, то что выше написали и еще ThrowNativeError ThrowError
ThrowError отрубает плагин где было вызвано это... можно как-то его не оключать? просто ошибку написало и живем дальше)
 
Последнее редактирование:

fl0wer

Участник
Сообщения
19
Реакции
3
Ан нет, я упоролся. Моя ошибка. У меня LogError стояло, оно не указывало строку, сейчас посмотрел там ThrowError.
 

Banana

Участник
Сообщения
892
Реакции
113
Плагин №1.

PHP:
public GetFullAdminInfoForStaemID(char SteamID[32])
{
    new Handle:b_pack = CreateDataPack();   
        WritePackCell(b_pack, 0);
        WritePackString(b_pack, "INVALID_STEAMID");
        return b_pack;
  }


Плагин №2 вызывает функцию в плагине №1... (цель - получить данные из b_pack который отправил плагин №1 в качестве ответа плагину №2).

PHP:
int rtn;
    Call_StartForward(h_GetFullAdminInfoForStaemID);
    Call_PushString(SteamID);
    Call_Finish(rtn);

DataPack b_pack = view_as<DataPack>(rtn); // Получаем наш DataPack
    ResetPack(b_pack);

ERROR на ResetPack(b_pack); - L 08/09/2019 - 03:55:08: [SM] Exception reported: Invalid data pack handle 32870127 (error 5)
Сообщения автоматически склеены:

Или предложите как передать данные разных типов через Forward
 
Последнее редактирование:

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #27
Покажите код создания форварда.В
Вообще, пятый код ошибки - это "Нет доступа". Передайте права на хендл нужному плагину.
 
Последнее редактирование:

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #28
по идее это из-за того что владелец хендла - плагин №1 и эта переменная находится в его стеке, получается что она доступна только ему.
Если ты хочешь чтобы тебе в ответ всегда возвращался датапак - просто создавай его в плагине 2 и передавай параметром в форварде, тогда можно и не возвращать т.к. он по ссылке будет изменять оригинал.
Или через CloneHandle сделать плагин 2 владельцем, но тогда нужно зать его handle
 

Banana

Участник
Сообщения
892
Реакции
113
Покажите код создания форварда.В
Вообще, пятый код ошибки - это "Нет доступа". Передайте права на хендл нужному плагину.
ПЛАГИН №2
PHP:
new Handle:h_GetFullAdminInfoForStaemID; 

public OnPluginStart()
{
h_GetFullAdminInfoForStaemID = CreateGlobalForward("GetFullAdminInfoForStaemID", ET_Single, Param_String);
}

bool GetFullAdminInfoForStaemIDFunc(char SteamID[32])
{
    int rtn;
    Call_StartForward(h_GetFullAdminInfoForStaemID);
    Call_PushString(SteamID);
    Call_Finish(rtn); 
    
    return rtn;
}

//Где-то мы вызываем его..
int iDataPack = GetFullAdminInfoForStaemIDFunc(SteamID);
    new Handle:b_pack = view_as<DataPack>(iDataPack); // Получаем наш DataPack
    ResetPack(b_pack);

ПЛАГИН №1

PHP:
public GetFullAdminInfoForStaemID(char SteamID[32])
{
    new Handle:b_pack = CreateDataPack();   
        WritePackCell(b_pack, 0);
        WritePackString(b_pack, "INVALID_STEAMID");
        return b_pack;
  }
Сообщения автоматически склеены:

по идее это из-за того что владелец хендла - плагин №1 и эта переменная находится в его стеке, получается что она доступна только ему.
Если ты хочешь чтобы тебе в ответ всегда возвращался датапак - просто создавай его в плагине 2 и передавай параметром в форварде, тогда можно и не возвращать т.к. он по ссылке будет изменять оригинал.
Или через CloneHandle сделать плагин 2 владельцем, но тогда нужно зать его handle
Пожалуйста помогите кодом так мне будет куда понятней что вы хотите предложить.
Сообщения автоматически склеены:

"Передать права на хэндл".. дайте пример пожалуйста, я без понятия как это делать.
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #30
Если что, на форуме можно уже форматировать в С++ стиле, а не в PHP. [CODE=cpp]код[/CODE]

Пожалуйста помогите кодом так мне будет куда понятней что вы хотите предложить.
Это сложно, потому что реализация "смены владельца" требует иметь хендл плагина, кому нужно передать права. В Вашей реализации такого не предусмотрено.
Добавьте в форвард ещё один Cell, и:
C++:
Call_PushCell(GetMyHandle())
А в том плагине, в котором производите "махинации":
C++:
public GetFullAdminInfoForStaemID(char SteamID[32], Handle hRequester) // в данном случае, предполагаем, что хендл приходит вторым аргументом
{
    new Handle:hPack = CreateDataPack();   
    WritePackCell(hPack, 0);
    WritePackString(hPack, "INVALID_STEAMID");

    new Handle:hReturnPack = CloneHandle(hPack, hRequester);
    hPack.Close();
    return hReturnPack;
}
 

Banana

Участник
Сообщения
892
Реакции
113
Если что, на форуме можно уже форматировать в С++ стиле, а не в PHP. [CODE=cpp]код[/CODE]


Это сложно, потому что реализация "смены владельца" требует иметь хендл плагина, кому нужно передать права. В Вашей реализации такого не предусмотрено.
Добавьте в форвард ещё один Cell, и:
C++:
Call_PushCell(GetMyHandle())
А в том плагине, в котором производите "махинации":
C++:
public GetFullAdminInfoForStaemID(char SteamID[32], Handle hRequester) // в данном случае, предполагаем, что хендл приходит вторым аргументом
{
    new Handle:hPack = CreateDataPack();  
    WritePackCell(hPack, 0);
    WritePackString(hPack, "INVALID_STEAMID");

    new Handle:hReturnPack = CloneHandle(hPack, hRequester);
    hPack.Close();
    return hReturnPack;
}

В 2 ПЛАГИНЕ ТАК ДОЛЖНО БЫТЬ?
PHP:
}
    h_GetFullAdminInfoForStaemID = CreateGlobalForward("GetFullAdminInfoForStaemID", ET_Single, Param_String, Param_Cell);
}

bool GetFullAdminInfoForStaemIDFunc(char SteamID[32])
{
    int rtn;
    Call_StartForward(h_GetFullAdminInfoForStaemID);
    Call_PushString(SteamID);
    Call_PushCell(h_GetFullAdminInfoForStaemID)
    Call_Finish(rtn); 
    
    return rtn;
}
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #32
Зачем форвард передаёте?
Нужно передавать именно хендл плагина (его возвращает натив GetMyHandle()).
А так, да.
 

Banana

Участник
Сообщения
892
Реакции
113
Сообщения автоматически склеены:

Если вас не затруднит подскажите как передать массив данных через Forward в другой плагин?
Сообщения автоматически склеены:

Может вы подскажете)
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #37
Вы документацию пробовали читать? Только честно.
Рядом с этим нативом располагается Call_PushArrayEx(), который умеет еще возвращать в плагин, откуда производится вызов, модифицированный массив.

Не ленитесь читать документацию, плз. На 90% Ваших вопросов по скриптингу, ответ в ней есть.
 

Banana

Участник
Сообщения
892
Реакции
113
Call_StartForward(h_OnGetPlayers);
Call_PushArrayEx(array, MAXPLAYERS+1, SM_PARAM_COPYBACK);
Call_Finish();

Ругается на Call_PushArrayEx -
L 08/31/2019 - 13:59:05: [SM] Exception reported: Maximum number of parameters reached
сама функция такая - CreateGlobalForward("OnGetPlayers", ET_Ignore); //ET_Ignoreпотому что по сути мы изменяем входящий массив но ничего не возвращаем (подумал я...)
Сообщения автоматически склеены:

Блин какой я не внимательный забыл указать Param_Array ... вопрос снят спасибо.
 
Последнее редактирование:

Banana

Участник
Сообщения
892
Реакции
113
Можно ли передать двумерый массив типа char через Forward?
 

rejchev

менеджер клоунов
Сообщения
1,669
Реакции
1,291
@Banana ,
Как то так:
void func()
{
    char szBuffer[MAXPLAYERS+1][PMP];

    //...

    ArrayList aBuffer = ConVertToArrayList(szBuffer, sizeof(szBuffer), sizeof(szBuffer[]));

    Call_StartForward(/*...*/);
    Call_PushCell(aBuffer);
    Call_Finish();

}

ArrayList ConVertToArrayList(const char[][] szBuffer, int iSize, const int iBlockSize)
{
    ArrayList aBuffer = new ArrayList(iBlockSize, 0);

    for(int i; i < iSize; i++)
        aBuffer.PushString(i, szBuffer[i]);

    return aBuffer;
}
 
Сверху Снизу