24.12.2014, 20:18
Доброго времени суток.
Перед новым годом принято дарить подарки и я хочу представить результат проделанной мной работы.Хочу представить вам небольшой include, который позволит вам без труда сделать мультиязычный сервер. На написание includ-а меня сподвиг tutorial Мультиязычный интерфейс.
В данном tutorial-е рассмотренный классические схемы построения мультиязычного сервера, но данные схемы неудобны при написании больших модов, некие схемы с точки зрения производительности пагубны для сервера, третьи имеют плохую плотность данных, происходит выделение большого количества памяти для хранения текста, которые в свою очередь не заполняет всю память, выделенной для её хранения. Пример:
pawn Code:
new str[128] = "123";
-Вторым направление было, повышение удобства программирования. Каждый из вас согласится с тем, что запоминать кучу идентификаторов текста, как число, очень не удобно и даже отталкивает. Возьмём пример из tutorial-а
pawn Code:
SendClientMessage(playerid, 0xFDE39DFF, Language[GetPVarInt(playerid, "Language")][0]);
pawn Code:
#define RUS_TEXT_TWO "Текст %s текст"
#define ENG_TEXT_ONE "Text %s text"
pawn Code:
enum Text
{
Text_1[32],
Text_2[32],
};
new var[2][Text];
//...
var[1][Text_2] = "123"; /*тоже самое что и*/ var[1][1] = "123";
//Пример:
SendClientMessage(playerid, 0xFDE39DFF, Language[GetPVarInt(playerid, "Language")][Text_2]);
Так как у нас буффер большой длины и нужно извлекать необходимые тексты, требуется знать место(ячейку) с которого начинается текст. Для этого создана переменная, которая хранит указатель на ячейку с которого начинается текст, текст у нас ассоциируется с полем enumenator-a, а само поле выступает в качестве идентификатора. (смотри код в includ-e )
-Третьим направление было, хранение текстов и их размещение. Самым удобным вариантом, конечно же является хранения текстов в файле, его можно в любое время открыть, подредактировать. Обычно структура таких файлов является: [ключ]текст, но это нужно писать обработчик, поиск ключей, проверять ключ по условию чтобы положить в нужную переменную и т.д. Решение оказалось на удивление простым. Был взят enumenator и вынесен в отдельный файл, а рядом с полем написаны тексты. Выглядит это всё следующим образом:
pawn Code:
enum E_Lng {
Error_Localization/*системная строка*/,//Ошибка локализации.
Localization,//Русский
asdasd_2,//резервная строка
Line_1,//Я строка номер %s, моя длина %d символов.
Line_2,//Я строка номер %s, моя длина %d символов и я длиннее.
Line_3,//Я строка номер %s, моя длина %d символов,\r\nкто следующий?.
};
Закончим вводную часть.
Преимущества данного includ-а:
- Поддержка большого количества локализаций, по умолчанию до 256.
- Локализация хранится в файле.
- Возможность быстрой правки локализации и задействование её не перезагружая сервер.
- Хорошая плотность данных.
- Стабильная и достаточна быстрая работа.
- Лёгкость в программировании, по сравнению с другими схемами.
- Система контроля ошибок.
- Нельзя добавлять тексты(строка) без перекомпиляции мода. Особенно если текст(строка) добавлен в середине файла локализации - вызывает смещение данных.
- Для того, чтобы на ходу делать правки, расширять тексты, нужно предварительно выделить больше ячеек памяти. отвечает за это #define MAX_ML_CHARACTER
- При добавлении новых локализаций, необходимо учесть два минуса, указанных выше и соответственно вписать файл в ML_Text_Files
Функции:
pawn Code:
ML_Load(); //Загружает/перезагружает локализации.
ML_Text(lngid, textid); //Возвращает текст. Параметры: (ид языка, ид текста)
ML_Player_Text(playerid, textid); //Возвращает текст c учётом установленного языка для игрока Параметры: (ид игрока, ид текста)
ML_S_Text(language, E_Lng:text, source[], len = sizeof(source)); //Безопасное перекладывание текста. Возвращает истину если успешно переложено. Параметры: (ид языка, ид текста, название массив, длина массива)
ML_S_Player_Text(playerid, E_Lng:text, source[], len = sizeof(source)); //Безопасное перекладывание текста c учётом установленного языка для игрока. Возвращает истину если успешно переложено. Параметры: (ид языка, ид текста, название массив, длина массива)
ML_SetPlayerLanguage(playerid, language); //Установка языка игроку, Вернёт истуну в случае успеха. Параметры: (ид игрока, ид языка)
- Скачать архив.
- Распаковать в папку с сервером.
- В моде подключить следующим образом: #include "../include/ML.inc"
- Подстроить настройки в includ-e
pawn Code:
#include <a_samp>
#include "../include/ML.inc" // Мультиязычность.
public OnFilterScriptInit()
{
ML_Load(); // Загрузим локализации
print(ML_Text(0, Localization)); // Выведем в консоль текст
new source[16];
if(ML_S_Text(0, Line_1, source)) //Безопасно извлекаем строку
{
print(source); // Выведем в консоль текст
}
else
{
print("Строка не была извлечена!");
}
new source_2[64];
format(source_2, sizeof(source_2), ML_Text(0, Line_2), "два" ,strlen(ML_Text(0, Line_1)));// Формируем текст
print(source_2); // Выведем в консоль текст
print(ML_Text(1, Line_3));
return 1;
}
Версия 1.0: >>> solidfiles.com инклуд+локализации+пример
Просмотреть:
Версия 1.0: >>> pastebin.com