R1KO
fuck society
- Сообщения
- 9,457
- Реакции
- 7,786
- Команда форума
- #1
[SourcePawn] Урок 4 - Форматирование текста и мультиязычность
<- К содержанию
- Форматирование текста (строк)
Для этой задачи используются функции Format, FormatEx и VFormat.
Эти функции получают в качестве аргументов:- Строку (буфер), куда будет записан результат
- Максимальный размер буфера (чтобы не выйти за пределы),
- Правило формата
- Аргументы для подстановки
В результате мы получим такую строку:PHP:char szBuffer[128]; Format(szBuffer, sizeof(szBuffer), "Игрок: %N, убийств - %i, смертей - %i", iClient, GetClientFrags(iClient), GetClientDeaths(iClient));
Как вы поняли функция заменяет все эти %N, %i и т.д. на аргументы, которые ей передали.PHP:"Игрок: R1KO, убийств - 4, смертей - 2"
Типы данных для форматирования:- Численные
- %i или %d - Целое число (%u - беззнаковое, только положительные значения)
Результат:PHP:FormatEx(szBuffer, sizeof(szBuffer), "Число - %i", 5);
PHP:"Число - 5" - %b - Двоичный тип (выводит значение в двоичном виде отсекая ноли слева)
Результат:PHP:FormatEx(szBuffer, sizeof(szBuffer), "Значение #1 - %b, Значение #2 - %b", true, 13);
PHP:"Значение #1 - 1, Значение #2 - 1101" - %f - Число с запятой (дробное)
Результат:PHP:FormatEx(szBuffer, sizeof(szBuffer), "Число - %f", 16.3);
По умолчанию после запятой выводится 6 знаков.PHP:"Число - 16.300000"
Это число можно изменить:
Результат:PHP:FormatEx(szBuffer, sizeof(szBuffer), "Число - %.2f", 16.3); // Указываем что будет выводиться только 2 знака после запятой
PHP:"Число - 16.30" - %x или %X - Шестнадцатеричное представление двоичного значения
Результат:PHP:FormatEx(szBuffer, sizeof(szBuffer), "Число - %x", 75);
PHP:"Число - 00004B"
- %i или %d - Целое число (%u - беззнаковое, только положительные значения)
- Символьные
- %s - Строка
Результат:PHP:FormatEx(szBuffer, sizeof(szBuffer), "Строка - %s", "my_string");
PHP:"Строка - my_string" - %c - Символ
Результат:PHP:FormatEx(szBuffer, sizeof(szBuffer), "Символ - %c", 'r');
PHP:"Символ - r" - %t и %T - Перевод фразы (подробнее будет дальше)
- %s - Строка
- Специальные
- %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><>"
- %N - Ник игрока. Аргументом передается индекс игрока
- Больше информации можно найти здесь: printf - C++ Reference и здесь printf — Википедия
Важно передавать аргументы в функцию в той же последовательности, в какой они встречаются в правиле формата.
В чем же отличие функций Format, FormatEx и VFormatмежду собой?- Format - Форматирует строку в соответствии с правилами формата
- FormatEx - Форматирует строку в соответствии с правилами формата, отличается от Format тем, что у FormatEx входным аргументом не может быть та же строка. Работает быстрее чем Format.
С FormatEx такие фокусы не проходят. По идее это может и будет работать, но как написано в api:PHP:char szBuffer[128]; strcopy(szBuffer, sizeof(szBuffer), "my_string"); // Записываем в szBuffer значение "my_string" Format(szBuffer, sizeof(szBuffer), "Значение - %s", szBuffer); // Передаем аргументом ту же строку, в которую будет помещен результат
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 - Форматирует строку в соответствии с правилами формата, но правила формата принимает не как аргумент, а как параметр функции.
Это используется для создания собственных функций с форматированием. (Например, morecolors, csgo_colors)PHP:void MyFunc(const char[] szFormat, any ...) { int iLen = strlen(szFormat) + 255; // Получаем длину строки с правилами формата и прибавляем запас нужный для подстановки значений char[] szBuffer = new char[iLen]; // Создаем буфер с полученным размером VFormat(szBuffer, iLen, szFormat, 2); // 2 это номер параметра any ... в заголовке функции. // В нашем случае 1-й параметр это szFormat, а 2-й уже any ... // Само объявление any ... означает что в функцию может передаваться любое количество аргументов // В функции эти параметры являются скрытыми PrintToServer("Результат VFormat: %s", szBuffer); } // Вызываем нашу функцию: MyFunc("Число: %i, Строка: %s", 5, "my_string"); // Получаем "Результат VFormat: Число: 5, Строка: my_string"
- Мультиязычность
Мультиязычность позволяет выводить игрокам сообщения (в чат, меню, консоль и вообще куда только можно) в зависимости от языка клиента игрока.
Для работы с мультиязычностью важно знать такие термины:- Языки - предварительно заданные языки перевода устанавливаются в configs\languages.cfg. Если язык перевода отсутствует в этом файле, он не может быть переведен до тех пор, пока не будет добавлен в этот файл и обновлена кэш-память переводов.
- Фразы/Ключи перевода - Короткие, общие ключевые фразы, используемые для определения набора переводов. Они находятся в конфигурационных файлах в папке translations. Они называются файлы перевода.
- Переводы - Содержат фразы текста перевода для данного языка. Они находятся в файлах перевода.
- Файлы перевода - файлы с расширением .phrases.txt, которые расположены в addons/sourcemod/translations/
- Примечание: Переводы и Фразы, чувствительны к регистру.
Для использования файла перевода его необходимо подключить к плагину:
При этом файл должен будет иметь название: my_file.phrases.txtPHP:LoadTranslations("my_file.phrases");
Плагины должны вызывать функцию LoadTranslations на каждый файл с переводом, который они хотят использовать. Если это не будет сделано, то никакие переводы работать не будут, даже если другой плагин загрузил те же самые файлы. Это поможет предотвратить конфликты фраз между плагинами.
Фразы находятся в файлах перевода, которые имеют такую структуру:
Ключ "#format" задает количество параметров, для подстановки и их тип. Нумеруются они в том порядке в каком были переданы аргументы в функцию форматирования.PHP:"Phrases" { "MyPhrase" // Имя фразы { "en" "My Phrase" // Перевод фразы для языка с кодом en "ru" "Моя фраза" // Перевод фразы для языка с кодом ru } "Welcome" { "en" "Welcome to SourceMod" "ru" "Добро пожаловать в SourceMod" } "ClientConnected" { "#format" "{1:N}" "en" "Playe {1} joined" "ru" "Игрок {1} подключился" } }
В файле перевода: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);
В ключе "#format" мы сообщаем:PHP:"Phrases" { "MyPhrase" // Имя фразы { "#format" "{1:i},{2:s},{3:f}" "en" "string value: {2}, int value: {1}, float value: {3}" "ru" "строчное значение: {2}, целое значение: {1}, дробное значение: {3}" } }- Параметр №1 имеет тип int
- Параметр №2 имеет тип char
- Параметр №3 имеет тип float
- Когда использовать %t, а когда %T?
- %t используется если форматирование происходит после SetGlobalTransTarget.
Функция SetGlobalTransTarget устанавливает индекс игрока, для языка которого в данный момент будет выполняться форматирование. Если её аргумент равен 0 или LANG_SERVER то форматирование будет выполнено для языка сервера.
В функциях PrintToChat, PrintToChatAll, PrintCenterText, PrintCenterTextAll, PrintHintText, PrintHintTextToAll присутствует функция SetGlobalTransTarget, поэтому при форматировании текста в них нужно писать %t.PHP:SetGlobalTransTarget(iClient); FormatEx(szBuffer, sizeof(szBuffer), "Перевод: %t", "MyPhrase", 123, "my_string", 22.4); - %T требует чтобы 2-м аргументом (1-й это фраза) передавался индекс игрока, для которого будет выполняться форматирование.
Следовательно этот код аналогичен этому:PHP:FormatEx(szBuffer, sizeof(szBuffer), "Перевод: %T", "MyPhrase", iClient, 123, "my_string", 22.4); // 2-й аргумент - индекс игрока
Так же %T не допускает использования фразы внутри перевода:PHP:SetGlobalTransTarget(iClient); FormatEx(szBuffer, sizeof(szBuffer), "Перевод: %t", "MyPhrase", 123, "my_string", 22.4);
PHP:SetGlobalTransTarget(iClient); FormatEx(szBuffer, sizeof(szBuffer), "%t", "MyPhrase", "MyPhrase2");
В файле перевода:
Здесь фраза "MyPhrase2" передана аргументом для форматирования фразы "MyPhrase".PHP:"Phrases" { "MyPhrase" // Имя фразы { "#format" "{1:t}" "en" "My Phrase: {1}" "ru" "Моя фраза: {1}" } "MyPhrase2" // Имя фразы { "en" "My Phrase 1" "ru" "Моя фраза 2" } }
Т. е. вместо {1} будет подставлен перевод фразы "MyPhrase2".
Но это доступно только для %t, с %T так делать нельзя.
- %t используется если форматирование происходит после SetGlobalTransTarget.
Источники:
Последнее редактирование: