Как по логам узнать поднял ли игрок оружие

Tretlenz

Участник
Сообщения
37
Реакции
0
Операционная система
Windows
Всем привет! Можно ли как-то выводить в логи информацию о том, что игрок поднял что-то с земли(оружие, гранаты)? Если да, то какой командой?
Заранее спасибо!
 

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
Что конкретно вы подразумеваете под поднятием оружия?
1) Подбор лежавшего на земле
2) Подбор только что купленного оружия
3) Подбор по иным причинам (выдан плагином)
4) всё из выше перечисленного
5) Свой вариант
 
Последнее редактирование:

Tretlenz

Участник
Сообщения
37
Реакции
0
Что конкретно вы подразумеваете под поднятием оружия?
1) Подбор лежавшего на земле
2) Подбор только что купленного оружия
3) Подбор по иным причинам (выдан плагином)
4) Свой вариант
Подбор лежавшего на земле/которое дропнули
А что имеется ввиду под "Подбор только что купленного оружия"?
 

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
А что имеется ввиду под "Подбор только что купленного оружия"?
Игрок купил, ему выдалось оружие. Это тоже считается за выдачу.

Логировать можно плагином с вышеуказанным фильтрами как по отдельности, так и просто по "любая выдача".

Домой прийду напишу такой плагин, если требуется
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
C-подобный:
#include <sdkhooks>

File hFile;
ConVar cvType;
int iType;

public void OnClientPostAdminCheck(int client)
{
    SDKHook(client, SDKHook_WeaponCanUse, WeaponCanUse);
}

public void OnPluginEnd()
{
    delete hFile;
}

public void OnCvHooked(ConVar convar, const char[] OldValue, const char[] NewValue)
{
    if(convar != INVALID_HANDLE)
    {
        if(convar == cvType) iType = convar.IntValue;
    }
}

public void OnPluginStart()
{
    HookConVarChange((cvType = CreateConVar("log_type", "1")), OnCvHooked);

    char path[PLATFORM_MAX_PATH];
    BuildPath(Path_SM, path, sizeof(path), "logs/info.log");
    hFile = OpenFile(path, "a+");
}

public Action WeaponCanUse(int client, int weapon)
{
    if(weapon != -1 && 0 < client && IsClientInGame(client) && !IsFakeClient(client))
    {
        char sWeaponName[64];
        GetEntityClassname(weapon, sWeaponName, sizeof(sWeaponName));
        if(sWeaponName[0] && hFile != INVALID_HANDLE)
        {
            switch(iType)
            {
                case 0: WriteFileLine(hFile, "%N поднял %s", client, sWeaponName);
                case 1: LogMessage("%N поднял %s", client, sWeaponName);
            }
        }
    }
  
    return Plugin_Continue;
}
переменная log_type отвечает за тип лога(0 - Запись в файл, 1 - Вывод в консоле сервера)
логгирует все что поднимаешь
логгирует в addons/sourcemod/logs/info.log
 
Последнее редактирование:

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
C-подобный:
#include <sdkhooks>

File hFile;
ConVar cvType;
int iType;

public void OnClientPostAdminCheck(int client)
{
    SDKHook(client, SDKHook_WeaponCanUse, WeaponCanUse);
}

public void OnPluginEnd()
{
    HookConVarChange((cvType = CreateConVar("log_type", "1")), OnCvHooked);

    delete hFile;
}

public void OnCvHooked(ConVar convar, const char[] OldValue, const char[] NewValue)
{
    if(convar != INVALID_HANDLE)
    {
        if(convar == cvType) iType = convar.IntValue;
    }
}

public void OnPluginStart()
{
    char path[PLATFORM_MAX_PATH];
    BuildPath(Path_SM, path, sizeof(path), "logs/info.log");
    hFile = OpenFile(path, "a+");
}

public Action WeaponCanUse(int client, int weapon)
{
    if(weapon != -1 && 0 < client && IsClientInGame(client) && !IsFakeClient(client))
    {
        char sWeaponName[64];
        GetEntityClassname(weapon, sWeaponName, sizeof(sWeaponName));
        if(sWeaponName[0] && hFile != INVALID_HANDLE)
        {
            switch(iType)
            {
                case 0: WriteFileLine(hFile, "%N поднял %s", client, sWeaponName);
                case 1: LogMessage("%N поднял %s", client, sWeaponName);
            }
        }
    }
  
    return Plugin_Continue;
}
переменная log_type отвечает за тип лога(0 - Запись в файл, 1 - Вывод в консоле сервера)
логгирует все что поднимаешь
Лучше через "%L", что бы в логе потом через SteamId можно было идентифицировать игрока
 

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
@Tretlenz, вам подойдёт плагин что написал @Palonez или мне написать версию с фильтрами по типам подбора и выложить его в ресурсы?
 

Tretlenz

Участник
Сообщения
37
Реакции
0
@Tretlenz, вам подойдёт плагин что написал @Palonez или мне написать версию с фильтрами по типам подбора и выложить его в ресурсы?
Если можно, я посмотрел бы и на Вашу версию
Сообщения автоматически склеены:

C-подобный:
#include <sdkhooks>

File hFile;
ConVar cvType;
int iType;

public void OnClientPostAdminCheck(int client)
{
    SDKHook(client, SDKHook_WeaponCanUse, WeaponCanUse);
}

public void OnPluginEnd()
{
    HookConVarChange((cvType = CreateConVar("log_type", "1")), OnCvHooked);

    delete hFile;
}

public void OnCvHooked(ConVar convar, const char[] OldValue, const char[] NewValue)
{
    if(convar != INVALID_HANDLE)
    {
        if(convar == cvType) iType = convar.IntValue;
    }
}

public void OnPluginStart()
{
    char path[PLATFORM_MAX_PATH];
    BuildPath(Path_SM, path, sizeof(path), "logs/info.log");
    hFile = OpenFile(path, "a+");
}

public Action WeaponCanUse(int client, int weapon)
{
    if(weapon != -1 && 0 < client && IsClientInGame(client) && !IsFakeClient(client))
    {
        char sWeaponName[64];
        GetEntityClassname(weapon, sWeaponName, sizeof(sWeaponName));
        if(sWeaponName[0] && hFile != INVALID_HANDLE)
        {
            switch(iType)
            {
                case 0: WriteFileLine(hFile, "%N поднял %s", client, sWeaponName);
                case 1: LogMessage("%N поднял %s", client, sWeaponName);
            }
        }
    }
  
    return Plugin_Continue;
}
переменная log_type отвечает за тип лога(0 - Запись в файл, 1 - Вывод в консоле сервера)
логгирует все что поднимаешь
логгирует в addons/sourcemod/logs/info.log
Спасибо!
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@Palonez, ты бы границы значений квара задал (и имя более понятное сделал):
HookConVarChange((cvType = CreateConVar("log_type", "1")), OnCvHooked);
==>
HookConVarChange((cvType = CreateConVar("weapon_pickup_log_type", "1", _, _, true, _, true, 1.0)), OnCvHooked);
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Ну и заодно переместил создание квара из OnPluginEnd() в OnPluginStart() ^_^
Сообщения автоматически склеены:

В хуке изменения квара вот эта проверка без надобности: if(convar != INVALID_HANDLE)

Вот тут проверять наличие хэндла нужно только при сохрании в отдельный файл: if(sWeaponName[0] && hFile != INVALID_HANDLE)

Переменную iType имеет смысл сделать bool, раз у неё бывает всего 2 значения. Ну и вместо switch() достаточно if ... else
Сообщения автоматически склеены:

и в OnPluginEnd() удалять хэндл без надобности: емнип, при завершении работы плагина все хэндлы им созданные удаляются
Сообщения автоматически склеены:

В каллбэке WeaponCanUse() не нужны проверки индекса (индекс игрока не меняется пока игрок на сервере), в игре ли игрок (при выходе игрока хук повешеный на него удаляется) и является ли игрок ботом (эту проверку лучше поместить в создание хука, чего зря нагружать проц бессмысленными действиями?).
Сообщения автоматически склеены:

В общем я бы сделал вот так (и в лог бы писалось независимо от значения квара даже если файл "logs/info.log" невозможно создать и открыть):
C-подобный:
#pragma semicolon 1
#pragma newdecls required

#include <sdkhooks>

File hFile;

public void OnPluginStart()
{
    ConVar cvar = CreateConVar("weapon_pickup_log_type", "1", "Запись в: 0 - info.log, 1 - обычный лог", _, true, _, true, 1.0);
    cvar.AddChangeHook(CVarChange);
    CVarChange(cvar, "", "");
}

public void CVarChange(ConVar cvar, const char[] OldValue, const char[] NewValue)
{
    if(cvar.BoolValue == !hFile)
        return;

    if(!hFile)
    {
        char path[PLATFORM_MAX_PATH];
        BuildPath(Path_SM, path, sizeof(path), "logs/info.log");
        hFile = OpenFile(path, "a");
    }
    else delete hFile;
}

public void OnClientPostAdminCheck(int client)
{
    if(!IsFakeClient(client)) SDKHook(client, SDKHook_WeaponEquipPost, WeaponEquipPost);
}

public void WeaponEquipPost(int client, int weapon)
{
    static char class[32];
    if(weapon <= MaxClients || !GetEntityClassname(weapon, class, sizeof(class)))
        return;

    if(hFile)    // выбрана запись в файл info.log и при этом получилось его открыть/создать
        WriteFileLine(hFile, "%N поднял %s", client, class);
    else LogMessage("%N поднял %s", client, class);
}
Сообщения автоматически склеены:

И да, SDKHook_WeaponCanUse - это не поднял, а только прикоснулся к оружию.
 
Последнее редактирование:

Tretlenz

Участник
Сообщения
37
Реакции
0
Ну и заодно переместил создание квара из OnPluginEnd() в OnPluginStart() ^_^
Сообщения автоматически склеены:

В хуке изменения квара вот эта проверка без надобности: if(convar != INVALID_HANDLE)

Вот тут проверять наличие хэндла нужно только при сохрании в отдельный файл: if(sWeaponName[0] && hFile != INVALID_HANDLE)

Переменную iType имеет смысл сделать bool, раз у неё бывает всего 2 значения. Ну и вместо switch() достаточно if ... else
Сообщения автоматически склеены:

и в OnPluginEnd() удалять хэндл без надобности: емнип, при завершении работы плагина все хэндлы им созданные удаляются
Сообщения автоматически склеены:

В каллбэке WeaponCanUse() не нужны проверки индекса (индекс игрока не меняется пока игрок на сервере), в игре ли игрок (при выходе игрока хук повешеный на него удаляется) и является ли игрок ботом (эту проверку лучше поместить в создание хука, чего зря нагружать проц бессмысленными действиями?).
Сообщения автоматически склеены:

В общем я бы сделал вот так (и в лог бы писалось независимо от значения квара даже если файл "logs/info.log" невозможно создать и открыть):
C-подобный:
#pragma semicolon 1
#pragma newdecls required

#include <sdkhooks>

File hFile;

public void OnPluginStart()
{
    ConVar cvar = CreateConVar("weapon_pickup_log_type", "1", "Запись в: 0 - info.log, 1 - обычный лог", _, true, _, true, 1.0);
    cvar.AddChangeHook(CVarChange);
    CVarChange(cvar, "", "");
}

public void CVarChange(ConVar cvar, const char[] OldValue, const char[] NewValue)
{
    if(cvar.BoolValue == !hFile)
        return;

    if(!hFile)
    {
        char path[PLATFORM_MAX_PATH];
        BuildPath(Path_SM, path, sizeof(path), "logs/info.log");
        hFile = OpenFile(path, "a");
    }
    else delete hFile;
}

public void OnClientPostAdminCheck(int client)
{
    if(!IsFakeClient(client)) SDKHook(client, SDKHook_WeaponEquipPost, WeaponEquipPost);
}

public void WeaponEquipPost(int client, int weapon)
{
    static char class[32];
    if(weapon <= MaxClients || !GetEntityClassname(weapon, class, sizeof(class)))
        return;

    if(hFile)    // выбрана запись в файл info.log и при этом получилось его открыть/создать
        WriteFileLine(hFile, "%N поднял %s", client, class);
    else LogMessage("%N поднял %s", client, class);
}
Сообщения автоматически склеены:

И да, SDKHook_WeaponCanUse - это не поднял, а только прикоснулся к оружию.
А если мне потом потребуется отправлять логи на веб-сервер, то нудно что-то будет поменять в коде или эти логи будут отправляться вместе с теми, что отправляются без плагина?
 

iLoco

Пишу плагины за печеньки 🍪🍪🍪
Сообщения
2,265
Реакции
1,323
А если мне потом потребуется отправлять логи на веб-сервер, то нудно что-то будет поменять в коде или эти логи будут отправляться вместе с теми, что отправляются без плагина?
нет, без проблем. Возможно даже не понадобиться ничего дописывать. Если плагин, что отправляет на WEB работает через `OnLogAction`.
Сообщения автоматически склеены:

@Tretlenz, вам подойдёт плагин что написал @Palonez или мне написать версию с фильтрами по типам подбора и выложить его в ресурсы?
 
Последнее редактирование:

Tretlenz

Участник
Сообщения
37
Реакции
0
нет, без проблем. Возможно даже не понадобиться ничего дописывать. Если плагин, что отправляет на WEB работает через `OnLogAction`.
Сообщения автоматически склеены:


Спасибо большое!
 

Tretlenz

Участник
Сообщения
37
Реакции
0
нет, без проблем. Возможно даже не понадобиться ничего дописывать. Если плагин, что отправляет на WEB работает через `OnLogAction`.
Сообщения автоматически склеены:


Извините, а не могли бы, пожалуйста, подсказать этот плагин? Всё ищу как отправить на веб, но ничего не могу найти
 

MagoG

Хочу быть как truyn
Сообщения
896
Реакции
608
Извините, а не могли бы, пожалуйста, подсказать этот плагин? Всё ищу как отправить на веб, но ничего не могу найти
Rest In Pawn в помощь если надо на апи отправлять, если так, то в MSQL записывать =) Да и если этим 100% придётся забивать бд, чувствую, умрёт она у тебя через месяц, если она ещё и на арене то через неделю забьётся, т.к там всего то максимум вроде 1гб =)
 
Последнее редактирование:

Tretlenz

Участник
Сообщения
37
Реакции
0
Rest In Pawn в помощь если надо на апи отправлять, если так, то в MSQL записывать =) Да и если этим 100% придётся забивать бд, чувствую, умрёт она у тебя через месяц, если она ещё и на арене то через неделю забьётся, т.к там всего то максимум вроде 1гб =)
А не подскажите какой тип должен быть у входного параметра, если по апи передавать? Я ставил String/Map/JSONObject, но Spring мне говорит, что это всё не те типы, которые ему нужны
 

MagoG

Хочу быть как truyn
Сообщения
896
Реакции
608
А не подскажите какой тип должен быть у входного параметра, если по апи передавать? Я ставил String/Map/JSONObject, но Spring мне говорит, что это всё не те типы, которые ему нужны
JSONObject ты передаёшь любые данные, ключ -> значение, но ты передавай в ключи нужное.
Пример:
C++:
JSONObject hObj = new JSONObject();
char sBuffer[256];

g_hCvar_ServerName.GetString(sBuffer, sizeof(sBuffer));
hObj.SetString("server_name", sBuffer);
hObj.SetInt("tt_win", GetTeamScore(CS_TEAM_T));
 
Сверху Снизу