ReHLDS/ReAPI AWPoff

fantom

Разработчик
Регистрация
11 Июн 2017
Сообщения
426
Симпатии
293
Пол
Мужской
Я не знаю, мб он сейчас подправлен в реапи, я не чекал обновлений, и не знаю какая сейчас обстановка там с апишкой.
но тогда и в harestrictitem был такой косячок
Хз когда он был косячным, всегда адекватно работал. Скорей всего не учитывалось множественные тачи с оружием на карте. Думаю посмотреть в исход регейма и все бы стало на свои места.

А HasRestrictItem заменил на BuyWeaponByWeaponID из-за того что вторрой хук срабатывает онли при покупке
Хукаем пост BuyWeaponByWeaponID, получаем с помощью GetHookChainReturn ентити и выставляем например var_iuser1 что авп куплено. Готово. Также в посте RG_CBasePlayer_AddPlayerItem можно убрать что куплено и считать его поднятым или полученым с вип магазина (которій кстати также может иметь свою цену). В таком случае мы дважды выставляем и убираем маркировку (при покупке), но зато надежно работает.

Ну и касательно убирания в начале раунда, то тут уже чисто ИМХО, которое также высказал Vaqtincha. Убирать в начале раунда незачем.
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame
fantom,
Хз когда он был косячным, всегда адекватно работал. Скорей всего не учитывалось множественные тачи с оружием на карте. Думаю посмотреть в исход регейма и все бы стало на свои места.
Ну что я видел, то и косстылил


Хукаем пост BuyWeaponByWeaponID, получаем с помощью GetHookChainReturn ентити и выставляем например var_iuser1 что авп куплено. Готово. Также в посте RG_CBasePlayer_AddPlayerItem можно убрать что куплено и считать его поднятым или полученым с вип магазина (которій кстати также может иметь свою цену). В таком случае мы дважды выставляем и убираем маркировку (при покупке), но зато надежно работает.
Это классно, что мы отследим, что авп куплено, но так же надо ослеживать статус авп у игрока куплено/поднято/выброшено/нет


Ну и касательно убирания в начале раунда, то тут уже чисто ИМХО, которое также высказал @Vaqtincha. Убирать в начале раунда незачем.
//#define NOEND //Если разкоментировано, то не будет отбирать АВП в конце раунда из-за низкого онлайна. [Если онлайн ниже чем указан в кваре и человек сам дропнет авп или потеряет ее, то подобрать заного не сможет]

Еще раз спрошу, Вы точно смотрели код плагина и вникали вообще в его работу?
 

fantom

Разработчик
Регистрация
11 Июн 2017
Сообщения
426
Симпатии
293
Пол
Мужской
Это классно, что мы отследим, что авп куплено, но так же надо ослеживать статус авп у игрока куплено/поднято/выброшено/нет
Эммм. Я же расписал почти весь алгоритм. В ентити авп мы и храним значение. Если оно було куплено то вызов будет примерно следующым
BuyWeaponByWeaponID пре
HasRestrictItem пре
HasRestrictItem пост
AddPlayerItem пре
AddPlayerItem пост (убрали флаг что куплено)
BuyWeaponByWeaponID пост (установили флаг что куплено)
Если кто то выбросит его, и другой игрок поднимет, то последовательность будет примерно такой
CArmoury или CWeaponBox Touch пре
HasRestrictItem пре
HasRestrictItem пост
AddPlayerItem пре
AddPlayerItem пост (убрали флаг что куплено)
CArmoury или CWeaponBox Touch пост.
Убрали из ентити что оно куплено.

Если будет выдано плагином, то последовательность будет примерно так же как и выше, кроме тача с CWeaponBox или CArmoury.
По сути любая выдача оружия игроку это тач ентити оружия с игроком внутри которого идет вызов AddPlayerItem.
 

cpCTRL

bruh
Скриптер
Постоялец
Регистрация
20 Фев 2018
Сообщения
263
Симпатии
65
Пол
Мужской
paffgame, и еще раз костыль с хуком BuyWeaponByWeaponID. А если скидка на авп в магазине для випов? Вот так нужно делать
Код:
public CBasePlayer_HasRestrictItem_Pre(const id, const ItemID:item, const ItemRestType:type) {
    if (/*если не авп или авп и разрешено выходим*/) {
        return HC_CONTINUE;
    }

    if (type == ITEM_TYPE_BUYING) {
        // оповещаем игрока что купить не возможно.
        // Можно еще и при подьеме оповещать, но нужно учесть несколько раз вызов тача
    }

    SetHookChainReturn(ATYPE_BOOL, true);
    return HC_SUPERCEDE;
}
Все. Таким образом покупка у нас запрещена. Никаких денег возвращать не нужно. Также тач с оружием на карте проверили и с выброшенным также. Плюс ко всему еще экипировку при спавне также проверяем, но можно опустить.

А вот хук для выдачи авп всякими випками и прочими плагинами
Код:
public CBasePlayer_AddPlayerItem_Pre(const id, const item) {
   if (/*если не авп или авп и разрешено выходим*/) {
        return HC_CONTINUE;
    }

    // оповещаем игрока что не возможно получить авп.
    SetHookChainReturn(ATYPE_INTEGER, false);
    return HC_SUPERCEDE;
}
Стоит также учесть что после покупки будет вызван также CBasePlayer_AddPlayerItem. Это легко решается либо временным хранением результата с ид игрока, ид итема и результатом ровно на 1 кадр, либо отключением и включением хука. И все 2 хука всего лишь.

Остается только решить вопрос с говновипками которые не проверяют валидность итема после выдачи. Но тут как говорится проблемы тех кто пользуется ими, а не лимитера. Также для проверки есть ли авп у игрока легко использовать битовую маску
Код:
get_entvar(player, var_weapons) & BIT(WEAPON_AWP)
Итого у нас код сокращается в двое, нет дурацкого выбрасывания АВП и возврат денег. Нам все это не нужно.
Не проверял, но по данной логике должно работать без отбирания, онли блок
Код:
#include <amxmodx>
#include <reapi>
#include <amxmisc>

enum    {
    BLOCK_ONLINE = 1,
    BLOCK_LIMIT
};

new g_iAw1kInTeam[TeamName: TEAM_SPECTATOR];

new g_iMinOnline, g_iAw1kAllowed;

public plugin_init()    {
    register_plugin("Awp Restrictions", "1.1", "wrx?!");

    RegisterHookChain(RG_CBasePlayer_AddPlayerItem, "CBasePlayer_AddPlayerItem_Pre", false);
    RegisterHookChain(RG_CBasePlayer_HasRestrictItem, "CBasePlayer_HasRestrictItem_Pre", false);
    RegisterHookChain(RG_CBasePlayer_RemovePlayerItem, "CBasePlayer_RemoveItem_Pre", false);

    register_logevent("LogEvent_RestartRound", 2, "1&Restart_Round_");

    new pCvar    = create_cvar(
        "awp_min_online",
        "10",
        .description = "Минимальное количество игроков для доступа к АВП",
        .has_min = true, .min_val = 1.0,
        .has_max = true, .max_val = 32.0
    );
    bind_pcvar_num(pCvar, g_iMinOnline);

    pCvar    = create_cvar(
        "awp_allowed",
        "2",
        .description = "Сколько АВП на команду разрешено",
        .has_min = true, .min_val = 1.0,
        .has_max = true, .max_val = 16.0
    );
    bind_pcvar_num(pCvar, g_iAw1kAllowed);

    AutoExecConfig(true, "awp_restrictions");
}

public plugin_natives()    {
    register_native("is_awp_blocked", "_is_awp_blocked", false);
}

public _is_awp_blocked(plugin, params)    {
    enum { arg_player = 1 };

    new id = get_param(arg_player);

    if (!(id >= 1 && id <= MaxClients) || !is_user_connected(id))
        return 0;

    return is_awp_blocked(id);
}

public plugin_cfg()    {
    register_dictionary("awp_restrictions.txt");
}

public LogEvent_RestartRound()    {
    g_iAw1kInTeam[TEAM_CT] = 0;
    g_iAw1kInTeam[TEAM_TERRORIST] = 0;
}

public CBasePlayer_HasRestrictItem_Pre(id, ItemID: eItem, ItemRestType: eType)    {
    if (eItem != ITEM_AWP)
        return HC_CONTINUE;

    if (!is_awp_blocked(id))    {
        g_iAw1kInTeam[get_member(id, m_iTeam)]++;
        return HC_CONTINUE;
    }

    client_print(id, print_center, "%L", id, is_awp_blocked(id) == BLOCK_ONLINE ? "AWP_LOW_ONLINE" : "AWP_LIMIT");

    SetHookChainReturn(ATYPE_BOOL, true);
    return HC_SUPERCEDE;
}

public CBasePlayer_AddPlayerItem_Pre(id, pItem){
    if (get_member(pItem, m_iId) != WEAPON_AWP)
        return HC_CONTINUE;

    if (!is_awp_blocked(id))    {
        g_iAw1kInTeam[get_member(id, m_iTeam)]++;
        return HC_CONTINUE;
    }

    client_print(id, print_center, "%L", id, is_awp_blocked(id) == BLOCK_ONLINE ? "AWP_LOW_ONLINE" : "AWP_LIMIT");

    SetHookChainReturn(ATYPE_INTEGER, false);
    return HC_SUPERCEDE;
}

public CBasePlayer_RemoveItem_Pre(id, pItem)    {
    if (get_member(pItem, m_iId) == WEAPON_AWP)    {
        g_iAw1kInTeam[get_member(id, m_iTeam)]--;
    }
    return HC_CONTINUE;
}

stock is_awp_blocked(id)    {
    new eType,
        playersCount[2];

    playersCount[0] = get_playersnum_ex(GetPlayers_ExcludeHLTV | GetPlayers_MatchTeam, "CT");
    playersCount[1] = get_playersnum_ex(GetPlayers_ExcludeHLTV | GetPlayers_MatchTeam, "TERRORIST");

    if ((playersCount[0] + playersCount[1]) < g_iMinOnline)
        eType = BLOCK_ONLINE;
    else if (g_iAw1kInTeam[get_member(id, m_iTeam)] >= g_iAw1kAllowed)
        eType = BLOCK_LIMIT;
    else
        eType = 0;

    return eType;
}
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame
Хз когда он был косячным, всегда адекватно работал. Скорей всего не учитывалось множественные тачи с оружием на карте. Думаю посмотреть в исход регейма и все бы стало на свои места.
Без имени-1.pngБез имени-2.pngБез имени-2.png
 

Вложения

fantom

Разработчик
Регистрация
11 Июн 2017
Сообщения
426
Симпатии
293
Пол
Мужской
/* * * Первая "покупка" при нехватке денег проскакивает >< * * */
Касательно этого. Нам и не нужна проверка денег по сути. Да она находится ниже проверки рестрикта. Но нам нужно проверить только не попали мы в лимит на количество в команде или онлайну или еще чего то там. А хватает денег или нет в конкретном случае нас мало волнует. Если мы попали в лимит мы так и пишем игроку, что превышен лимит. Если все ок, то геймдлл сам проверит количество денег и если их не хватит выведет стандартное сообщение о том, что игрок бомж и купить авп не получится. А также еще проверка на то есть ли оружие у игрока или нет ну и множество других. Все прям внутри самого регейма. Ничего сверху городить не нужно.[DOUBLEPOST=1579555479][/DOUBLEPOST]
Не проверял, но по данной логике должно работать без отбирания, онли блок
Так я о чем и говорю.
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame
fantom, cpCTRL, до вас доходит, хотя бы до одного человека, когда в моем плагине происходит ОТБОР авп?

Ладно не нравятся массивы - ок, переживу
но АВП здесь лочится, а не отбирается
 

fantom

Разработчик
Регистрация
11 Июн 2017
Сообщения
426
Симпатии
293
Пол
Мужской
Ну йомайо. Хукаешь пре хуки. Я выше полностью расписал подробно очередь пре и пост хуков. Для чег ои для кого. Ясень пень что пре хук RG_BuyWeaponByWeaponID будет вызван в первую очередь. А внутри него RG_CBasePlayer_HasRestrictItem и RG_CBasePlayer_AddPlayerItem
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame
fantom, ну так и азчем мне так много хуков когда можно все прекраснов пре обработать, процессор от такого плагина не умрет[DOUBLEPOST=1579555736][/DOUBLEPOST]да и вобщее, если так пошло, то почему бы просто уже не сделать кому-нибудь одному нормальный плагин подобный, а мой просто закинуть в топку

Я на место скриптера нормального никогда не претендовал, и здесь группу получил случайно
 

fantom

Разработчик
Регистрация
11 Июн 2017
Сообщения
426
Симпатии
293
Пол
Мужской
ну так и азчем мне так много хуков когда можно все прекраснов пре обработать, процессор от такого плагина не умрет
Все понятно. Зря старался донести мысль. В первом же сообщении я описал всего 2 хука с помощью которых можно лочить выдачу. Потом я описал алгоритм хука покупное или нет. По сути еще 2 пост хука. Потом я описал весь порядок вызовов при разных сценариях. Но если до сих пор не дошло, то и дальше не дойдет. Думаю на этом можно закончить ибо дальше не вижу смысла расписывать весь процесс выдачи. Просто загляни в исходники.
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame
fantom, вот на этом и закончим тогда
 

fantom

Разработчик
Регистрация
11 Июн 2017
Сообщения
426
Симпатии
293
Пол
Мужской
Я ваше мнение поддерживаю, и благодаря вам мб останусь на своем варианте.
Так то касательно выдачи он прав. Там лочится. Можно конечно доебатся к вот этому куску (сократил код)
Код:
public AddItem(id, pItem){
    SetHookChainReturn(ATYPE_INTEGER, false);
    return HC_SUPERCEDE;
}
Так как там не булевая false, а поинтер, и если лочить то нужно возвращать nullptr, а это 0. Но павн такой что false конвертирует в 0 и все работает.
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame

cpCTRL

bruh
Скриптер
Постоялец
Регистрация
20 Фев 2018
Сообщения
263
Симпатии
65
Пол
Мужской
Так то касательно выдачи он прав. Там лочится.
Да, но куски кода с отбором авп для меня лишние, да и читабильность из-за кучи #ifdef хромает как по мне, функционал остается тот-же, лишнего - меньше
 

fantom

Разработчик
Регистрация
11 Июн 2017
Сообщения
426
Симпатии
293
Пол
Мужской
бляяя, хоть кто-то просмотрел исход.
Я смотрел и до этого код. Ах да, раз ты тут уже. Еще доеб минимальный. Двойная проверка на лимит при покупке. Сначала в BuyWeaponByWeaponID потом в AddItem. Почему уже сам думай. Я и так почти полностью все написал выше
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame
fantom, нету атм двойной проверки, я вот прям уверен.
потому что
C++:
gAwp[id] > AWP_NONE
все гасит, или не гасит???

Да гасит же, наверное потому-что аддитем вызывается после байвеапона, о чем было мне и самому сложно догадаться :c
 

fantom

Разработчик
Регистрация
11 Июн 2017
Сообщения
426
Симпатии
293
Пол
Мужской
paffgame, Не гасит при условии что ты разрешил все таки покупку
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame
fantom, если покупка разрешилась, то gAwp[id] = AWP_BUY;, если не разрешена то аддитем даже и не вызовется.

А теперь ссамый сок:

C++:
enum {
    AWP_DROP = 0,
    AWP_NONE,
    AWP_BUY,
    AWP_PICK_UP
};
Ну и если забыли, то вот:
/
C++:
public AddItem(id, pItem){
    if(get_member(pItem, m_iId) != WEAPON_AWP || gAwp[id] > AWP_NONE || !is_user_valid(id))
        return HC_CONTINUE;
 

paffgame

D0L64E6
Разработчик
Регистрация
9 Июн 2017
Сообщения
154
Симпатии
84
Пол
Мужской
Telegram
@paffgame
Ну йомайо. Хукаешь пре хуки.
Без имени-1.pngБез имени-2.png

Единственное в чем выиграл HasRestrictItem - в том, что он не реагирует на покупку во время истечения mp_buytime
Из-за чего конечно есть смысл обратно вернуться на него, но делать связку пре + пост смысла нет (это если я правильно Вашу мысль улавливал)

Так что костыль навеки со мной :Drinks:
 

Вложения

Сверху Снизу