Team Select Menu проверка кода

Статус
В этой теме нельзя размещать новые ответы.
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
В чем смысл блока деф.меню (можно просто текст поменять в хуке)? И в чем смысл реквестфрейма.
 
Сообщения
499
Реакции
271
Помог
6 раз(а)
fl0wer, это BlackSignature всё))) Надо ждать его ответа по этому поводу.
Помнится, у меня падал сервер на моменте входе игрока в игру, каждые 3 дня (+- пару часов). путем отключения плагинов с 90% вероятностью было выявлено, что дело в Team select от вактинчи. BlackSignature посоветовал сделать как выше, открытие меню в новом кадре. После этого, падения с данной частотой прекратились.
У меня тоже меню через следующий кадр работает. Интересно посмотреть, как выглядит стабильный вариант без реквест фрейма.
 
Сообщения
443
Реакции
319
Помог
13 раз(а)
Тебе уже написали как... Меняешь аргумент прямо в коллбеке.
1586240221000.png
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
CHEL74, RG_ShowMenu ловишь и меняешь аргументы, в итоге будет "деф" менюшка, но с твоими фичами. В RG_HandleMenu_ChooseTeam ловишь кнопки и так же, делаешь что угодно. В RG_ShowVGUIMenu можно отключить вгуи.

Как работает хук: https://github.com/s1lentq/ReGameDL...c2d2d8498f23aa/regamedll/dlls/client.cpp#L409
Как вызывается хук: https://github.com/s1lentq/ReGameDL...2d2d8498f23aa/regamedll/dlls/client.cpp#L2051

Сам ShowMenu вызывается только от деф.менюшек и который вызывается из ShowVGUIMenu.
https://github.com/s1lentq/ReGameDL...c2d2d8498f23aa/regamedll/dlls/client.cpp#L397
 
Сообщения
1,032
Реакции
828
Помог
10 раз(а)
fl0wer, не додумался сразу менять в коллбеке, тот вариант что в первом посте работает сразу и на олд меню и на графическое меню без дополнительных манипуляций, так сказать :D
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Javekson, доп.манипуляция это поставить оффсет?)
 
Сообщения
1,032
Реакции
828
Помог
10 раз(а)
fl0wer, все таки замечаю за собой, что сложно прерываться на неделю две от кода, что-то махом забываю все =D В общем я не нашел где вы обсуждали о rg_join_team и почему его надо юзать в путинсервере, а не в том варианте, в каком он сейчас используется у меня
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Javekson, при коннекте у игрока не спектаторская команда. Для входа используется натив с названием join, где производятся различ.манипуляции. А если игрок уже имеет команду (т, кт, спектатор), то можно просто команду менять.

https://github.com/s1lentq/ReGameDLL_CS/blob/master/regamedll/dlls/API/CSPlayer.cpp#L31
 
Сообщения
1,032
Реакции
828
Помог
10 раз(а)
fl0wer, в общем взял код фантома, пока наброском сделал, вроде работает все

Код:
#include < amxmodx >
#include < reapi >

#pragma semicolon 1

new const MENU_CONTENT[ ] =
{
    "^t^t^t^t\rVK.COM/GMFORCE^n\
    ^t^t^t^t\yМеню выбора команды^n^n\
    ^t^t^t^t\y1. \wТеррористы^n\
    ^t^t^t^t\y2. \wКонтр-террористы^n^n\
    ^t^t^t^t\y5. \wСлучайный выбор^n\
    ^t^t^t^t\y6. \wНаблюдатели^n^n\
    ^t^t^t^t\y0. \wВыход"
};

new HookChain: g_hookShowMenu;

public plugin_init( )
{
    RegisterHookChain( RG_ShowVGUIMenu, "hook_ShowVGUIMenu", .post = false );
    RegisterHookChain( RG_HandleMenu_ChooseTeam, "hook_HandleMenuChooseTeamPre", .post = false );
    RegisterHookChain( RG_HandleMenu_ChooseTeam, "hook_HandleMenuChooseTeamPost", .post = true );
    
    DisableHookChain( g_hookShowMenu = RegisterHookChain( RG_ShowMenu, "hook_ShowMenu", .post = false ) );
}

public hook_ShowVGUIMenu( const id, VGUIMenu: menuType, const bitsSlots, const szOldMenu[ ] )
{
    if( menuType != VGUI_Menu_Team )
    {
        return HC_CONTINUE;
    }
    
    set_member( id, m_bForceShowMenu, true );
    
    SetHookChainArg( 3, ATYPE_INTEGER, MENU_KEY_0 | MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_6 );
    
    SetHookChainArg( 4, ATYPE_STRING, MENU_CONTENT );
    
    if( strlen( MENU_CONTENT ) > 192 )
    {
        EnableHookChain( g_hookShowMenu );
    }
    
    return HC_CONTINUE;
}

public hook_HandleMenuChooseTeamPre( const id, const MenuChooseTeam: slot )
{
    if( is_user_alive( id ) )
    {
        user_silentkill( id );
    }
    
    set_member_game( m_bSkipShowMenu, true );
    
    return HC_CONTINUE;
}

public hook_HandleMenuChooseTeamPost( const id, const MenuChooseTeam: slot )
{
    set_member( id, m_bTeamChanged, false );
    
    set_member_game( m_bSkipShowMenu, false );
    
    set_member( id, m_iMenu, Menu_ChooseAppearance );
    
    rg_internal_cmd( id, "joinclass", "5" );
}

public hook_ShowMenu( const id, const bitsSlots, const iDisplayTime, const iNeedMore, pszText[ ] )
{
    DisableHookChain( g_hookShowMenu );
    
    show_menu( id, bitsSlots, pszText, iDisplayTime );
    
    set_member( id, m_iMenu, Menu_ChooseTeam );
    
    return HC_SUPERCEDE;
}
 

Ayk

Сообщения
763
Реакции
478
Помог
19 раз(а)
Кто может объяснить мне эту часть?
Код:
    if( strlen( MENU_CONTENT ) > 192 )
    {
        EnableHookChain( g_hookShowMenu );
    }

// ...

public hook_ShowMenu( const id, const bitsSlots, const iDisplayTime, const iNeedMore, pszText[ ] )
{
    DisableHookChain( g_hookShowMenu );
    
    show_menu( id, bitsSlots, pszText, iDisplayTime );
    
    set_member( id, m_iMenu, Menu_ChooseTeam );
    
    return HC_SUPERCEDE;
}
 
Сообщения
1,293
Реакции
2,295
Помог
57 раз(а)
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Ayk, в менюшке нельзя много текста, отправляют несколькими мессагами.
Note: Multipart should be 1 if your menu takes up multiple messages (i.e.: string is too big to fit into one). On the final message, Multipart should be 0.
https://wiki.alliedmods.net/Half-Life_1_Game_Events#ShowMenu
 
Сообщения
1,032
Реакции
828
Помог
10 раз(а)
Ayk, как сказали выше, нельзя больше 192 байтов, иначе крашится сервер, поэтому обходим это иным способом, а так либо первый вариант, где мы строим свое меню, либо этот вариант, где подменяем меню
 
  • Нравится
Реакции: Ayk
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
Ayk, все просто. Если текст меню длиннее и не помещается в 1 сообщение, то отправка идет в нескольких через параметр multipart. В регейме же используется только 1 сообщение (из-за чего текст длиннее 192 байта не влезет). А отправка мультыпарт меню в регейме и не нужна, так как по умолчанию там обычный текст ("#CT_Select" и другие). Здесь же трюк состоит в том, чтобы перехватить отображение меню и вызвать show_menu. Там уже организована поддержка multipart. Таким образом мы способны отобразить больше текста. В идеале же лучше сделать свой сток для отображения меню.
 
Сообщения
1,032
Реакции
828
Помог
10 раз(а)
fantom, такой вариант тоже не плохо работает, убрал rg_join_team так-как при нем RG_HandleMenu_ChooseTeam не вызывался вроде бы вообще, что наверное критично будет для других плагинов, поэтому заменил на rg_internal_cmd, провел первые тесты, работает, что с олд меню, что с вгуи меню

Код:
#include < amxmodx >
#include < reapi >

#pragma semicolon 1

const MENU_KEYS        =    MENU_KEY_0 | MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_6;
const TIME_MENU        =    -1;

new const MENU_IDENT__TEAM_SELECT_MENU[ ]    =    "TEAM SELECT MENU";

enum
{
    KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0
}

new const MENU_CONTENT[ ] =
{
    "^t^t^t^t\yМеню выбора команды^n^n\
    ^t^t^t^t\y1. \wТеррористы^n\
    ^t^t^t^t\y2. \wКонтр-террористы^n^n\
    ^t^t^t^t\y5. \wСлучайный выбор^n\
    ^t^t^t^t\y6. \wНаблюдатели^n^n\
    ^t^t^t^t\y0. \wВыход"
};

public plugin_init( )
{
    RegisterHookChain( RG_ShowVGUIMenu, "hook_ShowVGUIMenu", .post = false );
  
    register_menucmd( register_menuid( MENU_IDENT__TEAM_SELECT_MENU ), MENU_KEYS, "handler_TeamSelectMenu" );
}

public hook_ShowVGUIMenu( const id, VGUIMenu: menuType, const bitsSlots, const szOldMenu[ ] )
{
    if( menuType != VGUI_Menu_Team )
    {
        return HC_CONTINUE;
    }
  
    RequestFrame( "func_OpenTeamSelectMenu", id );
  
    return HC_SUPERCEDE;
}

public func_OpenTeamSelectMenu( const id )
{
    set_member( id, m_bForceShowMenu, true );
  
    show_menu( id, MENU_KEYS, MENU_CONTENT, TIME_MENU, MENU_IDENT__TEAM_SELECT_MENU );
  
    return PLUGIN_CONTINUE;
}

public handler_TeamSelectMenu( const id, const iKey )
{
    switch( iKey )
    {
        case KEY_1:
        {
            rg_internal_cmd( id, "jointeam", "1" );
        }
      
        case KEY_2:
        {
            rg_internal_cmd( id, "jointeam", "2" );
        }
      
        case KEY_5:
        {
            rg_internal_cmd( id, "jointeam", "5" );
        }
      
        case KEY_6:
        {
            user_silentkill( id );
          
            rg_internal_cmd( id, "jointeam", "6" );
        }
      
        case KEY_0:
        {
            return PLUGIN_HANDLED;
        }
    }
  
    rg_internal_cmd( id, "joinclass", "5" );
  
    set_member( id, m_bTeamChanged, false );
  
    return PLUGIN_HANDLED;
}
 
Сообщения
77
Реакции
7
Помог
4 раз(а)
Javekson, Нажимаешь "Выход" и тупа бегаешь наблюдателем!:dirol:
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Попробовал отправить большой текст кусками (566). Лимит 512 все равно.
Правда почему 192 решили. Даже в этом вашем амхмодх указано 175.
https://github.com/alliedmodders/am...577ca35426053db8dd7f8902/amxmodx/util.cpp#L48
1586255280949.png
Код:
#pragma semicolon 1

#include <amxmodx>

public plugin_init()
{
    register_clcmd("say t", "@t");
}

@t(id)
{
    new text[][175] =
    {
        "Counter-Strike (CS) is a series of multiplayer^n",
        "first-person shooter video games,^n",
        "in which teams of terrorists battle to perpetrate^n",
        "an act of terror (bombing, hostage-taking, assassination)^n",
        "and counter-terrorists try to prevent it^n",
        "(bomb defusal, hostage rescue).^n",
        "The series began on Windows in 1999 with^n",
        "the first game, Counter-Strike.^n",
        "It was initially released as a modification^n",
        "(^"mod^")for Half-Life^n",
        "and designed by Minh ^"Gooseman^" Le^n",
        "and Jess ^"Cliffe^" Cliffe^n",
        "before the rights to the game's intellectual^n",
        "property were acquired by Valve,^n",
        "the developers of Half-Life.",
    };

    new len, i;

    for (i = 0; i < sizeof(text) - 1; i++)
    {
        len += strlen(text[i]);
        SendShowMenu(id, 1023, -1, 1, text[i]);
    }

    i = sizeof(text) - 1;
    len += strlen(text[i]);

    SendShowMenu(id, 1023, -1, 0, text[i]);

    client_print(0, print_chat, "%d", len);
}

SendShowMenu(id, keys, time, multipart, text[])
{
    static msg;

    if (!msg)
        msg = get_user_msgid("ShowMenu");

    message_begin(MSG_ONE, msg, _, id);
    write_short(keys);
    write_char(time);
    write_byte(multipart);
    write_string(text);
    message_end();
}
 
Последнее редактирование:
Сообщения
1,032
Реакции
828
Помог
10 раз(а)
Abram4ik, как ля? почему у меня такого нету? Подробнее пожалуйста всю последовательность действий, и какой из двух тут вариантов использовалось?
7 Апр 2020
fl0wer, потому что крашится с ошибкой
Host_Error: PF_MessageEnd_I: Refusing to send user message ShowMenu of 243 bytes to client, user message size limit is 192 bytes
 
Сообщения
1,032
Реакции
828
Помог
10 раз(а)
fl0wer,

Код:
public hook_ShowVGUIMenu( const id, VGUIMenu: menuType, const bitsSlots, const szOldMenu[ ] )
{
    SetHookChainArg( 3, ATYPE_INTEGER, MENU_KEY_0 | MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_6 );
    
    SetHookChainArg( 4, ATYPE_STRING, MENU_CONTENT );
    
    return HC_CONTINUE;
}
user message size limit is 192 bytes
Или я не так понимаю ошибку краша в лимит 192 байта?
 
Статус
В этой теме нельзя размещать новые ответы.

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу