SourcePawn [SourcePawn] Урок 4 - Форматирование текста и мультиязычность

Pushistik↯❤

Команда форума
Регистрация
6 Июл 2017
Сообщения
393
Реакции
97
Баллы
28
[SourcePawn] Урок 4 - Форматирование текста и мультиязычность
<= К содержанию
  • Форматирование текста (строк)
Для этой задачи используются функции Format, FormatEx и VFormat.
Эти функции получают в качестве аргументов:
  • Строку (буфер), куда будет записан результат
  • Максимальный размер буфера (чтобы не выйти за пределы),
  • Правило формата
  • Аргументы для подстановки
Пример:
PHP:
char szBuffer[128];
Format(szBuffer, sizeof(szBuffer), "Игрок: %N, убийств - %i, смертей - %i", iClient, GetClientFrags(iClient), GetClientDeaths(iClient));
В результате мы получим такую строку:
PHP:
"Игрок: R1KO, убийств - 4, смертей - 2"
Как вы поняли функция заменяет все эти %N, %i и т.д. на аргументы, которые ей передали.
Типы данных для форматирования:
  • Численные
    • %i или %d - Целое число (%u - беззнаковое, только положительные значения)
    PHP:
    FormatEx(szBuffer, sizeof(szBuffer), "Число - %i", 5);
    Результат:
    PHP:
    "Число - 5"
    • %b - Логический тип (подставляет 1 если значение истинно и 0 если ложно)
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Значение #1 - %b, Значение #2 - %b", true, false);
      Результат:
      PHP:
      "Значение #1 - 1, Значение #2 - 0"
    • %f - Число с запятой (дробное)
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Число - %f", 16.3);
      Результат:
      PHP:
      "Число - 16.300000"
      По умолчанию после запятой выводится 6 знаков.
    • Это число можно изменить:
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Число - %.2f", 16.3); // Указываем что будет выводиться только 2 знака после запятой
      Результат:
      PHP:
      "Число - 16.30"
    • %x или %X - Шестнадцатеричное представление двоичного значения
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Число - %x", 75);
      Результат:
      PHP:
      "Число - 00004B"
  • Символьные
    • %s - Строка
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Строка - %s", "my_string");
      Результат:
      PHP:
      "Строка - my_string"
    • %c - Символ
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Символ - %c", 'r');
      Результат:
      PHP:
      "Символ - r"
    • %t и %T - Перевод фразы (подробнее будет дальше)
  • Специальные
    • %N - Ник игрока. Аргументом передается индекс игрока
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Ник - %N", iClient);
      Результат:
      PHP:
      "Ник - R1KO"
    • %L - Данные игрока (Ник <юзер_ид><стим_ид><>). Аргументом передается индекс игрока
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Игрок - %L", iClient);
      Результат:
      PHP:
      "Игрок - Tonki_Ton<406><STEAM_1:0:81729330><>"
  • Больше информации можно найти здесь: printf - C++ Reference
Важно передавать аргументы в функцию в той же последовательности, в какой они встречаются в правиле формата.
В чем же отличие функций Format, FormatEx и VFormat между собой?
  • Format - Форматирует строку в соответствии с правилами формата
  • FormatEx - Форматирует строку в соответствии с правилами формата, отличается от Format тем, что у FormatEx входным аргументом не может быть та же строка. Работает быстрее чем Format.
    PHP:
    char szBuffer[128];
    [/LIST]
    strcopy(szBuffer, sizeof(szBuffer), "my_string");    // Записываем в szBuffer значение "my_string"
    Format(szBuffer, sizeof(szBuffer), "Значение - %s", szBuffer);    // Передаем аргументом ту же строку, в которую будет помещен результат
    С FormatEx такие фокусы не проходят. По идее это может и будет работать, но как написано в api:
    This is the same as Format(), except none of the input buffers can overlap the same memory as the output buffer. Since this security check is removed, it is slightly faster.
    • VFormat - Форматирует строку в соответствии с правилами формата, но правила формата принимает не как аргумент, а как параметр функции.
      PHP:
      void MyFunc(const char[] szFormat, any ...)
      {
          int iLen = strlen(szFormat) + 255;    // Получаем длину строки с правилами формата и прибавляем запас нужный для подстановки значений
          char[] szBuffer = new char[iLen];    // Создаем буфер с полученным размером
          VFormat(szBuffer, sizeof(szBuffer), szFormat, 2);    // 2 это номер параметра any ... в заголовке функции.
          // В нашем случае 1-й параметр это szFormat, а 2-й уже any ...
          // Само объявление any ... означает что в функцию может передаваться любое количество аргументов
          // В функции эти параметры являются скрытими
          PrintToServer("Результат VFormat: %s", szBuffer);
      }
      
      // Вызываем нашу функцию:
      MyFunc("Число: %i, Строка: %s", 5, "my_string");
      // Получаем
      "Результат VFormat: Число: 5, Строка: my_string"
    Это используется для создания собственных функций с форматированием. (Например, morecolors, csgo_colors)​
    • Мультиязычность
      Мультиязычность позволяет выводить игрокам сообщения (в чат, меню, консоль и вообще куда только можно) в зависимости от языка клиента игрока.

      Для работы с мультиязычностью важно знать такие термины:
      • Языки - предварительно заданные языки перевода устанавливаются в configs\languages.cfg. Если язык перевода отсутствует в этом файле, он не может быть переведен до тех пор, пока не будет добавлен в этот файл и обновлена кэш-память переводов.
      • Фразы/Ключи перевода - Короткие, общие ключевые фразы, используемые для определения набора переводов. Они находятся в конфигурационных файлах в папке translations. Они называются файлы перевода.
      • Переводы - Содержат фразы текста перевода для данного языка. Они находятся в файлах перевода.
      • Файлы перевода - файлы с расширением .phrases.txt, которые расположены в addons/sourcemod/translations/
      Примечание: Переводы и Фразы, чувствительны к регистру.

      Для использования файла перевода его необходимо подключить к плагину:
      PHP:
      LoadTranslations("my_file.phrases");
    При этом файл должен будет иметь название: my_file.phrases.txt

    Плагины должны вызывать функцию LoadTranslations на каждый файл с переводом, который они хотят использовать. Если это не будет сделано, то никакие переводы работать не будут, даже если другой плагин загрузил те же самые файлы. Это поможет предотвратить конфликты фраз между плагинами.

    Фразы находятся в файлах перевода, которые имеют такую структуру:
    PHP:
    "Phrases"
    {
        "MyPhrase"    // Имя фразы
        {
            "en"        "Моя фраза"        // Перевод фразы для языка с кодом en
            "ru"        "My Phrase"        // Перевод фразы для языка с кодом ru
        }
    
        "Welcome"
        {
            "en"        "Welcome to SourceMod"
            "ru"        "Добро пожаловать в SourceMod"
        }
    
        "ClientConnected"
        {
            "#format"    "{1:N}"
            "en"        "Playe {1} joined"
            "ru"        "Игрок {1} подключился"
        }
    }
    Ключ "#format" задает количество параметров, для подстановки и их тип. Нумеруются они в том порядке в каком были переданы аргументы в функцию форматирования.
    PHP:
    FormatEx(szBuffer, sizeof(szBuffer), "%t", "MyPhrase", 123, "my_string", 22.4);
    В файле перевода:
    PHP:
    "Phrases"
    {
        "MyPhrase"    // Имя фразы
        {
            "#format"    "{1:i},{2:s},{3:f}"
            "en"        "int value: {1}, string value: {2}, float value: {3}"
            "ru"        "целое значение: {1}, строчное значение: {2}, дробное значение: {3}"
        }
    }
    Но в самом переводе они могут меняться местами:
    PHP:
    FormatEx(szBuffer, sizeof(szBuffer), "%t", "MyPhrase", 123, "my_string", 22.4);
    В файле перевода:
    PHP:
    "Phrases"
    {
        "MyPhrase"    // Имя фразы
        {
            "#format"    "{1:i},{2:s},{3:f}"
            "en"        "string value: {2}, int value: {1}, float value: {3}"
            "ru"        "строчное значение: {2}, целое значение: {1}, дробное значение: {3}"
        }
    }
    В ключе "#format" мы сообщаем:
    • Параметр №1 имеет тип int
    • Параметр №2 имеет тип char
    • Параметр №3 имеет тип float
    Типы были описаны в начале урока.
    • Когда использовать %t, а когда %T ?
      • %t используется если форматирование происходит после SetGlobalTransTarget.
        Функция SetGlobalTransTarget устанавливает индекс игрока, для языка которого в данный момент будет выполняться форматирование. Если её аргумент равен 0 или LANG_SERVER то форматирование будет выполнено для языка сервера.
    PHP:
    SetGlobalTransTarget(iClient);
    FormatEx(szBuffer, sizeof(szBuffer), "Перевод: %t", "MyPhrase", 123, "my_string", 22.4);
    В функциях PrintToChat, PrintToChatAll, PrintCenterText, PrintCenterTextAll, PrintHintText, PrintHintTextToAll присутствует функция SetGlobalTransTarget, поэтому при форматировании текста в них нужно писать %t.
    • %T требует чтобы 2-м аргументом (1-й это фраза) передавался индекс игрока, для которого будет выполняться форматирование.
      PHP:
      FormatEx(szBuffer, sizeof(szBuffer), "Перевод: %T", "MyPhrase", iClient, 123, "my_string", 22.4);    // 2-й аргумент - индекс игрока
      Следовательно этот код аналогичен этому:
      PHP:
      SetGlobalTransTarget(iClient);
      FormatEx(szBuffer, sizeof(szBuffer), "Перевод: %t", "MyPhrase", 123, "my_string", 22.4);
      Так же %T не допускает использования фразы внутри перевода:
      PHP:
      SetGlobalTransTarget(iClient);
      FormatEx(szBuffer, sizeof(szBuffer), "%t", "MyPhrase", "MyPhrase2");
      В файле перевода:
      PHP:
      "Phrases"
      {
          "MyPhrase"    // Имя фразы
          {
              "#format"    "{1:t}"
              "en"        "My Phrase: {1}"
              "ru"        "Моя фраза: {1}"
          }
          "MyPhrase2"    // Имя фразы
          {
              "en"        "My Phrase 1"
              "ru"        "Моя фраза 2"
          }
      }
    Чтобы вывести просто символ процента % нужно написать %%
    Здесь фраза "MyPhrase2" передана аргументом для форматирования фразы "MyPhrase".
    Т. е. вместо {1} будет подставлен перевод фразы "MyPhrase2".
    Но это доступно только для %t, с %T так делать нельзя.

    Источники:
<= К содержанию
 
Последнее редактирование:
Сверху Снизу