Написание плагинов

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
PHP:
#pragma semicolon 1

#include <sourcemod>
#include <sdktools>
#include <hosties>
#include <lastrequest>

#define HEBATTLE_VERSION "1.0.2"

new g_LREntryNum;
new LR_Player_Guard;
new LR_Player_Prisoner;
new String:g_sLR_Name[64];
new bool:IsThisLRInProgress = false;
new g_iHealth;
new starthp = 100;
new Handle:g_Cvar_Health;

public Plugin:myinfo =
{
    name = "Last Request: HE Battle",
    author = "Jason Bourne & Kolapsicle",
    description = "",
    version = HEBATTLE_VERSION,
    url = ""
};


public OnPluginStart()
{
    LoadTranslations("hebattle.phrases");

    Format(g_sLR_Name, sizeof(g_sLR_Name), "%T", "LR Name", LANG_SERVER);

    HookEvent("player_hurt", EventPlayerHurt, EventHookMode_Pre);
    HookEvent("hegrenade_detonate", GrenadeDetonate);

    g_iHealth = FindSendPropOffs("CCSPlayer", "m_iHealth");
    if (g_iHealth == -1)
    {
        SetFailState("Error - Unable to get offset for CSSPlayer::m_iHealth");
    }
 
    g_Cvar_Health = CreateConVar("sm_hebattle_health", "100", "How much health should be given?", FCVAR_PLUGIN, true, 0.0, false);
    CreateConVar("hebattle_version", HEBATTLE_VERSION, "Current Max Damage version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
    AutoExecConfig(true, "hebattle");
}


public OnConfigsExecuted ()
{
    starthp = GetConVarInt(g_Cvar_Health);
 
    static bool:bAddedCustomLR = false;
    if ( ! bAddedCustomLR)
    {
        g_LREntryNum = AddLastRequestToList(LR_Start, LR_Stop, g_sLR_Name);
        bAddedCustomLR = true;
    }
}


public OnPluginEnd()
{
    RemoveLastRequestFromList(LR_Start, LR_Stop, g_sLR_Name);
}


public LR_Start(Handle:LR_Array, iIndexInArray)
{
    new This_LR_Type = GetArrayCell(LR_Array, iIndexInArray, _:Block_LRType);
    if (This_LR_Type == g_LREntryNum)
    {
        LR_Player_Prisoner = GetArrayCell(LR_Array, iIndexInArray, _:Block_Prisoner);
        LR_Player_Guard = GetArrayCell(LR_Array, iIndexInArray, _:Block_Guard);

        // check datapack value
        new LR_Pack_Value = GetArrayCell(LR_Array, iIndexInArray, _:Block_Global1);
        switch (LR_Pack_Value)
        {
            case -1:
            {
                PrintToServer("no info included");
            }
        }

        SetEntityHealth(LR_Player_Prisoner, starthp);
        SetEntityHealth(LR_Player_Guard, starthp);

        StripAllWeapons(LR_Player_Prisoner);
        StripAllWeapons(LR_Player_Guard);

        GivePlayerItem(LR_Player_Prisoner, "weapon_hegrenade");
        GivePlayerItem(LR_Player_Guard, "weapon_hegrenade");

        IsThisLRInProgress = true;
        PrintToChatAll(CHAT_BANNER, "LR Start", LR_Player_Prisoner, LR_Player_Guard);

        CreateTimer(60.0, LR_Timeout);
        PrintCenterTextAll("Игра закончится через %d секунд!", 60);
    }
}

public Action:LR_Timeout(Handle:hTimer, any:data) {
    if (IsThisLRInProgress)
        ForcePlayerSuicide((GetEntData(LR_Player_Guard, g_iHealth, 4) < GetEntData(LR_Player_Prisoner, g_iHealth, 4)) ? LR_Player_Guard : LR_Player_Prisoner);
}


public LR_Stop(This_LR_Type, Player_Prisoner, Player_Guard)
{
    if (IsThisLRInProgress && This_LR_Type == g_LREntryNum)
    {
        LR_Player_Prisoner = Player_Prisoner;
        LR_Player_Guard = Player_Guard;

        if (IsPlayerAlive(LR_Player_Prisoner) && IsPlayerAlive(LR_Player_Guard))
        {
            SetEntityHealth(LR_Player_Prisoner, 100);
            GivePlayerItem(LR_Player_Prisoner, "weapon_knife");
            SetEntityHealth(LR_Player_Guard, 100);
            GivePlayerItem(LR_Player_Guard, "weapon_knife");
            PrintToChatAll(CHAT_BANNER, "LR No Winner");
        } else if (IsPlayerAlive(LR_Player_Prisoner))
        {
            SetEntityHealth(LR_Player_Prisoner, 100);
            GivePlayerItem(LR_Player_Prisoner, "weapon_knife");
            PrintToChatAll(CHAT_BANNER, "LR Winner", LR_Player_Prisoner);
        } else if (IsPlayerAlive(LR_Player_Guard))
        {
            SetEntityHealth(LR_Player_Guard, 100);
            GivePlayerItem(LR_Player_Guard, "weapon_knife");
            PrintToChatAll(CHAT_BANNER, "LR Winner", LR_Player_Guard);
        }
    }

    IsThisLRInProgress = false;
}


public Action:EventPlayerHurt(Handle:event, const String:name[],bool:dontBroadcast)
{
    new victim = GetClientOfUserId(GetEventInt(event, "userid"));
    new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
    new dhealth = GetEventInt(event, "dmg_health");
    new health = GetEventInt(event, "health");

    if (IsThisLRInProgress && IsClientInLastRequest(victim))
    {
        decl String:wname[64];
        GetEventString(event, "weapon", wname, sizeof(wname));

        if (victim == LR_Player_Guard || victim == LR_Player_Prisoner)
        {
            if ( ! StrEqual(wname, "hegrenade", false) || (attacker != LR_Player_Prisoner && attacker != LR_Player_Guard))
            {
                SetEntData(victim, g_iHealth, (health + dhealth), 4, true);
            }
        }
    }
    return Plugin_Continue;
}


public Action:GrenadeDetonate(Handle:event, const String:name[], bool:dontBroadcast)
{
    new client = GetClientOfUserId(GetEventInt(event, "userid"));

    if(StrEqual(name, "hegrenade_detonate"))
    {
        if (IsThisLRInProgress && (client == LR_Player_Guard || client == LR_Player_Prisoner))
        {
            GivePlayerItem(client, "weapon_hegrenade");
        }
    }
 
    return Plugin_Handled;
}
 
Последнее редактирование:

ivanms1337

Участник
Сообщения
69
Реакции
2
Ох уж эта css(лично для меня), ну не играл я в нее, не играл.. Тьфу ты, точнее не держал сервера там.

Попробуйте так...
PHP:
public OnPluginStart() HookEvent("player_death", PlayerDeath);

public Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
   new client = GetClientOfUserId(GetEventInt(event, "userid"));
 
   if(GetClientFrags(client) < 0) SetEntProp(client, Prop_Data, "m_iFrags", 0);
}
Все равно
 

DarklSide

Участник
Сообщения
931
Реакции
468
PHP:
public OnPluginStart()HookEvent("player_death", PlayerDeath);
public Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    if (client > 0)CreateTimer(0.1, TimerFrags, GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE);
}
public Action:TimerFrags(Handle:timer, any:serial)
{
    new client = GetClientFromSerial(serial);
    if (IsClientInGame(client) && GetClientFrags(client) < 0)SetEntProp(client, Prop_Data, "m_iFrags", 0);
    return Plugin_Stop;
}
 

ivanms1337

Участник
Сообщения
69
Реакции
2
PHP:
public OnPluginStart()HookEvent("player_death", PlayerDeath);
public Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    if (client > 0)CreateTimer(0.1, TimerFrags, GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE);
}
public Action:TimerFrags(Handle:timer, any:serial)
{
    new client = GetClientFromSerial(serial);
    if (IsClientInGame(client) && GetClientFrags(client) < 0)SetEntProp(client, Prop_Data, "m_iFrags", 0);
    return Plugin_Stop;
}
Спасибо все замечательно работает
 

ivanms1337

Участник
Сообщения
69
Реакции
2
Можете добавить в плагин что бы когда кикало, писал сервер что кикнут игрок?

PHP:
#pragma semicolon 1
#include <sourcemod>

public OnPluginStart()
{
    HookEvent("player_changename", player_changename);
}

public player_changename(Handle:event, const String:name[], bool:dontBroadcast)
{
    KickClient(GetClientOfUserId(GetEventInt(event, "userid")), "Запрещенно менять ник на сервере");
}
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
PHP:
#pragma semicolon 1
#include <sourcemod>

public OnPluginStart()
{
    HookEvent("player_changename", player_changename);
}

public player_changename(Handle:event, const String:name[], bool:dontBroadcast) {
    new iClient = GetClientOfUserId(GetEventInt(event, "userid"));

    PrintToChatAll("[SM] Игрок %N кикнут за изменение имени", iClient);
    KickClient(iClient, "Запрещено менять ник на сервере");
}
Оффтоп
 

edik06041

Участник
Сообщения
2
Реакции
0
Помогите установил MYJB сборку, в консоле пишет что все плагины ERORS или Failed
 

ivanms1337

Участник
Сообщения
69
Реакции
2
PHP:
#pragma semicolon 1
#include <sourcemod>

public OnPluginStart()
{
    HookEvent("player_changename", player_changename);
}

public player_changename(Handle:event, const String:name[], bool:dontBroadcast) {
    new iClient = GetClientOfUserId(GetEventInt(event, "userid"));

    PrintToChatAll("[SM] Игрок %N кикнут за изменение имени", iClient);
    KickClient(iClient, "Запрещено менять ник на сервере");
}
Оффтоп
В этом коде игрок успевает сменить ник, после смены только кикает, а надо что бы его кикнуло и он не успел сменить ник
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
@ivanms1337, А по другому и никак. Смиритесь.
И вообще неясно, зачем Вам такое.
 

Someone

Участник
Сообщения
1,933
Реакции
1,653

Аналогично с другими типами голосований (basevotes/votekick.sp и другие).

PHP:
public Action Command_Vote(int client, int args)
{
    if (args < 1)
    {
        ReplyToCommand(client, "[SM] Usage: sm_vote <question> [Answer1] [Answer2] ... [Answer5]");
        return Plugin_Handled; 
    }
  
    if (IsVoteInProgress())
    {
        ReplyToCommand(client, "[SM] %t", "Vote in Progress");
        return Plugin_Handled;
    }
      
    if (!TestVoteDelay(client))
    {
        return Plugin_Handled;
    }
  
    char text[256];
    GetCmdArgString(text, sizeof(text));

    char answers[5][64];
    int answerCount; 
    int len = BreakString(text, g_voteArg, sizeof(g_voteArg));
    int pos = len;
  
    while (args > 1 && pos != -1 && answerCount < 5)
    { 
        pos = BreakString(text[len], answers[answerCount], sizeof(answers[]));
        answerCount++;
      
        if (pos != -1)
        {
            len += pos;
        } 
    }

    LogAction(client, -1, "\"%L\" initiated a generic vote.", client);
    ShowActivity2(client, "[SM] ", "%t", "Initiate Vote", g_voteArg);
  
    g_voteType = question;
  
    g_hVoteMenu = new Menu(Handler_VoteCallback, MENU_ACTIONS_ALL);
    g_hVoteMenu.SetTitle("%s?", g_voteArg);
    
    g_hVoteMenu.AddItem("", "Свой текст", ITEMDRAW_DISABLED);
    g_hVoteMenu.AddItem("", "Свой текст 2", ITEMDRAW_DISABLED);
    
    FormatEx(text, sizeof(text), "%t", "My_Text_3");
    g_hVoteMenu.AddItem("", text, ITEMDRAW_DISABLED);
  
    if (answerCount < 2)
    {
        g_hVoteMenu.AddItem(VOTE_YES, "Yes");
        g_hVoteMenu.AddItem(VOTE_NO, "No");
    }
    else
    {
        for (int i = 0; i < answerCount; i++)
        {
            g_hVoteMenu.AddItem(answers[i], answers[i]);
        } 
    }
  
    g_hVoteMenu.ExitButton = false;
    g_hVoteMenu.DisplayVoteToAll(20);     
  
    return Plugin_Handled; 
}
 

Someone

Участник
Сообщения
1,933
Реакции
1,653
ничего не изменилось, создал голосование за карту, 5 карт и все, текста нету
--- Добавлено позже ---
хотелсь бы как в этом плагине MapChooser Extended 1.10.2 (Updated 2014-02-05) - AlliedModders
--- Добавлено позже ---
текст такой
1. Не менять
2. Выбери, какая карта будет следующей...
3. ...и не клацай кнопки,не подумав ;-)
4 карта
5. карта
6. карта
7. карта
8. карта
Я там только для sm_vote сделал.

Аналогично с другими типами голосований (basevotes/votekick.sp и другие).

Просто скопируй, то что я написал и в ставь в другие голосования.
 
Последнее редактирование:

ivanms1337

Участник
Сообщения
69
Реакции
2
@ivanms1337, А по другому и никак. Смиритесь.
И вообще неясно, зачем Вам такое.
Можете сюда еще добавить ?

PHP:
#include <sourcemod>

#define PLUGIN_VERSION "1.1.5"

new bool:g_bKickedByPlugin[MAXPLAYERS+1];

new Handle:g_kvDB = INVALID_HANDLE;

new Handle:cvar_ar_time = INVALID_HANDLE;
new Handle:cvar_ar_admin_immunity = INVALID_HANDLE;
new Handle:cvar_ar_disconnect_by_user_only = INVALID_HANDLE;
new Handle:cvar_lan = INVALID_HANDLE;

new bool:isLAN = false;
new ar_time = 30;
new ar_disconnect_by_user_only = true;
new ar_admin_immunity = false;


public OnPluginStart()
{
    g_kvDB = CreateKeyValues("AntiReconnect");
    
    CreateConVar("sm_anti_reconnect_version", PLUGIN_VERSION, "Версия плагина", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
    cvar_ar_time = CreateConVar("sm_anti_reconnect_time", "10", "Время в секундах, после которого игрок снова может зайти на сервер.", FCVAR_PLUGIN, true, 0.0);
    cvar_ar_disconnect_by_user_only = CreateConVar("sm_anti_reconnect_disconnect_by_user_only", "1", "\n0: Заблокировать все реконекты, \n1: Заблокировать, если игрок вышел самостоятельно.", FCVAR_PLUGIN, true, 0.0, true, 1.0);
    cvar_ar_admin_immunity = CreateConVar("sm_anti_reconnect_admin_immunity", "1", "Включить/выключить иммунитет.", FCVAR_PLUGIN, true, 0.0, true, 1.0);
    cvar_lan = FindConVar("sv_lan");
    
    HookConVarChange(cvar_ar_time, OnCVarChange);
    HookConVarChange(cvar_ar_disconnect_by_user_only, OnCVarChange);
    HookConVarChange(cvar_ar_admin_immunity, OnCVarChange);
    HookConVarChange(cvar_lan, OnCVarChange);
    
    HookEvent("player_disconnect", Event_PlayerDisconnect, EventHookMode_Post);
    
    AutoExecConfig(true, "AntiReconnect");
    LoadTranslations("AntiReconnect.phrases");
}

public Action:Event_PlayerDisconnect(Handle:event, const String:name[], bool:dontBroadcast)
{
    decl String:reason[128];
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    
    if (g_bKickedByPlugin[client] || !client)
        return;
    
    GetEventString(event, "reason", reason, 128);

    if (StrEqual(reason, "Disconnect by user.") || !ar_disconnect_by_user_only)
    {
        if (isLAN || ar_time == 0 || IsFakeClient(client))
            return;
        
        if (GetUserFlagBits(client) && ar_admin_immunity)
            return;
        
        decl String:steamId[30];
        GetClientAuthString(client, steamId, sizeof(steamId));
        
        KvSetNum(g_kvDB, steamId, GetTime());
    }
}

public OnClientPostAdminCheck(client)
{
    g_bKickedByPlugin[client] = false;
    
    if (isLAN || ar_time == 0 || IsFakeClient(client) || !IsClientConnected(client))
        return;
    
    decl String:steamId[30];   
    GetClientAuthString(client, steamId, sizeof(steamId));   
    
    new disconnect_time = KvGetNum(g_kvDB, steamId, -1);
    
    if (disconnect_time == -1)
        return;
    
    new wait_time = disconnect_time + ar_time - GetTime();
    
    if (wait_time <= 0)
    {
        KvDeleteKey(g_kvDB, steamId);
    }
    else
    {
        g_bKickedByPlugin[client] = true;
        KickClient(client, "%t", "You are not allowed to reconnect for X seconds", wait_time);
        LogAction(-1, client,"Kicked \"%L\". Player is not allowed to reconnect for %d seconds.", client, wait_time);
    }
}

public OnCVarChange(Handle:convar_hndl, const String:oldValue[], const String:newValue[])
{
    GetCVars();
}

public OnConfigsExecuted()
{
    GetCVars();
}

public OnMapStart()
{
    CloseHandle(g_kvDB);
    g_kvDB = CreateKeyValues("AntiReconnect");
}

public GetCVars()
{
    isLAN = GetConVarBool(cvar_lan);
    ar_time = GetConVarInt(cvar_ar_time);
    ar_disconnect_by_user_only = GetConVarBool(cvar_ar_disconnect_by_user_only);
    ar_admin_immunity = GetConVarBool(cvar_ar_admin_immunity);
}
 

kleuser

Участник
Сообщения
1,838
Реакции
732
Кто может сделать простой плагин?
Нужно когда игрок не двигается (афк в начале раунда) его нельзя было убить, и при этому моделька окрашивалась в любой указанный цвет. Что-то типо как в плагине KnifeDozor.
 

wayLANder

Где AlmazON?
Сообщения
1,742
Реакции
577
@ivanms1337, не получится никаким способом сделать кик игрока до того, как он будет определён плагином как запрещённый.
Смотри пример:
У меня есть мой обычный ник
Я меняю его на тот, который у тебя запрещён
Плагин видит, что ник запрещён (тоесть ник обрабатывается ТОЛЬКО после того, как он был сменен) и кикает игрока.
Даже, если и сделать кучу всяких наворотов, по итогу все равно в причине кика будет указан запрещенный ник (игрок (тут ник игрока с запрещенными словами) был кикнут).
Плагин не сможет кикнуть игрока до того, как его ник, собственно, поменяется.
 

MaDaRa

Участник
Сообщения
49
Реакции
2
Кто может сделать простой плагин?
Нужно когда игрок не двигается (афк в начале раунда) его нельзя было убить, и при этому моделька окрашивалась в любой указанный цвет. Что-то типо как в плагине KnifeDozor.
есть плагин который дает гм в начале раунда на 5 сек...
--- Добавлено позже ---
Плагин не сможет кикнуть игрока до того, как его ник, собственно, поменяется.
поставь плагин запрещения смены ника на сервере и плагин на запрещенные ники поставь захочет сменить кикнет с сервера захочет зайти за запрещёным ником тупо не сможет зайти его кикнет возможно и забанит. ну а машине всегда надо проверять, такой тебе пример будет ник обычный не заперещёный и у тебя такой плагин который не проверяет а сразу банит вот и будет банить всех подряд, тоже самое у меня в сампе плагин был бан по железу написал без серийника он забанил кого то другого
 
Последнее редактирование:

Kruzya

Участник
Сообщения
12,970
Реакции
10,914

Someone

Участник
Сообщения
1,933
Реакции
1,653
текст такой
Выбери, какая карта будет следующей...
...и не клацай кнопки,не подумав ;-)
4

ну так, это же и есть по идеии, в админке/управление голосованием/смена карты, и ничего не изменилось
 

Вложения

  • basevotes.rar
    10.7 КБ · Просмотры: 11

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,981
Надо как-то "отловить" смену ника до того, как это произойдёт.
разве HookEvent("player_changename", Event_PlayerChangename, EventHookMode_Pre); уже не работает?
PHP:
public void OnPluginStart()
{
...
    HookEvent("player_changename", Event_PlayerChangename, EventHookMode_Pre);
...
}

public Action Event_PlayerChangename(Event event, const char[] name, bool dontBroadcast)

{
    char sName[65];
    int client = GetClientOfUserId(GetEventInt(event, "userid"));
    if(IsFakeClient(client)) return Plugin_Continue;

    GetEventString(event, "newname", sName, sizeof(sName));
    SetNewName(client, sName);
    return Plugin_Changed; // avoid printing the change to the chat
}

void SetNewName(int client, char[] sName)
{...}
 
Сверху Снизу