Склад функций SourcePawn

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@Dragokas, а почему не сделать вот так?
C-подобный:
#include <UTF-8-string>

public void OnPluginStart()
{
    char TEST[] = "фАYgfвАПиаОРИГОРТUYfyutTYGFfvygtf";
    PrintToServer("\n<TEST>\nOrig: %s", TEST);
    int num = NormalizeName(TEST);
    PrintToServer("Norm: %s\nNum: %i\n</TEST>\n", TEST, num);
}

stock int NormalizeName(char[] str)
{
    if(!str[0])
        return 0;

    int num, start = GetCharBytes(str[0]);
    char buffer[4];
    int i;
    while(i < start)
    {
        buffer[i] = str[i];
        i++;
    }
    buffer[start] = i = 0

    num = UTF8CharToUpper(buffer) + UTF8CharToLower(str[start]);
    while(i < start)
    {
        str[i] = buffer[i];
        i++;
    }
    return num;
}
Результат:
<TEST>
Orig: фАYgfвАПиаОРИГОРТUYfyutTYGFfvygtf
Norm: Фаygfвапиаоригортuyfyuttygffvygtf
Num: 18
</TEST>
Сообщения автоматически склеены:

Функции UTF8CharTo*() проигнорят же пробелы и так, поэтому нет необходимости в проверке IsCharSpace(str).
Да и цикл по строке тоже не нужен: UTF8CharTo*() сами пройдут по строке.
 
Последнее редактирование:

Dragokas

Добрая душа
Сообщения
229
Реакции
213
Потому что у меня был именно такой use-case, сохранить регистр 1-х букв слов:
Работает по правилу:
1-я буква 1-го слова - Большая.
1-я буква остальных слов - не трогаем.
Остальные буквы - маленькие.
Юзал для нормализации названий кампаний и миссий. У кого-то use-case может быть другой.
Согласен, не самое популярное действие, и далеко не самый короткий код.
Можно, как у вас, если надо проще. Можно заюзать как у Wend4r, если только EN/RU интересует,
а можно просто пройтись CharToLower/CharToUpper по символам, если в тексте только EN.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
Потому что у меня был именно такой use-case, сохранить регистр 1-х букв слов:
т.е. никаких отличий от моего решения, кроме кучи лишних телодвижений (у тебя в коде я не вижу проверки конца предложения по знакам препинания)
 

Dragokas

Добрая душа
Сообщения
229
Реакции
213
Ой, ну если не нравится, напишите модератору, удалите, мне вообще похрен.
Развели тут обсуждений. Нравится / не нравится.
(у тебя в коде я не вижу проверки конца предложения по знакам препинания)
Еще не хватает проверки на наличие фильтра нецензурных слов, блекджека и шлюх.
Если меряться пиписьками, то твое решение (которое на самом деле получиться чисто код Феникса), без проверок и оптимизаций можно записать в 2 строки:
C-подобный:
UTF8CharToUpper(str);
UTF8CharToLower(str[1]);
А вот инков от феникса и правда не хватает в 1-м посту. Полезное, а хрен найдешь.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
Еще не хватает проверки на наличие фильтра нецензурных слов, блекджека и шлюх.
а как же вот это?
Нормализация регистра символов слов в предложении.
Так получается не в предложении, а просто в куске текста. Точнее любая первая буква в строке делается заглавной, а остальные - строчными независимо от того являются ли эти буквы первыми в новом предложении или же нет.
Так-то я предложил гораздо более простую альтернативу (даже функции от феникса переписывать не понадобилось).

Хотя я и инклюд феникса когда-то (в феврале 2019-го январе 2018-го) подправлял под себя.
Сообщения автоматически склеены:

Сейчас смотрю свою версию: а ведь есть ещё что поправить (в 2 местах у трёх функций else не нужно, т.е. в 6 местах инклюда).
 

Вложения

  • UTF-8-string.inc
    7.4 КБ · Просмотры: 4

Dragokas

Добрая душа
Сообщения
229
Реакции
213
ак получается не в предложении, а просто в куске текста. Точнее любая первая буква в строке делается заглавной, а остальные - строчными независимо от того являются ли эти буквы первыми в новом предложении или же нет.
Так-то я предложил гораздо более простую альтернативу (даже функции от феникса переписывать не понадобилось).
В 1 предложении, а не в предложениях.

Твоя версия:
"ПРИВЕТ из БУНКЕРА." => "Привет из бункера."
"ПРИВЕТ из бУНКЕРА." => "Привет из бункера."

Моя версия:
"ПРИВЕТ из БУНКЕРА." => "Привет из Бункера."
"ПРИВЕТ из бУНКЕРА." => "Привет из бункера."

Надеюсь, разница видна.
Полезно, в случаях, когда есть предложение, в котором некоторые слова должны писаться с большой буквы (часто так принято например в английском языке).
При этом непонятно, в каком виде данные будут приходить на вход. Разумеется в рус. яз. такое может выглядеть нелепо.
При незначительной модификации, можно сделать, чтобы функция делала КАЖДОЕ слово с большой буквы.
Специфический юз кейс. Я никого не обязываю юзать такое правило. Но лично мне удобно было нормализовать миссии именно таким способом и теперь их названия выглядят хорошо.
 

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
Мимоходом запилил убирание незначащих нулей у float при форматировании текста.
Дефолтом у нас при форматировании без ограничения количества символов после десятичной запятой выводится 6 знаков.
PrintToServer("%f", 0.1); выведет 0.100000
Данная функция уберёт лишние нули (кроме самой первой, если другие цифры после запятой отсутствуют):
C-подобный:
stock char FloatRemoveZeros(float val)
{
    static char buffer[12];
    int i = FloatToString(val, buffer, sizeof(buffer)))-1;
    while(i > 0 && buffer[i] == '0') i--;
    if(buffer[i] == '.') buffer[++i] = '0';
    buffer[++i] = 0;

    return buffer;
}
Правда Крузя говорит, что возвращение строкового массива функцией может спровоцировать утечки памяти в SM 1.8 (про более свежие версии информации у него нет).
Использовать в коде можно вот так:
C-подобный:
public void OnPluginStart()
{
    float f = 0.1;
    PrintToServer("%f = %s", f, FloatRemoveZeros(f));
}
В результате выведется следующая строка: 0.100000 = 0.1
Лишняя скобка
C-подобный:
int i = FloatToString(val, buffer, sizeof(buffer))-1;
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
С сентября 2021 года юзаю вот такой код для определения у кого в данный момент бомба.
C-подобный:
int hPlayerResource = -1;

public void OnMapStart()
{
    hPlayerResource = -1;
}

stock int GetCarrier()
{
    return hPlayerResource != -1 || (hPlayerResource = FindEntityByClassname(hPlayerResource, "cs_player_manager")) != -1
        ? GetEntProp(hPlayerResource, Prop_Send, "m_iPlayerC4") : -1;
}
По идее должно работать не только в CS:S, но и в CS:GO.
Сообщения автоматически склеены:

В публичных плагинах код не использовался ещё, емнип.
 

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
@Kailo, вроде можно проще разбить секунды на большие промежутки времени
Вот так, например (собственно разбиение занимает всего 1 строку):
PHP:
static const char sName[][][] =
{
    {"день",    "дня",        "дней"},
    {"час",        "часа",        "часов"},
    {"минута",    "минуты",    "минут"},
    {"секунда",    "секунды",    "секунд"}
};

public void OnPluginStart()
{
    int time = GetTime() - 1471777116;
    // вот эту строку, где форматируется текст
    PrintToServer("Время, которое прошло после написания поста:%s%s%s%s", NumToName(time/3600/24, 0), NumToName(time/3600%24, 1), NumToName(time/60%60, 2), NumToName(time%60, 3));
}

stock char NumToName(int num, const int type)
{
    static char buffer[PLATFORM_MAX_PATH];
    buffer[0] = 0;

    int form;
    switch(num)
    {
        case 0:        return buffer;
        case 1:        form = 0;
        case 2,3,4:    form = 1;
        default:
        {
            if(num < 21)    form = 2;
            else switch(num%10)
            {
                case 1:        form = 0;
                case 2,3,4:    form = 1;
                default:    form = 2;
            }
        }
    }
    FormatEx(buffer, sizeof(buffer), " %i %s", num, sName[type][form]);
    return buffer;
}
[ANY] Определение окончания слова день (дня, дней)
warning 246: function NumToName returns an array but return type is not marked as an array
sourcemod-1.11.0-git6927
У себя та поправил, но тут наверное тоже хорошо бы
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@Nekro, емнип, для 1.11 нужно просто делать так: stock char[] NumToName(int num, const int type)
 

Grey83

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

xstage

🏹
Сообщения
726
Реакции
754
Код, позволяющий получить информацию о процессоре. Linux / CS:GO

1695573097876.png


C++:
#include <sdktools>

Handle hGetProccessInfo;

public void OnPluginStart()
{
    ConVar cvDeveloper[2];

    cvDeveloper[0] = FindConVar("developer");
    cvDeveloper[1] = FindConVar("sv_max_allowed_developer");

    int iDeveloper = cvDeveloper[0].IntValue;
    int iDeveloperCount = cvDeveloper[1].IntValue;

    StartPrepSDKCall(SDKCall_Static);
    PrepSDKCall_SetSignature(SDKLibrary_Engine, "\x55\x89\xE5\x57\x56\x53\x81\xEC\x2C\x02\x00\x00\x65\xA1\x14\x00\x00\x00", 72/4);
  
    if (!(hGetProccessInfo = EndPrepSDKCall()))
    {
        SetFailState("outdated signature");
    }

    cvDeveloper[1].SetInt(32);
    cvDeveloper[0].SetInt(2);

    SDKCall(hGetProccessInfo);

    cvDeveloper[0].SetInt(iDeveloper);
    cvDeveloper[1].SetInt(iDeveloperCount);
}
 

7pElllHuK

Участник
Сообщения
1,416
Реакции
465
Функция удаляющая цвета, которые находятся в фигурных скобках из строки (полезно если хотите использовать 1 файл перевода, для вывода текста как в чате, так и в HUD/По центру экрана/в хинт)

C-подобный:
void RemoveColors(const char[] sInput, char[] sOutput, int iOutputSize)
{
    int iInputLen = strlen(sInput),
        iOutIndex;

    bool bInBraces;

    for (int i = 0; i < iInputLen; i++)
    {
        if (sInput[i] == '{') bInBraces = true;
        else if (sInput[i] == '}') bInBraces = false;
        else if (!bInBraces)
            if (iOutIndex < iOutputSize - 1)
                sOutput[iOutIndex++] = sInput[i];
    }

    sOutput[iOutIndex] = '\0';
}

Пример использования:
char sMsg[256] = {"{red}[Prefix{red}] {green}тестовое сообщение!"},
    sMsg_FIX[256];
RemoveColors(sMsg, sMsg_FIX, sizeof(sMsg_FIX));

PrintToChatAll("%s", sMsg_FIX); //на выходе получим [Prefix] тестовое сообщение!
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@7pElllHuK, а не лучше было бы сначала циклом пройтись по строке и определить наличие вставок тегов в фигурных скобках, а потом при их наличии с помощью Format() скопировать куски в буферную строковую переменную? Какие куски копировать при первом проходе можно занести в двумерный ArrayList (заносить туда позиции открывающей и закрывающей скобок).
Сообщения автоматически склеены:

Ну или с помощью strcopy, а не Format.
 

7pElllHuK

Участник
Сообщения
1,416
Реакции
465
@7pElllHuK, а не лучше было бы сначала циклом пройтись по строке и определить наличие вставок тегов в фигурных скобках, а потом при их наличии с помощью Format() скопировать куски в буферную строковую переменную? Какие куски копировать при первом проходе можно занести в двумерный ArrayList (заносить туда позиции открывающей и закрывающей скобок).
Сообщения автоматически склеены:

Ну или с помощью strcopy, а не Format.
Возможно и проще, но опыта не хватает это сделать) Так что если можете сделать пример, буду только рад
 

who

Участник
Сообщения
34
Реакции
16
Функция удаляющая цвета, которые находятся в фигурных скобках из строки (полезно если хотите использовать 1 файл перевода, для вывода текста как в чате, так и в HUD/По центру экрана/в хинт)

C-подобный:
void RemoveColors(const char[] sInput, char[] sOutput, int iOutputSize)
{
    int iInputLen = strlen(sInput),
        iOutIndex;

    bool bInBraces;

    for (int i = 0; i < iInputLen; i++)
    {
        if (sInput[i] == '{') bInBraces = true;
        else if (sInput[i] == '}') bInBraces = false;
        else if (!bInBraces)
            if (iOutIndex < iOutputSize - 1)
                sOutput[iOutIndex++] = sInput[i];
    }

    sOutput[iOutIndex] = '\0';
}

Пример использования:
char sMsg[256] = {"{red}[Prefix{red}] {green}тестовое сообщение!"},
    sMsg_FIX[256];
RemoveColors(sMsg, sMsg_FIX, sizeof(sMsg_FIX));

PrintToChatAll("%s", sMsg_FIX); //на выходе получим [Prefix] тестовое сообщение!
А зачем, в multicolors уже есть MC_RemoveTags
 
Сверху Снизу