[Any] Welcome Sound/Музыка при входе

[Any] Welcome Sound/Музыка при входе 1.0.1

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
Не проигрывать приветствие повторно если игрок не выходил с сервера
Ты имеешь в виду при смене карты?
В принципе такую проверку возможно сделать, только придётся заморочиться с сохранением SteamId игроков бывших на карте перед её сменой. И ещё нужно как-то определить, что выход с сервера был вызван именно сменой карты (при смене карты происходит перезаход игроков на сервер).
 

Nekro

Терра инкогнита
Сообщения
4,042
Реакции
2,295
  • Автор ресурса
  • #42
Ты имеешь в виду при смене карты?
В принципе такую проверку возможно сделать, только придётся заморочиться с сохранением SteamId игроков бывших на карте перед её сменой. И ещё нужно как-то определить, что выход с сервера был вызван именно сменой карты (при смене карты происходит перезаход игроков на сервер).
Наверное просто легче запомнить, что если игрок заходил N времени назад, то не проигрывать звук
 

zAntibot

Участник
Сообщения
133
Реакции
50
Ты имеешь в виду при смене карты?
В принципе такую проверку возможно сделать, только придётся заморочиться с сохранением SteamId игроков бывших на карте перед её сменой. И ещё нужно как-то определить, что выход с сервера был вызван именно сменой карты (при смене карты происходит перезаход игроков на сервер).
Да, как то сделать что бы один раз в день или там раз в 3 часа... Или там раз в энное количество карт
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
@Nekro, да просто получать SteamId при авторизации и писать его в ArrayList.
При старте (или может лучше наоборот завершении) раунда чистить этот ArrayList от отсутствующих игроков.
И если при авторизации нового игрока его SteamId всё ещё в этом ArrayList, то игнорировать его.
 

MODER DEV

Участник
Сообщения
60
Реакции
14
Да, как то сделать что бы один раз в день или там раз в 3 часа... Или там раз в энное количество карт
Конфигурационный файл welcome_sound.cfg создается автоматически в папке cfg/sourcemod/

// Громкость приветственных звуков по умолчанию (0.0 - 1.0)
sm_welcome_sound_default_volume "1.0"

// Показывать сообщение в чате при входе (0 или 1)
sm_welcome_sound_show_chat "1"

// Разрешить игрокам доступ к меню настроек (0 или 1)
sm_welcome_sound_allow_settings "1"

// Интервал повторного воспроизведения звука при перезаходе(0 = всегда воспроизводить)
sm_welcome_sound_play_interval "60"


Меню открывается двумя командами

!welcome
!ws


В меню :
  1. Статус: Позволяет включить или выключить воспроизведение приветственного звука при входе на сервер.
  2. Громкость: Открывает подменю для выбора громкости приветственных звуков. Можно установить значение от 0% до 100%.
  3. Прослушать: Воспроизводит случайный звук из списка доступных приветственных звуков для проверки.
 

Вложения

  • welcome_sound.sp
    11.4 КБ · Просмотры: 13
  • welcome_sound.smx
    10 КБ · Просмотры: 8

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
Поправил чуток код, добавил проверки валидности путей при добавлении файлов в ArrayList и сделал так, чтобы событие хукалось только если в ArrayList были добавлены звуки.
Сообщения автоматически склеены:

@MODER DEV, что-то много лишнего кода.

C-подобный:
#define MAX_SOUND_PATH_LENGTH 256
Вообще-то дефайн PLATFORM_MAX_PATH равен 256. Для чего ещё один заводить? =)
C-подобный:
    GetClientCookie(client, g_hCookieEnabled, sEnabled, sizeof(sEnabled));
    GetClientCookie(client, g_hCookieVolume, sVolume, sizeof(sVolume));
Я обычно такое в один файл сохраняю через разделители, чтобы место сэкономить (3 - 4 значения легко можно запихнуть, если число знаков небольшое).

C-подобный:
g_bClientEnabled[client] = (sEnabled[0] == '\0') ? true : (StringToInt(sEnabled) != 0);
...
char sValue[8];
IntToString(g_bClientEnabled[client], sValue, sizeof(sValue));
SetClientCookie(client, g_hCookieEnabled, sValue);
а ведь можно было так:
C-подобный:
g_bClientEnabled[client] = sEnabled[0] != '0';
...
SetClientCookie(client, g_hCookieEnabled, g_bClientEnabled[client] ? "1" : "0");

Ну и это:
C-подобный:
        TrimString(sLine);
        StripComments(sLine);
        if (sLine[0] == '\0') continue;
...
void StripComments(char[] line)
{
    int iPos = StrContains(line, "//");
    if (iPos == -1) iPos = StrContains(line, "#");
    if (iPos == -1) iPos = StrContains(line, ";");
    if (iPos != -1) line[iPos] = '\0';
    TrimString(line);
}
я бы поменял на вот это:
C-подобный:
        if (!StripComments(sLine)) continue;
...
int StripComments(char[] line)
{
    int iPos;
    if ((iPos = StrContains(line, "//")) != -1) line[iPos] = 0;
    if ((iPos = StrContains(line, "#"))  != -1) line[iPos] = 0;
    if ((iPos = StrContains(line, ";"))  != -1) line[iPos] = 0;
    return TrimString(line);
}
и после вызова StripComments() ещё бы добавил проверку валидности полученого пути, как у меня в файле.
 

Вложения

  • welcome_sound 1.0.2_20.08.2025.sp
    2.3 КБ · Просмотры: 15
Последнее редактирование:

MODER DEV

Участник
Сообщения
60
Реакции
14
Поправил чуток код, добавил проверки валидности путей при добавлении файлов в ArrayList и сделал так, чтобы событие хукалось только если в ArrayList были добавлены звуки.
Сообщения автоматически склеены:

@MODER DEV, что-то много лишнего кода.

C-подобный:
#define MAX_SOUND_PATH_LENGTH 256
Вообще-то дефайн PLATFORM_MAX_PATH равен 256. Для чего ещё один заводить? =)
C-подобный:
    GetClientCookie(client, g_hCookieEnabled, sEnabled, sizeof(sEnabled));
    GetClientCookie(client, g_hCookieVolume, sVolume, sizeof(sVolume));
Я обычно такое в один файл сохраняю через разделители, чтобы место сэкономить (3 - 4 значения легко можно запихнуть, если число знаков небольшое).

C-подобный:
g_bClientEnabled[client] = (sEnabled[0] == '\0') ? true : (StringToInt(sEnabled) != 0);
...
char sValue[8];
IntToString(g_bClientEnabled[client], sValue, sizeof(sValue));
SetClientCookie(client, g_hCookieEnabled, sValue);
а ведь можно было так:
C-подобный:
g_bClientEnabled[client] = sEnabled[0] != '0';
...
SetClientCookie(client, g_hCookieEnabled, g_bClientEnabled[client] ? "1" : "0");

Ну и это:
C-подобный:
        TrimString(sLine);
        StripComments(sLine);
        if (sLine[0] == '\0') continue;
...
void StripComments(char[] line)
{
    int iPos = StrContains(line, "//");
    if (iPos == -1) iPos = StrContains(line, "#");
    if (iPos == -1) iPos = StrContains(line, ";");
    if (iPos != -1) line[iPos] = '\0';
    TrimString(line);
}
я бы поменял на вот это:
C-подобный:
        if (!StripComments(sLine)) continue;
...
int StripComments(char[] line)
{
    int iPos;
    if ((iPos = StrContains(line, "//")) != -1) line[iPos] = 0;
    if ((iPos = StrContains(line, "#"))  != -1) line[iPos] = 0;
    if ((iPos = StrContains(line, ";"))  != -1) line[iPos] = 0;
    return TrimString(line);
}
и после вызова StripComments() ещё бы добавил проверку валидности полученого пути, как у меня в файле.
Сообщения автоматически склеены:

как у меня в файле.
C-подобный:
#pragma semicolon 1
#pragma newdecls required

#include <sdktools_sound>
#include <sdktools_stringtables>

ArrayList
    hSoundList;
bool
    bHooked;

public Plugin myinfo =
{
    name        = "[Any] Welcome Sound/Музыка при входе",
    version        = "1.0.2_20.08.2025 (rewritten by Grey83)",
    description    = "Музыка при входе",
    author        = "Nek.'a 2x2 | ggwp.site ",
    url            = "https://ggwp.site/"
};

public void OnPluginStart()
{
    hSoundList = new ArrayList(ByteCountToCells(PLATFORM_MAX_PATH));
}

public void OnMapStart()
{
    if(hSoundList.Length) hSoundList.Clear();

    char sPath[PLATFORM_MAX_PATH];
    BuildPath(Path_SM, sPath, sizeof(sPath), "configs/welcome_sound.ini");

    File hFile = OpenFile(sPath, "r");
    if(!hFile)
    {
        ThrowError("Файл [%s] не существует!", sPath);
    }

    int pos, len;
    char line[PLATFORM_MAX_PATH];
    // Упрощено условие цикла
    while (ReadFileLine(hFile, line, sizeof(line)))
    {
        if ((pos = StrContains(line, "//")) != -1) line[pos] = 0;
        if ((pos = StrContains(line, "#")) != -1)  line[pos] = 0;
        if ((pos = StrContains(line, ";")) != -1)  line[pos] = 0;

        //  Переписана и исправлена проверка расширения файла
        // Получаем длину строки после TrimString
        len = TrimString(line);
        // Проверяем длину и расширение файла
        if(len < 5 ||
           (StrContains(line, ".mp3", false) != (len - 4) &&
            StrContains(line, ".wav", false) != (len - 4))
            || !PrecacheSound(line, false))
            continue;

        hSoundList.PushString(line);

        Format(line, sizeof(line), "sound/%s", line);
        AddFileToDownloadsTable(line);
    }
    delete hFile;

    // Переписана логика управления хуком
    // Всегда отписываемся, если подписаны, на случай изменения конфига
    if (bHooked)
    {
        UnhookEvent("player_activate", Event_Activate, EventHookMode_Pre);
        bHooked = false;
    }

    // Подписываемся, если есть звуки
    if (hSoundList.Length > 0)
    {
        HookEvent("player_activate", Event_Activate, EventHookMode_Pre);
        bHooked = true;
    }
}

public void Event_Activate(Event event, const char[] name, bool dontBroadcast)
{
    int client = GetClientOfUserId(event.GetInt("userid"));
    if(!client || !IsClientInGame(client) || IsFakeClient(client))
        return;

    char sSound[PLATFORM_MAX_PATH];
    hSoundList.GetString(GetRandomInt(0, hSoundList.Length - 1), sSound, sizeof(sSound));
    EmitSoundToClient(client, sSound);
}
 

Вложения

  • welcome_sound.smx
    4.8 КБ · Просмотры: 6
  • welcome_sound.sp
    2.6 КБ · Просмотры: 7

zAntibot

Участник
Сообщения
133
Реакции
50
Поправил чуток код, добавил проверки валидности путей при добавлении файлов в ArrayList и сделал так, чтобы событие хукалось только если в ArrayList были добавлены звуки.
Сообщения автоматически склеены:

@MODER DEV, что-то много лишнего кода.

C-подобный:
#define MAX_SOUND_PATH_LENGTH 256
Вообще-то дефайн PLATFORM_MAX_PATH равен 256. Для чего ещё один заводить? =)
C-подобный:
    GetClientCookie(client, g_hCookieEnabled, sEnabled, sizeof(sEnabled));
    GetClientCookie(client, g_hCookieVolume, sVolume, sizeof(sVolume));
Я обычно такое в один файл сохраняю через разделители, чтобы место сэкономить (3 - 4 значения легко можно запихнуть, если число знаков небольшое).

C-подобный:
g_bClientEnabled[client] = (sEnabled[0] == '\0') ? true : (StringToInt(sEnabled) != 0);
...
char sValue[8];
IntToString(g_bClientEnabled[client], sValue, sizeof(sValue));
SetClientCookie(client, g_hCookieEnabled, sValue);
а ведь можно было так:
C-подобный:
g_bClientEnabled[client] = sEnabled[0] != '0';
...
SetClientCookie(client, g_hCookieEnabled, g_bClientEnabled[client] ? "1" : "0");

Ну и это:
C-подобный:
        TrimString(sLine);
        StripComments(sLine);
        if (sLine[0] == '\0') continue;
...
void StripComments(char[] line)
{
    int iPos = StrContains(line, "//");
    if (iPos == -1) iPos = StrContains(line, "#");
    if (iPos == -1) iPos = StrContains(line, ";");
    if (iPos != -1) line[iPos] = '\0';
    TrimString(line);
}
я бы поменял на вот это:
C-подобный:
        if (!StripComments(sLine)) continue;
...
int StripComments(char[] line)
{
    int iPos;
    if ((iPos = StrContains(line, "//")) != -1) line[iPos] = 0;
    if ((iPos = StrContains(line, "#"))  != -1) line[iPos] = 0;
    if ((iPos = StrContains(line, ";"))  != -1) line[iPos] = 0;
    return TrimString(line);
}
и после вызова StripComments() ещё бы добавил проверку валидности полученого пути, как у меня в файле.
скомпилировал, не работает совсем
Сообщения автоматически склеены:

Сообщения автоматически склеены:


C-подобный:
#pragma semicolon 1
#pragma newdecls required

#include <sdktools_sound>
#include <sdktools_stringtables>

ArrayList
    hSoundList;
bool
    bHooked;

public Plugin myinfo =
{
    name        = "[Any] Welcome Sound/Музыка при входе",
    version        = "1.0.2_20.08.2025 (rewritten by Grey83)",
    description    = "Музыка при входе",
    author        = "Nek.'a 2x2 | ggwp.site ",
    url            = "https://ggwp.site/"
};

public void OnPluginStart()
{
    hSoundList = new ArrayList(ByteCountToCells(PLATFORM_MAX_PATH));
}

public void OnMapStart()
{
    if(hSoundList.Length) hSoundList.Clear();

    char sPath[PLATFORM_MAX_PATH];
    BuildPath(Path_SM, sPath, sizeof(sPath), "configs/welcome_sound.ini");

    File hFile = OpenFile(sPath, "r");
    if(!hFile)
    {
        ThrowError("Файл [%s] не существует!", sPath);
    }

    int pos, len;
    char line[PLATFORM_MAX_PATH];
    // Упрощено условие цикла
    while (ReadFileLine(hFile, line, sizeof(line)))
    {
        if ((pos = StrContains(line, "//")) != -1) line[pos] = 0;
        if ((pos = StrContains(line, "#")) != -1)  line[pos] = 0;
        if ((pos = StrContains(line, ";")) != -1)  line[pos] = 0;

        //  Переписана и исправлена проверка расширения файла
        // Получаем длину строки после TrimString
        len = TrimString(line);
        // Проверяем длину и расширение файла
        if(len < 5 ||
           (StrContains(line, ".mp3", false) != (len - 4) &&
            StrContains(line, ".wav", false) != (len - 4))
            || !PrecacheSound(line, false))
            continue;

        hSoundList.PushString(line);

        Format(line, sizeof(line), "sound/%s", line);
        AddFileToDownloadsTable(line);
    }
    delete hFile;

    // Переписана логика управления хуком
    // Всегда отписываемся, если подписаны, на случай изменения конфига
    if (bHooked)
    {
        UnhookEvent("player_activate", Event_Activate, EventHookMode_Pre);
        bHooked = false;
    }

    // Подписываемся, если есть звуки
    if (hSoundList.Length > 0)
    {
        HookEvent("player_activate", Event_Activate, EventHookMode_Pre);
        bHooked = true;
    }
}

public void Event_Activate(Event event, const char[] name, bool dontBroadcast)
{
    int client = GetClientOfUserId(event.GetInt("userid"));
    if(!client || !IsClientInGame(client) || IsFakeClient(client))
        return;

    char sSound[PLATFORM_MAX_PATH];
    hSoundList.GetString(GetRandomInt(0, hSoundList.Length - 1), sSound, sizeof(sSound));
    EmitSoundToClient(client, sSound);
}
во спасибо работает
 
Последнее редактирование:

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
не работает совсем
в логах соурсмода ошибки какие-нибудь есть?
Сообщения автоматически склеены:

Добавил проверку на то что был ли игрок на сервере в конце прошлого раунда или нет. Думаю этого будет достаточно.
А выходящие перед концом раунда и заходящие после него пусть страдают. =)

Ещё добавил сообщений в лог ошибок, если будут какие-то косяки с файлом welcome_sound.ini.
 

Вложения

  • welcome_sound 1.1.0_21.08.2025.sp
    3.9 КБ · Просмотры: 9
Последнее редактирование:
Сверху Снизу