У меня тоже меню через следующий кадр работает. Интересно посмотреть, как выглядит стабильный вариант без реквест фрейма.Помнится, у меня падал сервер на моменте входе игрока в игру, каждые 3 дня (+- пару часов). путем отключения плагинов с 90% вероятностью было выявлено, что дело в Team select от вактинчи. BlackSignature посоветовал сделать как выше, открытие меню в новом кадре. После этого, падения с данной частотой прекратились.
#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;
}
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;
}
У меня суперцидится RG_ShowVGUIMenu, потому сразу подменять меню нельзя, не сработает при входе это нормально. Метод же другой, по коду это очевидно.это BlackSignature всё)))
"#CT_Select"
и другие). Здесь же трюк состоит в том, чтобы перехватить отображение меню и вызвать show_menu. Там уже организована поддержка multipart. Таким образом мы способны отобразить больше текста. В идеале же лучше сделать свой сток для отображения меню.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;
}
#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();
}
Host_Error: PF_MessageEnd_I: Refusing to send user message ShowMenu of 243 bytes to client, user message size limit is 192 bytes
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;
}
Или я не так понимаю ошибку краша в лимит 192 байта?user message size limit is 192 bytes