Kick игрока с причиной в меню админа Sourcemod

Тема в разделе "Общие вопросы", создана пользователем ★Сириус★, 10 дек 2013.

  1. ★Сириус★

    ★Сириус★

    Сообщения:
    748
    Симпатии:
    199
    Kick игрока с причиной в меню админа Sourcemod

    [​IMG]
    Есть два варианта для добавления причин Кика в меню админа, рассмотрим эти два варианта.

    Вариант №1
    Открываем файл: ../addons/sourcemod/configs/adminmenu_custom.txt
    и заполняем его следующим:
    Код:
    "Commands"
    {
        "PlayerCommands"
        {
    		"Кикнуть игрока"
            {
                "cmd"        "sm_kick #1 @2"
                "1"
                {
                    "title"       "Выберите игрока"
                    "type"        "player"
                }
                "2"
                {
                    "title"        "Причина кика"
                    "type"         "list"
                        "1"            "мат"
                        "2"            "оскорбление игроков"
                        "3"            "реклама"
                        "4"            "спам в микрофон"
                        "5"            "игнорирование админа"
                        "6"            "некорректный спрей"
                        "7"            "нарушение правил сервера"
                        "8"            "другое"
                        "9"            "долгое время в спеках"
                }
            }
        }		
    } 
    но после этого, у нас в меню админа, в категории «Управление игроками», появится два пункта Кик игрока (стандартное и наше, вновь встроенное). Поэтому данный вариант не очень удобный. И во втором варианте рассмотрим, как добавить причины Кика в стандартную функцию.


    Вариант №2
    В этом варианте добавим причины в стандартную функцию Кика. Но здесь мы будем уже редактировать стандартные исходники плагинов, а затем компилировать уже.
    1. Открываем файл: ../addons/sourcemod/scripting/basecommands.sp
      И вставляем в него после строчек:
      Код:
      new Handle:g_MapList;
      new Handle:g_ProtectedVars;
      следующее:
      Код:
      new g_kickTarget[MAXPLAYERS+1];
      Сохраняем этот файл.

    2. Теперь открываем файл: ../addons/sourcemod/scripting/basecommands/kick.sp
      Находим строку (48 примерно)
      Код:
      DisplayKickMenu(client)
      и заменяем на:
      Код:
      DisplayKickTargetMenu(client)
      Теперь после этой функции:
      Код:
      DisplayKickTargetMenu(client)
      {
      	new Handle:menu = CreateMenu(MenuHandler_Kick);
      	
      	decl String:title[100];
      	Format(title, sizeof(title), "%T:", "Kick player", client);
      	SetMenuTitle(menu, title);
      	SetMenuExitBackButton(menu, true);
      	
      	AddTargetsToMenu(menu, client, false, false);
      	
      	DisplayMenu(menu, client, MENU_TIME_FOREVER);
      }
      вставляем наши причины:
      Код:
      DisplayKickReasonMenu(client)
      {
      	new Handle:menu = CreateMenu(MenuHandler_Reason);
      	
      	decl String:title[100];
      	Format(title, sizeof(title), "Kick reason", client);
      	SetMenuTitle(menu, title);
      	SetMenuExitBackButton(menu, true);
      
      	AddMenuItem(menu, "Abusive", "Abusive");
      	AddMenuItem(menu, "Racism", "Racism");
      	AddMenuItem(menu, "General cheating/exploits", "General cheating/exploits");
      	AddMenuItem(menu, "Wallhack", "Wallhack");
      	AddMenuItem(menu, "Aimbot", "Aimbot");
      	AddMenuItem(menu, "Speedhacking", "Speedhacking");
      	AddMenuItem(menu, "Mic spamming", "Mic spamming");
      	AddMenuItem(menu, "Admin disrepect", "Admin disrepect");
      	AddMenuItem(menu, "Camping", "Camping");
      	AddMenuItem(menu, "Team killing", "Team killing");
      	AddMenuItem(menu, "Unacceptable Spray", "Unacceptable Spray");
      	AddMenuItem(menu, "Breaking Server Rules", "Breaking Server Rules");
      	AddMenuItem(menu, "Other", "Other");
      	
      	DisplayMenu(menu, client, MENU_TIME_FOREVER);
      }
      Находим строчку (101 примерно строка):
      Код:
      		DisplayKickMenu(param);
      заменяем на:
      Код:
      		DisplayKickTargetMenu(param);
      находим (110 примерно строка)
      Код:
      			decl String:name[MAX_NAME_LENGTH];
      			GetClientName(target, name, sizeof(name));
      			ShowActivity2(param1, "[SM] ", "%t", "Kicked target", "_s", name);
      			PerformKick(param1, target, "");
      заменяем на:
      Код:
      			g_kickTarget[param1] = target;
      			DisplayKickReasonMenu(param1);
      		}
      	}
      }
      
      public MenuHandler_Reason(Handle:menu, MenuAction:action, param1, param2)
      {
      	if (action == MenuAction_End)
      	{
      		CloseHandle(menu);
      	}
      	else if (action == MenuAction_Cancel)
      	{
      		if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
      		{
      			DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
      		}
      	}
      	else if (action == MenuAction_Select)
      	{
      		new target = g_kickTarget[param1];
      		decl String:info[64];
      		
      		GetMenuItem(menu, param2, info, sizeof(info));
      
      		if (target == 0)
      		{
      			PrintToChat(param1, "[SM] %t", "Player no longer available");
      		}
      		else if (!CanUserTarget(param1, target))
      		{
      			PrintToChat(param1, "[SM] %t", "Unable to target");
      		}
      		else
      		{			
      			ShowActivity2(param1, "[SM] ", "%N kicked %N (Reason: %s)", param1, target, info);
      			PerformKick(param1, target, info);
      находим (119 примерно строка):
      Код:
      			DisplayKickMenu(param1);
      заменяем на:
      Код:
      			DisplayKickTargetMenu(param1);
      Компилируем плагин, и кидаем на сервер. После чего, наша родная встроенная функция Кик игрока, будет с причинами.

      Примечание: Если вы причины указываете на русском, то перед компиляцией плагина, необходимо исходник kick.sp перевести в кодировку UTF8 без BOM.
      И число символов в левой части не должно превышать 62 знака, иначе причины игроку будут показываться обрезанными.
      Подсчитать символы можно с помощью программы Notepad++
      Пример ниже
      [​IMG]
    Послесловие от меня: Данной модификацией пользуюсь уже примерно месяцев 7 и это очень помогает порой объяснить игроку, что так делать нельзя, при этом без лишних слов.
    Эту модификацию я нашел здесь: forums.alliedmods.net
    Ниже во вложении прилагаются готовые файлы для Sourcemod_1.5.2
     

    Вложения:

    666FoX666, tikto0, Alcone и 14 другим нравится это.
  2. ★Сириус★

    ★Сириус★

    Сообщения:
    748
    Симпатии:
    199
    блин, я тему наверно не там создал, прошу прощения

    Добавлено через 19 минут
    кстати, если кодеры помогут сделать причины в отдельный файл, было бы вообще здорово.
    Например не приходилось бы под каждый сервер компилировать плагин со своими причинами
     
    Последнее редактирование: 10 дек 2013
  3. CTe6eJIeK_vRn

    CTe6eJIeK_vRn Супер-модератор

    Сообщения:
    2.014
    Симпатии:
    1.797
  4. White Wolf

    White Wolf [] (int _n) -> double { return (_n % 2) == 0;}); Супер-модератор

    Сообщения:
    1.187
    Симпатии:
    413
    Ну кода-же разрабы сами запилят это в исходник. А то приходиться все делать самим. Хотя в команду указание причины они добавили.
    sm_kick player reason
     
  5. OffsprinG

    OffsprinG

    Сообщения:
    59
    Симпатии:
    16
    Может хоть тут помогут :]
    Вызываю админ меню, выбираю пункт кик, выбираю игрока и тут он отсоединяется... и далее выбираю причину кика. Из-за этого такая ошибка:
    Код:
    L 12/09/2013 - 00:50:24: SourceMod error session started
    L 12/09/2013 - 00:50:24: Info (map "de_dust2") (file "errors_20131209.log")
    L 12/09/2013 - 00:50:24: [SM] Native "CanUserTarget" reported: Client 5 is not connected
    L 12/09/2013 - 00:50:24: [SM] Displaying call stack trace for plugin "basecommands.smx":
    L 12/09/2013 - 00:50:24: [SM]   [0]  Line 170, basecommands/kick.sp::MenuHandler_Reason()
    Прошу помочь.
     
  6. ★Сириус★

    ★Сириус★

    Сообщения:
    748
    Симпатии:
    199
    Ошибка которая может произойти раз на 1000000 случаев и совсем не опасная, за 7 месяцев ни разу такого не произошло.
    Забудь и юзай дальше.
    Если у тебя постоянно на сервере перезаходят, поставь это: http://hlmod.ru/forum/plaginy-dlya-sourcemod/98-anti-reconnect-v-1-1-5-a.html
    Если есть желание наказать вышедших, поставь это: http://hlmod.ru/forum/plaginy-dlya-sourcemod/4323-ban-disconnected-players-1-04-a.html
    или это при наличии Системы банов: http://hlmod.ru/forum/plaginy-dlya-sourcemod/16982-offline-ban-list-v1-0-9-sourcebans.html
     
    OffsprinG нравится это.
  7. Серый™

    Серый™ CS:S Server

    Сообщения:
    2.558
    Симпатии:
    1.143
    ★Сириус★, просто надо добавить проверку есть ли игрок на сервере.
     
    OffsprinG и ★Сириус★ нравится это.
  8. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.972
    Симпатии:
    2.978
    Ошибки быть не должно, скомпилируйте сами
     

    Вложения:

    ★Сириус★ и OffsprinG нравится это.
  9. ★Сириус★

    ★Сириус★

    Сообщения:
    748
    Симпатии:
    199
    R1KO, то есть судя по твоему решению, я так понял, найти в: kick.sp
    Код:
    	else if (action == MenuAction_Select)
    	{
    		decl String:info[32];
    		new userid, target;
    		
    		GetMenuItem(menu, param2, info, sizeof(info));
    		userid = StringToInt(info);
    
    		if ((target = GetClientOfUserId(userid)) == 0)
    		{
    			PrintToChat(param1, "[SM] %t", "Player no longer available");
    		}
    		else if (!CanUserTarget(param1, target))
    		{
    			PrintToChat(param1, "[SM] %t", "Unable to target");
    		}
    		else
    		{
    			g_kickTarget[param1] = target;
    			DisplayKickReasonMenu(param1);
    		}
    
    	}
    и заменить на:
    Код:
    	else if (action == MenuAction_Select)
    	{
    		decl String:info[32];
    
    		GetMenuItem(menu, param2, info, sizeof(info));
    		
    		new target = GetClientOfUserId(StringToInt(info));
    
    		if (target > 0 && IsClientInGame(target))
    
    		{
    			g_kickTarget[param1] = target;
    			DisplayKickReasonMenu(param1);
    		}
    		else PrintToChat(param1, "[SM] %t", "Player no longer available");
    	}
     
    OffsprinG нравится это.
  10. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.972
    Симпатии:
    2.978
    ★Сириус★, один из вариантов.
     
  11. OffsprinG

    OffsprinG

    Сообщения:
    59
    Симпатии:
    16
    Все это и так есть.
    Вот, то что надо :)
    Спасибо что откликнулись.
    Проверю - отпишу.
     
  12. ★Сириус★

    ★Сириус★

    Сообщения:
    748
    Симпатии:
    199
    ждем, мне нечем проверять, все мои сервера кроме апокалипсиса дохлые
     
  13. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.972
    Симпатии:
    2.978
    А еще лучше так:

    PHP:
    if(target && IsClientInGame(target))

        {
            if(
    CanUserTarget(param1target))
            {
                
    g_kickTarget[param1] = target;
                
    DisplayKickReasonMenu(param1);
            } else 
    PrintToChat(param1"[SM] %t""Unable to target");
        } else 
    PrintToChat(param1"[SM] %t""Player no longer available");
     
    Последнее редактирование: 10 дек 2013
  14. OffsprinG

    OffsprinG

    Сообщения:
    59
    Симпатии:
    16
    Я взял твое вложение и все равно ошибки:
    Код:
    L 12/10/2013 - 20:43:07: SourceMod error session started
    L 12/10/2013 - 20:43:07: Info (map "de_dust2") (file "errors_20131210.log")
    L 12/10/2013 - 20:43:07: [SM] Native "CanUserTarget" reported: Client 3 is not connected
    L 12/10/2013 - 20:43:07: [SM] Displaying call stack trace for plugin "basecommands.smx":
    L 12/10/2013 - 20:43:07: [SM]   [0]  Line 156, H:\SERVER\01-scripting-sm1.5.2\addons\sourcemod\scripting\basecommands/kick.sp::MenuHandler_Reason()
    Сейчас проверю.

    Добавлено через 10 минут
    :(

    [​IMG]

    Вот как выглядит кусок кода, верно же все?

    PHP:
    public MenuHandler_Kick(Handle:menuMenuAction:actionparam1param2)
    {
        if (
    action == MenuAction_End)
        {
            
    CloseHandle(menu);
        }
        else if (
    action == MenuAction_Cancel)
        {
            if (
    param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
            {
                
    DisplayTopMenu(hTopMenuparam1TopMenuPosition_LastCategory);
            }
        }
        else if (
    action == MenuAction_Select)
        {
            
    decl String:info[32];
            
    GetMenuItem(menuparam2infosizeof(info));
            
            new 
    target GetClientOfUserId(StringToInt(info));

            if (
    target && IsClientInGame(target)) 
            { 
              if(
    CanUserTarget(param1target
              { 
                  
    g_kickTarget[param1] = target
                  
    DisplayKickReasonMenu(param1); 
              } 
              else 
    PrintToChat(param1"[SM] %t""Unable to target"); 
            } 
            else 
    PrintToChat(param1"[SM] %t""Player no longer available");
        }
    }
     
    Последнее редактирование: 10 дек 2013
  15. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.972
    Симпатии:
    2.978
  16. OffsprinG

    OffsprinG

    Сообщения:
    59
    Симпатии:
    16
  17. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.972
    Симпатии:
    2.978
    OffsprinG, я исправил его
     
  18. OffsprinG

    OffsprinG

    Сообщения:
    59
    Симпатии:
    16
    [​IMG]
    Но сейчас только проверю.
     
  19. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.972
    Симпатии:
    2.978
    OffsprinG, это просто предупреждение. Не обращай внимания.
     
  20. OffsprinG

    OffsprinG

    Сообщения:
    59
    Симпатии:
    16
    :(

    PHP:
    L 12/10/2013 22:57:36: [SMNative "CanUserTarget" reportedClient 3 is not connected
    L 12
    /10/2013 22:57:36: [SMDisplaying call stack trace for plugin "basecommands.smx":
    L 12/10/2013 22:57:36: [SM]   [0]  Line 159H:\SERVER\01-scripting-sm1.5.2\addons\sourcemod\scripting\basecommands/kick.sp::MenuHandler_Reason()
    PHP:
    public MenuHandler_Kick(Handle:menuMenuAction:actionparam1param2)
    {
        if (
    action == MenuAction_End)
        {
            
    CloseHandle(menu);
        }
        else if (
    action == MenuAction_Cancel)
        {
            if (
    param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
            {
                
    DisplayTopMenu(hTopMenuparam1TopMenuPosition_LastCategory);
            }
        }
        else if (
    action == MenuAction_Select)
        {
            
    decl String:info[32];
            
    GetMenuItem(menuparam2infosizeof(info));
            
            new 
    target GetClientOfUserId(StringToInt(info));

            if(
    target && IsClientInGame(target))

        {
            if(
    CanUserTarget(param1target))
            {
                
    g_kickTarget[param1] = target;
                
    DisplayKickReasonMenu(param1);
            } else 
    PrintToChat(param1"[SM] %t""Unable to target");
        } else 
    PrintToChat(param1"[SM] %t""Player no longer available");
        }
    }

    Что же опять не так?