samp.directory
← Scripts e bibliotecas

KW46/omp_language

Language system designed for open.mp

Outro★ 10atualizado há 6 diasGPL-3.0Pawn
Abrir no GitHub

README.md

omp_language

Yet another multiple languages system.
This language system is designed for open.mp - Most of it could be made compatible with SA-MP, except using in-memory SQLite database (unless if there's a plugin I don't know about), but highly discouraged since that would be very slow.

Index

Features

  • Uses in-memory SQLite database
  • Use embedded colour names in language files (eg. {YELLOW}[NOTICE] {WHITE}Hello world!)
  • Languages can be added/removed/modified without restarting the server
  • Uses multiple files - No huge single file please
  • Works best with YSI, but works without it (biggest drawback: no variable arguments if not using YSI)

To main index

Semantics

Language directory
A directory inside scriptfiles/languages, named as languageCode_languageName, that holds all language files of that language.

Language code
A two-letter code of a language. See ISO 639, Set 1

Language name
The full name of a language

Language file
A single file inside a language directory, or language sub-directory

Table
Refers to a single language file from runtime perspective.
Function descriptions refer to table because data is fetched from an SQLite database (which uses tables), and not directly from the files.

Identifier
Entry in a table/language file that identifies a single string.

To main index

How to use

To main index

Including the language system

  1. Make sure you're using open.mp, the provided 3.10.11 compiler and that you have the dependencies listed in dependencies.txt
  2. Make sure omp_language.inc is in your includes directory
  3. Optionally, add omp_language_colours.inc to your includes directory (see Embedded colour names)
  4. Make sure scriptfiles/languages is added to your server files
  5. Include omp_language: #include <omp_language>

That's all! <!> Make sure at least one language exist: This language system doesn't support having no languages added and may cause issues. Pointless anyway to include this language system if you're not using any language

To index

Compile options

Before including omp_language you can set several compile options:

SQLITE_INVALID_HANDLE
Since open.mp doesn't have a definition for this, it's added by this include.
Default value if not defined: (DB:0)

LANGUAGE_MAX_CONTENT_LENGTH
Defines the maximum allowed length of language strings.
This sets array sizes of retrieved language strings and the size of the VARCHAR column in the language tables.
Default value if not defined: (1024)

LANGUAGES_MAX
Defines the maximum amount of languages that can be added.
Default value if not defined: (4)

LANGUAGE_DEFAULT
Defines the default server language.
<!> Ultimately the default language is stored to a variable. If this given language does not exist, the default language is changed to the first available language! (language at index 0)
Default value if not defined: "en"

LANGUAGE_SQLITE_PERSISTENT_DATA
Define this to create an on-disk database file.
<!> Only use this to investigate the language database (since there is no sqlite shell)
<!> SIGNIFICANTLY slower than using in-memory database. Do NOT use this in production!

LANGUAGE_SQLITE_PERSISTENT_FILE
If LANGUAGE_SQLITE_PERSISTENT_DATA is defined, this definition is the name of the created language database.
Default value if not defined: "languages.db"

DIALOG_SELECT_LANGUAGE
If YSI is not used (or at least if y_dialog and y_inline are not used), the default ShowPlayerDialog() and OnDialogResponse() are used (instead of Dialog_ShowCallBack() and an inline on dialog response callback).
Since those require a dialog ID, this sets that dialog ID. Only effective if y_dialog or y_inline is not included.
Default value if not defined: (1) for gamemodes, (2) for filterscripts (FILTERSCRIPT must be defined)

LANGUAGE_NO_BUILD_MESSAGE
By default, when the language database is built some messages are printed:

[Info] ===== Building language database =====
[Info] Found 2 language(s):
[Info]    0: (en) English
[Info]    1: (nl) Nederlands
[Info] > Adding language files to language database
[Info] >> Adding data for language "English"...
[Info] >> Adding data for language "Nederlands"...
[Info] ===== Language database built =====

If you don't want that, simply define LANGUAGE_NO_BUILD_MESSAGE

LANGUAGE_NO_YSI
Define this to prevent inclusion of any YSI include.

LANGUAGE_NO_YSI_HOOKS
Define this to prevent inclusion of y_hooks.

LANGUAGE_NO_YSI_VA
Define this to prevent inclusion of y_va.

LANGUAGE_NO_YSI_FOREACH
Define this to prevent inclusion of y_foreach.

LANGUAGE_NO_YSI_DIALOG
Define this to prevent inclusion of y_dialog and y_inline.
If not defined, omp_language will attempt to include both y_dialog and y_inline.

LANGUAGE_SORT_LANGUAGES
readdir() does not guarantee ordering items. Those who want their languages ordered can define LANGUAGE_SORT_LANGUAGES.
When defined, you'll also have to define either LANGUAGE_SORT_BY_NAME or LANGUAGE_SORT_BY_CODE.
This requires md-sort to be included (must be in either (include_path)/md-sort.inc or (include_path)/md-sort/md-sort.inc).
Note that YSI provides md-sort already.

LANGUAGE_SORT_BY_NAME
Define this to sort languages by language name when sorting languages.

LANGUAGE_SORT_BY_CODE
Define this to sort languages by language code when sorting languages.

LANGUAGE_SORT_METHOD
Optional. Define this with either SORT_ASC or SORT_DESC to order languages ascending or descending.
Default value if not defined: SORT_ASC

To index

Embedded colour names

The language files are added in run-time and therefore macros (eg COL_RED) can't be used.
Since it would be very inconvenient to use hexadecimal numbers all the time, this language system allows using colour names.
There is a default set of language colours, included in file includes/omp_language_colours.inc. This creates a constant array called gLanguageColours.
You can simply use these colours, or define the array yourself before including omp_language.
<!> You can use this language system without using this array, though that will throw a compile warning. If gLanguageColours exists, all colour names are translated to colour numbers when creating the database.

To index

Adding language data

First of all, to add a language, create a directory named languageCode_languageName (eg en_English) inside scriptfiles/languages.
Language name is preferably in its own language (so nl_Nederlands and de_Deutsch, not nl_Dutch and de_German).

Inside a language directory, you can create text files (.txt) or directories.
When calling a language, you can get content from those files using fileName or directoryName-fileName.
Take this directory tree:

scriptfiles/
├─ languages/
│  ├─ en_English/
│  │  ├─ command/
│  │  │  ├─ admin.txt
│  │  │  ├─ player.txt
│  │  ├─ global.txt

To retrieve a string from global.txt you would use "global". To retrieve one from admin.txt inside the command directory, you would use "command-admin".
<!> Only one sub-directory is supported, creating another directory inside a sub-directory (in this case, command) will not work: Those files will not be added.

To add strings to a language file, simply create an identifier, and then the string attached to that identifier. Use a space (or preferably one or more tabs) to separate those two.
<!> Empty lines and lines starting with # are ignored. As are invalid lines (single words) For example:

## This line is ignored and thus functions as a comment.
# This is the preferred way of adding entries: Identifier fully capitalized, using words and underscores only, identating all strings on the same column (? did I call that right ?)
MY_IDENTIFIER       This is my identifier!
HELLO_WORLD         Hello {GREEN}world!

# However, this is also valid:
_foo BAR
$myIdentifier0 This is my ugly identifier!

# Even this is valid: 
Hello world!
Lorem ipsum dolor sit amet

# This is invalid:
TEST

NOTE: Make sure that all language directories have the same sub directories and files, and the same identifiers!
NOTE 2: Since version 1.03, any file extension (or none) is valid. But .txt is still preferred and recommended.

To index

Fetching language data

I'll keep this short, since all available functions are described below.
To fetch data from the database, use Language_Get() or Player_Language_Get()
To set/get language of a player, use Player_SelectLanguage() or Player_SetLanguage() and Player_GetLanguage()
To get amount of available languages and their language codes and names, use Language_Count() and Language_GetIDFromData(). For example, to print all available languages to the server log:

for (new i = 0, j = Language_Count(); i < j; i++)
{
    new languageCode[3], languageName[32];
    Language_GetDataFromID(i, languageCode, languageName);
    PrintF("> %s(%s)", languageName, languageCode);
}

For some more examples, see the example directory in this repository.

To index

Should I use YSI?

Yes.

  1. Even though support for not using YSI is added, it wasn't tested thoroughly and may not be stable
  2. Using YSI makes life much easier thanks to variable arguments, which is a standard in open.mp anyway

To main index

Functions

Functions and callbacks

To main index


Language_Count

Language_Count()
Returns the amount of available languages

Parameters
None

Returns
(int) Amount of available languages

Notes
None

Related functions/callbacks

To index


Language_Default

string:Language_Default()
Retrieves server's default language

Parameters
None

Returns
(string) Default language of the server.

Notes
LANGUAGE_DEFAULT may not be the actual default language if that language doesn't exist.
When that happens, default language becomes the first available language.
This function returns that language.

Related functions/callbacks
None

To index


Language_GetDataFromID

bool:Language_GetDataFromID(const languageId, string:languageCode[], string:languageName[], const lenLanguageCode = sizeof(languageCode), const lenLanguageName = sizeof(languageName))
Retrieves language code and language name from given language ID

Parameters
const languageId: Language ID to get data from
string:languageCode[]: (reference) Array to store language code in
string:languageName[]: (reference) Array to store language name in
const lenLanguageCode: (optional) Size of array languageCode[]
const lenLanguageName: (optional) Size of array languageName[]

Returns
(bool) true: Language exists, data retrieved. false: Given language does not exist

Notes
None

Related functions/callbacks

To index


Language_GetIDFromData

Language_GetIDFromData(const string:search[])
Gets the language ID by looking up language code or language name.

Parameters
const string:search[]: Language to get the ID of, using language code or language name.

Returns
(int) Language ID, or LANGUAGE_INVALID_ID if given language does not exist

Notes
<!> search[] must be the full language code or name
Case insensitive

Related functions/callbacks

To index


Language_Exists

bool:Language_Exists(const string:search[])
Checks if given language exists

Parameters
const string:search[]: Language to check, using language code or language name.

Returns
(bool) true: Language exists. false: Language does not exist

Notes
<!> search[] must be the full language code or name
Case insensitive

Related functions/callbacks

To index


LanguageDB_Build

bool:LanguageDB_Build()
Builds or rebuilds the entire language database for the current script.
Automatically used on script initialization. Can be used to rebuild the language database during runtime (in an admin command), useful if languages were modified.

Parameters
None

Returns
(bool) true: Language database created. false: Directory "scriptfiles/languages" does not exist

Notes
1: <!> Returns true if no languages were added (which happens if directory "scriptfiles/languages" is empty or doesn't have valid language directory names)
2: When running multiple scripts (ie gamemode, and one or more filterscripts): Using this function only re-creates the database for the script it's used in!
So for example, if you use this function in your gamemode, the database of the filterscript(s) will not be updated.

Related functions/callbacks

To index


LanguageDB_BuildSingleTable

void:LanguageDB_BuildSingleTable(const string:file[], const string:subDir[] = "")
(Re-)builds a single table for all running scripts.

Parameters
const string:file[]: Full filename to reload
const string:subDir[]: (optional) Sub-directory where the file is located

Returns
(nothing)

Notes
1: Only works for existing languages. If languages are added/removed/modified, use LanguageDB_Build() instead
2: If LANGUAGE_NO_BUILD_MESSAGE is not defined, it will print messages for each script (where said constant is not defined)
3: Useful if only one or just a few language files were modified. This is faster than reloading the entire database.
It does not matter if it is called from the gamemode or a filterscript.
So you could create an admin command that calls this function, or OnRconCommand() (so you could reload it without having to go in-game, assuming (remote) RCON is enabled or you have console access).

The reason why this function uses file and subDir instead of table (eg foo or global-foo) is because all (or no) file extensions are allowed.
CBA to scan directories and check if there is a non-exact match (since files would have to be scanned twice then, since this function calls an internal function already used by LanguageDB_Build()).

Related functions/callbacks

To index


Language_Get

string:Language_Get(const string:languageCode[], const string:table[], const string:identifier[], OPEN_MP_TAGS:...)
Retrieves a language string. Optionally formats retrieved string (only when using YSI)

Parameters
const string:languageCode[]: Language to get content from, using the language code
const string:table[]: Table to get the content from
const string:identifier[]: String to retrieve from given language code and table
OPEN_MP_TAGS:...: (optional) Used for formatting the string if format specifiers were used. Only works when using YSI

Returns
(string) Retrieved (and formatted) string

Notes
<!> If given language, table or identifier doesn't exist, it returns [languageCode]table:identifier (eg. [en]global:SOME_IDENTIFIER)

Related functions/callbacks

To index


Player_GetLanguage

string:Player_GetLanguage(const playerid)
Returns the language of a player

Parameters
const playerid: Player to get language from

Returns
(string) Language code the player is using

Notes
If no language was selected for the player, or if the player doesn't exist, it returns the server default language

Related functions/callbacks

To index


Player_SetLanguage

bool:Player_SetLanguage(const playerid, const string:language[])
Sets the language for a player

Parameters
const playerid: Player to set the language for
const string:language[]: Language to set, using language code

Returns
(bool) true: Language was set for the player. false: Language unchanged: Player isn't connected or given language doesn't exist

Notes
None

Related functions/callbacks

To index


Player_SelectLanguage

void:Player_SelectLanguage(const playerid)
Shows a dialog to the player displaying all available languages, allowing them to change their language to one of them.

Parameters
const playerid: Player to show the dialog to

Returns
Nothing

Notes
If only one language is available, no dialog is displayed and their language is set to that language.
After changing their language, OnPlayerSelectLanguage() is called.

Related functions/callbacks

To index

Ler o resto no GitHub

Esta página é montada com o que o GitHub publica sobre o repositório. O samp.directory não hospeda o código. Avisar de um problema com esta página