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

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Ошибка .sp(51) : error 008: must be a constant expression; assumed zero

C++:
#include <sdktools>

float fClientPoint[MAXPLAYERS+1][2][3];
bool bInSets[MAXPLAYERS+1] = {false, ...};
int g_HaloSprite, g_BeamSprite;

enum
{
    x = 0,
    y,
    z
};

public void OnPluginStart()
{
    RegConsoleCmd("sm_goo", CMDGOO);
}

public void OnMapStart()
{
    g_HaloSprite = PrecacheModel("sprites/halo.vmt", true);
    g_BeamSprite = PrecacheModel("sprites/laserbeam.vmt", true);
}

public Action CMDGOO(int i, int args)
{
    if(IsClientInGame(i) && !IsFakeClient(i) && IsPlayerAlive(i))
    {
        float fDistance[3];
        fDistance = GetDistanceEyePoint(i);
        if(!bInSets[i])
        {
            bInSets[i] = true;
            for(int j = 0; j <= 2; j++)
                fClientPoint[i][0][j] = fDistance[j];
        }
        else
        {
            bInSets[i] = false;
            for(int j = 0; j <= 2; j++)
                fClientPoint[i][1][j] = fDistance[j];
 
            CreateCube(fClientPoint[i][0], fClientPoint[i][1]);
        }
    }
    return Plugin_Handled;
}

void CreateCube(const float pos1[3], const float pos2[3])
{
    TE_SetupBeamPoints(pos1, {pos1[x], pos1[y], pos2[z]}, g_BeamSprite, g_HaloSprite, 0, 66, 50.0, 2.0, 2.0, 10, 0.0, {255, 255, 0, 255}, 1000);
    TE_SendToAll();
}

float[] GetDistanceEyePoint(int i)
{
    float a[3], o[3], e[3] = {0.0, 0.0, 0.0};
    GetClientEyePosition(i, o);
    GetClientEyeAngles(i, a);
    Handle hTrace = TR_TraceRayFilterEx(o, a, CONTENTS_SOLID, RayType_Infinite, CMDFilter, i);
    if(TR_DidHit(hTrace) && hTrace != INVALID_HANDLE) TR_GetEndPosition(e, hTrace);
    return e;
}

public bool CMDFilter(int client, int mask)
{
    return client ? false : true;
}
И еще вопрос. При инициализации одномерного массива одинаковыми элементами можно делать так:
C-подобный:
bool bVal[1024] = {true, ...}
А что делать, если массив допустим такой
C++:
float fVal[MAXPLAYERS+1][2][3]
C-подобный:
такой вариант:
{
    {
        {
            0.0, 0.0, 0.0
        },
    
        {
            0.0, 0.0, 0.0
        }
    }, ...
};
или такой
{ { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0} }, ...}; - выдает ошибку array sizes do not match, or destination array is too small
 
Последнее редактирование:

HAIRAKE

Участник
Сообщения
36
Реакции
4
L 10/20/2022 - 12:21:04: [SM] Blaming: thc_rpg.smx
L 10/20/2022 - 12:21:04: [SM] Call stack trace:
L 10/20/2022 - 12:21:04: [SM] [0] Call_StartFunction
L 10/20/2022 - 12:21:04: [SM] [1] Line 477, src\thc_rpg/base/eventmanager.inc::EventMgr_Forward
L 10/20/2022 - 12:21:04: [SM] [2] Line 231, src\thc_rpg/base/modulemanager.inc::ModuleMgr_Disable
L 10/20/2022 - 12:21:04: [SM] [3] Line 152, src\thc_rpg/core.inc::CoreModule_ConfigCache
L 10/20/2022 - 12:21:04: [SM] [5] Call_Finish
L 10/20/2022 - 12:21:04: [SM] [6] Line 320, src\thc_rpg/base/configmanager.inc::ConfigMgr_CacheKv
L 10/20/2022 - 12:21:04: [SM] [7] Line 221, src\thc_rpg/core.inc::Core_OnMapStart
L 10/20/2022 - 12:21:04: [SM] [9] Call_Finish
L 10/20/2022 - 12:21:04: [SM] [10] Line 503, src\thc_rpg/base/eventmanager.inc::EventMgr_Forward
L 10/20/2022 - 12:21:04: [SM] [11] Line 145, src\thc_rpg/project_events.inc::OnMapStart
причина?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@txxbio, отсутствует первая строка сообщения об ошибке
 

0-BuTaJIuK-0

Участник
Сообщения
235
Реакции
57
Есть сервера csgo для турниров. В зависимости от режима 1х1 2х2 5х5 - меняются конфиги, плагины и т.д.
Задача: использовать стандартные карты из 5x5 для 2x2. (Не нужно предлагать скачать урезанные.)
Решение: заблокировать проходы и менять их работу в конфигах по квару enable/disable.

Прошерстил плагины в паблике, итого два варианта:
1) Делать зоны, которые дают нагрузку, проверяя игроков и push`at их обратно. Если зона маленькая, то можно ещё и перепрыгнуть через неё.
2) Заблочить проходы пропами (не красиво и нужно латать все дыры, что бы они еще не могли перелезть) может быть, только если свои большие пропы сделать с маленькой шириной.

P.S. В кс 1.6 был плагин "2х2 mode", который создавал не проходимую стену. Нужно реализовать что-то подобное.
Ниже прикрепил примеры как в кс 1.6 и как примерно должно быть в кс:го

ИТОГО: У кого какие идеи, как реализовать? Хоть координаты в ручную буду прописывать. Может наброски у кого есть или готовые примеры.
Грубо говоря - нужно как в 1 варианте указать зону и чтобы эта зона превращалась в большой проп как во 2 варианте.
 

Вложения

  • 16529817.jpg
    16529817.jpg
    153.7 КБ · Просмотры: 79
  • Screenshot_1.png
    Screenshot_1.png
    884.6 КБ · Просмотры: 76
Последнее редактирование:

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
Заблочить проходы пропами (не красиво и нужно латать все дыры, что бы они еще не могли перелезть)
как реализовать? Хоть координаты в ручную буду прописывать
Что то противоречие..
 

0-BuTaJIuK-0

Участник
Сообщения
235
Реакции
57
Что то противоречие..
Грубо говоря - нужно как в 1 варианте указать зону и чтобы эта зона превращалась в большой проп как во 2 варианте.
На турнирах - всё заставить заборами, которые будут выпирать где-то либо заходить в стены. Такой себе уровень качества.

Но думаю остановиться на втором варианте. Сделать большие прозрачные пропы и символический забор.
 
Последнее редактирование:

Мотыга

сила в силе духа ☠️☠️☠️
Сообщения
84
Реакции
49
Кто может помочь написать плагин css v34 sm 1.11 , при заходе игрока за определенную команду Т-СТ будет проигрывать определенный звук с указанием пути к нему?,если такого еще нет!
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Кто может помочь написать плагин css v34 sm 1.11 , при заходе игрока за определенную команду Т-СТ будет проигрывать определенный звук с указанием пути к нему?,если такого еще нет!
Помочь или написать? Если помочь, то видимо должна быть уже часть кода, которую нужно доработать или с чем помочь?
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Написать, если не сложно это сделать
C++:
#include <sourcemod>
#include <sdktools>
char CTSound[] = "sounds/zvuk_CT.wav";
char TSound[] = "sounds/zvuk_T.wav";
public void OnPluginStart()
{
    HookEvent("player_team", pteam, EventHookMode_Post);
}
public void OnMapStart()
{
    AddFileToDownloadsTable(CTSound);
    AddFileToDownloadsTable(TSound);
    PrecacheSound(CTSound, true);
    PrecacheSound(TSound, true);
}
public void pteam(Event hEvent, const char[] sEvent, bool bdb)
{
    int client = GetClientOfUserId(hEvent.GetInt("userid"));
    if(client > 0 && IsClientInGame(client) && !IsFakeClient(client))
    {
        int team = hEvent.GetInt("team");
        if(team == 2) EmitSoundToClient(client, TSound, SOUND_FROM_PLAYER, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, SNDVOL_NORMAL, SNDPITCH_NORMAL, -1, NULL_VECTOR);
        else if(team == 3) EmitSoundToClient(client, CTSound, SOUND_FROM_PLAYER, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, SNDVOL_NORMAL, SNDPITCH_NORMAL, -1, NULL_VECTOR);
    }
}
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@Palonez, ну начнём с того, что звуки должны быть в папке sound, а не sounds.
Кроме того для прекеша в пути эта самая папка не нужна, как и для воспроизведения звука.

Т.е. должно было получиться примерно вот так:
C-подобный:
#include <sdktools_sound>
#include <sdktools_stringtables>

static const char
    SND_CT[]= "sound/zvuk_CT.wav",
    SND_T[]    = "sound/zvuk_T.wav";

public void OnPluginStart()
{
    HookEvent("player_team", Event_Team);
}

public void OnMapStart()
{
    AddFileToDownloadsTable(SND_CT);
    AddFileToDownloadsTable(SND_T);

    PrecacheSound(SND_CT[6], true);
    PrecacheSound(SND_T[6], true);
}

public void Event_Team(Event event, const char[] name, bool bdb)
{
    int team = event.GetInt("team");
    if(team < 2) return;

    int client = GetClientOfUserId(event.GetInt("userid"));
    if(!client || !IsClientInGame(client) || IsFakeClient(client)) return;

    if(team == 2) EmitSoundToClient(client, SND_T[6]);
    else EmitSoundToClient(client, SND_CT[6]);
}
UPD Исправил воспроизведение трека наблюдателям.
 
Последнее редактирование:

0-BuTaJIuK-0

Участник
Сообщения
235
Реакции
57
Привет! Подскажите пожалуйста.
Есть бд привязанная к сайту. Сайт будет выводить статистику серверов. Мне необходимо залить плагин на сервера, который заполнит все необходимые строки и будет обновлять онлайн на сервере.
1) Почему плагин не работает, когда я хукаю ConVar sm_reserved_slots в int premiumSlots
2) Избавиться от подсчёта бота GOTV, но я уже поменял GetClientCount() на цикл с IsClientInGame(i) && !IsFakeClient(i)
3) Вакханалия какая-то с HookEvent("player_connect", Player_update); и HookEvent("player_disconnect", Player_update);.
Не срабатывает, когда захожу на сервер и два раза срабатывает, когда выхожу с него.
Тут можно костылями, на вход таймер, а на выход bool, который через раз будет срабатывать
Второй вариант, не тестировал. Это через функции OnClientPutInServer, OnClientConnect, OnClientConnected, OnClientDisconnect, OnClientDisconnect_Post.

Код:
#include <sourcemod>

public Plugin:myinfo =
{
    name = "Players Update Server Saite",
    author = "0-BuTaJIuK-0",
    description = "Обновление счётчика игроков на сайте",
    version = "1.0",
    url = "*********"
};

Database g_hDatabase; // Глобальная переменная для соединения с базой
char serverPortz[32]; // Переменная для порта сервера
int premiumSlots; // Зарезервированные слоты
int MaxHumansz; // Слоты сервара

public void OnPluginStart()
{
    HookEvent("player_connect", Player_update);
    HookEvent("player_disconnect", Player_update);
    Database.Connect(ConnectCallBack, "imba"); // sp_lessons Имя секции в databases.cfg

    MaxHumansz = GetMaxHumanPlayers();
    GetConVarString(FindConVar("hostport"), serverPortz, sizeof(serverPortz)); // Хук порта сервера
    premiumSlots = GetConVarInt(FindConVar("sm_reserved_slots"));
    SQLplayer_update();
}


// БД*******************************************************************************************************************
public void ConnectCallBack (Database hDatabase, const char[] szError, any data) // Пришел результат соединения
{
    if (hDatabase == null || szError[0]) // Соединение не удачное
    {
        SetFailState("Database failure: %s", szError); // Отключаем плагин
        return;
    }
    g_hDatabase = hDatabase; // Присваиваем глобальной переменной соединения значение текущего соединения
}

// Обработчик ошибок
public void SQL_Callback_CheckError(Database hDatabase, DBResultSet results, const char[] szError, any data)
{
    if(szError[0])
    {
        LogError("SQL_Callback_CheckError: %s", szError);
    }
}
// **********************************************************************************************************************

public void Player_update(Handle event, const char[] name, bool DB)
{
    SQLplayer_update();
}


public void SQLplayer_update()
{
    //int iCount = GetClientCount(); // Один из вариантов хука кол-во слотов, но с ботом GOTV
    int iCount = 0;
    for(new i = 1; i <= MaxClients; i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            iCount++;
        }
    }

    char szQuery[512];
    FormatEx(szQuery, sizeof(szQuery), "UPDATE `servers` SET `slots` = %i, `usersOnline` = %i WHERE `port` = %s;", MaxHumansz, iCount, serverPortz);
    g_hDatabase.Query(SQL_Callback_CheckError, szQuery);

    PrintToServer("****************************")  // DEBUG
    PrintToServer("MaxHumans: %i", MaxHumansz)
    PrintToServer("iCount: %i", iCount)
    PrintToServer("premiumSlots: %i", premiumSlots)
    PrintToServer("serverPort: %s", serverPortz)
    PrintToServer("SzQuery: %s", szQuery)
    PrintToServer("****************************")  // DEBUG
}
 

Вложения

  • Screenshot_2.png
    Screenshot_2.png
    23.2 КБ · Просмотры: 33
Последнее редактирование:

0-BuTaJIuK-0

Участник
Сообщения
235
Реакции
57
Зачем делать произвольные запросы раз в N секунд на N серверов, если я могу сразу залить в бд инфу и пользователи на сайте будут получать актуальную информацию без запросов.

У меня стоит GitHub - n0la/rcon: Source RCON client for command line
---------------------------------------------------------------------------------------------------------------------------------------------
Сообщения автоматически склеены:

Привет! Подскажите пожалуйста.
Есть бд привязанная к сайту. Сайт будет выводить статистику серверов. Мне необходимо залить плагин на сервера, который заполнит все необходимые строки и будет обновлять онлайн на сервере.
Итого, что получилось:
C++:
#include <sourcemod>

public Plugin:myinfo =
{
    name = "Players Update Server Saite",
    author = "0-BuTaJIuK-0",
    description = "Обновление счётчика игроков на сайте",
    version = "1.0",
    url = "****"
};

Database g_hDatabase; // Глобальная переменная для соединения с базой
char serverPortz[32]; // Переменная для порта сервера
char serverPortGoTvz[32]; // Переменная для порта GOTV
int premiumSlots; // Зарезервированные слоты
int MaxHumansz; // Слоты сервара

public OnPluginStart()
{
    Database.Connect(ConnectCallBack, "imba"); // sp_lessons Имя секции в databases.cfg
    GetConVarString(FindConVar("hostport"), serverPortz, sizeof(serverPortz)); // Хук порта сервера
    GetConVarString(FindConVar("tv_port"), serverPortGoTvz, sizeof(serverPortGoTvz)); // Хук порта сервера
    premiumSlots = FindConVar("sm_reserved_slots");
}


// БД*******************************************************************************************************************
public ConnectCallBack (Database hDatabase, const char[] szError, any data) // Пришел результат соединения
{
    if (hDatabase == null || szError[0]) // Соединение не удачное
    {
        SetFailState("Database failure: %s", szError); // Отключаем плагин
        return;
    }
    g_hDatabase = hDatabase; // Присваиваем глобальной переменной соединения значение текущего соединения
}

// Обработчик ошибок
public SQL_Callback_CheckError(Database hDatabase, DBResultSet results, const char[] szError, any data)
{
    if(szError[0])
    {
        LogError("SQL_Callback_CheckError: %s", szError);
    }
}
// **********************************************************************************************************************

public OnClientPutInServer()
{
    SQLplayer_update();
}

public OnClientDisconnect_Post()
{
    SQLplayer_update();
}



public SQLplayer_update()
{
    //int iCount = GetClientCount(); // Один из вариантов хука кол-во слотов, но с ботом GOTV
    MaxHumansz = GetMaxHumanPlayers();
    int iCount = 0;
    for(new i = 1; i <= MaxClients; i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            iCount++;
        }
    }

    char szQuery[512];
    FormatEx(szQuery, sizeof(szQuery), "UPDATE `servers` SET `portGoTv` = %s, `slots` = %i, `usersOnline` = %i, `premiumSlots` = %i WHERE `port` = %s;", serverPortGoTvz, MaxHumansz, iCount, premiumSlots, serverPortz);
    g_hDatabase.Query(SQL_Callback_CheckError, szQuery);

    PrintToServer("****************************")  // DEBUG
    PrintToServer("MaxHumans: %i", MaxHumansz)
    PrintToServer("iCount: %i", iCount)
    PrintToServer("premiumSlots: %i", premiumSlots)
    PrintToServer("serverPort: %s", serverPortz)
    PrintToServer("serverPortGoTvz: %s", serverPortGoTvz)
    PrintToServer("SzQuery: %s", szQuery)
    PrintToServer("****************************")  // DEBUG
}

1) Ошибка в консоли (но плагин работает)
L 11/01/2022 - 15:05:03: [SM] Exception reported: Invalid database Handle 0 (error: 4)
L 11/01/2022 - 15:05:03: [SM] Blaming: PlayersUpdateServerSaite.smx
L 11/01/2022 - 15:05:03: [SM] Call stack trace:
L 11/01/2022 - 15:05:03: [SM] [0] Database.Query
L 11/01/2022 - 15:05:03: [SM] [1] Line 75, c:\Users\BuT\Desktop\SP\addons\sourcemod\scripting\PlayersUpdateServerSaite.sp::SQLplayer_update
L 11/01/2022 - 15:05:03: [SM] [2] Line 50, c:\Users\BuT\Desktop\SP\addons\sourcemod\scripting\PlayersUpdateServerSaite.sp::OnClientPutInServer

2) MaxHumansz = GetMaxHumanPlayers();
В OnPluginStart() - показывает 64, не знаю почему сервер запускается под 64 слота, а потом меняет на то что я указал. Пришлось его в SQLplayer_update() переместить.

3) Как это раюотает?
premiumSlots = FindConVar("sm_reserved_slots"); - РАБОТАЕТ, но в OnPluginStart() иногда пишет огромное цифры, тоже в SQLplayer_update() нужно переместить.
premiumSlots = GetConVarInt(FindConVar("sm_reserved_slots")); - Не работает, просто Error при запуске плагина.
 
Последнее редактирование:

Мотыга

сила в силе духа ☠️☠️☠️
Сообщения
84
Реакции
49
Кто может помочь с данным плагином ([ClientMod] KDLP Game Events:)
Плагин не удаляет стандартные сообщение о подключении игрока(которых не должно быть)
Выглядит это так

My Server | Suchiy Pego заходит на сервер - (сообщение плагина)
Suchiy Pego вошел в игру (стандартное сообщение)

Нужно убрать второе стандартное сообщение,заранее спасибо.

[ClientMod] KDLP Game Events:
#include <morecolors>
#include <clientmod>

public Plugin:myinfo =
{
    name = "[CS:S v34][CM][KDLP] Game Events",
    author = "KorDen",
    description = "ClientMod Edition",
    version = "1.0.1",
    url = "dev.sky-play.ru / vk.com/clientmod"
}
public OnPluginStart()
{
    HookEvent("player_disconnect", OnConn, EventHookMode_Pre);
    HookEvent("player_connect", OnConn, EventHookMode_Pre);
    HookEvent("player_team", OnTeam, EventHookMode_Pre);
    HookEventEx("player_connect_client", OnConn2, EventHookMode_Pre);
}

public Action:OnTeam(Handle:event, String:name[], bool:dontBroadcast)
{
    if (!dontBroadcast && !GetEventBool(event,"disconnect") && !GetEventBool(event,"silent"))
    {
        new target = GetClientOfUserId(GetEventInt(event, "userid"));
    
        SetEventBroadcast(event, true);
        switch (GetEventInt(event, "team"))
        {
            case 1:
            {
                for(new i = 1; i <= MaxClients; i++)
                {
                    if(IsClientInGame(i) && !IsFakeClient(i))
                    {
                        // Это будет показываться тем, кто играет через обычный клиент CS:S v34:
                        if(!CM_IsClientModUser(i, true)) PrintToChat(i, "\x03My Server \x04| \x01%N \x04переходит к \x03Наблюдателям", target);
                        // Это будет показываться тем, кто играет через ClientMod:
                        else if(CM_IsClientModUser(i, true)) CPrintToChat(i, "{deeppink}My Server {black}| {lime}%N {white}переходит к {darkgray}Наблюдателям", target); // new client
                    }
                }
            }
            case 2:
            {
                for(new i = 1; i <= MaxClients; i++)
                {
                    if(IsClientInGame(i) && !IsFakeClient(i))
                    {
                        // Это будет показываться тем, кто играет через обычный клиент CS:S v34:
                        if(!CM_IsClientModUser(i, true)) PrintToChat(i, "\x03My Server \x04| \x01%N \x04переходит к \x03Террористам", target);
                        // Это будет показываться тем, кто играет через ClientMod:
                        else if(CM_IsClientModUser(i, true)) CPrintToChat(i, "{deeppink}My Server {black}| {lime}%N {white}переходит к {fullred}Террористам", target); // new client
                    }
                }
            }
            case 3:
            {
                for(new i = 1; i <= MaxClients; i++)
                {
                    if(IsClientInGame(i) && !IsFakeClient(i))
                    {
                        // Это будет показываться тем, кто играет через обычный клиент CS:S v34:
                        if(!CM_IsClientModUser(i, true)) PrintToChat(i, "\x03My Server \x04| \x01%N \x04переходит к \x03Спецназовцам", target);
                        // Это будет показываться тем, кто играет через ClientMod:
                        else if(CM_IsClientModUser(i, true)) CPrintToChat(i, "{deeppink}My Server {black}| {lime}%N {white}переходит к {fullblue}Спецназовцам", target); // new client
                    }
                }
            }
        }
    }
    return Plugin_Continue;
}

public Action:OnConn(Handle:event, const String:name[], bool:dontBroadcast)
{
    if (!dontBroadcast)
    SetEventBroadcast(event, true);
    decl String:rawmsg[255], String:rawadmmsg[255], String:rawmsg2[255], String:rawadmmsg2[255], String:nick[MAX_NAME_LENGTH],
String:steam[24], String:ip[16], String:reason[192];
    new i;
    GetEventString(event, "networkid", steam, sizeof(steam));
    GetEventString(event, "name", nick, sizeof(nick));
    if (strcmp(name,"player_disconnect"))
    {   
        GetEventString(event, "address", ip, sizeof(ip));
        SplitString(ip, ":", ip, sizeof(ip));
        
        // Это будет показываться тем, кто играет через обычный клиент CS:S v34:
        FormatEx(rawmsg, sizeof(rawmsg), "\x03My Server \x04| \x01%s \x04заходит на сервер", nick);
        FormatEx(rawadmmsg, sizeof(rawadmmsg), "\x03My Server \x04| \x01%s \x04| \x03%s \x04заходит на сервер", nick, ip);
        
        // Это будет показываться тем, кто играет через ClientMod:
        FormatEx(rawmsg2, sizeof(rawmsg2), "{deeppink}My Server {black}| {lime}%s {white}заходит на сервер", nick); // new client
        FormatEx(rawadmmsg2, sizeof(rawadmmsg2), "{deeppink}My Server {black}| {lime}%s {black}| {fullred}%s {white}заходит на сервер", nick, ip); // new client
    }
    else
    {
        i = GetClientOfUserId(GetEventInt(event,"userid"));
        if(i < 1)
        return;
        GetEventString(event, "reason", reason, sizeof(reason));
        GetClientIP(i, ip, sizeof(ip)); // В player_disconnect нет address
        ReplaceString(reason, sizeof(reason), "\n", " ");
        
        // Это будет показываться тем, кто играет через обычный клиент CS:S v34:
        FormatEx(rawadmmsg, sizeof(rawadmmsg),"\x03My Server \x04| \x01%s \x04| \x03%s \x04уходит с сервера \x03- \x01%s", nick, ip, reason);
        FormatEx(rawmsg, sizeof(rawmsg),"\x03My Server \x04| \x01%s \x04уходит с сервера \x03- \x01%s", nick, reason);
        
        // Это будет показываться тем, кто играет через ClientMod:
        FormatEx(rawadmmsg2, sizeof(rawadmmsg2),"{deeppink}My Server {black}| {lime}%s {black}| {fullred}%s {white}уходит с сервера {black}- {white}%s", nick, ip, reason); // new client
        FormatEx(rawmsg2, sizeof(rawmsg2),"{deeppink}My Server {black}| {lime}%s {white}уходит с сервера {black}- {white}%s", nick, reason); // new client
    }   
    
    for (i = 1; i <= MaxClients; i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            if(!CM_IsClientModUser(i, true)) PrintToChat(i, (GetUserFlagBits(i) & (ADMFLAG_GENERIC+ADMFLAG_ROOT)) ? rawadmmsg : rawmsg);
            else if(CM_IsClientModUser(i, true)) CPrintToChat(i, (GetUserFlagBits(i) & (ADMFLAG_GENERIC+ADMFLAG_ROOT)) ? rawadmmsg2 : rawmsg2); // new client
        }
    }
}
public Action:OnConn2(Handle:event, const String:name[], bool:dontBroadcast)
{
    if (!dontBroadcast)
    SetEventBroadcast(event, true);
    return Plugin_Continue;
}
 

0-BuTaJIuK-0

Участник
Сообщения
235
Реакции
57
Итого, что получилось:
Осталась ошибка:
L 11/01/2022 - 21:17:51: [SM] Exception reported: Invalid database Handle 0 (error: 4)
L 11/01/2022 - 21:17:51: [SM] Blaming: PlayersUpdateServerSaite.smx
L 11/01/2022 - 21:17:51: [SM] Call stack trace:
L 11/01/2022 - 21:17:51: [SM] [0] Database.Query
L 11/01/2022 - 21:17:51: [SM] [1] Line 67, c:\Users\BuT\Desktop\SP\addons\sourcemod\scripting\PlayersUpdateServerSaite.sp::SQLplayer_update
L 11/01/2022 - 21:17:51: [SM] [2] Line 51, c:\Users\BuT\Desktop\SP\addons\sourcemod\scripting\PlayersUpdateServerSaite.sp::OnClientPutInServer

КОД:

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

public Plugin:myinfo =
{
    name = "Players Update Server Saite",
    author = "0-BuTaJIuK-0",
    description = "Обновление счётчика игроков на сайте",
    version = "1.0",
    url = "*****"
};

Database g_hDatabase; // Глобальная переменная для соединения с базой
char serverPortz[32]; // Переменная для порта сервера
char serverPortGoTvz[32]; // Переменная для порта GOTV
ConVar premiumSlots; // Зарезервированные слоты
int MaxHumansz; // Слоты сервара
bool ReloadMap = false;

public OnPluginStart()
{
    premiumSlots = FindConVar("sm_reserved_slots");
    GetConVarString(FindConVar("hostport"), serverPortz, sizeof(serverPortz)); // Хук порта сервера
    GetConVarString(FindConVar("tv_port"), serverPortGoTvz, sizeof(serverPortGoTvz)); // Хук порта сервера
    Database.Connect(ConnectCallBack, "imba"); // sp_lessons Имя секции в databases.cfg
}


// *** СТАРТ/СТОП карты
public OnMapStart()
{
    MaxHumansz = GetMaxHumanPlayers();

    char szQueryMap[512];
    FormatEx(szQueryMap, sizeof(szQueryMap), "UPDATE `servers` SET `portGoTv` = %s, `slots` = %i, `usersOnline` = %i, `premiumSlots` = %i WHERE `port` = %s;", serverPortGoTvz, MaxHumansz, iCountFunc(), premiumSlots, serverPortz);
    g_hDatabase.Query(SQL_Callback_CheckError, szQueryMap);
    PrintToServer("Запись в бд: %s", szQueryMap); // DEBUG
    ReloadMap = false;
}

public OnMapEnd()
{
    ReloadMap = true;
}
// **********************

public OnClientPutInServer()
{
    if(ReloadMap == false)
    {
        SQLplayer_update();
    }
}

public OnClientDisconnect_Post()
{
    if(ReloadMap == false)
    {
        SQLplayer_update();
    }
}

public SQLplayer_update()
{
    char szQuery[512];
    FormatEx(szQuery, sizeof(szQuery), "UPDATE `servers` SET `usersOnline` = %i WHERE `port` = %s;", iCountFunc(), serverPortz);
    g_hDatabase.Query(SQL_Callback_CheckError, szQuery);
    PrintToServer("Онлайн сервера: %s", szQuery); // DEBUG
}

int iCountFunc()
{
    //int iCount = GetClientCount(); // Один из вариантов хука кол-во слотов, но с ботом GOTV
    int iCount = 0;
    for(new i = 1; i <= MaxClients; i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            iCount++;
        }
    }
    return iCount;
}

// БД**************************************************************************************************************************************
public ConnectCallBack (Database hDatabase, const char[] szError, any data) // Пришел результат соединения
{
    if (hDatabase == null || szError[0]) // Соединение не удачное
    {
        SetFailState("Database failure: %s", szError); // Отключаем плагин
        return;
    }
    g_hDatabase = hDatabase; // Присваиваем глобальной переменной соединения значение текущего соединения
    g_hDatabase.SetCharset("utf8"); // Устанавливаем кодировку
}

// Обработчик ошибок
public SQL_Callback_CheckError(Database hDatabase, DBResultSet results, const char[] szError, any data)
{
    if(szError[0])
    {
        LogError("SQL_Callback_CheckError: %s", szError);
    }
}
// **************************************************************************************************************************************

/*
public OnConfigsExecuted()
{
    PrintToServer("TEST-------------")
}
        PrintToServer("****************************FYEC")  // DEBUG
        PrintToServer("MaxHumans: %i", MaxHumansz)
        PrintToServer("iCount: %i", iCountFunc())
        PrintToServer("premiumSlots: %i", premiumSlots)
        PrintToServer("serverPort: %s", serverPortz)
        PrintToServer("serverPortGoTvz: %s", serverPortGoTvz)
        PrintToServer("SzQuery: %s", szQueryMap)
        PrintToServer("****************************")  // DEBUG

*/

Screenshot_2.png
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Осталась ошибка:
L 11/01/2022 - 21:17:51: [SM] Exception reported: Invalid database Handle 0 (error: 4)
L 11/01/2022 - 21:17:51: [SM] Blaming: PlayersUpdateServerSaite.smx
L 11/01/2022 - 21:17:51: [SM] Call stack trace:
L 11/01/2022 - 21:17:51: [SM] [0] Database.Query
L 11/01/2022 - 21:17:51: [SM] [1] Line 67, c:\Users\BuT\Desktop\SP\addons\sourcemod\scripting\PlayersUpdateServerSaite.sp::SQLplayer_update
L 11/01/2022 - 21:17:51: [SM] [2] Line 51, c:\Users\BuT\Desktop\SP\addons\sourcemod\scripting\PlayersUpdateServerSaite.sp::OnClientPutInServer

КОД:

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

public Plugin:myinfo =
{
    name = "Players Update Server Saite",
    author = "0-BuTaJIuK-0",
    description = "Обновление счётчика игроков на сайте",
    version = "1.0",
    url = "*****"
};

Database g_hDatabase; // Глобальная переменная для соединения с базой
char serverPortz[32]; // Переменная для порта сервера
char serverPortGoTvz[32]; // Переменная для порта GOTV
ConVar premiumSlots; // Зарезервированные слоты
int MaxHumansz; // Слоты сервара
bool ReloadMap = false;

public OnPluginStart()
{
    premiumSlots = FindConVar("sm_reserved_slots");
    GetConVarString(FindConVar("hostport"), serverPortz, sizeof(serverPortz)); // Хук порта сервера
    GetConVarString(FindConVar("tv_port"), serverPortGoTvz, sizeof(serverPortGoTvz)); // Хук порта сервера
    Database.Connect(ConnectCallBack, "imba"); // sp_lessons Имя секции в databases.cfg
}


// *** СТАРТ/СТОП карты
public OnMapStart()
{
    MaxHumansz = GetMaxHumanPlayers();

    char szQueryMap[512];
    FormatEx(szQueryMap, sizeof(szQueryMap), "UPDATE `servers` SET `portGoTv` = %s, `slots` = %i, `usersOnline` = %i, `premiumSlots` = %i WHERE `port` = %s;", serverPortGoTvz, MaxHumansz, iCountFunc(), premiumSlots, serverPortz);
    g_hDatabase.Query(SQL_Callback_CheckError, szQueryMap);
    PrintToServer("Запись в бд: %s", szQueryMap); // DEBUG
    ReloadMap = false;
}

public OnMapEnd()
{
    ReloadMap = true;
}
// **********************

public OnClientPutInServer()
{
    if(ReloadMap == false)
    {
        SQLplayer_update();
    }
}

public OnClientDisconnect_Post()
{
    if(ReloadMap == false)
    {
        SQLplayer_update();
    }
}

public SQLplayer_update()
{
    char szQuery[512];
    FormatEx(szQuery, sizeof(szQuery), "UPDATE `servers` SET `usersOnline` = %i WHERE `port` = %s;", iCountFunc(), serverPortz);
    g_hDatabase.Query(SQL_Callback_CheckError, szQuery);
    PrintToServer("Онлайн сервера: %s", szQuery); // DEBUG
}

int iCountFunc()
{
    //int iCount = GetClientCount(); // Один из вариантов хука кол-во слотов, но с ботом GOTV
    int iCount = 0;
    for(new i = 1; i <= MaxClients; i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            iCount++;
        }
    }
    return iCount;
}

// БД**************************************************************************************************************************************
public ConnectCallBack (Database hDatabase, const char[] szError, any data) // Пришел результат соединения
{
    if (hDatabase == null || szError[0]) // Соединение не удачное
    {
        SetFailState("Database failure: %s", szError); // Отключаем плагин
        return;
    }
    g_hDatabase = hDatabase; // Присваиваем глобальной переменной соединения значение текущего соединения
    g_hDatabase.SetCharset("utf8"); // Устанавливаем кодировку
}

// Обработчик ошибок
public SQL_Callback_CheckError(Database hDatabase, DBResultSet results, const char[] szError, any data)
{
    if(szError[0])
    {
        LogError("SQL_Callback_CheckError: %s", szError);
    }
}
// **************************************************************************************************************************************

/*
public OnConfigsExecuted()
{
    PrintToServer("TEST-------------")
}
        PrintToServer("****************************FYEC")  // DEBUG
        PrintToServer("MaxHumans: %i", MaxHumansz)
        PrintToServer("iCount: %i", iCountFunc())
        PrintToServer("premiumSlots: %i", premiumSlots)
        PrintToServer("serverPort: %s", serverPortz)
        PrintToServer("serverPortGoTvz: %s", serverPortGoTvz)
        PrintToServer("SzQuery: %s", szQueryMap)
        PrintToServer("****************************")  // DEBUG

*/

Посмотреть вложение 103934
Ошибка вообще говорит, что нет подключения к базе. Типо хендл подключения равен нулю
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Но при этом, в базу записывает 😳
Зачем на 67 строке выводить сам запрос в дебаг? Если тебе нужно новый строить запрос для получения онлайна вместо
public OnClientPutInServer() лучше наверное на public void OnClientPostAdminCheck(int client)
 
Сверху Снизу