Контакты (заказать плагин/исправить ошибки/другое) Поиск

[ вход ]
[ последние сообщения ]

  • Страница 1 из 1
  • 1
Игрок с клиент мода, как его определить?
Karandachik Дата: Понедельник, 05.02.2024, 12:17:45 | Сообщение # 1
Сообщений: 62
Репутация: 3 [ +/- ]
Привет, задумала я значит сделать плагин оверлей в конце раунда.
Ничего сложного, но фишечка в том, что хочу выделить игроков с клиент мода.
Схема такая. если простой игрок то ему один оверлей, а если с клиент мода то другой.
Нашла в интернете много плагинов где используется распознавание по квару или просто способ вывода текста, но не видела нигде простого логического определения игрока с клиент мода.
По типу если игрок жив + он в игре+ с клиент мода - оверлей, если нет то другой оверлей.
Помогите с определением игрока клиентмода пожалуйста.
 
_wS_ Дата: Понедельник, 05.02.2024, 19:47:24 | Сообщение # 2
Код
bool g_bClientMod[MAXPLAYERS + 1];

public void OnPluginStart()
{
    for (int client = 1; client <= MaxClients; ++client) {
        if (IsClientInGame(client)) {
            OnClientPutInServer(client);
        }
    }
}

public void OnClientPutInServer(int client)
{
    // Этот вариант уже не работает.
    //char s[4];
    //g_bClientMod[client] = GetClientInfo(client, "~clientmod", s, sizeof(s)) && s[0];

    // Этот должен работать.
    char s[12];
    g_bClientMod[client] = GetClientInfo(client, "_client_version", s, sizeof(s)) && s[2]/*strlen(s) > 2*/ && StringToInt(s) > 0;
}

/*
if (g_bClientMod[client]) {
    ClientMod
}
*/
 
Karandachik Дата: Понедельник, 12.02.2024, 13:28:48 | Сообщение # 3
Сообщений: 62
Репутация: 3 [ +/- ]
Цитата _wS_ ()
public void OnClientConnected(int client)
{
char s[4];
g_bClientMod[client] = GetClientInfo(client, "~clientmod", s, sizeof(s)) && s[0];
}

Я думала есть что-то проще, по типу
if (IsClientInGame(client) && !IsClientmodClient(client) && !IsPlayerAlive(client))
 
_wS_ Дата: Понедельник, 12.02.2024, 22:09:28 | Сообщение # 4
Это и есть простой вариант, чтобы зря не ставить дополнительный plugin.
После этого просто if (g_bClientMod[client]) ..

Если хочется if (CM_IsClientModUser(client)), то ставим clientmod.sp plugin и берём там .inc.
 
Karandachik Дата: Вторник, 13.02.2024, 10:13:36 | Сообщение # 5
Сообщений: 62
Репутация: 3 [ +/- ]
Цитата _wS_ ()
Это и есть простой вариант, чтобы зря не ставить дополнительный plugin.
После этого просто if (g_bClientMod[client]) ..

Если хочется if (CM_IsClientModUser(client)), то ставим clientmod.sp plugin и берём там .inc.

Спасибо, я знала что есть что-то очень простое и гениальное.

Добавлено (05.03.2026, 12:23:02)
---------------------------------------------
Цитата _wS_ ()
Если хочется if (CM_IsClientModUser(client)), то ставим clientmod.sp plugin и берём там .inc.

А есть что-то для старого синтаксиса на 164 или 170???
Там инклуд на новом синтаксисе, мне нужно именно под старый сделать код.
Может у кого то завалялся способ определить игрока с криент мода он или нет под sourcemod 163 ???

Код
new bool:g_bClientMod[MAXPLAYERS + 1];

public OnPluginStart()
{
    for (new client = 1; client <= MaxClients; ++client) {
        if (IsClientConnected(client)) {
            OnClientConnected(client);
        }
    }
}

public OnClientConnected(client)
{
    new String:s[4];
    g_bClientMod[client] = GetClientInfo(client, "~clientmod", s, sizeof(s)) && s[0];
}

КакаяТоФункция(client)
{
    if (g_bClientMod[client]) {
        Клиент мод
    } else {
        Не клиент мод
    }
}
 
TXCodding Дата: Пятница, 08.05.2026, 21:33:33 | Сообщение # 6
Сообщений: 5
Репутация: 0 [ +/- ]
Цитата _wS_ ()
bool g_bClientMod[MAXPLAYERS + 1];
 
public void OnClientConnected(int client)
{
    char s[4];
    g_bClientMod[client] = GetClientInfo(client, "~clientmod", s, sizeof(s)) && s[0];
}


Это не сработает
Эта функция работает только с ключами, которые сервер получает от клиента автоматически (например, "name", "model"). Переменная "~clientmod" не является стандартным ключом — клиент-мод её просто так не отправит, и вызов всегда будет возвращать false.

Код
// Пример из реального расширения — проверка через QueryClientConVar
public void OnClientPutInServer(int client)
{
    // Запрашиваем у клиента значение его квара
    QueryClientConVar(client, "clientmod_version", QueryVersionCallback, GetClientUserId(client));
}

public void QueryVersionCallback(QueryCookie cookie, int client, ConVarQueryResult result, const char[] cvarName, const char[] cvarValue, any userId)
{
    if (result == ConVarQuery_Okay && !StrEqual(cvarValue, ""))
    {
        g_bClientMod[client] = true;  // Это пользователь ClientMod
        PrintToServer("%N использует ClientMod версии %s", client, cvarValue);
    }
}

Добавлено (08.05.2026, 21:35:58)
---------------------------------------------

Цитата Karandachik ()
А есть что-то для старого синтаксиса на 164 или 170???
Там инклуд на новом синтаксисе, мне нужно именно под старый сделать код.
Может у кого то завалялся способ определить игрока с криент мода он или нет под sourcemod 163 ???

new bool:g_bClientMod[MAXPLAYERS + 1];
 
public OnPluginStart()
{
    for (new client = 1; client <= MaxClients; ++client) {
        if (IsClientConnected(client)) {
            OnClientConnected(client);
        }
    }
}
 
public OnClientConnected(client)
{
    new String:s[4];
    g_bClientMod[client] = GetClientInfo(client, "~clientmod", s, sizeof(s)) && s[0];
}
 
КакаяТоФункция(client)
{
    if (g_bClientMod[client]) {
        Клиент мод
    } else {
        Не клиент мод
    }
}


Код
#include <sourcemod>

#define PLUGIN_NAME    "ClientMod Detector"
#define PLUGIN_VERSION "1.0"

new bool:g_bClientMod[MAXPLAYERS + 1];

public Plugin:myinfo =
{
    name = PLUGIN_NAME,
    author = "YourName",
    description = "Detects ClientMod users",
    version = PLUGIN_VERSION,
    url = ""
};

public OnPluginStart()
{
    // Пустая, но можно добавить команду для теста
    RegAdminCmd("sm_testmod", Command_TestMod, ADMFLAG_GENERIC, "Test if player uses ClientMod");
}

public OnClientPutInServer(client)
{
    // Сбрасываем флаг при входе
    g_bClientMod[client] = false;
    
    // Запрашиваем у клиента версию ClientMod
    QueryClientConVar(client, "clientmod_version", OnClientModVersionQuery, GetClientUserId(client));
}

public OnClientDisconnect(client)
{
    g_bClientMod[client] = false;
}

public OnClientModVersionQuery(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[], any:userId)
{
    // Проверяем, что клиент всё ещё в игре
    new realClient = GetClientOfUserId(userId);
    if (realClient == 0)
        return;
    
    // Если запрос успешен и значение не пустое — это ClientMod
    if (result == ConVarQuery_Okay && !StrEqual(cvarValue, ""))
    {
        g_bClientMod[realClient] = true;
        LogMessage("%N detected as ClientMod user (version: %s)", realClient, cvarValue);
    }
    else
    {
        // Пользователь без ClientMod
        g_bClientMod[realClient] = false;
    }
}

// Пример использования в любой функции
public Action:Command_TestMod(client, args)
{
    if (client == 0)
    {
        PrintToServer("Command available in-game only");
        return Plugin_Handled;
    }
    
    if (g_bClientMod[client])
    {
        ReplyToCommand(client, "[SM] You are using ClientMod!");
    }
    else
    {
        ReplyToCommand(client, "[SM] You are NOT using ClientMod.");
    }
    
    return Plugin_Handled;
}

// Глобальная функция для проверки (вызывай откуда угодно)
bool:IsClientModUser(client)
{
    if (client < 1 || client > MaxClients || !IsClientInGame(client))
        return false;
    
    return g_bClientMod[client];
}
 
_wS_ Дата: Суббота, 09.05.2026, 06:09:34 | Сообщение # 7
Цитата TXCodding ()
Это не сработает

Это работало раньше, а сейчас нужно проверять _client_version и GetClientInfo с этим справляется.

---

Код
char s[12];
g_bClientMod[client] = GetClientInfo(client, "_client_version", s, sizeof(s)) && s[2]/*strlen(s) > 2*/ && StringToInt(s) > 0;
 
TXCodding Дата: Суббота, 09.05.2026, 13:06:16 | Сообщение # 8
Сообщений: 5
Репутация: 0 [ +/- ]
Код
new bool:g_bClientMod[MAXPLAYERS + 1];

public OnClientPutInServer(client)
{
    // Сброс при входе
    g_bClientMod[client] = false;
    
    // Небольшая задержка, чтобы ClientMod успел отправить данные
    CreateTimer(0.3, Timer_CheckClientMod, GetClientUserId(client));
}

public Action:Timer_CheckClientMod(Handle:timer, any:userId)
{
    new client = GetClientOfUserId(userId);
    if (client == 0 || !IsClientConnected(client))
        return Plugin_Stop;
    
    decl String:sVersion[12];
    
    // Пытаемся получить версию ClientMod
    if (GetClientInfo(client, "_client_version", sVersion, sizeof(sVersion)) && sVersion[2])
    {
        new versionNum = StringToInt(sVersion);
        if (versionNum > 0)
        {
            g_bClientMod[client] = true;
            LogMessage("%N detected as ClientMod user (version: %s)", client, sVersion);
        }
    }
    
    return Plugin_Stop;
}

// Функция проверки
stock bool:IsClientModUser(client)
{
    if (client < 1 || client > MaxClients || !IsClientInGame(client))
        return false;
    
    return g_bClientMod[client];
}

Тогда так
 
_wS_ Дата: Суббота, 09.05.2026, 16:14:00 | Сообщение # 9
Цитата TXCodding ()
// Небольшая задержка, чтобы ClientMod успел отправить данные

Это подтолкнуло покопать исх и узнать нового starik Как раз именно перед OnClientPutInServer игроку ставится SIGNONSTATE_FULL (игрок полностью подключен, все userinfo переменные передал и т.д.), а значит таймер в OnClientPutInServer не нужен. Хоть часто и работает в OnClientConnected, но, получается, может стрелять, а значит лучше юзать OnClientPutInServer.

Кст GetClientOfUserId уже проверяет на Connected (IsClientConnected лишнее).
Бывают ещё странные моменты, когда может пригодиться IsClientInGame, но это если игрок между OnClientConnect и OnClientPutInServer (маловероятно).

---
Ещё с sVersion[2] может быть проблема, если GetClientInfo записало < 3 символов.
Старый decl не занулял переменные/массивы и в них был мусор:

Код
public void OnPluginStart()
{
    decl s[4];
    for (int i = 0; i < sizeof(s); ++i) {
        PrintToServer("%d", s[i] == '\0');
    }
    // Мне выдало:
    // 1
    // 1
    // 0 привет..
    // 1
}
 
TXCodding Дата: Суббота, 09.05.2026, 20:33:05 | Сообщение # 10
Сообщений: 5
Репутация: 0 [ +/- ]
Точно! 💯ты прав !
OnClientPutInServer наступает строго после того, как игрок передал все userinfo-переменные, включая _client_version. Таймер там не нужен.
Упрощаем
Код
new bool:g_bClientMod[MAXPLAYERS + 1];

public OnClientPutInServer(client)
{
    decl String:sVersion[12];
    
    if (GetClientInfo(client, "_client_version", sVersion, sizeof(sVersion)) && sVersion[2])
    {
        g_bClientMod[client] = StringToInt(sVersion) > 0;
    }
    else
    {
        g_bClientMod[client] = false;
    }
}

public OnClientDisconnect(client)
{
    g_bClientMod[client] = false;
}

stock bool:IsClientModUser(client)
{
    return client >= 1 && client <= MaxClients && IsClientInGame(client) && g_bClientMod[client];
}


Сообщение отредактировал TXCodding - Суббота, 09.05.2026, 20:34:02
 
  • Страница 1 из 1
  • 1
Поиск: