Merge branch 'master' into jgrpp-beta

# Conflicts:
#	src/console_cmds.cpp
#	src/debug.cpp
#	src/lang/vietnamese.txt
#	src/network/core/address.cpp
#	src/network/core/address.h
#	src/network/core/config.h
#	src/network/core/os_abstraction.cpp
#	src/network/core/os_abstraction.h
#	src/network/core/tcp_listen.h
#	src/network/core/udp.cpp
#	src/network/core/udp.h
#	src/network/network.cpp
#	src/network/network_client.cpp
#	src/network/network_gamelist.cpp
#	src/network/network_server.cpp
#	src/network/network_udp.cpp
#	src/newgrf.cpp
#	src/openttd.cpp
#	src/saveload/saveload.h
#	src/settings.cpp
#	src/settings_table.cpp
#	src/settings_type.h
#	src/table/settings/network_settings.ini
pull/332/head
Jonathan G Rennison 3 years ago
commit f764fcfb1f

@ -383,7 +383,7 @@ Both 'stable' and 'nightly' versions are available for download:
- most people should choose the 'stable' version, as this has been more extensively tested
- the 'nightly' version includes the latest changes and features, but may sometimes be less reliable
On some platforms OpenTTD will also be available via your OS package manager or a similar service.
OpenTTD is also available for free on [Steam](https://store.steampowered.com/app/1536610/OpenTTD/), [GOG.com](https://www.gog.com/game/openttd), and the [Microsoft Store](https://www.microsoft.com/p/openttd-official/9ncjg5rvrr1c). On some platforms OpenTTD will be available via your OS package manager or a similar service.
## 1.2) OpenTTD gameplay manual

@ -0,0 +1,64 @@
# Game Coordinator
To allow two players to play together, OpenTTD uses a Game Coordinator to
facilitate this.
When a server starts, it can register itself to the Game Coordinator. This
happens when `server_game_type` is set to either `invite-only` or `public`.
Upon registration, the Game Coordinator probes the network of the server, and
assigns the server an unique code, called an `invite code`.
When a client wants to join a server, it asks the Game Coordinator to help
with this by giving it the `invite code` of the server. The Game Coordinator
will, in this order, attempt several ways to connect the client and server
together:
## 1) Via direct IPv4 / IPv6
Upon registration, the Game Coordinator probes the server to see if a
direction connection to the server is possible based on the game port. It
tries this over the public IPv4 and IPv6, as announced by the server.
If either (or both) are successful, a client will always be asked to try
these direct IPs first when it wants to connect to this server.
- If the server is IPv4 only, the client is only asked to connect via IPv4.
- If the server is IPv6 only, the client is only asked to connect via IPv6.
- If the server is both IPv4 and IPv6, the client is asked to connect to to
one of those first. If that fails, it is asked to connect to the other.
Whether it tries IPv4 or IPv6 first, strongly depends on several network
infrastructure related events. The biggest influence is the network
latency over both protocols to the OpenTTD infrastructure.
In the end, if either the server is not reachable directly from the Internet
or the client fails to connect to either one of them, the connection attempt
continues with the next available method.
## 2) Via STUN
When a client wants to join a server via STUN, both the client and server
are asked to create a connection to the STUN server (normally
`stun.openttd.org`) via both IPv4 and IPv6. If the client or server has no
IPv4 or IPv6, it will not make a connection attempt via that protocol.
The STUN server collects the public IPv4 and/or IPv6 of the client and server,
together with the port the connection came in from. For most NAT gateways it
holds true that as long as you use the same local IP + port, your public
IP + port will remain the same, and allow for bi-directional communication.
And this fact is used to later on pair the client and server.
The STUN server reports this information directly to the Game Coordinator
(this in contrast to most STUN implementation, where this information is
first reported back to the peer itself, which has to relay it back to the
coordinator. OpenTTD skips this step, as the STUN server can directly talk to
the Game Coordinator). When the Game Coordinator sees a matching pair (in
terms of IPv4 / IPv6), it will ask both the client and server to connect to
their peer based on this public IP + port.
As the NAT gateway forwards the traffic on the public IP + port to the local
port, this creates a bi-directional socket between client and server. The
connection to the STUN server can now safely be closed, and the client and
server can continue to talk to each other.
Some NAT gateways do not allow this method; for those this attempt will fail,
and this also means that it is not possible to create a connection between
the client and server.

@ -48,6 +48,10 @@ Last updated: 2011-02-16
- click add server
- type in the ip address or hostname
- if you want to add a port use :<port>
- If you want to play and you have the invite code of the game server you
want connect to.
- click add server
- type in the invite code
- Now you can select a company and press: "Join company", to help that company
- Or you can press "Spectate game", to spectate the game
- Or you can press "New company", and start your own company (if there are
@ -110,9 +114,10 @@ Last updated: 2011-02-16
- You can let your server automatically restart a map when, let's say, year 2030
is reached. See 'set restart_game_date' for detail.
- If you want to be on the server-list, enable Advertising. To do this, select
'Internet (advertise)' in the Start Server menu, or type in console:
'set server_advertise 1'.
- If you want to be on the server-list, make your server public. You can do
this either from the Start Server GUI, via the in-game Online Players GUI,
or by typing in the console:
'set server_game_type public'.
- You can protect your server with a password via the console: 'set server_pw',
or via the Start Server menu.

@ -793,9 +793,10 @@ DEF_CONSOLE_CMD(ConServerInfo)
return true;
}
IConsolePrintF(CC_DEFAULT, "Current/maximum clients: %2d/%2d", _network_game_info.clients_on, _settings_client.network.max_clients);
IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %2d/%2d", (int)Company::GetNumItems(), _settings_client.network.max_companies);
IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), _settings_client.network.max_spectators);
IConsolePrintF(CC_DEFAULT, "Invite code: %s", _network_server_invite_code.c_str());
IConsolePrintF(CC_DEFAULT, "Current/maximum clients: %3d/%3d", _network_game_info.clients_on, _settings_client.network.max_clients);
IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %3d/%3d", (int)Company::GetNumItems(), _settings_client.network.max_companies);
IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %3d/%3d", NetworkSpectatorCount(), _settings_client.network.max_spectators);
return true;
}
@ -3470,7 +3471,6 @@ void IConsoleStdLibRegister()
IConsole::AliasRegister("name", "setting client_name %+");
IConsole::AliasRegister("server_name", "setting server_name %+");
IConsole::AliasRegister("server_port", "setting server_port %+");
IConsole::AliasRegister("server_advertise", "setting server_advertise %+");
IConsole::AliasRegister("max_clients", "setting max_clients %+");
IConsole::AliasRegister("max_companies", "setting max_companies %+");
IConsole::AliasRegister("max_spectators", "setting max_spectators %+");

@ -204,9 +204,7 @@ static void debug_print(const char *dbg, const char *buf)
* crashing, and NetworkTextMessage includes these */
#if defined(_WIN32)
if (strcmp(dbg, "desync") != 0) {
wchar_t system_buf[512];
convert_to_fs(buffer, system_buf, lengthof(system_buf));
fputws(system_buf, stderr);
fputs(buffer, stderr);
}
#else
fputs(buffer, stderr);

@ -828,7 +828,7 @@ static std::string GetHomeDir()
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
return std::string(path.Path());
#else
const char *home_env = getenv("HOME"); // Stack var, shouldn't be freed
const char *home_env = std::getenv("HOME"); // Stack var, shouldn't be freed
if (home_env != nullptr) return std::string(home_env);
const struct passwd *pw = getpwuid(getuid());
@ -846,7 +846,7 @@ void DetermineBasePaths(const char *exe)
std::string tmp;
const std::string homedir = GetHomeDir();
#ifdef USE_XDG
const char *xdg_data_home = getenv("XDG_DATA_HOME");
const char *xdg_data_home = std::getenv("XDG_DATA_HOME");
if (xdg_data_home != nullptr) {
tmp = xdg_data_home;
tmp += PATHSEP;
@ -977,7 +977,7 @@ void DeterminePaths(const char *exe, bool only_local_path)
#ifdef USE_XDG
std::string config_home;
const std::string homedir = GetHomeDir();
const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
const char *xdg_config_home = std::getenv("XDG_CONFIG_HOME");
if (xdg_config_home != nullptr) {
config_home = xdg_config_home;
config_home += PATHSEP;

@ -617,9 +617,9 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa)
if (this->fs == FS_NORMAL && !aa) {
for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) : HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
if (HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR;
sprite.data[1 + x + (1 + y) * sprite.width].a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF;
sprite.data[1 + x + (1 + y) * sprite.width].a = 0xFF;
}
}
}

@ -988,7 +988,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
bool lowered = !HasBit(_legend_excluded_cargo, cs->Index());
/* Redraw box if lowered */
if (lowered) DrawFrameRect(r.left, y, r.right, y + this->line_height - 1, COLOUR_BROWN, lowered ? FR_LOWERED : FR_NONE);
if (lowered) DrawFrameRect(r.left, y, r.right, y + this->line_height - 1, COLOUR_BROWN, FR_LOWERED);
byte clk_dif = lowered ? 1 : 0;
int rect_x = clk_dif + (rtl ? r.right - this->legend_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT);

@ -608,9 +608,9 @@ public:
ShowErrorMessage(STR_ERROR_CAN_T_GENERATE_INDUSTRIES, STR_ERROR_MUST_FOUND_TOWN_FIRST, WL_INFO);
} else {
extern void GenerateIndustries();
_generating_world = true;
Backup<bool> old_generating_world(_generating_world, true, FILE_LINE);
GenerateIndustries();
_generating_world = false;
old_generating_world.Restore();
}
}
@ -712,15 +712,15 @@ public:
}
Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
_generating_world = true;
Backup<bool> old_generating_world(_generating_world, true, FILE_LINE);
_ignore_restrictions = true;
DoCommandP(tile, (layout_index << 8) | this->selected_type, seed,
CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry);
cur_company.Restore();
old_generating_world.Restore();
_ignore_restrictions = false;
_generating_world = false;
} else {
success = DoCommandP(tile, (layout_index << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY));
}

@ -1915,6 +1915,8 @@ STR_FACE_TIE :Das:
STR_FACE_EARRING :Oorbel:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Verander das of oorbel
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multispeler
@ -1964,7 +1966,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Begin be
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Begin u eie verskaffer
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Tik in jou naam
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Invoeg die adres van die gasheer
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Begin nuwe multispeler speletjie
@ -2042,6 +2043,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Toeskou
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Verskaffer
@ -2152,6 +2156,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Die vers
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Die verskaffer is besig om te weerbegin...{}Wag asb...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} is geskop. Rede: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Laai Inhoud af
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipe

@ -1612,6 +1612,8 @@ STR_FACE_TIE :الربطة:
STR_FACE_EARRING :أقراط الأذان:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}غير الربطة أو أقراط الأذن
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}تعدد اللاعبين
@ -1661,7 +1663,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}أبدأ
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}أبدأ خادمك الخاص
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}أدخل أسمك
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}أدخل عنوان المضيف
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}أبدا لعبة متعددة اللاعبين جديدة
@ -1739,6 +1740,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :شاهد
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :خادم
@ -1837,6 +1841,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ق
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}اقفل الخادم الجلسة
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}يتم بدأ الخادم من جديد ...{} الرجاء الأنتظار
# Content downloading window
STR_CONTENT_TITLE :{WHITE}تنزيل المحتوى
STR_CONTENT_TYPE_CAPTION :{BLACK} نوع

@ -1790,6 +1790,8 @@ STR_FACE_TIE :Korbata:
STR_FACE_EARRING :Belarritakoak:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Aldatu korbata eta belarritakoak
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multijokalaria
@ -1839,7 +1841,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Zerbitza
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Zure zerbitzaria sortu
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Sartu zure izena
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Sartu antolatzailearen helbidea
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Multijokalari joko berri bat hasi
@ -1917,6 +1918,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Ikusle
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Zerbitzaria
@ -2025,6 +2029,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING}-k
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Zebitzariak saioa itxi du
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Zerbitzaria berriro hasten ari da...{}Mesedez itxaron...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Edukiak deskargatzen
STR_CONTENT_TYPE_CAPTION :{BLACK}Mota

@ -2225,6 +2225,8 @@ STR_FACE_TIE :Гальшту
STR_FACE_EARRING :Завушніца:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Зьмяніць гальштук або завушніцу
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Сеткавая гульня
@ -2274,7 +2276,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Запу
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Запуск сэрвэра на вашым кампутары. Да гэтае гульні змогуць далучыцца іншыя гульцы.
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Увядзіце вашае імя
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Увядзіце адрас сэрвэра
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Запуск новай сеткавай гульні
@ -2352,6 +2353,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Назірац
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Сэрвэр
@ -2461,6 +2465,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} з
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Гэты сэрвэр закрыў сэсію
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Гэты сэрвэр перазапускаецца...{}Пачакайце, калі ласка
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Кантэнт запампоўваецца
STR_CONTENT_TYPE_CAPTION :{BLACK}Тып

@ -2002,8 +2002,9 @@ STR_FACE_TIE :Gravata:
STR_FACE_EARRING :Brinco:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Alterar gravata ou brinco
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privado
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Público
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multi-jogador
@ -2057,7 +2058,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Iniciar
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Iniciar um servidor próprio
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Coloque seu nome
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Coloque o endereço IP do servidor
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Iniciar novo jogo
@ -2162,6 +2162,9 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Esse é
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Esse é o hospedeiro do jogo
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} / {NUM} empresa{P "" s}
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Expulsar
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Banir
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Excluir
@ -2289,6 +2292,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servid
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor está reiniciando...{}Aguarde...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} foi kickado. Motivo: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Baixando conteúdo
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo

@ -1832,6 +1832,8 @@ STR_FACE_TIE :Вратовр
STR_FACE_EARRING :Oбица:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Cмени вратовръзкатa или oбицатa
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Онлайн играчи
@ -1881,7 +1883,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Пуск
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Пуснете ваш собствен сървър
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Въведете името си
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Въведете адреса на хоста
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Започни нова мрежова игра
@ -1959,6 +1960,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Наблюда
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Сървър
@ -2067,6 +2071,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} с
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Сървърът прекъсна сесията
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Сървърът се рестартира...{}Моля изчакайте...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Съдържание за сваляне
STR_CONTENT_TYPE_CAPTION :{BLACK}Вид

@ -2002,8 +2002,9 @@ STR_FACE_TIE :Corbata:
STR_FACE_EARRING :Arracades:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Canvia la corbata o les arracades
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privada
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Pública
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multijugador
@ -2057,7 +2058,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Inicia e
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Inicia en un servidor propi
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Posa el teu nom
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Entra l'adreça IP del servidor
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Inicia una partida multijugador nova
@ -2162,6 +2162,9 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Aquest e
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Aquest és l'hoste de la partida.
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} companyi{P a es}
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Treu
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Expulsa
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Esborra
@ -2289,6 +2292,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}El servi
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}El servidor està reiniciant...{}Espera un moment...
STR_NETWORK_MESSAGE_KICKED :*** S'ha expulsat {STRING}. Motiu: {STRING}
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Descàrregues de contingut
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipus

@ -731,6 +731,8 @@ STR_FACE_COLLAR :Ҫуха:
STR_FACE_TIE :Галстук:
STR_FACE_EARRING :Алка:
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_PLAYER_NAME :{BLACK}Вӑйӑҫӑ ят:
@ -793,6 +795,9 @@ STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Вырн
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
@ -814,6 +819,7 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING}
############ Leave those lines in this order!!
############ End of leave-in-this-order
# Content downloading window
STR_CONTENT_DETAIL_VERSION :{SILVER}Верси: {WHITE}{STRING}

@ -2020,6 +2020,8 @@ STR_FACE_TIE :Kravata:
STR_FACE_EARRING :Naušnica:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Promijeni kravatu ili naušnicu
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Više igrača
@ -2069,7 +2071,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Pokreni
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Pokreni vlastiti poslužitelj
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Upiši svoje ime
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Unesi adresu domaćina
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Započni novu igru za više igrača
@ -2147,6 +2148,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Promatraj
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Poslužitelj
@ -2257,6 +2261,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Posluži
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Poslužitelj se ponovno pokreće...{}Molimo pričekajte...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} je izbačen. Razlog: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Preuzimanje sadržaja
STR_CONTENT_TYPE_CAPTION :{BLACK}Vrsta

@ -1243,6 +1243,7 @@ STR_CONFIG_SETTING_TYPE_GAME_MENU :Nastavení hry
STR_CONFIG_SETTING_TYPE_GAME_INGAME :Nastavení hry (uchováno v uložené hře; ovlivní pouze stávající hru)
STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Nastavení společnosti (uchováno v uložených hrách; ovlivní pouze nové hry)
STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Nastavení společnosti (uchováno v uložené hře; ovlivní pouze stávající společnost)
STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}Tato akce resetuje všechna nastavení hry na výchozí hodnoty.{}Jste si jistý, že chcete pokračovat?
STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Kategorie:
STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Druh:
@ -2331,6 +2332,8 @@ STR_FACE_TIE :Kravata:
STR_FACE_EARRING :Náušnice:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Změnit kravatu nebo náušnice
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer
@ -2384,7 +2387,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Spustit
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Spustit vlastní server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Zadej své jméno
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Vlož IP adresu serveru
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Začít novou hru
@ -2461,8 +2463,19 @@ STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Seznam hráčů
STR_NETWORK_COMPANY_LIST_SPECTATE :Pozorovat
# Network client list
STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Název serveru, na kterém hrajete
STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Upravte název svého serveru
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Název serveru
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Jméno vašeho hráče
STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Připojit se a hrát za tuto společnost
STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Poslat zprávu tomuto hráči
STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Poslat zprávu všem hráčům této firmy
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Jste si jisti, že chcete smazat společnost '{COMPANY}'?
STR_NETWORK_SERVER :Server
STR_NETWORK_CLIENT :Klient
@ -2519,6 +2532,7 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Vložen
STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Tvůj počítač je přiliš pomalý pro udržení kroku se serverem
STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Tvému počítači trvalo stahování mapy příliš dlouho
STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Tvému počítači trvalo připojování na server příliš dlouho
STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Jméno vašeho hráče není platné
############ Leave those lines in this order!!
STR_NETWORK_ERROR_CLIENT_GENERAL :všeobecná chyba
@ -2578,6 +2592,8 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server u
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server se restartuje...{}Počkejte prosím...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} byl vyhozen. Důvod: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Váš server neumožňuje vzdálené připojení
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Součásti ke stažení
STR_CONTENT_TYPE_CAPTION :{BLACK}Druh

@ -1930,6 +1930,8 @@ STR_FACE_TIE :Slips:
STR_FACE_EARRING :Ørering:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Ændre slips eller ørering
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Netværksspil
@ -1979,7 +1981,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start se
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start en ny server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Indtast dit navn
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Skriv adressen på en server
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start et nyt netværksspil
@ -2057,6 +2058,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Tilslut som til
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Server
@ -2167,6 +2171,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serveren
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Serveren genstarter...{}Vent venligst...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} blev sparket ud. Grund: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Download af indhold
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -2001,8 +2001,11 @@ STR_FACE_TIE :Stropdas:
STR_FACE_EARRING :Oorbel:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Verander das of oorbel
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privé
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Lokaal
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Openbaar
STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Alleen op uitnodiging
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Netwerkspel
@ -2036,6 +2039,7 @@ STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Serverv
STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Serveradres: {WHITE}{STRING}
STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Startdatum: {WHITE}{DATE_SHORT}
STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Huidige datum: {WHITE}{DATE_SHORT}
STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Spelscript: {WHITE}{STRING} (v{NUM})
STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}Beveiligd met wachtwoord!
STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}SERVER OFFLINE
STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVER VOL
@ -2051,12 +2055,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Op het i
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Op LAN zoeken
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Op lokaal netwerk zoeken naar servers
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Voeg server toe
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Voegt een server toe aan de lijst die altijd gecontroleerd zal worden op draaiende spellen
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Voegt een server toe aan de lijst. Dit kan een serveradres of een uitnodigingscode zijn
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start server
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start eigen server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Vul je naam in
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Voer het IP-adres van de server in
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Voer serveradres of uitnodigingscode in
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Nieuw spel met meerdere spelers starten
@ -2143,6 +2147,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}De naam
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Servernaam
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Zichtbaarheid
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Bepaalt of andere mensen je server kunnen zien in de openbare lijst
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Uitnodigingscode
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Uitnodigingscode waarmee andere spelers toegang krijgen tot deze server
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Type verbinding
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Of en hoe je server toegankelijk is voor anderen
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Speler
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Naam
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Je spelernaam
@ -2161,6 +2169,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dit ben
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dit is de host van het spel
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klant{P "" en} / {NUM} bedrij{P f ven}
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Lokaal
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Externe spelers kunnen geen verbinding maken
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Openbaar
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Eruit schoppen
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bannen
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Verwijderen
@ -2288,6 +2302,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}De serve
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}De server wordt opnieuw gestart...{}Wacht alstublieft...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} is eruit geschopt. Reden: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Serverregistratie mislukt
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Je server staat geen externe verbindingen toe
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Andere spelers krijgen geen toegang tot je server
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Download extra inhoud
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -2434,8 +2434,11 @@ STR_FACE_TIE :Tie:
STR_FACE_EARRING :Earring:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Change tie or earring
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Private
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Local
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Public
STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Invite only
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer
@ -2469,6 +2472,7 @@ STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Server
STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Server address: {WHITE}{RAW_STRING}
STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Start date: {WHITE}{DATE_SHORT}
STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Current date: {WHITE}{DATE_SHORT}
STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Game Script: {WHITE}{RAW_STRING} (v{NUM})
STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}Password protected!
STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}SERVER OFFLINE
STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVER FULL
@ -2484,12 +2488,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Search i
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Search LAN
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Search local area network for servers
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Add server
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Adds a server to the list which will always be checked for running games
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Adds a server to the list. This can either be a server address or an invite code
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start server
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start your own server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Enter your name
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Enter the address of the host
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Enter server address or invite code
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start new multiplayer game
@ -2576,6 +2580,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Edit the
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Name of the server
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Visibility
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Whether other people can see your server in the public listing
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Invite code
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Invite code other players can use to join this server
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Connection type
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Whether and how your server can be reached by others
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Player
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Name
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Your player name
@ -2594,6 +2602,13 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}This is
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}This is the host of the game
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies}
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Local
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Remote players can't connect
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Public
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_STUN :{BLACK}Behind NAT
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kick
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Ban
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Delete
@ -2724,6 +2739,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The serv
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait...
STR_NETWORK_MESSAGE_KICKED :*** {RAW_STRING} was kicked. Reason: ({RAW_STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Server registration failed
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Your server doesn't allow remote connections
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Other players won't be able to connect to your server
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Content downloading
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -1870,6 +1870,8 @@ STR_FACE_TIE :Tie:
STR_FACE_EARRING :Earring:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Change tie or earring
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer
@ -1919,7 +1921,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start se
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start your own server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Enter your name
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Enter the address of the host
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start new multiplayer game
@ -1997,6 +1998,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Spectate
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Server
@ -2105,6 +2109,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ha
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Content downloading
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -2025,8 +2025,10 @@ STR_FACE_TIE :Tie:
STR_FACE_EARRING :Earring:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Change tie or earring
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Private
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Local
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Public
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer
@ -2075,12 +2077,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Search i
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Search LAN
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Search local area network for servers
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Add server
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Adds a server to the list which will always be checked for running games
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Adds a server to the list. This can either be a server address or an invite code
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start server
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start your own server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Enter your name
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Enter the IP address of the server
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Enter server address or invite code
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start new multiplayer game
@ -2166,6 +2168,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Edit the
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Name of the server
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Visibility
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Whether other people can see your server in the public listing
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Invite code
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Invite code other players can use to join this server
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Connection type
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Whether and how your server can be reached by others
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Player
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Name
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Your player name
@ -2184,6 +2190,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}This is
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}This is the host of the game
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies}
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Local
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Remote players can't connect
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Public
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kick
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Ban
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Delete
@ -2312,6 +2324,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The serv
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} was kicked. Reason: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Server registration failed
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Your server doesn't allow remote connections
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Other players won't be able to connect to your server
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Content downloading
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -1530,6 +1530,8 @@ STR_FACE_TIE :Kravato:
STR_FACE_EARRING :Orelringo:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Ŝanĝi kravaton aŭ orelringon.
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Pluraj ludantoj
@ -1579,7 +1581,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Startu s
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Startu propran servilon
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Tajpu vian nomon
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Enigu la adreson de la gastiganto
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Komencu novan ludon por pluraj ludantoj
@ -1657,6 +1658,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Spekti
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Servilo
@ -1753,6 +1757,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ŝ
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}La servilo fermis la seancon
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}La servilo restartiĝas...{}Bonvolu atendi...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Enhavo elŝutiĝas
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo

@ -2049,8 +2049,9 @@ STR_FACE_TIE :Lips:
STR_FACE_EARRING :Kõrvarõngas:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Vaheta kraed või kõrvarõngast
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privaatne
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Avalik
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Mitmikmäng
@ -2104,7 +2105,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Tee serv
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Tee oma server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Sisesta enda nimi
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Sisesta serveri aadress
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Mitmikmängu alustamine
@ -2209,6 +2209,9 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Loo uus
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Tema oled sina
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Tema on mängu korraldaja
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Viska välja
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Keela
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Kustuta
@ -2335,6 +2338,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server s
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server restardib...{}Palun oota...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} visati välja. Põhjendus: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Aineste allalaadimine
STR_CONTENT_TYPE_CAPTION :{BLACK}Liik

@ -1696,6 +1696,8 @@ STR_FACE_TIE :Slips:
STR_FACE_EARRING :Oyraringur:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Broyt slips ella oyraring
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Hópspæl
@ -1745,7 +1747,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Set serv
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Set tín egna servara í gongd
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Skriva títt navn
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Skriva bústað hjá verti
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Byrja eitt nýtt hópspæl
@ -1823,6 +1824,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Eygleið
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Servari
@ -1931,6 +1935,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} he
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Servarin endaði setuna
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Servarin endurbyrjar...{}Vinarliga bíða...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Tilfar verur heinta niður
STR_CONTENT_TYPE_CAPTION :{BLACK}Slag

@ -2001,8 +2001,11 @@ STR_FACE_TIE :Solmio:
STR_FACE_EARRING :Korvakoru:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Vaihda solmio tai korvakoru
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Yksityinen
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Paikallinen
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Julkinen
STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Vain kutsutut
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Moninpeli
@ -2051,12 +2054,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Etsi jul
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Etsi lähiverkosta
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Etsi palvelimia lähiverkosta
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Lisää palvelin
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Lisää palvelin listaan, joka käydään läpi aina uusia pelejä haettaessa
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Lisää palvelimen luetteloon. Tämä voi olla palvelimen osoite tai kutsukoodi.
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Käynnistä palvelin
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Käynnistä oma palvelin
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Kirjoita nimesi
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Syötä palvelimen IP-osoite
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Anna palvelimen osoite tai kutsukoodi
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Aloita uusi peli
@ -2143,6 +2146,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Muokkaa
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Palvelimen nimi
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Näkyvyys
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Näkyykö palvelimesi muille julkisessa listauksessa
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Kutsukoodi
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Kutsukoodi, jolla muut pelaajat voivat liittyä tälle palvelimelle
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Yhteystyyppi
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Voivatko muut ottaa yhteyden palvelimeesi, ja miten
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Pelaaja
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Nimi
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Pelaajanimesi
@ -2161,6 +2168,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Tämä o
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Tämä on pelin ylläpitäjä
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} pelaaja{P "" a} / {NUM} yhtiö{P "" tä}
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Paikallinen
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Etäpelaajat eivät voi ottaa yhteyttä
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Julkinen
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Potki
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Estä
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Poista
@ -2288,6 +2301,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Palvelin
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Palvelin käynnistyy uudelleen...{}Odota, ole hyvä...
STR_NETWORK_MESSAGE_KICKED :{STRING} potkaistiin ulos. Syy: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Palvelimen rekisteröinti epäonnistui
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Palvelimesi ei salli etäyhteyksiä
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Muut pelaajat eivät voi saada yhteyttä palvelimeesi
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Sisällön lataus
STR_CONTENT_TYPE_CAPTION :{BLACK}Tyyppi

@ -2002,8 +2002,9 @@ STR_FACE_TIE :Cravate{NBSP}:
STR_FACE_EARRING :Boucle d'oreille{NBSP}:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Modifier la cravate ou la boucle d'oreille
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privé
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Public
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multijoueurs
@ -2057,7 +2058,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Héberge
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Démarrer son propre serveur, sur cet ordinateur-ci
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Entrer votre nom
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Saisir l'adresse IP du serveur
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Commencer une nouvelle partie
@ -2161,6 +2161,9 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Créer u
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}C'est vous
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}C'est l'hôte du jeu
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Exclure
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bannir
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Supprimer
@ -2288,6 +2291,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Le serve
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Le serveur redémarre...{}Veuillez patienter...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} a été exclu. Raison{NBSP}: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Téléchargement de modules
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -1795,6 +1795,8 @@ STR_FACE_TIE :Strik:
STR_FACE_EARRING :Earbel:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Feroarje strik of earbel
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer
@ -1834,7 +1836,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start ts
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start dien eigen tsjinner
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Fier dyn namme in
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Fier de namme fan de host yn
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start in spul foar multispilers
@ -1899,6 +1900,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :{WHITE}Taskôgj
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Tsjinner
@ -1977,6 +1981,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} is
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} hat syn/har namme oanpast nei {STRING}
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Tsjinner hat de ferbining sluten
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Ynhâld delheljen
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -2081,6 +2081,8 @@ STR_FACE_TIE :Tàidh:
STR_FACE_EARRING :Fàinne-chluaise:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Atharraich an tàidh no an fhàinne-chluaise
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Ioma-chluicheadair
@ -2130,7 +2132,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Tòisich
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Tòisich frithealaiche agad fhèin
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Cuir d' ainm a-steach
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Cuir seòladh an òstair a-steach
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Tòisich geama ioma-chluicheadair ùr
@ -2208,6 +2209,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Coimhead air
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Frithealaiche
@ -2316,6 +2320,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** Dh'atharrai
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Dhùin am frithealaiche an seisean
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Tha am frithealaiche ag ath-thòiseachadh...{}Fuirich greis...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Susbaint ri luchdadh a-nuas
STR_CONTENT_TYPE_CAPTION :{BLACK}Seòrsa

@ -1917,6 +1917,8 @@ STR_FACE_TIE :Garavata:
STR_FACE_EARRING :Pendentes:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Cambia-la garavata ou os pendentes
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multixogador
@ -1966,7 +1968,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Iniciar
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Comezar o teu propio servidor
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Escribe o teu nome
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Introduce a dirección IP do servidor
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Comezar nova partida multixogador
@ -2044,6 +2045,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Observar
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Servidor
@ -2153,6 +2157,7 @@ STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} de
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servidor pechou a sesión
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor estase a reiniciar...{}Agarda por favor...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Descargando contidos
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo

@ -2312,8 +2312,10 @@ STR_FACE_TIE :Krawatte:
STR_FACE_EARRING :Ohrring:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Krawatte oder Ohrring ändern
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privat
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Lokal
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Öffentlich
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Mehrspieler
@ -2362,12 +2364,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Internet
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}LAN durchsuchen
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Lokales Netzwerk nach Spielservern durchsuchen
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Server hinzufügen
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Fügt einen Server zu der Liste von Servern hinzu, die immer nach laufenden Spielen kontrolliert werden
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Fügt einen Server zur Liste hinzu. Dies kann entweder eine Serveradresse oder ein Einladungscode ein
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Server starten
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Einen eigenen Server starten
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Bitte eigenen Namen eingeben
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}IP-Adresse des Servers eingeben
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Serveradresse oder Einladungscode eingeben
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Neues Mehrspieler-Spiel beginnen
@ -2454,6 +2456,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Ihren Se
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Name des Servers
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Sichtbarkeit
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Ob andere Personen Ihren Server in der öffentlichen Liste sehen können
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Einladungscode
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Einladungscode, den andere Spieler benutzen können, um diesem Server beizutreten
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Verbindungstyp
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Ob und wie dein Server von anderen erreicht werden kann
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Spieler
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Name
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Ihr Spielername
@ -2472,6 +2478,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Das sind
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dies ist der Host des Spiels
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} Client{P "" s} / {NUM} Firm{P a en}
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Lokal
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Nicht-lokale Spieler können sich nicht verbinden
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Öffentlich
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Hinauswerfen
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bannen
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Löschen
@ -2602,6 +2614,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Der Serv
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Der Server startet neu...{}Bitte warten...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} wurde vom Server hinausgeworfen. Grund: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Serverregistration fehlgeschlagen
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Dein Server lässt keine nicht-lokalen Verbindungen zu
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Andere Spieler werden nicht in der Lage sein, sich zu deinem Server zu verbinden
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Herunterladen von Erweiterungen
STR_CONTENT_TYPE_CAPTION :{BLACK}Art

@ -2037,6 +2037,8 @@ STR_FACE_TIE :Γραβάτα:
STR_FACE_EARRING :Σκουλαρίκι:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Αλλαγή γραβάτας ή σκουλαρικιού
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Παιχνίδι πολλών παικτών
@ -2087,7 +2089,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Εκκί
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Ξεκινήστε το δικό σας διακομιστή
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Εισάγετε το όνομά σας
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Εισάγετε τη διεύθυνση του οικοδεσπότη
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Έναρξη νέου παιχνιδιού για πολλούς παίκτες
@ -2165,6 +2166,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Παρακολ
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Διακομιστής
@ -2278,6 +2282,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Ο δι
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Ο διακομιστής επανεκκινεί...{}Παρακαλώ περιμένετε...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} εκδιώχθηκε. Λόγος: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Περιεχόμενο κατεβαίνει
STR_CONTENT_TYPE_CAPTION :{BLACK}Τύπος

@ -1895,6 +1895,8 @@ STR_FACE_TIE ::עניבה
STR_FACE_EARRING ::עגילים
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK} שנה עניבה/עגילים
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}משחק רשת
@ -1944,7 +1946,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}הפעל
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}הפעל שרת חדש
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK} :שמך
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}הזן את הכתובת של השרת
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}התחל משחק רב-משתתפים חדש
@ -2022,6 +2023,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :צפה
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :שרת
@ -2130,6 +2134,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :{STRING} שינ
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}השרת סגר את המשחק
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}השרת מופעל מחדש...{}אנא המתן...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}הורדת תוכן
STR_CONTENT_TYPE_CAPTION :{BLACK}סוג

@ -44,6 +44,7 @@ STR_CARGO_PLURAL_FRUIT :फल
STR_CARGO_SINGULAR_NOTHING :
STR_CARGO_SINGULAR_MAIZE :मक्का
STR_CARGO_SINGULAR_SWEETS :मिठाई
STR_CARGO_SINGULAR_BUBBLE :बुलबुला
STR_CARGO_SINGULAR_TOFFEE :टॉफी
# Quantity of cargo
@ -73,6 +74,7 @@ STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp
# Common window strings
STR_TOOLTIP_RESIZE :{BLACK}खिड़की का आकार बदलने के लिये क्लिक करके खींचें
# Show engines button
@ -107,6 +109,8 @@ STR_SCENEDIT_FILE_MENU_QUIT :निकास
############ range for SE file menu starts
############ range for settings menu starts
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :समायोजन
STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :पथ-संकेतों के नाम दिखायें
############ range ends here
############ range for file menu starts
@ -132,6 +136,7 @@ STR_INDUSTRY_MENU_INDUSTRY_CHAIN :औद्यो
############ range ends here
############ range for railway construction menu starts
STR_RAIL_MENU_ELRAIL_CONSTRUCTION :विद्युतिकृत रेलवे निर्माण
############ range ends here
############ range for road construction menu starts
@ -161,13 +166,16 @@ STR_ORDINAL_NUMBER_2ND :द्वित
############ range for ordinal numbers ends
############ range for days starts
STR_DAY_NUMBER_15TH :१५वीं
STR_DAY_NUMBER_14TH :१४
STR_DAY_NUMBER_15TH :१५
STR_DAY_NUMBER_23RD :२३
############ range for days ends
############ range for months starts
STR_MONTH_ABBREV_JAN :जन
STR_MONTH_ABBREV_NOV :नव
STR_MONTH_AUG :अगस्त
############ range for months ends
# Graph window
@ -201,6 +209,7 @@ STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS :{BIG_FONT}{WHIT
# Smallmap window
STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}ट्रक लदान वीथी
STR_SMALLMAP_LEGENDA_BARE_LAND :{TINY_FONT}{BLACK}रिक्त भूमि
STR_SMALLMAP_LEGENDA_TOWNS :{TINY_FONT}{BLACK}नगर
@ -290,6 +299,7 @@ STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}एक
STR_VARIETY_MEDIUM :मध्यम
STR_AI_SPEED_SLOW :धीमा
@ -321,17 +331,19 @@ STR_CONFIG_SETTING_BRIBE_HELPTEXT :कंपनि
STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :सक्षम होने पर वाहनों के निर्देशों की आवधिक जाँच की जाती है, और कुछ सुस्पष्ट मामलों क पता चलते ही एक संदेश द्वारा बताया जाता है।
STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :सक्षम होने पर वाहनों के निर्देशों की आवधिक जाँच की जाती है, और कुछ सुस्पष्ट मामलों क पता चलते ही एक संदेश द्वारा बताया जाता है।
STR_CONFIG_SETTING_ORDER_REVIEW_OFF :नहीं
STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :एक स्टेशन के हिस्सों के विस्तार हेतु अधिकतम क्षेत्र निर्धारित करें। ऊंची संख्या खेल को धीमा कर सकती है।
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :बैंगनी
STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :अक्षम
STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_ZERO :सीमाहीन (आपके कंप्यूटर द्वारा सीमित)
STR_CONFIG_SETTING_SOUND_NEWS :समाचार पत्र: {STRING}
@ -352,6 +364,7 @@ STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA}
STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_IN_2X :२x
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :अंतर्राष्ट्रीय मानक (m/s)
@ -397,7 +410,10 @@ STR_ABANDON_SCENARIO_QUERY :{YELLOW}क्
# Face selection window
STR_FACE_LOAD_DONE :{WHITE}ओपनटीटीडी प्रारूप पत्र से आपका प्रिय चेहरा भर लिया गया है
STR_FACE_COLLAR_TOOLTIP :{BLACK}कॉलर बदलें
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
@ -433,6 +449,9 @@ STR_NETWORK_GAME_LOBBY_INAUGURATION_YEAR :{SILVER}उद
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
@ -456,13 +475,16 @@ STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_3 :खेल अ
############ End of leave-in-this-order
STR_NETWORK_MESSAGE_CLIENT_LEAVING :छोड़ रहा है
# Content downloading window
STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}खोजी गयी सामग्री OpenTTD की सामग्री सेवा में उपलब्ध नहीं है, आप OpenTTD से असंबद्ध वेबसाइटों पर खोज सकते हैं
STR_CONTENT_DETAIL_SUBTITLE_ALREADY_HERE :{SILVER}यह आपके पास पहले से मौजूद है
STR_CONTENT_DETAIL_SUBTITLE_DOES_NOT_EXIST :{SILVER}यह सामग्री अज्ञात है और इसे ओपनटीटीडी में प्राप्त नहीं किया जा सकता है
# Order of these is important!
# Content downloading progress window
STR_CONTENT_DOWNLOAD_COMPLETE :{WHITE}डाउनलोड पूरा हुआ
# Content downloading error messages
STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD :{WHITE}डाउनलोड असफल हुआ...
@ -567,6 +589,7 @@ STR_LAI_STATION_DESCRIPTION_RAILROAD_STATION :रेलवे
STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL :इस्पात का रेल झूला पुल
STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL :इस्पात बाहुधरण रेल पुल
@ -574,6 +597,7 @@ STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL :इस्पा
# About OpenTTD window
# Framerate display window
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms
STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms
STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES}
STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES}
@ -603,6 +627,7 @@ STR_MAPGEN_BORDER_RANDOM :{BLACK}या
STR_GENERATION_PROGRESS_NUM :{BLACK}{NUM} / {NUM}
# NewGRF settings
STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}चुने गये पूर्वनिश्चित समायोजन को खोलें
@ -637,6 +662,7 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING
# Placeholders for other invalid stuff, e.g. vehicles that have gone (Game Script).
# NewGRF scanning window
STR_NEWGRF_SCAN_MESSAGE :{BLACK}NewGRF खोजा जा रहा है। संख्या के अनुसार इसमें कुछ समय लग सकता है...
# Sign list window
@ -658,6 +684,7 @@ STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}फै
STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN :लघु विज्ञापन अभियान
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}नगरों के सड़क तंत्र के पुनर्निर्माण में निवेश करें।{}इससे अधिकतम ६ महीने तक यातायात में बहुत विघ्न पड़ता है।{}मूल्य : {CURRENCY_LONG}
# Goal window
STR_GOALS_TEXT :{ORANGE}{STRING}
@ -704,6 +731,7 @@ STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOIN
# Finances window
STR_FINANCES_YEAR :{WHITE}{NUM}
STR_FINANCES_SECTION_PROPERTY_MAINTENANCE :{GOLD}संपत्ति का रखरखाव
STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG}
STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG}
STR_FINANCES_BORROW_BUTTON :{BLACK}{CURRENCY_LONG} उधार
@ -756,6 +784,7 @@ STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING
############ range for vehicle availability starts
STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :नई ट्रेनें
############ range for vehicle availability ends
STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}मूल्य : {GOLD}{CURRENCY_LONG}{BLACK} भार : {GOLD}{WEIGHT_SHORT}
@ -856,6 +885,7 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE
# Order view
STR_ORDER_INDEX :{COMMA}:{NBSP}
STR_ORDER_TEXT :{STRING} {STRING} {STRING}
@ -968,6 +998,7 @@ STR_ERROR_TOO_HIGH :{WHITE}... ब
# Company related errors
STR_ERROR_CAN_T_SELL_25_SHARE_IN :{WHITE}इस कंपनी का २५% अंश नहीं बेच सकते...
# Town related errors
STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}नगर का नाम नहीं बदला जा सकता है...
@ -979,6 +1010,7 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... व
# Station construction related errors
STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}अत्यधिक स्टेशन/लादन क्षेत्र
# Station destruction related errors
@ -1002,8 +1034,10 @@ STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}पट
# Road construction errors
STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... असंगत ट्रामवे
# Waterway construction errors
STR_ERROR_MUST_BE_BUILT_ON_WATER :{WHITE}... पानी पर बनाया जाना चाहिये।
# Tree related errors
@ -1053,6 +1087,7 @@ STR_BASESOUNDS_WIN_DESCRIPTION :ट्रां
##id 0x4800
# industry names
STR_INDUSTRY_NAME_POWER_STATION :बिजलीघर
STR_INDUSTRY_NAME_STEEL_MILL :इस्पात चक्की
STR_INDUSTRY_NAME_BANK_TROPIC_ARCTIC :बैंक
############ WARNING, using range 0x6000 for strings that are stored in the savegame
@ -1062,6 +1097,7 @@ STR_SV_EMPTY :
STR_SV_STNAME :{STRING}
STR_SV_STNAME_NORTH :{STRING} उत्तर
STR_SV_STNAME_CENTRAL :{STRING} केंद्रीय
STR_SV_STNAME_AIRPORT :{STRING} हवाई अड्डा
STR_SV_STNAME_BUOY :{STRING}
STR_SV_STNAME_WAYPOINT :{STRING}
@ -1074,8 +1110,10 @@ STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COAL_CAR :कोयला
STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FRUIT_TRUCK :फल वाहन
STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_X2001_ELECTRIC :'X2001' (विद्युतीय)
STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :खिलौनों का डब्बा
STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_WATER_TANKER :पानी का टैंकर
STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BUBBLE_VAN :बबल वैन
STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKIII_BUS :प्लॉडीपीहट एमके३ बस
STR_VEHICLE_NAME_ROAD_VEHICLE_MORELAND_WOOD_TRUCK :मोरलैंड काष्ठ ट्रक
STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_ARMORED_TRUCK :फोस्टर कवचयुक्त ट्रक
STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_CANDY_TRUCK :पावरनोट मिष्ठान्न ट्रक
STR_VEHICLE_NAME_AIRCRAFT_BAKEWELL_COTSWALD_LB_3 :बेकवेल कॉट्सवॉल्ड एलबी-३

@ -2056,8 +2056,9 @@ STR_FACE_TIE :Nyakkendő:
STR_FACE_EARRING :Fülbevaló:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Nyakkendő vagy fülbevaló cseréje
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privát
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Nyilvános
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Hálózati játék
@ -2111,7 +2112,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Szerver
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Saját szervert indít
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Add meg a neved
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Írd be a szerver IP címét
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Új játékot kezd
@ -2215,6 +2215,9 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Hozz lé
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Ez vagy te
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Ez a játék elindítója
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kirúgás
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Tiltás
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Törlés
@ -2341,6 +2344,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}A szerve
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}A szerver újraindul...{}Türelem...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} ki lett rúgva. Oka: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Tartalom letöltés
STR_CONTENT_TYPE_CAPTION :{BLACK}Típus

@ -1734,6 +1734,8 @@ STR_FACE_TIE :Bindi:
STR_FACE_EARRING :Eyrnalokkur:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Breyta bindi eða eyrnalokk
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Fjölspilun
@ -1783,7 +1785,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Hefja þ
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Hefja eigin þjón
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Sláðu inn nafn þitt
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Sláðu inn IP tölu þjónsins
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Hefja nýjan fjölspilunarleik
@ -1861,6 +1862,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Fylgjast með
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Þjónn
@ -1969,6 +1973,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} he
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Þjónninn sleit tengingunni
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Verið er að endurræsa þjóninn...{}Vinsamlega bíðið...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Niðurhel efni
STR_CONTENT_TYPE_CAPTION :{BLACK}Týpa

@ -607,6 +607,8 @@ STR_QUIT_NO :{BLACK}Ne
# Face selection window
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
@ -641,6 +643,9 @@ STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT :{BLACK}{COMMA}x
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
@ -664,6 +669,7 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING}
############ Leave those lines in this order!!
############ End of leave-in-this-order
# Content downloading window
# Order of these is important!

@ -1992,8 +1992,9 @@ STR_FACE_TIE :Dasi:
STR_FACE_EARRING :Anting-anting:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Ubah dasi atau anting-anting
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privat
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Umum
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Bermain bersama
@ -2047,7 +2048,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Mulai se
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Mulai melayani
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Masukkan nama anda
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Masukkan alamat IP server
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Mulai permainan bersama baru
@ -2151,6 +2151,9 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Ciptakan
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Ini adalah Anda
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Ini adalah hos permainan
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Diusir
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Melarang
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Hapus
@ -2277,6 +2280,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server m
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server memulai ulang...{}Tunggulah...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} telah dikeluarkan. Alasan: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Mengunduh konten
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipe

@ -1869,6 +1869,8 @@ STR_FACE_TIE :Carbhat:
STR_FACE_EARRING :Fáinne cluaise:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Athraigh carbhat nó fáinne cluaise
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Ilimreoirí
@ -1918,7 +1920,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Tosaigh
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Tosaigh d'fhreastalaí féin
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Iontráil d'ainm
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Iontráil seoladh an óstaigh
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Tosaigh cluiche ilimreora nua
@ -1996,6 +1997,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Féach air
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Freastalaí
@ -2104,6 +2108,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** D'athraigh
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Dhún an freastalaí an seisiún
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Tá an freastalaí á atosú...{}Fan go fóill...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Inneachar á íoslódáil
STR_CONTENT_TYPE_CAPTION :{BLACK}Cineál

@ -2006,6 +2006,8 @@ STR_FACE_TIE :Cravatta:
STR_FACE_EARRING :Orecchino:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Cambia la cravatta o l'orecchino
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multigiocatore
@ -2059,7 +2061,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Avvia se
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Avvia il proprio server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Inserire il nome del giocatore
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Digitare l'indirizzo del server
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Avvia nuova partita multigiocatore
@ -2138,6 +2139,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Diventa spettat
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Sei sicuro di voler eliminare la compagnia '{COMPANY}'?
@ -2252,6 +2256,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Il serve
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Il server si sta riavviando...{}Attendere prego...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} è stato espulso. Motivo: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Download contenuti
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo

@ -1997,8 +1997,9 @@ STR_FACE_TIE :ネクタイ:
STR_FACE_EARRING :イヤリング:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}ネクタイ/イヤリングを変更します
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :プライベート
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :公開
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}マルチプレイヤーゲーム
@ -2052,7 +2053,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}サー
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}自分でサーバーを立ち上げます
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}プレイヤー名を入力
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}ホストアドレスを入力します
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}新規マルチプレイヤーゲームを開始
@ -2156,6 +2156,9 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}新し
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}これはあなたです
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}ゲームのホストです
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :キック
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :BAN
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :削除
@ -2283,6 +2286,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}サー
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}このサーバーは再起動中です…{}しばらくお待ちください…
STR_NETWORK_MESSAGE_KICKED :*** {STRING}がキックされました。理由: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}コンテンツをダウンロード中
STR_CONTENT_TYPE_CAPTION :{BLACK}種類

@ -2063,7 +2063,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX :승객에 대
STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"대칭"은 A역에서 B역으로 가려는 승객의 수가 B에서 A로 가려는 승객의 수와 비슷하다는 뜻입니다. "비대칭"은 승객이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 승객 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다.
STR_CONFIG_SETTING_DISTRIBUTION_MAIL :우편에 대한 분배 형식: {STRING}
STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"대칭"은 A역에서 B역으로 가려는 우편물의 수가 B에서 A로 가려는 우편물의 수와 비슷하다는 뜻입니다. "비대칭"은 우편물이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 우편물 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다.
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :장갑 화물에 대한 분배 형식: {STRING}
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :귀금속 화물에 대한 분배 형식: {STRING}
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :장갑 화물은 온대 기후의 귀금속, 아열대 기후의 다이아몬드 또는 아한대 기후의 금을 말합니다. NewGRF을 사용하면 달라질 수 있습니다. "대칭"은 A역에서 B역으로 가려는 화물의 수가 B에서 A로 가려는 화물의 수와 비슷하다는 뜻입니다. "비대칭"은 화물이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 화물 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다. 아한대 기후에서는 대칭으로 설정하면 은행이 금광으로 금을 보내지 않으려 하기 때문에 비대칭이나 수동으로 설정하는 것을 추천합니다. 온대 기후나 아열대 기후에서는 은행이 일부 적재한 귀금속을 원래 은행으로 보내려고 하기 때문에 대칭을 선택해도 됩니다.
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :다른 화물에 대한 분배 형식: {STRING}
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"비대칭"은 화물이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 화물 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다. 특별한 이유가 없는 한, "비대칭"이나 "수동"으로 설정하십시오.
@ -2434,8 +2434,11 @@ STR_FACE_TIE :넥타이:
STR_FACE_EARRING :귀걸이:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}넥타이/귀걸이 변경
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :비공개
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :로컬
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :공개
STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :초대만
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}멀티 플레이
@ -2484,12 +2487,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}인터
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}LAN 검색
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}로컬 영역 네트워크에서 서버를 검색합니다
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}서버 추가
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}서버를 목록에 수동으로 추가합니다.
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}서버를 목록에 추가합니다. 서버 주소나 초대 코드를 입력하세요.
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}서버 열기
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}당신이 서버가 되어 게임을 진행합니다.
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}이름을 입력하세요
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}호스트(IP) 주소 입력
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}서버 주소나 초대 코드를 입력하세요
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}새 멀티플레이 게임 시작하기
@ -2576,6 +2579,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}서버
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :서버 이름
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}공개 여부
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}서버 목록에 이 서버를 공개할 지 여부를 설정합니다
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}초대 코드
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}다른 플레이어가 이 서버에 들어오기 위한 초대 코드입니다
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}접속 방식
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}다른 사람이 이 서버에 들어올 수 있는지 여부를 나타냅니다
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}플레이어
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}이름
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}당신의 접속자 이름입니다
@ -2594,6 +2601,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}당신
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}이 게임을 연 사람입니다
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}접속자 {NUM}명 / 회사 {NUM}개
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}로컬
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}다른 플레이어가 접속할 수 없게 됩니다
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}공개
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :추방
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :차단
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :삭제
@ -2724,6 +2737,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}서버
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}서버가 재시작되고 있습니다...{}기다려주세요...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} - 서버에서 강제로 추방되었습니다. 사유: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}서버 등록 실패
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}서버가 원격 접속을 허용하지 않습니다
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}다른 플레이어가 이 서버에 들어올 수 없게 될 것입니다
# Content downloading window
STR_CONTENT_TITLE :{WHITE}콘텐츠 다운로드
STR_CONTENT_TYPE_CAPTION :{BLACK}종류

@ -2088,6 +2088,8 @@ STR_FACE_TIE :Focale:
STR_FACE_EARRING :Inauris:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Mutare focale vel inaurem
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Modus Plurium Lusorum
@ -2137,7 +2139,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Servatru
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Servatrum tuum proprium incohare
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Nomen tuum inscribe
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Inscribe inscriptionem IP servatri
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Incipere novum ludum cum pluribus lusoribus
@ -2215,6 +2216,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Spectare
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Servatrum
@ -2323,6 +2327,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} no
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Servatrum iam clausum est
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Servatrum resumit...{}Maneas...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Arcessitus Rerum
STR_CONTENT_TYPE_CAPTION :{BLACK}Typus

@ -1961,6 +1961,8 @@ STR_FACE_TIE :Kaklasaite:
STR_FACE_EARRING :Auskars:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Mainīt kaklasaiti vai auskarus
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Vairākspēlētāju spēle
@ -2014,7 +2016,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Palaist
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Palaist jūsu personīgo serveri
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Ievadīt savu vārdu
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Ievadīt servera adresi
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Sākt jaunu vairākspēlētāju spēli
@ -2092,6 +2093,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Skatīt
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Serveris
@ -2205,6 +2209,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serveris
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Serveris pārstartējas...{}Lūdzu uzgaidiet...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} tika izmests. Iemesls: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Satura lejupielāde
STR_CONTENT_TYPE_CAPTION :{BLACK}Tips

@ -2205,6 +2205,8 @@ STR_FACE_TIE :Kaklaraištis:
STR_FACE_EARRING :Auskaras:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Pakeisti kaklaraištį arba auskarą
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Žaidimas tinkle
@ -2258,7 +2260,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Sukurti
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Sukurti savo serverį
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Įrašykite savo vardą
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Įvesk adresą (IP)
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Pradėti naują daugiažaidėjinį žaidimą
@ -2336,6 +2337,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Stebėti
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Serveris
@ -2449,6 +2453,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serveris
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Serveris persikrauna...{}Prašau palaukti...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} buvo išmestas. Priežastis: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Turinio atsisiuntimas
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipas

@ -1986,6 +1986,8 @@ STR_FACE_TIE :Krawatt:
STR_FACE_EARRING :Ouerréng:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Krawatt oder Ouerréng änneren
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer
@ -2039,7 +2041,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Server s
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Eegenen Server starten
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Gëff däin Numm an
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}D'Address vum Host uginn
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Nei Multiplayerpartie starten
@ -2117,6 +2118,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Nokucken
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Server
@ -2230,6 +2234,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}De Serve
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}De Server gëtt nei gestart...{}W.e.g. waarden...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} gouf gekickt. Grond: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Lueden Inhalt erof
STR_CONTENT_TYPE_CAPTION :{BLACK}Typ

@ -965,6 +965,8 @@ STR_ABANDON_GAME_QUERY :{YELLOW}Дал
# Face selection window
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
@ -999,6 +1001,9 @@ STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT :{BLACK}{COMMA}x
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
@ -1024,6 +1029,7 @@ STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_4 :Игра ушт
STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :игра скрипта
############ End of leave-in-this-order
# Content downloading window
STR_CONTENT_SEARCH_EXTERNAL :{BLACK}Пребарај надворешни веб-страни
STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}Вие заминувате од OpenTTD!

@ -1631,6 +1631,8 @@ STR_FACE_TIE :Tali leher:
STR_FACE_EARRING :Anting-anting:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Tukar tali leher atau anting-anting
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Pemain berbilang
@ -1680,7 +1682,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Mulakan
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Mulakan pelayan sendiri
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Masukkan nama anda
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Masukkan alamat hos
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Mulakan permainan baru berbilang pemain
@ -1758,6 +1759,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Saksi
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Pelayan
@ -1866,6 +1870,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} te
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Pelayan telah menutup sesi ini
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Pelayan sedang dimulakan semula...{}Harap bersabar...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Kandungan sedang dimuat turun
STR_CONTENT_TYPE_CAPTION :{BLACK}Jenis

@ -533,6 +533,8 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Ibdel is
# Face selection window
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
@ -569,6 +571,9 @@ STR_NETWORK_CONNECTING_DOWNLOADING_2 :{BLACK}{BYTES}
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
@ -593,6 +598,7 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING}
############ Leave those lines in this order!!
############ End of leave-in-this-order
# Content downloading window
# Order of these is important!

@ -897,6 +897,8 @@ STR_FACE_LIPS_MOUSTACHE_TOOLTIP :{BLACK}ओठ
STR_FACE_CHIN :हनुवटी:
STR_FACE_CHIN_TOOLTIP :{BLACK}हनुवटी बदला
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
@ -939,6 +941,9 @@ STR_NETWORK_CONNECTING_DOWNLOADING_2 :{BLACK}{BYTES}
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
@ -962,6 +967,7 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING}
############ Leave those lines in this order!!
############ End of leave-in-this-order
# Content downloading window
# Order of these is important!

@ -2004,8 +2004,9 @@ STR_FACE_TIE :Slips:
STR_FACE_EARRING :Ørering:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Endre slips eller ørering
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privat
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Offentlig
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Flerspiller
@ -2059,7 +2060,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start tj
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start en egen tjener
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Skriv inn ditt navn
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Skriv inn IP-adressen til verten
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start et nytt flerspillerspill
@ -2165,6 +2165,9 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dette er
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dette er verten for spillet
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" s} / {NUM} firma{P et er}
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Spark
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Utesteng
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Slett
@ -2292,6 +2295,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Tjeneren
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Tjeneren starter på nytt...{}Vennligst vent...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} ble kastet ut. Grunn: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Laster ned innhold
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -1793,6 +1793,8 @@ STR_FACE_TIE :Slips:
STR_FACE_EARRING :Øyrering:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Byt slips eller øyrering
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Fleirspelar
@ -1842,7 +1844,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start te
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start ein eigen tenar
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Set inn namnet ditt
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Skriv inn IP-adressa til tenaren
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start eit nytt fleirspelarspel
@ -1920,6 +1921,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Vær tilskodar
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Tenar
@ -2028,6 +2032,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ha
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Tenaren avslutta spelet
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Tenaren startar om att...{}Vær venleg og vent...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Lastar ned innhald
STR_CONTENT_TYPE_CAPTION :{BLACK}Type

@ -1591,6 +1591,8 @@ STR_FACE_TIE :کراوات:
STR_FACE_EARRING :گوشواره:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}تغییر کراوات یا گوشواره
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}چندنفره
@ -1640,7 +1642,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}اجرا
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}راه اندازی سرویس دهنده خود
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}نام خود را وارد نماببد
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}نشانی میزبان را وارد کنید
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}آغاز بازی چندنفره
@ -1718,6 +1719,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :{WHITE}تماش
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :سرویس دهنده
@ -1826,6 +1830,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ن
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}سرویس دهنده جلسه را تعطیل کرد
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}راه اندازی مجدد سرویس دهنده...{}لطفا صبر کنید...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}در حال دانلود
STR_CONTENT_TYPE_CAPTION :{BLACK}نوع

@ -2372,6 +2372,8 @@ STR_FACE_TIE :Krawat:
STR_FACE_EARRING :Kolczyk:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Zmień krawat lub kolczyk
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Gra wieloosobowa
@ -2425,7 +2427,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Uruchom
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Uruchom własny serwer
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Wprowadź swoje imię
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Wpisz adres IP serwera
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Rozpocznij nową grę wieloosobową
@ -2503,6 +2504,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Obserwuj
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Serwer
@ -2616,6 +2620,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serwer z
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Restart serwera...{}Proszę czekać...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} został wyrzucony. Powód: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Przeglądarka dodatkowej zawartości
STR_CONTENT_TYPE_CAPTION :{BLACK}Typ

@ -2002,8 +2002,11 @@ STR_FACE_TIE :Gravata:
STR_FACE_EARRING :Brinco:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Mudar gravata ou brinco
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privado
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Local
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Público
STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Apenas convites
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multi-jogador
@ -2037,6 +2040,7 @@ STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Versão
STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Endereço do servidor: {WHITE}{STRING}
STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Data de início: {WHITE}{DATE_SHORT}
STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Data actual: {WHITE}{DATE_SHORT}
STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Script de Jogo: {WHITE}{STRING} (v{NUM})
STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}Protegido por palavra-chave!
STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}SERVIDOR DESLIGADO
STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVIDOR CHEIO
@ -2052,12 +2056,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Pesquisa
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Search LAN
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK} Pesquisa de rede local para servidores
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Adicionar servidor
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Adiciona um servidor à lista que será sempre verificado se existem jogos a decorrer.
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Adiciona um servidor à lista. Pode ser um endereço de servidor ou um código de convite
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Iniciar servidor
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Iniciar um servidor próprio
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Introduza o seu nome
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Introduza o endereço IP do servidor
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Introduza o endereço de servidor ou código de convite
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Iniciar novo jogo
@ -2144,6 +2148,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Editar o
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Nome do servidor
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Visibilidade
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Se as outras pessoas podem ver o seu servidor na lista pública
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Código de convite
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Código de convite que os outros jogadores podem usar para entrar neste servidor
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Tipo de conexão
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Se e como o seu servidor pode ser alcançado por outros
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Jogador
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Nome
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}O seu nome de jogador
@ -2162,6 +2170,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Este é
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Este é o anfitrião do jogo
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} / {NUM} companhi{P a as}
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Local
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Jogadores remotos não conseguem conetar
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Público
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Expulsar
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Banir
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Apagar
@ -2289,6 +2303,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servid
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor está a reiniciar...{}Por favor espere...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} foi expulso. Motivo: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Falha ao registar o servidor
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}O seu servidor não permite conexões remotas
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Outros jogadores não conseguirão conetar ao seu servidor
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Descarregamento de conteúdo
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo

@ -1919,7 +1919,8 @@ STR_FACE_TIE :Cravată:
STR_FACE_EARRING :Cercei:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Schimbă cravata sau cerceii
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privat
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer
@ -1973,7 +1974,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Porneşt
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Porneşte un server propriu
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Introduceţi numele dvs.
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Introduceţi adresa serverului
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Începe un joc nou
@ -2056,6 +2056,9 @@ STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}Modific
STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Trimite un mesaj tuturor jucătorilor acestei companii
STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Trimite un mesaj tuturor spectatorilor
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Deblocare cu parolă
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Sigur vrei să dai afară jucătorul '{STRING}'?
@ -2171,6 +2174,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serverul
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Serverul este repornit...{}Vă rugăm aşteptaţi...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} a fost dat afară. Motiv: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Descărcare resurse online
STR_CONTENT_TYPE_CAPTION :{BLACK}Tip

@ -2155,8 +2155,9 @@ STR_FACE_TIE :Галстук:
STR_FACE_EARRING :Серьга:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Изменить галстук или серьгу
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Публичный
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Частный
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Сетевая игра
@ -2210,7 +2211,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Запу
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Запуск сервера на вашем компьютере. К этой игре смогут подсоединяться другие игроки.
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Введите ваше имя
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Введите адрес сервера
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Запуск новой сетевой игры
@ -2315,6 +2315,9 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Это
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Это организатор игры
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} клиент{P "" а ов} / {NUM} компани{P я и й}
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Отключить
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Заблокировать
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Удалить
@ -2442,6 +2445,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Серв
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Сервер перезапускается...{}Пожалуйста, подождите...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} был исключён из игры. Причина: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Загрузка контента
STR_CONTENT_TYPE_CAPTION :{BLACK}Тип

@ -2181,6 +2181,8 @@ STR_FACE_TIE :Kravata:
STR_FACE_EARRING :Minđuše:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Promena kravate ili minđuša
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Mrežna partija
@ -2234,7 +2236,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Pokreni
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Pokrenite sopstveni server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Unesite Vaše ime
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Unesite adresu računara-servera
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Pokreni novu mrežnu partiju
@ -2312,6 +2313,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Praćenje
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Server
@ -2425,6 +2429,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server j
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server se ponovo pokreće...{}Molimo sačekajte...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} je izvačen. Razlog: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Dodaci za preuzimanje
STR_CONTENT_TYPE_CAPTION :{BLACK}Vrsta

@ -1991,6 +1991,8 @@ STR_FACE_TIE :领带
STR_FACE_EARRING :耳环
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}选择领带或是耳环
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}联机游戏
@ -2044,7 +2046,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}启动
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}启动本机作为服务器
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}输入姓名
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}输入服务器地址
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}开始新的联机游戏
@ -2122,6 +2123,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :旁观
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :服务器
@ -2235,6 +2239,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}服务
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}服务器正在重新启动。{}请等待……
STR_NETWORK_MESSAGE_KICKED :*** {STRING} 被踢出服务器。原因:({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}下载内容
STR_CONTENT_TYPE_CAPTION :{BLACK}类型

@ -2060,8 +2060,9 @@ STR_FACE_TIE :Kravata:
STR_FACE_EARRING :Náušnica:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Zmeniť kravatu alebo náušnicu
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privátny
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Verejný
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Hra pre viac hráčov
@ -2115,7 +2116,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Spustiť
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Spustiť vlastný server
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Zadajte vaše meno
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Zadajte IP adresu serveru
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Spustiť novú hru pre viacero hráčov
@ -2219,6 +2219,9 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Založi
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Toto ste vy
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Toto je hosť hry
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Vyhodiť
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Ban
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Vymazať
@ -2345,6 +2348,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server u
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server sa reštartuje...{}Čakajte prosím...
STR_NETWORK_MESSAGE_KICKED :*** Hráč {STRING} bol vyhodený. Dôvod: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Sťahovanie obsahu
STR_CONTENT_TYPE_CAPTION :{BLACK}Typ

@ -2025,6 +2025,8 @@ STR_FACE_TIE :Kravata:
STR_FACE_EARRING :Uhani:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Spremeni kravato ali uhane
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Več igralcev
@ -2074,7 +2076,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Poženi
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Poženi lasten streznik
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Vpiši tvoje ime
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Vnesi naslov gostitelja
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Poženi novo igro za več igralcev
@ -2152,6 +2153,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Opazuj
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Strežnik
@ -2260,6 +2264,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} je
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Strežnik je zaprl sejo
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Strežnik se zaganja...{}Prosim počakaj...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Prenos vsebin
STR_CONTENT_TYPE_CAPTION :{BLACK}Vrsta

@ -2002,8 +2002,9 @@ STR_FACE_TIE :Corbata:
STR_FACE_EARRING :Pendientes:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Cambiar corbata o pendientes
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privado
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Público
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multijugador
@ -2057,7 +2058,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Iniciar
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Inicia un servidor nuevo
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Introduce tu nombre
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Introduce la dirección IP del servidor
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Empezar nueva partida en multijugador
@ -2161,6 +2161,9 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Crea una
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Éste eres tú
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Éste es el servidor de la partida
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Expulsar
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Prohibir el acceso
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Eliminar
@ -2288,6 +2291,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}El servi
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}El servidor está reiniciando...{}Espera por favor...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} ha sido expulsado. Razón: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Descarga de contenido
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo

@ -307,7 +307,7 @@ STR_SORT_BY_TIMETABLE_DELAY :Retraso en itin
STR_SORT_BY_FACILITY :Tipo de estación
STR_SORT_BY_WAITING_TOTAL :Carga total en espera
STR_SORT_BY_WAITING_AVAILABLE :Carga disponible en espera
STR_SORT_BY_RATING_MAX :Valoración más alta de cargamento
STR_SORT_BY_RATING_MAX :Mayor índice de carga
STR_SORT_BY_RATING_MIN :Menor índice de carga
STR_SORT_BY_ENGINE_ID :Id. locomotora (orden clásico)
STR_SORT_BY_COST :Costo
@ -336,7 +336,7 @@ STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Avance r
STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opciones
STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Guardar partida y salir del juego
STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Mostrar mapa, ventana de vista adicional o lista de carteles
STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostrar guía de pueblos
STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostrar guía de localidades
STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Mostrar subsidios
STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Mostrar lista de estaciones
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Mostrar información financiera de la empresa
@ -370,9 +370,9 @@ STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR :{YELLOW}Editor
STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD :{BLACK}Retroceder un año la fecha de inicio
STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD :{BLACK}Avanzar un año la fecha de inicio
STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Clic para establecer el año inicial
STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Mostrar mapa, guía de pueblos
STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Mostrar mapa, guía de localidades
STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Generación de terreno
STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generación de pueblos
STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generación de localidades
STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generación de industrias
STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Construcción de carreteras
STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construcción de tranvía
@ -396,7 +396,7 @@ STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Configuración
STR_SETTINGS_MENU_SCRIPT_SETTINGS :Configuración de scripts
STR_SETTINGS_MENU_NEWGRF_SETTINGS :Configuración de NewGRF
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opciones de transparencia
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostrar nombres de pueblos
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostrar nombres de localidades
STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Mostrar nombres de estaciones
STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Mostrar puntos de ruta
STR_SETTINGS_MENU_SIGNS_DISPLAYED :Mostrar carteles propios
@ -422,8 +422,8 @@ STR_MAP_MENU_LINGRAPH_LEGEND :Leyenda de fluj
STR_MAP_MENU_SIGN_LIST :Lista de carteles
############ range for town menu starts
STR_TOWN_MENU_TOWN_DIRECTORY :Guía de pueblos
STR_TOWN_MENU_FOUND_TOWN :Fundar pueblo
STR_TOWN_MENU_TOWN_DIRECTORY :Guía de localidades
STR_TOWN_MENU_FOUND_TOWN :Fundar localidad
############ range ends here
############ range for subsidies menu starts
@ -647,8 +647,8 @@ STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Número
STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Utilidad del vehículo con menores ingresos (de entre aquellos con más de 2 años)
STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Cantidad de efectivo ganado en el trimestre con la utilidad más baja de los últimos 12 trimestres
STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP :{BLACK}Cantidad de efectivo ganado en el trimestre con la utilidad más alta de los últimos 12 trimestres
STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP :{BLACK}Unidades de cargamento entregadas en los últimos cuatro trimestres
STR_PERFORMANCE_DETAIL_CARGO_TOOLTIP :{BLACK}Número de tipos de cargamento entregados en el último trimestre
STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP :{BLACK}Unidades de carga entregadas en los últimos cuatro trimestres
STR_PERFORMANCE_DETAIL_CARGO_TOOLTIP :{BLACK}Número de tipos de carga entregadas en el último trimestre
STR_PERFORMANCE_DETAIL_MONEY_TOOLTIP :{BLACK}Cantidad de dinero que esta empresa tiene en el banco
STR_PERFORMANCE_DETAIL_LOAN_TOOLTIP :{BLACK}Cantidad de dinero que esta empresa ha recibido como préstamo
STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP :{BLACK}Total de puntos ganados del máximo posible
@ -760,12 +760,12 @@ STR_SMALLMAP_LEGENDA_TREES :{TINY_FONT}{BLA
STR_SMALLMAP_LEGENDA_ROCKS :{TINY_FONT}{BLACK}Rocas
STR_SMALLMAP_LEGENDA_WATER :{TINY_FONT}{BLACK}Agua
STR_SMALLMAP_LEGENDA_NO_OWNER :{TINY_FONT}{BLACK}Sin propietario
STR_SMALLMAP_LEGENDA_TOWNS :{TINY_FONT}{BLACK}Pueblos
STR_SMALLMAP_LEGENDA_TOWNS :{TINY_FONT}{BLACK}Localidades
STR_SMALLMAP_LEGENDA_INDUSTRIES :{TINY_FONT}{BLACK}Industrias
STR_SMALLMAP_LEGENDA_DESERT :{TINY_FONT}{BLACK}Desierto
STR_SMALLMAP_LEGENDA_SNOW :{TINY_FONT}{BLACK}Nieve
STR_SMALLMAP_TOOLTIP_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Mostrar u ocultar nombres de pueblos en el mapa
STR_SMALLMAP_TOOLTIP_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Mostrar u ocultar nombres de localidades en el mapa
STR_SMALLMAP_CENTER :{BLACK}Centrar la vista en la ubicación actual
STR_SMALLMAP_INDUSTRY :{TINY_FONT}{STRING} ({NUM})
STR_SMALLMAP_LINKSTATS :{TINY_FONT}{STRING}
@ -831,14 +831,14 @@ STR_NEWS_COMPANY_LAUNCH_DESCRIPTION :{BIG_FONT}{BLAC
STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLACK}¡{STRING} ha sido adquirida por {STRING}!
STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Presidente)
STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}¡{STRING} patrocina la creación del nuevo pueblo de {TOWN}!
STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}¡El nuevo pueblo de {TOWN} ha sido formado!
STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}¡{STRING} patrocinó la creación de la nueva localidad de {TOWN}!
STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}¡La nueva localidad de {TOWN} ha sido formada!
STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}¡Nuev{G o a} {STRING} en construcción cerca de {TOWN}!
STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}¡Nuev{G o a} {STRING} fundad{G o a} cerca de {TOWN}!
STR_NEWS_INDUSTRY_CLOSURE_GENERAL :{BIG_FONT}{BLACK}¡La industria {STRING} anuncia su inminente cierre!
STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS :{BIG_FONT}{BLACK}¡Problemas con suministros provocan que {STRING} anuncie su inminente cierre!
STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS :{BIG_FONT}{BLACK}¡La falta de abastecimiento provoca que {STRING} anuncie su inminente cierre!
STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES :{BIG_FONT}{BLACK}¡La falta de árboles hace que {STRING} anuncie su inminente cierre!
STR_NEWS_EURO_INTRODUCTION :{BIG_FONT}{BLACK}¡Unión Monetaria Europea!{}{}¡El Euro es introducido como la nueva moneda oficial de todas las transacciones!
@ -961,7 +961,7 @@ STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Manejar por la
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Manejar por la derecha
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nombres de pueblos:
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Elegir el estilo de nombres para pueblos
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Elegir el estilo de nombres para las localidades
############ start of townname region
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglés
@ -1313,8 +1313,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Probabilidad de
STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ninguno*
STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducida
STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal
STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir la construcción de paradas intermedias sobre carreteras en pueblos: {STRING}
STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Construir paradas de autobuses intermedias en carreteras que sean propiedad de los pueblos
STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir la construcción de paradas intermedias en localidades: {STRING}
STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permitir la construcción de paradas intermedias en carreteras propiedad de las localidades
STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir la construcción de paradas intermedias sobre carreteras de la competencia: {STRING}
STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Construir paradas de autobuses intermedias en carreteras que sean propiedad de otras empresas
STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}No se puede cambiar esta opción si ya existen vehículos
@ -1373,7 +1373,7 @@ STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Número de indu
STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Distancia máxima de industrias petrolíferas al borde del mapa: {STRING}
STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Distancia límite desde el borde del mapa a partir del cual se pueden construir refinerías y plataformas de petróleo. En mapas con forma de isla esto garantiza que se ubiquen cerca de la costa. En mapas de más de 256 casillas el valor se amplía.
STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Nivel de inicio de nieve: {STRING}
STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Controlar la altura donde la nieve empieza en mapas de clima Subártico, lo cual afectará la generación de industrias y los requisitos de crecimiento de pueblos. Este valor se puede cambiar en el Editor de mapas o se calculará según la "Extensión de nieve"
STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Controlar la altura al que empieza la nieve en geografía de Subártico, lo cual afectará la generación de industrias y los requisitos de crecimiento de localidades. Solo puede cambiarse en el Editor de mapas, si no, se calculará según la "Extensión de nieve"
STR_CONFIG_SETTING_SNOW_COVERAGE :Extensión de nieve: {STRING}
STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Controlar la cantidad aproximada de nieve al generar un mapa de geografía de Subártico, la cual afectará la generación de industrias y los requisitos de crecimiento de las localidades. La superficie casi al ras del nivel del mar nunca tiene nieve
STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}%
@ -1529,7 +1529,7 @@ STR_CONFIG_SETTING_MAX_SHIPS :Número máximo
STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Número máximo de barcos que una empresa puede tener
STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Desactivar trenes para la computadora: {STRING}
STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Activar esta opción para deshabilitar la construcción de trenes por jugadores no humanos
STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Activar esta opción deshabilita la construcción de trenes por jugadores no humanos
STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Desactivar vehículos de carretera para la computadora: {STRING}
STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Activar esta opción deshabilita la construcción de vehículos de carretera por jugadores no humanos
STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Desactivar aeroplanos para la computadora: {STRING}
@ -1643,8 +1643,8 @@ STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL :Solo señales d
STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Solo señales de ruta
STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :Todas
STR_CONFIG_SETTING_TOWN_LAYOUT :Diseño urbano para los nuevos pueblos: {STRING}
STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT :Diseño de carreteras y calles para las redes de transporte en los pueblos
STR_CONFIG_SETTING_TOWN_LAYOUT :Diseño urbano para nuevas localidades: {STRING}
STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT :Diseño de carreteras dentro de las localidades
STR_CONFIG_SETTING_TOWN_LAYOUT_DEFAULT :Original
STR_CONFIG_SETTING_TOWN_LAYOUT_BETTER_ROADS :Mejorado
STR_CONFIG_SETTING_TOWN_LAYOUT_2X2_GRID :Rejilla de 2×2
@ -1656,8 +1656,8 @@ STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Permitir a las
STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Activar esta opción permite a las localidades construir pasos a nivel
STR_CONFIG_SETTING_NOISE_LEVEL :Permitir el ruido de aeropuertos controlado por localidades: {STRING}
STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Al desactivarse, puede haber hasta dos aeropuertos por localidad. Al activarse, el número de aeropuertos por localidad depende de su nivel de ruido permitido, el cual depende de la población, el tamaño de cada aeropuerto y la distancia
STR_CONFIG_SETTING_TOWN_FOUNDING :Fundar pueblos: {STRING}
STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Los jugadores podrán crear nuevos pueblos durante la partida
STR_CONFIG_SETTING_TOWN_FOUNDING :Fundar localidades: {STRING}
STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Activar esta opción permite a los jugadores funda nuevas localidades durante la partida
STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Prohibido
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Permitido
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Permitido, diseño urbano personalizado
@ -1700,8 +1700,8 @@ STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x
STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN :4x
STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_IN_2X :2x
STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_NORMAL :1x
STR_CONFIG_SETTING_TOWN_GROWTH :Velocidad de crecimiento de pueblos: {STRING}
STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT :A qué velocidad se expanden los pueblos
STR_CONFIG_SETTING_TOWN_GROWTH :Velocidad de crecimiento de localidades: {STRING}
STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT :A qué velocidad se expanden las localidades
STR_CONFIG_SETTING_TOWN_GROWTH_NONE :Ninguna
STR_CONFIG_SETTING_TOWN_GROWTH_SLOW :Lenta
STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :Normal
@ -2002,8 +2002,11 @@ STR_FACE_TIE :Corbata:
STR_FACE_EARRING :Aretes:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Cambiar corbata o aretes
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privado
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Local
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Público
STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Solo con invitación
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multijugador
@ -2037,6 +2040,7 @@ STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Versió
STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Dirección del servidor: {WHITE}{STRING}
STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Fecha de inicio: {WHITE}{DATE_SHORT}
STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Fecha actual: {WHITE}{DATE_SHORT}
STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Script de juego: {WHITE}{STRING} (versión {NUM})
STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}¡Protegido por contraseña!
STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}SERVIDOR APAGADO
STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVIDOR LLENO
@ -2052,12 +2056,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Buscar s
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Buscar en red local
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Buscar servidores en la red local
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Añadir servidor
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Añadir el servidor a una lista que siempre será analizada en busca de partidas activas
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Añadir el servidor a la lista. Puede ser una dirección o un código de invitación
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Iniciar servidor
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Iniciar un nuevo servidor
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Introducir nombre del jugador
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Introducir la dirección IP del servidor
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Dirección del servidor o código de invitación
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Empezar nueva partida multijugador
@ -2144,6 +2148,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Modifica
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Nombre del servidor
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Visibilidad
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Quién puede ver tu servidor en la lista pública
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Código de invitación
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Código para que otros jugadores se unan a este servidor
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Tipo de conexión
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Quién puede conectarse a tu servidor
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Jugador
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Nombre
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Tu nombre de jugador
@ -2162,6 +2170,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Este ere
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Este es el host del juego
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s}/{NUM} empresa{P "" s}
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Local
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Los jugadores remotos no pueden conectarse
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Pública
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Expulsar
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bloquear acceso
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Eliminar
@ -2289,6 +2303,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}El servi
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Se está reiniciando el servidor...{}Espera por favor...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} ha sido expulsado. Razón: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}El registro del servidor falló
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Tu servidor no permite conexiones remotas
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Otros jugadores no podrán conectarse a tu servidor
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Descarga de contenido
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo
@ -2376,7 +2394,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Transpar
STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Transparencia de puentes. Ctrl+Clic para bloquear
STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Transparencia de estructuras como faros o antenas. Ctrl+Clic para bloquear
STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Transparencia de catenaria. Ctrl+Clic para bloquear
STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Transparencia de indicadores de cargamento. Ctrl+Clic para bloquear
STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Transparencia de indicadores de embarque. Ctrl+Clic para bloquear
STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Ocultar objetos totalmente
# Linkgraph legend window
@ -2471,7 +2489,7 @@ STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Señal d
STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Señal combo (eléctrica){}Hace lo mismo que las señales de entrada y de salida, lo que permite construir amplios "árboles" de señales condicionales
STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Señal de ruta (eléctrica){}Permite a más de un tren entrar al mismo tiempo en un tramo de vía con señales, en tanto que el tren pueda reservar una ruta hasta un lugar seguro. Puede ser pasada por detrás
STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Señal de ruta de un sentido (eléctrica){}Igual que una señal de ruta pero no puede ser pasada por detrás
STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Conversión de señal{}Activar para pulsar sobre una señal existente y convertirla en el tipo y variante elegidos. Ctrl+Clic permite cambiar entre variantes de señales. Mayús+Clic muestra una estimación del precio de conversión
STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Conversión de señal{}Activar para pulsar sobre una señal existente y convertirla en el tipo y variante elegidos. Ctrl+Clic permite cambiar entre variantes de señales. Mayús+Clic muestra un precio estimado
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Distancia entre señales
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Reducir distancia entre señales
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Aumentar distancia entre señales
@ -2583,13 +2601,13 @@ STR_STATION_BUILD_NOISE :{BLACK}Ruido ge
# Landscaping toolbar
STR_LANDSCAPING_TOOLBAR :{WHITE}Modificación de terreno
STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Disminuir una esquina del terreno. Al arrastrar el ratón se reduce la primera esquina elegida y se nivela el resto del terreno seleccionado a dicha altura. Ctrl para seleccionar un área en diagonal.
STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Elevar una esquina del terreno. Al arrastrar el ratón se eleva la primera esquina elegida y se nivela el resto del terreno seleccionado a dicha altura. Ctrl para seleccionar un área en diagonal. Mayús muestra una estimación del precio
STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nivela un área de terreno a la altura de la primera esquina seleccionada. Ctrl para seleccionar un área en diagonal. Mayús muestra una estimación del precio
STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para usos futuros. Mayús muestra una estimación del precio
STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Elevar una esquina del terreno. Al arrastrar el ratón se eleva la primera esquina elegida y se nivela el resto del terreno seleccionado a dicha altura. Ctrl para seleccionar un área en diagonal. Mayús muestra un precio estimado
STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nivelar un área de terreno a la altura de la primera esquina seleccionada. Ctrl para seleccionar un área en diagonal. Mayús muestra un precio estimado
STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para usos futuros. Mayús muestra un precio estimado
# Object construction window
STR_OBJECT_BUILD_CAPTION :{WHITE}Selección de objeto
STR_OBJECT_BUILD_TOOLTIP :{BLACK}Elegir una estructura u objeto a construir. Mayús muestra una estimación del precio
STR_OBJECT_BUILD_TOOLTIP :{BLACK}Elegir una estructura u objeto a construir. Mayús muestra un precio estimado
STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Elegir el tipo de objeto o estructura a construir
STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Vista previa del objeto
STR_OBJECT_BUILD_SIZE :{BLACK}Tamaño: {GOLD}{NUM}×{NUM} casillas
@ -2626,31 +2644,31 @@ STR_QUERY_RESET_LANDSCAPE_CAPTION :{WHITE}Restaura
STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}¿Eliminar todas las propiedades de las empresas?
# Town generation window (SE)
STR_FOUND_TOWN_CAPTION :{WHITE}Creación de pueblos
STR_FOUND_TOWN_NEW_TOWN_BUTTON :{BLACK}Nuevo pueblo
STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Fundar un nuevo pueblo. Mayús muestra una estimación del precio
STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Pueblo aleatorio
STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Fundar pueblo en un lugar aleatorio
STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Muchos pueblos aleatorios
STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cubrir el mapa con pueblos colocados al azar
STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nombre del pueblo:
STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Indicar el nombre del pueblo
STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Clic para indicar el nombre del pueblo
STR_FOUND_TOWN_CAPTION :{WHITE}Generación de localidades
STR_FOUND_TOWN_NEW_TOWN_BUTTON :{BLACK}Nueva localidad
STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Fundar una nueva localidad. Mayús muestra una estimación del precio
STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Localidad aleatoria
STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Fundar la localidad en un lugar aleatorio
STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Muchas localidades aleatorias
STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cubrir el mapa con localidades colocadas al azar
STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nombre de la localidad:
STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Ingresar el nombre de la localidad
STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Clic para ingresar el nombre de la localidad
STR_FOUND_TOWN_NAME_RANDOM_BUTTON :{BLACK}Nombre aleatorio
STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP :{BLACK}Generar nuevo nombre al azar
STR_FOUND_TOWN_INITIAL_SIZE_TITLE :{YELLOW}Tamaño del pueblo:
STR_FOUND_TOWN_INITIAL_SIZE_TITLE :{YELLOW}Tamaño de la localidad:
STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON :{BLACK}Pequeño
STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON :{BLACK}Mediano
STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON :{BLACK}Grande
STR_FOUND_TOWN_SIZE_RANDOM :{BLACK}Aleatorio
STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Elegir el tamaño del pueblo
STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Elegir el tamaño de la localidad
STR_FOUND_TOWN_CITY :{BLACK}Ciudad
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Las ciudades crecen más rápido que los pueblos{}Según la configuración del juego, al ser creadas tendrán mayor población
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Las ciudades crecen más rápido que las localidades{}Según la configuración del juego, al ser creadas son más grandes
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Diseño urbano:
STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT :{BLACK}Elegir el diseño de carreteras y cuadras para este pueblo
STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT :{BLACK}Elegir el diseño urbano de esta localidad
STR_FOUND_TOWN_SELECT_LAYOUT_ORIGINAL :{BLACK}Original
STR_FOUND_TOWN_SELECT_LAYOUT_BETTER_ROADS :{BLACK}Mejorado
STR_FOUND_TOWN_SELECT_LAYOUT_2X2_GRID :{BLACK}Rejilla de 2×2
@ -2912,7 +2930,7 @@ STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Generaci
STR_MAPGEN_MAPSIZE :{BLACK}Tamaño del mapa:
STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Elegir el tamaño del mapa en número de casillas. El número real de casillas disponibles en el mapa será ligeramente inferior
STR_MAPGEN_BY :{BLACK}×
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Núm. de pueblos:
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Núm. de localidades:
STR_MAPGEN_DATE :{BLACK}Fecha:
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Núm. de industrias:
STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Cima más alta:
@ -3183,7 +3201,7 @@ STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP :{BLACK}Ir al ca
STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Indicar un nombre para el cartel
# Town directory window
STR_TOWN_DIRECTORY_CAPTION :{WHITE}Pueblos
STR_TOWN_DIRECTORY_CAPTION :{WHITE}Localidades
STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ninguno -
STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA})
STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (ciudad){BLACK} ({COMMA})
@ -3201,19 +3219,19 @@ STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL :{ORANGE}{STRING}{GREEN} entregado
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED :{ORANGE}{CARGO_TINY}/{CARGO_LONG}{RED} (todavía requerido)
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED :{ORANGE}{CARGO_TINY}/{CARGO_LONG}{GREEN} (entregado)
STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}El pueblo crece cada {ORANGE}{COMMA}{BLACK}{NBSP}día{P "" s}
STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}El pueblo crece cada {ORANGE}{COMMA}{BLACK}{NBSP}días{P "" s} (obra negra)
STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}El pueblo {RED}no{BLACK} está creciendo
STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Nivel de ruido en el pueblo: {ORANGE}{COMMA}{BLACK} Máx.: {ORANGE}{COMMA}
STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}La localidad crece cada {ORANGE}{COMMA}{BLACK}{NBSP}día{P "" s}
STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}La localidad crece cada {ORANGE}{COMMA}{BLACK}{NBSP}días{P "" s} (obra negra)
STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}La localidad {RED}no{BLACK} está creciendo
STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Nivel de ruido en la localidad: {ORANGE}{COMMA}{BLACK} máx.: {ORANGE}{COMMA}
STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centrar la vista en el pueblo. Ctrl+Clic abre una vista aparte
STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Ayuntamiento
STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}Mostrar información sobre el ayuntamiento local
STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Cambiar nombre del pueblo
STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Cambiar nombre de la localidad
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Aumentar
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Aumentar la población del pueblo
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Aumentar la población de la localidad
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Eliminar
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Eliminar este pueblo completamente
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Eliminar esta localidad completamente
STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Cambiar nombre
@ -3224,7 +3242,7 @@ STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Mostrar
STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Evaluación de empresas de transporte:
STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING}
STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Acciones disponibles:
STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP :{BLACK}Lista de acciones que pueden llevarse a cabo en este pueblo. Clic en un elemento de la lista para obtener más detalles
STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP :{BLACK}Acciones que pueden realizarse en esta localidad. Clic muestra más detalles
STR_LOCAL_AUTHORITY_DO_IT_BUTTON :{BLACK}Realizar
STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP :{BLACK}Llevar a cabo la acción elegida de la lista
@ -3237,9 +3255,9 @@ STR_LOCAL_AUTHORITY_ACTION_NEW_BUILDINGS :Pagar la constr
STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Comprar los derechos exclusivos de transporte
STR_LOCAL_AUTHORITY_ACTION_BRIBE :Sobornar al ayuntamiento
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar una pequeña campaña publicitaria local para atraer más pasajeros y cargamento a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio pequeño alrededor del centro del pueblo.{}Costo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar una campaña publicitaria local mediana para atraer más pasajeros y cargamento a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio mediano alrededor del centro del pueblo.{}Costo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Iniciar una gran campaña publicitaria local para atraer más pasajeros y cargamento a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio grande alrededor del centro del pueblo.{}Costo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar una pequeña campaña publicitaria local para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio pequeño alrededor del centro de la localidad.{}Costo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar una campaña publicitaria local mediana para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio mediano alrededor del centro de la localidad.{}Costo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Iniciar una gran campaña publicitaria local para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio grande alrededor del centro de la localidad.{}Costo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Pagar la reconstrucción de las carreteras locales.{}Provoca considerables complicaciones al tráfico hasta por 6 meses.{}Costo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construir una estatua en honor a tu empresa.{}Otorga un aumento permanente a la evaluación estaciones en este pueblo.{}Costo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Pagar la construcción de nuevos edificios comerciales en el pueblo.{}Otorga un aumento temporal a su crecimiento.{}Costo: {CURRENCY_LONG}
@ -3330,12 +3348,12 @@ STR_STATION_VIEW_ACCEPTS_BUTTON :{BLACK}Acepta
STR_STATION_VIEW_ACCEPTS_TOOLTIP :{BLACK}Lista de carga aceptada
STR_STATION_VIEW_ACCEPTS_CARGO :{BLACK}Acepta: {WHITE}{CARGO_LIST}
STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF :{BLACK}Esta estación tiene los derechos exclusivos de transporte en este pueblo.
STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY :{YELLOW}{COMPANY}{BLACK} compró los derechos exclusivos de transporte en este pueblo.
STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF :{BLACK}Esta estación tiene los derechos exclusivos de transporte en esta localidad.
STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY :{YELLOW}{COMPANY}{BLACK} compró los derechos exclusivos de transporte en esta localidad.
STR_STATION_VIEW_RATINGS_BUTTON :{BLACK}Evaluación
STR_STATION_VIEW_RATINGS_TOOLTIP :{BLACK}Ver evaluación de la estación
STR_STATION_VIEW_SUPPLY_RATINGS_TITLE :{BLACK}Suministro mensual y evaluación local:
STR_STATION_VIEW_SUPPLY_RATINGS_TITLE :{BLACK}Abastecimiento mensual y evaluación local:
STR_STATION_VIEW_CARGO_SUPPLY_RATING :{WHITE}{STRING}: {YELLOW}{COMMA}/{STRING} ({COMMA}%)
STR_STATION_VIEW_GROUP :{BLACK}Agrupar por
@ -3451,7 +3469,7 @@ STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}Construi
STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}Ver sede
STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}Ver edificio de las oficinas centrales de la empresa
STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Reubicar sede
STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Reubicar la sede de la empresa a cualquier otro lugar con el costo del 1% del valor total de la empresa. Mayús+Clic muestra una estimación del precio sin mover la sede
STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Reubicar la sede de la empresa pagando el 1% del valor total de la empresa. Mayús+Clic muestra un precio estimado sin reubicar la sede
STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Detalles
STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}Ver informe detallado de infraestructura
STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}Transferir capital
@ -3468,8 +3486,8 @@ STR_COMPANY_VIEW_PRESIDENT_NAME_TOOLTIP :{BLACK}Cambiar
STR_COMPANY_VIEW_BUY_SHARE_BUTTON :{BLACK}Comprar un 25% de las acciones
STR_COMPANY_VIEW_SELL_SHARE_BUTTON :{BLACK}Vender 25% de las acciones
STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP :{BLACK}Comprar 25% de las acciones de esta empresa. Mayús+Clic muestra una estimación del precio sin comprar ninguna acción
STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP :{BLACK}Vender 25% de las acciones de esta empresa. Mayús+Clic muestra una estimación del beneficio sin vender ninguna acción
STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP :{BLACK}Comprar 25% de las acciones de esta empresa. Mayús+Clic muestra un precio estimado sin comprar nada
STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP :{BLACK}Vender 25% de las acciones de esta empresa. Mayús+Clic muestra el ingreso estimado sin vender ninguna acción
STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION :Nombre de la empresa
STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :Nombre del presidente
@ -3649,15 +3667,15 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar
STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar y reformar barco
STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar y reformar aeronave
STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar el tren elegido. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar el vehículo de carretera elegido. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar el barco elegido. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar la aeronave elegida. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar el tren elegido. Mayús+Clic muestra un precio estimado sin comprar nada
STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar el vehículo de carretera elegido. Mayús+Clic muestra un precio estimado sin comprar nada
STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar el barco elegido. Mayús+Clic muestra un precio estimado sin comprar nada
STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar la aeronave elegida. Mayús+Clic muestra un precio estimado sin comprar nada
STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar tren seleccionado. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar vehículo seleccionado. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar barco seleccionado. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar areonave seleccionada. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el tren elegido. Mayús+Clic muestra un precio estimado sin comprar nada
STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el vehículo de carretera elegido. Mayús+Clic muestra un precio estimado sin comprar nada
STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el barco elegido. Mayús+Clic muestra un precio estimado sin comprar nada
STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar la areonave seleccionada. Mayús+Clic muestra un precio estimado sin realizar la compra
STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Cambiar nombre
STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Cambiar nombre
@ -3737,10 +3755,10 @@ STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}Clonar
STR_DEPOT_CLONE_SHIP :{BLACK}Clonar
STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Clonar
STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Esto comprará una copia idéntica del tren, incluyendo todos sus vagones y carros. Clic en este botón y después en el tren a copiar. Ctrl+Clic para compartir las órdenes. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Esto comprará una copia idéntica del vehículo de carretera. Clic en este botón y después en el vehículo a copiar. Ctrl+Clic para compartir las órdenes. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Esto comprará una copia idéntica del barco. Clic en este botón y después en el barco a copiar. Ctrl+Clic para compartir las órdenes. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Esto comprará una copia idéntica de la aeronave. Clic en este botón y después en la aeronave a copiar. Ctrl+Clic para compartir las órdenes. Mayús+Clic muestra una estimación del precio sin realizar la compra
STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Esto comprará una copia del tren y sus vagones. Clic en este botón y después en el tren a copiar. Ctrl+Clic para compartir las órdenes. Mayús+Clic muestra un precio estimado sin comprar nada
STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Esto comprará una copia del vehículo de carretera. Clic en este botón y después en el vehículo a copiar. Ctrl+Clic para compartir las órdenes. Mayús+Clic muestra un precio estimado sin comprar nada
STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Esto comprará una copia del barco. Clic en este botón y después en el barco a copiar. Ctrl+Clic para compartir las órdenes. Mayús+Clic muestra un precio estimado sin comprar nada
STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Esto comprará una copia de la aeronave. Clic en este botón y después en la aeronave a copiar. Ctrl+Clic para compartir las órdenes. Mayús+Clic muestra un precio estimado sin comprar nada
STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Centrar la vista en el depósito de trenes. Ctrl+Clic abre una vista aparte
STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Centrar la vista en el depósito de vehículos. Ctrl+Clic abre una vista aparte
@ -4354,8 +4372,8 @@ STR_GAME_SAVELOAD_NOT_AVAILABLE :<no disponible>
STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}La partida fue guardada en una versión que no admite tranvías. Todos los tranvías serán eliminados
# Map generation messages
STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}Generación de mapa abortada...{}... no hay ubicaciones apropiadas para colocar pueblos
STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... no hay pueblos en el mapa
STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}Generación de mapa abortada...{}... no hay ubicaciones apropiadas para localidades
STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... no hay localidades en el mapa
STR_ERROR_PNGMAP :{WHITE}No se puede cargar mapa desde PNG...
STR_ERROR_PNGMAP_FILE_NOT_FOUND :{WHITE}... archivo no encontrado
@ -4407,7 +4425,7 @@ STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}No permi
# Local authority errors
STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS :{WHITE}El ayuntamiento de {TOWN} se opone a esta acción
STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT :{WHITE}El ayuntamiento de {TOWN} se opone a la construcción de otro aeropuerto en este pueblo
STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT :{WHITE}El ayuntamiento de {TOWN} se opone a la construcción de otro aeropuerto en esta localidad
STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE :{WHITE}El ayuntamiento de {TOWN} se opone a otorgar permiso para la construcción del aeropuerto debido a cuestiones de ruido
STR_ERROR_BRIBE_FAILED :{WHITE}El intento de soborno ha sido descubierto por un investigador de la zona
@ -4439,18 +4457,18 @@ STR_ERROR_CAN_T_SELL_25_SHARE_IN :{WHITE}No se pu
STR_ERROR_PROTECTED :{WHITE}Esta empresa es muy reciente para comerciar con acciones...
# Town related errors
STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}No se puede crear ningún pueblo
STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}No se puede cambiar nombre del pueblo...
STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}No se puede crear pueblo aquí...
STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}No se puede expandir el pueblo...
STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}No se puede crear ninguna localidad
STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}No se puede cambiar nombre de la localidad...
STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}No se puede crear localidad aquí...
STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}No se puede expandir la localidad...
STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... demasiado cerca del borde del mapa
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado cerca de otro pueblo
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiados pueblos
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado cerca de otra localidad
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiadas localidades
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ya no hay espacio en el mapa
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}El pueblo no construirá carreteras. La función de construcción de carreteras puede activarse en Configuración->Ambiente->Pueblos
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La localidad no construirá carreteras. Se puede activar esta función en Configuración->Ambiente->Localidades
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obras de carretera en progreso
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}No se puede eliminar este pueblo...{}Aún tiene estaciones o depósitos vinculados, o una casilla en su jurisdicción no se puede quitar
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... no hay ningún lugar apto para una estatua en el centro de este pueblo
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}No se puede eliminar esta localidad...{}Aún tiene una estación o depósito, o una de sus casillas no se puede quitar
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... no hay lugar apto para una estatua en el centro de esta localidad
# Industry related errors
STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... demasiadas industrias
@ -4458,13 +4476,13 @@ STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}No se pu
STR_ERROR_CAN_T_BUILD_HERE :{WHITE}No se puede construir {STRING} aquí...
STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}No se puede construir este tipo de industria aquí...
STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... demasiado cerca de otra industria
STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... primero se debe crear al menos un pueblo
STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... solo se permite una por pueblo
STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... solo se puede construir en pueblos de al menos 1,200 habitantes
STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... primero se debe crear al menos una localidad
STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... solo se permite una por localidad
STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... solo se puede construir en localidades de al menos 1,200 habitantes
STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}... solo se puede construir en áreas de selva
STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}... solo se puede construir en áreas desérticas
STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... solo se puede construir en pueblos (reemplazando casas)
STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER :{WHITE}... solo se puede construir cerca del centro de un pueblo
STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... solo se puede construir en localidades (reemplazando casas)
STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER :{WHITE}... solo se puede construir cerca del centro de una localidad
STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS :{WHITE}... solo se puede construir en zonas bajas
STR_ERROR_CAN_ONLY_BE_POSITIONED :{WHITE}... solo se puede situar cerca de los bordes del mapa
STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... los bosques solo se pueden plantar sobre la nieve
@ -4492,7 +4510,7 @@ STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Demasiad
STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Demasiado cerca de otro muelle
STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Demasiado cerca de otro aeropuerto
STR_ERROR_CAN_T_RENAME_STATION :{WHITE}No se puede cambiar nombre de la estación...
STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... esta carretera es propiedad de un pueblo
STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... esta carretera es propiedad de una localidad
STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... carretera en el sentido incorrecto
STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... las estaciones y paradas intermedias no pueden ponerse sobre esquinas
STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... las estaciones y paradas intermedias no pueden ponerse sobre intersecciones

@ -2001,8 +2001,11 @@ STR_FACE_TIE :Slips:
STR_FACE_EARRING :Örhänge:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Ändra slips eller örhänge
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privat
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Lokal
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Offentlig
STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Endast inbjudna
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Flera spelare
@ -2051,12 +2054,12 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Sök onl
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Sök LAN
STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Sök i lokalt nätverk för servrar
STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Lägg till server
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Lägg till en server till listan som alltid kommer kontrolleras för aktiva spel
STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Lägger till en server i listan. Denna kan antingen vara en serveradress eller en inbjudningskod
STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Starta server
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Starta en server för andra att ansluta till
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Mata in ditt namn
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}IP-adressen till servern
STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Ange serveradress eller inbjudningskod
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Starta ett nytt spel i flerspelarläge
@ -2143,6 +2146,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Ändra d
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Serverns namn
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Synlighet
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Huruvida andra människor kan se din server i den offentliga listan
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Inbjudningskod
STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Inbjudningskod som andra spelare kan använda för att ansluta till denna server
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Anslutningstyp
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Huruvida, och i så fall hur, din server kan nås av andra
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Spelare
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Namn
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Ditt spelarnamn
@ -2161,6 +2168,12 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Det här
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Det här är spelets värd
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" er} / {NUM} företag
############ Begin of ConnectionType
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Lokal
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Fjärran belägna spelare kan inte ansluta
STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Offentlig
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kasta ut
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bannlys
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Ta bort
@ -2288,6 +2301,10 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Servern
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Servern startar om...{}Var vänlig vänta...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} kastades ut. Orsak: ({STRING})
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Serverregistrering misslyckades
STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Din server tillåter inte fjärranslutningar
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Andra spelare kommer ej ha möjlighet att ansluta till din server
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Nedladdning av innehåll
STR_CONTENT_TYPE_CAPTION :{BLACK}Typ

@ -1736,6 +1736,8 @@ STR_FACE_TIE :Tie:
STR_FACE_EARRING :கம்மல்:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Tie அல்லது காதணியை மாற்றவும்
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}பல்வீரர்
@ -1857,6 +1859,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :கவனி
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :சர்வர்
@ -1965,6 +1970,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}சர
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}சர்வர் மீண்டும் தொடங்குகிறது...{}சற்று பொறுக்கவும்...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} வெளியேற்றப்பட்டார். காரணம்: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}கோப்புகள் பதிவிறக்கம் செய்யப்படுகின்றன
STR_CONTENT_TYPE_CAPTION :{BLACK}வகை

@ -1820,6 +1820,8 @@ STR_FACE_TIE :เนคไท
STR_FACE_EARRING :ต่างหู:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}เปลี่ยนเนคไทหรือต่างหู
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}เล่นหลายคน
@ -1869,7 +1871,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}เร
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}เริ่มเซิร์ฟเวอร์ใหม่ของคุณ
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}ป้อนชื่อของคุณ
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}ป้อนที่อยู่ของโฮสต์
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}เริ่มเกมผู้เล่นหลายคนใหม่
@ -1947,6 +1948,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :ผู้ชม
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :เซิฟเวอร์
@ -2055,6 +2059,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING}
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}เซิฟเวอร์ปืดเซสซั่นนี้
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}เซิฟเวอร์กำลังทำการเริ่มต้นใหม่...{}กรุณารอซักครู่...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}กำลังโหลดเนื้อหา
STR_CONTENT_TYPE_CAPTION :{BLACK}ประเภท

@ -1881,6 +1881,8 @@ STR_FACE_TIE :領帶:
STR_FACE_EARRING :耳飾:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}改變領帶或耳飾
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}多人遊戲
@ -1932,7 +1934,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}起動
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}起動您自己的伺服器
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}輸入您的名稱
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}輸入主機位址
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}開始新的多人遊戲
@ -2012,6 +2013,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :旁觀者
STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}多人遊戲
STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}伺服器
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :踢出
@ -2122,6 +2126,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}伺服
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}伺服器重新啟動中...{}請稍候...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} 已被踢出。原因:({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}內容下載中
STR_CONTENT_TYPE_CAPTION :{BLACK}種類

@ -1992,8 +1992,9 @@ STR_FACE_TIE :Kravat:
STR_FACE_EARRING :Küpe:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Kravatı veya küpeyi değiştir
STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Özel
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Halka açık
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Çok Oyunculu
@ -2047,7 +2048,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Sunucu b
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Kendi sunucunu başlat
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}İsminizi girin
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Sunucunun adresini girin
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Yeni çok oyunculu oyun başlat
@ -2151,6 +2151,9 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Yeni bir
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Bu sensin
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Bu, oyunun ev sahibi
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :At
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Yasakla
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Sil
@ -2277,6 +2280,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Sunucu k
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Sunucu baştan başlatılıyor...{}Lütfen bekleyin...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} atıldı. Sebep: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}İçerik indirme
STR_CONTENT_TYPE_CAPTION :{BLACK}Tür

@ -2114,6 +2114,8 @@ STR_FACE_TIE :Краватк
STR_FACE_EARRING :Сережки:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Змінити комір або сережки
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Мережева гра
@ -2167,7 +2169,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Ство
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Створити ваш власний сервер
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Введіть ваше ім'я
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Введіть адресу сервера
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Створити нову мережеву гру
@ -2245,6 +2246,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Спостер
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Сервер
@ -2358,6 +2362,7 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Серв
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Перезавантаження сервера...{}Зачекайте...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} відключено. Причина: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Завантаження вмісту
STR_CONTENT_TYPE_CAPTION :{BLACK}Тип

@ -1482,6 +1482,8 @@ STR_FACE_TIE :ٹائی:
STR_FACE_EARRING :بالیاں:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}ٹائی یا بالیاں بدلیں
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}زیادہ کھلاڑی
@ -1531,7 +1533,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}سرور
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}اپنا سرور خود شروع کریں
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}اپنا نام لکھیں
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}ہوسٹ کا ایڈریس لکھیں
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}نیا زیادہ کھلاڑیوں والا کھیل شروع کریں
@ -1609,6 +1610,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :{WHITE}نظار
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :سرور
@ -1717,6 +1721,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ن
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}سرور نے سیشن بند کر دیا
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}سرور دوبارہ سے سٹارٹ ہو رہا ہے - - -{}برائے مہربانی انتظار فرمائیے ۔ ۔ ۔
# Content downloading window
STR_CONTENT_TITLE :{WHITE}مواد ڈاون لوڈ کیا جا رہا ہے
STR_CONTENT_TYPE_CAPTION :{BLACK}طرذ

@ -889,6 +889,11 @@ STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}{STATION
STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}Lời đề nghị trợ cấp đã hết hạn:{}{}{STRING} từ {STRING} đến {STRING} bây giờ sẽ không có trợ cấp.
STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}Trợ cấp đã hết:{}{}Dịch vụ vận chuyển {STRING} từ {STRING} đến {STRING} sẽ không được trợ cấp nữa.
STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Đề nghị trợ cấp:{}{}Dịch vụ vận tải {STRING} đầu tiên từ {STRING} đến {STRING} sẽ nhận được tiền trợ cấp trong {NUM} năm của chính quyền địa phương!
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Trợ cấp dịch vụ được trao cho {STRING}!{}{}Dịch vụ {STRING} từ {STRING} đến {STRING} sẽ thu lợi cao hơn 50% trong vòng {NUM} năm tới!
STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Trợ cấp dịch vụ được trao cho {STRING}!{}{}Dịch vụ {STRING} từ {STRING} đến {STRING} sẽ thu lợi gấp đôi trong vòng {NUM} năm tới!
STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Trợ cấp dịch vụ được trao cho {STRING}!{}{}Dịch vụ {STRING} từ {STRING} đến {STRING} sẽ thu lợi gấp ba trong vòng {NUM} năm tới!
STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Trợ cấp dịch vụ được trao cho {STRING}!{}{}Dịch vụ {STRING} từ {STRING} đến {STRING} sẽ thu lợi gấp tư trong vòng {NUM} năm tới!
STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}Giao thông hỗn loạn tại {TOWN}!{}{}Chương trình sửa đường đầu tư bởi {STRING} mang 6 tháng khốn đốn cho người chạy mô tô!
STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}Độc quyền vận tải!
@ -954,7 +959,7 @@ STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaysi
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Lái bên trái
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Lái bên phải
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Tên thị trấn
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Tên thị trấn:
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Lựa chọn kiểu tên thị trấn
############ start of townname region
@ -994,6 +999,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :Hàng năm
STR_GAME_OPTIONS_LANGUAGE :{BLACK}Ngôn ngữ
STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Lựa chọn sử dụng ngôn ngữ giao diện
STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} (hoàn thành {NUM}%)
STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Toàn màn hình
STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Đánh dấu vào ô này để chơi OpenTTD ở chế độ fullscreen
@ -1007,6 +1013,8 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}Tăng t
STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}Đánh dấu vào ô này để cho phép OpenTTD thử sử dụng tăng tốc phần cứng. Sẽ có tác dụng sau khi khởi động lại trò chơi
STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Thiết lập chỉ có tác dụng sau khi khởi động lại trò chơi
STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync
STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Đánh dấu vào ô này để bật tính năng v-sync cho màn hình. Sẽ có tác dụng sau khi khởi động lại trò chơi. Chỉ có thể hoạt động khi tăng tốc phần cứng được bật
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Kích thước giao diện
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Chọn kích thước của các đối tượng trên giao diện
@ -1201,6 +1209,10 @@ STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Mức hỏng h
STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :Thiết lập mức độ hỏng hóc đối với phương tiện không bảo trì thường xuyên
STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :Tỉ lệ chi trả: {STRING}
STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Thiết lập mức chi trả cho tuyến vận chuyển phụ trợ
STR_CONFIG_SETTING_SUBSIDY_DURATION :Thời hạn trợ cấp: {STRING}
STR_CONFIG_SETTING_SUBSIDY_DURATION_HELPTEXT :Đặt số năm được hưởng trợ cấp dịch vụ
STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE :{NUM} năm
STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Không có trợ cấp
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Chi phí xây dựng: {STRING}
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Thiết lập mức độ xây dựng và chi phí mua sắm
STR_CONFIG_SETTING_RECESSIONS :Suy thoái: {STRING}
@ -1654,7 +1666,7 @@ STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Tỉ lệ bình
STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Tuyến tính
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Trồng cây trong trò chơi: {STRING}
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Điều khiển sự xuất hiện tự dộng của cây cối khi đang chơi. Điều này có thể ảnh hưởng đến những nhà máy dựa vào cây cối, ví dự như nhà máy chế biến gỗgỗ
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Điều khiển sự xuất hiện tự dộng của cây cối khi đang chơi. Điều này có thể ảnh hưởng đến những nhà máy dựa vào cây cối, ví dự như nhà máy chế biến gỗ
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :Mọc nhưng không trải {RED}(nhà máy chế biến gỗ sẽ không hoạt động)
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :Mọc nhưng chỉ trải ở rừng nhiệt đới
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_ALL :Mọc và trải mọi nơi
@ -1832,7 +1844,7 @@ STR_INTRO_LOAD_GAME :{BLACK}Nạp V
STR_INTRO_PLAY_SCENARIO :{BLACK}Chơi Màn Chơi Kịch Bản
STR_INTRO_PLAY_HEIGHTMAP :{BLACK}Chơi Bản Đồ Địa Hình
STR_INTRO_SCENARIO_EDITOR :{BLACK}Biên Tập Màn Chơi Kịch Bản
STR_INTRO_MULTIPLAYER :{BLACK}Chơi Trên Mạng
STR_INTRO_MULTIPLAYER :{BLACK}Nhiều Người Chơi
STR_INTRO_GAME_OPTIONS :{BLACK}Cấu Hình Trò Chơi
STR_INTRO_HIGHSCORE :{BLACK}Bảng điểm chơi cao nhất
@ -1847,7 +1859,7 @@ STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Tải tr
STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Chơi ván mới, dùng bản đồ địa hình làm nền đất
STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Chơi ván mới, dùng màn chơi kịch bản theo ý riêng
STR_INTRO_TOOLTIP_SCENARIO_EDITOR :{BLACK}Tạo màn chơi kịch bản/bản đồ theo ý riêng
STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}Bắt đầu chơi trên mạng nhiều người
STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}Bắt đầu ván chơi trên mạng nhiều người
STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}Chọn kiểu quang cảnh 'ôn hòa'
STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Chọn kiểu quang cảnh 'giá rét'
@ -1989,6 +2001,9 @@ STR_FACE_TIE :Cà vạt:
STR_FACE_EARRING :Bông tai:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Thay đổi cà vạt hoặc bông tai
############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Công khai
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Ván Chơi Mạng
@ -2042,7 +2057,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Tạo se
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Tạo server của riêng bạn
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Gõ tên của bạn
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Gõ địa chỉ của server
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Bắt đầu ván chơi mạng nhiều người
@ -2052,6 +2066,8 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Tên c
STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Đặt mật khẩu
STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Bảo vệ game của bạn bằng mật khẩu nếu bạn không muốn người khác vào tùy tiện
STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Hiển thị
STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Cho phép người khác thấy server của bạn trong danh sách công khai
STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} máy trạm
STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Số máy trạm tối đa:
STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Chọn số lượng máy trạm tối đa. Không nhất thiết phải chọn đầy các dòng
@ -2115,14 +2131,49 @@ STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server y
STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Công ty yêu cầu xác thực. Nhập mật khẩu
# Network company list added strings
STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Danh sách máy trạm
STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Người chơi trực tuyến
STR_NETWORK_COMPANY_LIST_SPECTATE :Xem
# Network client list
STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Chế độ nhiều người chơi
STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}Server
STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Tên
STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Tên server mà bạn đang chơi
STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Sửa tên server
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Tên của server
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Hiển thị
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Cho phép người khác thấy server của bạn trong danh sách công khai
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Người chơi
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Tên
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Tên người chơi
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}Sửa tên người chơi
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Tên người chơi
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Các tác vụ quản lý thực hiện cho client này
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Các tác vụ quản lý thực hiện cho công ty này
STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Gia nhập công ty này
STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Gửi tin nhắn tới người chơi này
STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Gửi tin nhắn tới tất cả người chơi trong công ty này
STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Gửi tin nhắn tới tất cả người xem
STR_NETWORK_CLIENT_LIST_SPECTATORS :Người xem
STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Công ty mới)
STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Khai sinh một công ty và gia nhập
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Đây là bạn
STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Đây là người tổ chức ván chơi
STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} người chơi / {NUM} công ty
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Đá ra
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Cấm
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Xoá
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Mật khẩu công ty
STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Tác vụ quản lý
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Bạn có muốn đá người chơi '{STRING}' ra?
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Bạn có muốn cấm người chơi '{STRING}'?
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Bạn có muốn xoá công ty '{COMPANY}'?
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Bạn có muốn đặt lại mật khẩu cho công ty '{COMPANY}'?
STR_NETWORK_SERVER :Server
STR_NETWORK_CLIENT :Máy trạm
@ -2167,6 +2218,8 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}Không t
STR_NETWORK_ERROR_CLIENT_START :{WHITE}Không thể tạo kết nối
STR_NETWORK_ERROR_TIMEOUT :{WHITE}Kết nối #{NUM} quá lâu
STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Có lỗi trong giao thức và kết nối bị đóng
STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Bạn chưa đặt tên người chơi. Bạn có thể đặt tên này tại phía trên của cửa sổ Chơi trên mạng
STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}Bạn chưa đặt tên server. Bạn có thể đặt tên này tại phía trên của cửa sổ Chơi trên mạng
STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Phiên bản của máy trạm không hợp với phiên bản máy server
STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Sai mật khẩu
STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Server bị đầy
@ -2179,6 +2232,8 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Bạn nh
STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Máy của bạn quá chậm để có thể theo kịp máy chủ
STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Thời gian tải bản đồ quá lâu
STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Thời gian tham gia máy chủ quá lâu
STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Tên người chơi không hợp lệ
STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}Server được yêu cầu dùng phiên bản cũ hơn so với client
############ Leave those lines in this order!!
STR_NETWORK_ERROR_CLIENT_GENERAL :lỗi chung
@ -2201,6 +2256,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :không nhận
STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :lỗi quá thời gian
STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :tải bản đồ quá thời gian
STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :xử lý bản đồ quá thời gian
STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :tên client không đúng
############ End of leave-in-this-order
STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Kết nối có thể đã bị mất
@ -2229,12 +2285,13 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} gi
STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} vào xem ván chơi
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} khai trương công ty mới (#{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} rời bỏ ván chơi ({2:STRING})
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} đổi tên thành {STRING}
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} đã đổi tên thành {STRING}
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} tặng {2:CURRENCY_LONG} cho {1:STRING}
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server kết thúc phiên
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server khởi động lại...{}Xin chờ...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} đã bị đá khỏi ván chơi. Lý do: ({STRING})
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Đang tải nội dung
STR_CONTENT_TYPE_CAPTION :{BLACK}Kiểu
@ -3044,6 +3101,7 @@ STR_NEWGRF_ERROR_MSG_WARNING :{RED}Cảnh bá
STR_NEWGRF_ERROR_MSG_ERROR :{RED}Lỗi: {SILVER}{STRING}
STR_NEWGRF_ERROR_MSG_FATAL :{RED}Lỗi nghiêm trọng: {SILVER}{STRING}
STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Xảy ra lỗi NewGRF nghiêm trọng:{}{STRING}
STR_NEWGRF_ERROR_POPUP :{WHITE}Có lỗi NewGRF xảy ra:{}{STRING}
STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} sẽ không hoạt động với phiên bản TTDPatch version theo như báo cáo của OpenTTD.
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} để dành cho phiên bản {STRING} của TTD.
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} được thiết kế để xài với {STRING}
@ -3521,7 +3579,7 @@ STR_GROUP_CREATE_TOOLTIP :{BLACK}Ấn và
STR_GROUP_DELETE_TOOLTIP :{BLACK}Xoá nhóm đã chọn
STR_GROUP_RENAME_TOOLTIP :{BLACK}Đổi tên nhóm
STR_GROUP_LIVERY_TOOLTIP :{BLACK}Thay đổi phục trang cho nhóm được chọn
STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Không để nhóm này tự thay thế (thiết lập chung) khi hết hạn
STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Không để nhóm này tự thay thế (thiết lập chung) khi hết hạn. Ctrl+Click để áp dụng lên nhóm con.
STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Xóa Nhóm
STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Bạn có chắc chắn muốn xóa nhóm này và tất cả con của nó?
@ -3774,7 +3832,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Đầu máy đ
STR_REPLACE_ROAD_VEHICLES :Các xe ô-tô
STR_REPLACE_TRAM_VEHICLES :Các xe điện
STR_REPLACE_REMOVE_WAGON :{BLACK}Xoá bỏ toa xe ({STRING}): {ORANGE}{STRING}
STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Tự động thay thế sẽ giữ nguyên độ dài đoàn tàu bằng cách bỏ bớt toa xe (bỏ từ phía đầu), nếu như việc thay thế đầu máy làm đoàn tàu dài hơn.
STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+Click để áp dụng cho nhóm con
# Vehicle view
STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE}

@ -1877,6 +1877,8 @@ STR_FACE_TIE :Tei:
STR_FACE_EARRING :Clustlws:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Newid tei neu glustlws
############ Next lines match ServerGameType
############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Amlchwaraewr
@ -1926,7 +1928,6 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Dechrau
STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Dechrau eich gweinydd eich hun
STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Rhowch eich enw
STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Rhowch gyfeiriad y gwesteiwr
# Start new multiplayer server
STR_NETWORK_START_SERVER_CAPTION :{WHITE}Dechrau gêm newydd amlchwaraewr
@ -2004,6 +2005,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :Gwylio
# Network client list
############ Begin of ConnectionType
############ End of ConnectionType
STR_NETWORK_SERVER :Gweinydd
@ -2112,6 +2116,7 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :*** Mae {STRING
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Fe gaewyd y sesiwn gan y gweinydd
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Mae'r gweinydd yn ailgychwyn...{}Arhoswch...
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Llawrlwytho cynnwys
STR_CONTENT_TYPE_CAPTION :{BLACK}Math

@ -14,6 +14,8 @@ add_files(
network_content.h
network_content_gui.cpp
network_content_gui.h
network_coordinator.cpp
network_coordinator.h
network_func.h
network_gamelist.cpp
network_gamelist.h
@ -22,6 +24,8 @@ add_files(
network_internal.h
network_server.cpp
network_server.h
network_stun.cpp
network_stun.h
network_type.h
network_udp.cpp
network_udp.h

@ -1,6 +1,7 @@
add_files(
address.cpp
address.h
config.cpp
config.h
core.cpp
core.h
@ -20,11 +21,15 @@ add_files(
tcp_content.cpp
tcp_content.h
tcp_content_type.h
tcp_coordinator.cpp
tcp_coordinator.h
tcp_game.cpp
tcp_game.h
tcp_http.cpp
tcp_http.h
tcp_listen.h
tcp_stun.cpp
tcp_stun.h
udp.cpp
udp.h
)

@ -10,6 +10,7 @@
#include "../../stdafx.h"
#include "address.h"
#include "../network_internal.h"
#include "../../debug.h"
#include "../../safeguards.h"
@ -335,13 +336,12 @@ static SOCKET ListenLoopProc(addrinfo *runp)
DEBUG(net, 1, "Setting no-delay mode failed: %s", NetworkError::GetLast().AsString());
}
int on = 1;
/* The (const char*) cast is needed for windows!! */
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) == -1) {
if (!SetReusePort(sock)) {
DEBUG(net, 0, "Setting reuse-address mode failed: %s", NetworkError::GetLast().AsString());
}
#ifndef __OS2__
int on = 1;
if (runp->ai_family == AF_INET6 &&
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) == -1) {
DEBUG(net, 3, "Could not disable IPv4 over IPv6: %s", NetworkError::GetLast().AsString());
@ -422,6 +422,38 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets)
}
}
/**
* Get the peer address of a socket as NetworkAddress.
* @param sock The socket to get the peer address of.
* @return The NetworkAddress of the peer address.
*/
/* static */ NetworkAddress NetworkAddress::GetPeerAddress(SOCKET sock)
{
sockaddr_storage addr = {};
socklen_t addr_len = sizeof(addr);
if (getpeername(sock, (sockaddr *)&addr, &addr_len) != 0) {
DEBUG(net, 0, "Failed to get address of the peer: %s", NetworkError::GetLast().AsString());
return NetworkAddress();
}
return NetworkAddress(addr, addr_len);
}
/**
* Get the local address of a socket as NetworkAddress.
* @param sock The socket to get the local address of.
* @return The NetworkAddress of the local address.
*/
/* static */ NetworkAddress NetworkAddress::GetSockAddress(SOCKET sock)
{
sockaddr_storage addr = {};
socklen_t addr_len = sizeof(addr);
if (getsockname(sock, (sockaddr *)&addr, &addr_len) != 0) {
DEBUG(net, 0, "Failed to get address of the socket: %s", NetworkError::GetLast().AsString());
return NetworkAddress();
}
return NetworkAddress(addr, addr_len);
}
/**
* Get the peer name of a socket in string format.
* @param sock The socket to get the peer name of.
@ -429,8 +461,27 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets)
*/
/* static */ const std::string NetworkAddress::GetPeerName(SOCKET sock)
{
sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
getpeername(sock, (sockaddr *)&addr, &addr_len);
return NetworkAddress(addr, addr_len).GetAddressAsString();
return NetworkAddress::GetPeerAddress(sock).GetAddressAsString();
}
/**
* Convert a string containing either "hostname", "hostname:port" or invite code
* to a ServerAddress, where the string can be postfixed with "#company" to
* indicate the requested company.
*
* @param connection_string The string to parse.
* @param default_port The default port to set port to if not in connection_string.
* @param company Pointer to the company variable to set iff indicated.
* @return A valid ServerAddress of the parsed information.
*/
/* static */ ServerAddress ServerAddress::Parse(const std::string &connection_string, uint16 default_port, CompanyID *company_id)
{
if (StrStartsWith(connection_string, "+")) {
std::string_view invite_code = ParseCompanyFromConnectionString(connection_string, company_id);
return ServerAddress(SERVER_ADDRESS_INVITE_CODE, std::string(invite_code));
}
uint16 port = default_port;
std::string_view ip = ParseFullConnectionString(connection_string, port, company_id);
return ServerAddress(SERVER_ADDRESS_DIRECT, std::string(ip) + ":" + std::to_string(port));
}

@ -12,6 +12,7 @@
#include "os_abstraction.h"
#include "config.h"
#include "../../company_type.h"
#include "../../string_func.h"
#include "../../core/smallmap_type.hpp"
@ -175,6 +176,8 @@ public:
static const char *SocketTypeAsString(int socktype);
static const char *AddressFamilyAsString(int family);
static NetworkAddress GetPeerAddress(SOCKET sock);
static NetworkAddress GetSockAddress(SOCKET sock);
static const std::string GetPeerName(SOCKET sock);
};
@ -191,4 +194,38 @@ private:
char buf[NETWORK_HOSTNAME_PORT_LENGTH + 7];
};
/**
* Types of server addresses we know.
*
* Sorting will prefer entries at the top of this list above ones at the bottom.
*/
enum ServerAddressType {
SERVER_ADDRESS_DIRECT, ///< Server-address is based on an hostname:port.
SERVER_ADDRESS_INVITE_CODE, ///< Server-address is based on an invite code.
};
/**
* Address to a game server.
*
* This generalises addresses which are based on different identifiers.
*/
class ServerAddress {
private:
/**
* Create a new ServerAddress object.
*
* Please use ServerAddress::Parse() instead of calling this directly.
*
* @param type The type of the ServerAdress.
* @param connection_string The connection_string that belongs to this ServerAddress type.
*/
ServerAddress(ServerAddressType type, const std::string &connection_string) : type(type), connection_string(connection_string) {}
public:
ServerAddressType type; ///< The type of this ServerAddress.
std::string connection_string; ///< The connection string for this ServerAddress.
static ServerAddress Parse(const std::string &connection_string, uint16 default_port, CompanyID *company_id = nullptr);
};
#endif /* NETWORK_CORE_ADDRESS_H */

@ -0,0 +1,69 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file config.cpp Configuration of the connection strings for network stuff using environment variables.
*/
#include "../../stdafx.h"
#include <cstdlib>
#include "../../string_func.h"
#include "../../safeguards.h"
/**
* Get the environment variable using std::getenv and when it is an empty string (or nullptr), return a fallback value instead.
* @param variable The environment variable to read from.
* @param fallback The fallback in case the environment variable is not set.
* @return The environment value, or when that does not exist the given fallback value.
*/
static const char *GetEnv(const char *variable, const char *fallback)
{
const char *value = std::getenv(variable);
return StrEmpty(value) ? fallback : value;
}
/**
* Get the connection string for the game coordinator from the environment variable OTTD_COORDINATOR_CS,
* or when it has not been set a hard coded default DNS hostname of the production server.
* @return The game coordinator's connection string.
*/
const char *NetworkCoordinatorConnectionString()
{
return GetEnv("OTTD_COORDINATOR_CS", "coordinator.openttd.org");
}
/**
* Get the connection string for the STUN server from the environment variable OTTD_STUN_CS,
* or when it has not been set a hard coded default DNS hostname of the production server.
* @return The STUN server's connection string.
*/
const char *NetworkStunConnectionString()
{
return GetEnv("OTTD_STUN_CS", "stun.openttd.org");
}
/**
* Get the connection string for the content server from the environment variable OTTD_CONTENT_SERVER_CS,
* or when it has not been set a hard coded default DNS hostname of the production server.
* @return The content server's connection string.
*/
const char *NetworkContentServerConnectionString()
{
return GetEnv("OTTD_CONTENT_SERVER_CS", "content.openttd.org");
}
/**
* Get the connection string for the content mirror from the environment variable OTTD_CONTENT_MIRROR_CS,
* or when it has not been set a hard coded default DNS hostname of the production server.
* @return The content mirror's connection string.
*/
const char *NetworkContentMirrorConnectionString()
{
return GetEnv("OTTD_CONTENT_MIRROR_CS", "binaries.openttd.org");
}

@ -12,26 +12,24 @@
#ifndef NETWORK_CORE_CONFIG_H
#define NETWORK_CORE_CONFIG_H
/** DNS hostname of the masterserver */
static const char * const NETWORK_MASTER_SERVER_HOST = "master.openttd.org";
/** DNS hostname of the content server */
static const char * const NETWORK_CONTENT_SERVER_HOST = "content.openttd.org";
/** DNS hostname of the HTTP-content mirror server */
static const char * const NETWORK_CONTENT_MIRROR_HOST = "binaries.openttd.org";
const char *NetworkCoordinatorConnectionString();
const char *NetworkStunConnectionString();
const char *NetworkContentServerConnectionString();
const char *NetworkContentMirrorConnectionString();
/** URL of the HTTP mirror system */
static const char * const NETWORK_CONTENT_MIRROR_URL = "/bananas";
/** Message sent to the masterserver to 'identify' this client as OpenTTD */
static const char * const NETWORK_MASTER_SERVER_WELCOME_MESSAGE = "OpenTTDRegister";
static const uint16 NETWORK_MASTER_SERVER_PORT = 3978; ///< The default port of the master server (UDP)
static const uint16 NETWORK_CONTENT_SERVER_PORT = 3978; ///< The default port of the content server (TCP)
static const uint16 NETWORK_CONTENT_MIRROR_PORT = 80; ///< The default port of the content mirror (TCP)
static const uint16 NETWORK_DEFAULT_PORT = 3979; ///< The default port of the game server (TCP & UDP)
static const uint16 NETWORK_ADMIN_PORT = 3977; ///< The default port for admin network
static const uint16 NETWORK_DEFAULT_DEBUGLOG_PORT = 3982; ///< The default port debug-log is sent to (TCP)
static const uint16 NETWORK_COORDINATOR_SERVER_PORT = 3976; ///< The default port of the Game Coordinator server (TCP)
static const uint16 NETWORK_STUN_SERVER_PORT = 3975; ///< The default port of the STUN server (TCP)
static const uint16 NETWORK_CONTENT_SERVER_PORT = 3978; ///< The default port of the content server (TCP)
static const uint16 NETWORK_CONTENT_MIRROR_PORT = 80; ///< The default port of the content mirror (TCP)
static const uint16 NETWORK_DEFAULT_PORT = 3979; ///< The default port of the game server (TCP & UDP)
static const uint16 NETWORK_ADMIN_PORT = 3977; ///< The default port for admin network
static const uint16 NETWORK_DEFAULT_DEBUGLOG_PORT = 3982; ///< The default port debug-log is sent to (TCP)
static const uint16 UDP_MTU = 1460; ///< Number of bytes we can pack in a single UDP packet
static const uint16 UDP_MTU_SHORT = 1400; ///< Number of bytes we can pack in a single UDP packet (conservative)
static const uint16 UDP_MTU = 1460; ///< Number of bytes we can pack in a single UDP packet
static const uint16 UDP_MTU_SHORT = 1400; ///< Number of bytes we can pack in a single UDP packet (conservative)
/*
* Technically a TCP packet could become 64kiB, however the high bit is kept so it becomes possible in the future
* to go to (significantly) larger packets if needed. This would entail a strategy such as employed for UTF-8.
@ -46,42 +44,56 @@ static const uint16 UDP_MTU_SHORT = 1400; ///< Number of
* Send_uint16(GB(size, 16, 14) | 0b10 << 14)
* Send_uint16(GB(size, 0, 16))
*/
static const uint16 TCP_MTU = 32767; ///< Number of bytes we can pack in a single TCP packet
static const uint16 COMPAT_MTU = 1460; ///< Number of bytes we can pack in a single packet for backward compatibility
static const uint16 TCP_MTU = 32767; ///< Number of bytes we can pack in a single TCP packet
static const uint16 COMPAT_MTU = 1460; ///< Number of bytes we can pack in a single packet for backward compatibility
static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use?
static const byte NETWORK_GAME_INFO_VERSION = 4; ///< What version of game-info do we use?
static const byte NETWORK_COMPANY_INFO_VERSION = 6; ///< What version of company info is this?
static const byte NETWORK_MASTER_SERVER_VERSION = 2; ///< What version of master-server-protocol do we use?
static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use?
static const byte NETWORK_GAME_INFO_VERSION = 5; ///< What version of game-info do we use?
static const byte NETWORK_COMPANY_INFO_VERSION = 6; ///< What version of company info is this?
static const byte NETWORK_COORDINATOR_VERSION = 3; ///< What version of game-coordinator-protocol do we use?
static const uint NETWORK_NAME_LENGTH = 80; ///< The maximum length of the server name and map name, in bytes including '\0'
static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0'
static const uint NETWORK_HOSTNAME_LENGTH = 80; ///< The maximum length of the host name, in bytes including '\0'
static const uint NETWORK_HOSTNAME_PORT_LENGTH = 80 + 6; ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536)
static const uint NETWORK_SERVER_ID_LENGTH = 33; ///< The maximum length of the network id of the servers, in bytes including '\0'
static const uint NETWORK_REVISION_LENGTH = 33; ///< The maximum length of the revision, in bytes including '\0'
static const uint NETWORK_LONG_REVISION_LENGTH = 64; ///< The maximum length of the revision, in bytes including '\0'
static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH)
static const uint NETWORK_CLIENTS_LENGTH = 200; ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0'
static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0'
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = COMPAT_MTU-3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
static const uint NETWORK_CHAT_LENGTH = 900; ///< The maximum length of a chat message, in bytes including '\0'
static const uint NETWORK_CONTENT_FILENAME_LENGTH = 48; ///< The maximum length of a content's filename, in bytes including '\0'.
static const uint NETWORK_CONTENT_NAME_LENGTH = 64; ///< The maximum length of a content's name, in bytes including '\0'.
static const uint NETWORK_CONTENT_VERSION_LENGTH = 16; ///< The maximum length of a content's version, in bytes including '\0'.
static const uint NETWORK_CONTENT_URL_LENGTH = 96; ///< The maximum length of a content's url, in bytes including '\0'.
static const uint NETWORK_CONTENT_DESC_LENGTH = 512; ///< The maximum length of a content's description, in bytes including '\0'.
static const uint NETWORK_CONTENT_TAG_LENGTH = 32; ///< The maximum length of a content's tag, in bytes including '\0'.
static const uint NETWORK_NAME_LENGTH = 80; ///< The maximum length of the server name and map name, in bytes including '\0'
static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0'
static const uint NETWORK_HOSTNAME_LENGTH = 80; ///< The maximum length of the host name, in bytes including '\0'
static const uint NETWORK_HOSTNAME_PORT_LENGTH = 80 + 6; ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536)
static const uint NETWORK_SERVER_ID_LENGTH = 33; ///< The maximum length of the network id of the servers, in bytes including '\0'
static const uint NETWORK_REVISION_LENGTH = 33; ///< The maximum length of the revision, in bytes including '\0'
static const uint NETWORK_LONG_REVISION_LENGTH = 64; ///< The maximum length of the revision, in bytes including '\0'
static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH)
static const uint NETWORK_CLIENTS_LENGTH = 200; ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0'
static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0'
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = COMPAT_MTU - 3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
static const uint NETWORK_CHAT_LENGTH = 900; ///< The maximum length of a chat message, in bytes including '\0'
static const uint NETWORK_CONTENT_FILENAME_LENGTH = 48; ///< The maximum length of a content's filename, in bytes including '\0'.
static const uint NETWORK_CONTENT_NAME_LENGTH = 64; ///< The maximum length of a content's name, in bytes including '\0'.
static const uint NETWORK_CONTENT_VERSION_LENGTH = 16; ///< The maximum length of a content's version, in bytes including '\0'.
static const uint NETWORK_CONTENT_URL_LENGTH = 96; ///< The maximum length of a content's url, in bytes including '\0'.
static const uint NETWORK_CONTENT_DESC_LENGTH = 512; ///< The maximum length of a content's description, in bytes including '\0'.
static const uint NETWORK_CONTENT_TAG_LENGTH = 32; ///< The maximum length of a content's tag, in bytes including '\0'.
static const uint NETWORK_ERROR_DETAIL_LENGTH = 100; ///< The maximum length of the error detail, in bytes including '\0'.
static const uint NETWORK_INVITE_CODE_LENGTH = 64; ///< The maximum length of the invite code, in bytes including '\0'.
static const uint NETWORK_INVITE_CODE_SECRET_LENGTH = 80; ///< The maximum length of the invite code secret, in bytes including '\0'.
static const uint NETWORK_TOKEN_LENGTH = 64; ///< The maximum length of a token, in bytes including '\0'.
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF
/**
* Maximum number of GRFs that can be sent.
* This limit is reached when PACKET_UDP_SERVER_RESPONSE reaches the maximum size of UDP_MTU bytes.
*
* This limit exists to avoid that the SERVER_INFO packet exceeding the
* maximum MTU. At the time of writing this limit is 32767 (TCP_MTU).
*
* In the SERVER_INFO packet is the NetworkGameInfo struct, which is
* 142 bytes + 100 per NewGRF (under the assumption strings are used to
* their max). This brings us to roughly 326 possible NewGRFs. Round it
* down so people don't freak out because they see a weird value, and you
* get the limit: 255.
*
* PS: in case you ever want to raise this number, please be mindful that
* "amount of NewGRFs" in NetworkGameInfo is currently an uint8.
*/
static const uint NETWORK_MAX_GRF_COUNT = 62;
static const uint NETWORK_MAX_GRF_COUNT_SHORT = 59;
static const uint NETWORK_MAX_GRF_COUNT = 255;
/**
* The number of landscapes in OpenTTD.
@ -91,6 +103,6 @@ static const uint NETWORK_MAX_GRF_COUNT_SHORT = 59;
* there is a compile assertion to check that this NUM_LANDSCAPE is equal
* to NETWORK_NUM_LANDSCAPES.
*/
static const uint NETWORK_NUM_LANDSCAPES = 4;
static const uint NETWORK_NUM_LANDSCAPES = 4;
#endif /* NETWORK_CORE_CONFIG_H */

@ -16,6 +16,8 @@
#include "../../date_func.h"
#include "../../debug.h"
#include "../../map_func.h"
#include "../../game/game.hpp"
#include "../../game/game_info.hpp"
#include "../../settings_type.h"
#include "../../string_func.h"
#include "../../rev.h"
@ -149,7 +151,11 @@ void FillStaticNetworkServerGameInfo()
*/
const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo()
{
/* Client_on is used as global variable to keep track on the number of clients. */
/* These variables are updated inside _network_game_info as if they are global variables:
* - clients_on
* - invite_code
* These don't need to be updated manually here.
*/
_network_game_info.companies_on = (byte)Company::GetNumItems();
_network_game_info.spectators_on = NetworkSpectatorCount();
_network_game_info.game_date = _date;
@ -199,6 +205,11 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info)
/* Update the documentation in game_info.h on changes
* to the NetworkGameInfo wire-protocol! */
/* NETWORK_GAME_INFO_VERSION = 5 */
GameInfo *game_info = Game::GetInfo();
p->Send_uint32(game_info == nullptr ? -1 : (uint32)game_info->GetVersion());
p->Send_string(game_info == nullptr ? "" : game_info->GetName());
/* NETWORK_GAME_INFO_VERSION = 4 */
{
/* Only send the GRF Identification (GRF_ID and MD5 checksum) of
@ -218,12 +229,7 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info)
uint index = 0;
for (c = info->grfconfig; c != nullptr; c = c->next) {
if (!HasBit(c->flags, GCF_STATIC)) {
if (index == NETWORK_MAX_GRF_COUNT - 1 && count > NETWORK_MAX_GRF_COUNT) {
/* Send fake GRF ID */
p->Send_uint32(0x56D2B000);
p->Send_binary((const char*) _out_of_band_grf_md5, 16);
} else if (index >= NETWORK_MAX_GRF_COUNT) {
if (index >= NETWORK_MAX_GRF_COUNT) {
break;
} else {
SerializeGRFIdentifier(p, &c->ident);
@ -327,6 +333,12 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
* to the NetworkGameInfo wire-protocol! */
switch (game_info_version) {
case 5: {
info->gamescript_version = (int)p->Recv_uint32();
info->gamescript_name = p->Recv_string(NETWORK_NAME_LENGTH);
FALLTHROUGH;
}
case 4: {
GRFConfig **dst = &info->grfconfig;
uint i;

@ -76,6 +76,8 @@ struct NetworkServerGameInfo {
byte spectators_on; ///< How many spectators do we have?
byte spectators_max; ///< Max spectators allowed on server
byte landscape; ///< The used landscape
int gamescript_version; ///< Version of the gamescript.
std::string gamescript_name; ///< Name of the gamescript.
};
/**

@ -180,6 +180,23 @@ bool SetNoDelay(SOCKET d)
#endif
}
/**
* Try to set the socket to reuse ports.
* @param d The socket to reuse ports on.
* @return True if disabling the delaying succeeded, otherwise false.
*/
bool SetReusePort(SOCKET d)
{
#ifdef _WIN32
/* Windows has no SO_REUSEPORT, but for our usecases SO_REUSEADDR does the same job. */
int reuse_port = 1;
return setsockopt(d, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse_port, sizeof(reuse_port)) == 0;
#else
int reuse_port = 1;
return setsockopt(d, SOL_SOCKET, SO_REUSEPORT, &reuse_port, sizeof(reuse_port)) == 0;
#endif
}
/**
* Try to shutdown the socket in one or both directions.
* @param d The socket to disable the delaying for.

@ -215,6 +215,7 @@ static inline socklen_t FixAddrLenForEmscripten(struct sockaddr_storage &address
bool SetNonBlocking(SOCKET d);
bool SetBlocking(SOCKET d);
bool SetNoDelay(SOCKET d);
bool SetReusePort(SOCKET d);
bool ShutdownSocket(SOCKET d, bool read, bool write, uint linger_timeout);
NetworkError GetSocketError(SOCKET d);

@ -95,10 +95,12 @@ private:
RESOLVING, ///< The hostname is being resolved (threaded).
FAILURE, ///< Resolving failed.
CONNECTING, ///< We are currently connecting.
CONNECTED, ///< The connection is established.
};
std::thread resolve_thread; ///< Thread used during resolving.
std::atomic<Status> status = Status::INIT; ///< The current status of the connecter.
std::atomic<bool> killed = false; ///< Whether this connecter is marked as killed.
addrinfo *ai = nullptr; ///< getaddrinfo() allocated linked-list of resolved addresses.
std::vector<addrinfo *> addresses; ///< Addresses we can connect to.
@ -109,17 +111,24 @@ private:
std::chrono::steady_clock::time_point last_attempt; ///< Time we last tried to connect.
std::string connection_string; ///< Current address we are connecting to (before resolving).
NetworkAddress bind_address; ///< Address we're binding to, if any.
int family = AF_UNSPEC; ///< Family we are using to connect with.
void Resolve();
void OnResolved(addrinfo *ai);
bool TryNextAddress();
void Connect(addrinfo *address);
bool CheckActivity();
virtual bool CheckActivity();
/* We do not want any other derived classes from this class being able to
* access these private members, but it is okay for TCPServerConnecter. */
friend class TCPServerConnecter;
static void ResolveThunk(TCPConnecter *connecter);
public:
TCPConnecter(const std::string &connection_string, uint16 default_port);
TCPConnecter() {};
TCPConnecter(const std::string &connection_string, uint16 default_port, NetworkAddress bind_address = {}, int family = AF_UNSPEC);
virtual ~TCPConnecter();
/**
@ -133,8 +142,25 @@ public:
*/
virtual void OnFailure() {}
void Kill();
static void CheckCallbacks();
static void KillAll();
};
class TCPServerConnecter : public TCPConnecter {
private:
SOCKET socket = INVALID_SOCKET; ///< The socket when a connection is established.
bool CheckActivity() override;
public:
ServerAddress server_address; ///< Address we are connecting to.
TCPServerConnecter(const std::string &connection_string, uint16 default_port);
void SetConnected(SOCKET sock);
void SetFailure();
};
#endif /* NETWORK_CORE_TCP_H */

@ -13,6 +13,7 @@
#include "../../thread.h"
#include "tcp.h"
#include "../network_coordinator.h"
#include "../network_internal.h"
#include <deque>
@ -23,16 +24,45 @@
static std::vector<TCPConnecter *> _tcp_connecters;
/**
* Create a new connecter for the given address
* @param connection_string the address to connect to
* Create a new connecter for the given address.
* @param connection_string The address to connect to.
* @param default_port If not indicated in connection_string, what port to use.
* @param bind_address The local bind address to use. Defaults to letting the OS find one.
*/
TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port)
TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port, NetworkAddress bind_address, int family) :
bind_address(bind_address),
family(family)
{
this->connection_string = NormalizeConnectionString(connection_string, default_port);
_tcp_connecters.push_back(this);
}
/**
* Create a new connecter for the server.
* @param connection_string The address to connect to.
* @param default_port If not indicated in connection_string, what port to use.
*/
TCPServerConnecter::TCPServerConnecter(const std::string &connection_string, uint16 default_port) :
server_address(ServerAddress::Parse(connection_string, default_port))
{
switch (this->server_address.type) {
case SERVER_ADDRESS_DIRECT:
this->connection_string = this->server_address.connection_string;
break;
case SERVER_ADDRESS_INVITE_CODE:
this->status = Status::CONNECTING;
_network_coordinator_client.ConnectToServer(this->server_address.connection_string, this);
break;
default:
NOT_REACHED();
}
_tcp_connecters.push_back(this);
}
TCPConnecter::~TCPConnecter()
{
if (this->resolve_thread.joinable()) {
@ -48,6 +78,16 @@ TCPConnecter::~TCPConnecter()
if (this->ai != nullptr) freeaddrinfo(this->ai);
}
/**
* Kill this connecter.
* It will abort as soon as it can and not call any of the callbacks.
*/
void TCPConnecter::Kill()
{
/* Delay the removing of the socket till the next CheckActivity(). */
this->killed = true;
}
/**
* Start a connection to the indicated address.
* @param address The address to connection to.
@ -60,6 +100,18 @@ void TCPConnecter::Connect(addrinfo *address)
return;
}
if (!SetReusePort(sock)) {
DEBUG(net, 0, "Setting reuse-port mode failed: %s", NetworkError::GetLast().AsString());
}
if (this->bind_address.GetPort() > 0) {
if (bind(sock, (const sockaddr *)this->bind_address.GetAddress(), this->bind_address.GetAddressLength()) != 0) {
DEBUG(net, 1, "Could not bind socket on %s: %s", NetworkAddressDumper().GetAddressAsString(&(this->bind_address)), NetworkError::GetLast().AsString());
closesocket(sock);
return;
}
}
if (!SetNoDelay(sock)) {
DEBUG(net, 1, "Setting TCP_NODELAY failed: %s", NetworkError::GetLast().AsString());
}
@ -123,6 +175,9 @@ void TCPConnecter::OnResolved(addrinfo *ai)
/* Convert the addrinfo into NetworkAddresses. */
for (addrinfo *runp = ai; runp != nullptr; runp = runp->ai_next) {
/* Skip entries if the family is set and it is not matching. */
if (this->family != AF_UNSPEC && this->family != runp->ai_family) continue;
if (resort) {
if (runp->ai_family == AF_INET6) {
addresses_ipv6.emplace_back(runp);
@ -219,7 +274,9 @@ void TCPConnecter::Resolve()
*/
bool TCPConnecter::CheckActivity()
{
switch (this->status.load()) {
if (this->killed) return true;
switch (this->status) {
case Status::INIT:
/* Start the thread delayed, so the vtable is loaded. This allows classes
* to overload functions used by Resolve() (in case threading is disabled). */
@ -246,6 +303,7 @@ bool TCPConnecter::CheckActivity()
return true;
case Status::CONNECTING:
case Status::CONNECTED:
break;
}
@ -344,9 +402,63 @@ bool TCPConnecter::CheckActivity()
}
this->OnConnect(connected_socket);
this->status = Status::CONNECTED;
return true;
}
/**
* Check if there was activity for this connecter.
* @return True iff the TCPConnecter is done and can be cleaned up.
*/
bool TCPServerConnecter::CheckActivity()
{
if (this->killed) return true;
switch (this->server_address.type) {
case SERVER_ADDRESS_DIRECT:
return TCPConnecter::CheckActivity();
case SERVER_ADDRESS_INVITE_CODE:
/* Check if a result has come in. */
switch (this->status) {
case Status::FAILURE:
this->OnFailure();
return true;
case Status::CONNECTED:
this->OnConnect(this->socket);
return true;
default:
break;
}
return false;
default:
NOT_REACHED();
}
}
/**
* The connection was successfully established.
* This socket is fully setup and ready to send/recv game protocol packets.
* @param sock The socket of the established connection.
*/
void TCPServerConnecter::SetConnected(SOCKET sock)
{
this->socket = sock;
this->status = Status::CONNECTED;
}
/**
* The connection couldn't be established.
*/
void TCPServerConnecter::SetFailure()
{
this->status = Status::FAILURE;
}
/**
* Check whether we need to call the callback, i.e. whether we
* have connected or aborted and call the appropriate callback

@ -0,0 +1,101 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file tcp_coordinator.cpp Basic functions to receive and send Game Coordinator packets.
*/
#include "../../stdafx.h"
#include "../../date_func.h"
#include "../../debug.h"
#include "tcp_coordinator.h"
#include "../../safeguards.h"
/**
* Handle the given packet, i.e. pass it to the right.
* parser receive command.
* @param p The packet to handle.
* @return True iff we should immediately handle further packets.
*/
bool NetworkCoordinatorSocketHandler::HandlePacket(Packet *p)
{
PacketCoordinatorType type = (PacketCoordinatorType)p->Recv_uint8();
switch (type) {
case PACKET_COORDINATOR_GC_ERROR: return this->Receive_GC_ERROR(p);
case PACKET_COORDINATOR_SERVER_REGISTER: return this->Receive_SERVER_REGISTER(p);
case PACKET_COORDINATOR_GC_REGISTER_ACK: return this->Receive_GC_REGISTER_ACK(p);
case PACKET_COORDINATOR_SERVER_UPDATE: return this->Receive_SERVER_UPDATE(p);
case PACKET_COORDINATOR_CLIENT_LISTING: return this->Receive_CLIENT_LISTING(p);
case PACKET_COORDINATOR_GC_LISTING: return this->Receive_GC_LISTING(p);
case PACKET_COORDINATOR_CLIENT_CONNECT: return this->Receive_CLIENT_CONNECT(p);
case PACKET_COORDINATOR_GC_CONNECTING: return this->Receive_GC_CONNECTING(p);
case PACKET_COORDINATOR_SERCLI_CONNECT_FAILED: return this->Receive_SERCLI_CONNECT_FAILED(p);
case PACKET_COORDINATOR_GC_CONNECT_FAILED: return this->Receive_GC_CONNECT_FAILED(p);
case PACKET_COORDINATOR_CLIENT_CONNECTED: return this->Receive_CLIENT_CONNECTED(p);
case PACKET_COORDINATOR_GC_DIRECT_CONNECT: return this->Receive_GC_DIRECT_CONNECT(p);
case PACKET_COORDINATOR_GC_STUN_REQUEST: return this->Receive_GC_STUN_REQUEST(p);
case PACKET_COORDINATOR_SERCLI_STUN_RESULT: return this->Receive_SERCLI_STUN_RESULT(p);
case PACKET_COORDINATOR_GC_STUN_CONNECT: return this->Receive_GC_STUN_CONNECT(p);
default:
DEBUG(net, 0, "[tcp/coordinator] Received invalid packet type %u", type);
return false;
}
}
/**
* Receive a packet at TCP level.
* @return Whether at least one packet was received.
*/
bool NetworkCoordinatorSocketHandler::ReceivePackets()
{
/*
* We read only a few of the packets. This allows the GUI to update when
* a large set of servers is being received. Otherwise the interface
* "hangs" while the game is updating the server-list.
*
* What arbitrary number to choose is the ultimate question though.
*/
std::unique_ptr<Packet> p;
static const int MAX_PACKETS_TO_RECEIVE = 42;
int i = MAX_PACKETS_TO_RECEIVE;
while (--i != 0 && (p = this->ReceivePacket()) != nullptr) {
bool cont = this->HandlePacket(p.get());
if (!cont) return true;
}
return i != MAX_PACKETS_TO_RECEIVE - 1;
}
/**
* Helper for logging receiving invalid packets.
* @param type The received packet type.
* @return Always false, as it's an error.
*/
bool NetworkCoordinatorSocketHandler::ReceiveInvalidPacket(PacketCoordinatorType type)
{
DEBUG(net, 0, "[tcp/coordinator] Received illegal packet type %u", type);
return false;
}
bool NetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_ERROR); }
bool NetworkCoordinatorSocketHandler::Receive_SERVER_REGISTER(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERVER_REGISTER); }
bool NetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_REGISTER_ACK); }
bool NetworkCoordinatorSocketHandler::Receive_SERVER_UPDATE(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERVER_UPDATE); }
bool NetworkCoordinatorSocketHandler::Receive_CLIENT_LISTING(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_CLIENT_LISTING); }
bool NetworkCoordinatorSocketHandler::Receive_GC_LISTING(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_LISTING); }
bool NetworkCoordinatorSocketHandler::Receive_CLIENT_CONNECT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_CLIENT_CONNECT); }
bool NetworkCoordinatorSocketHandler::Receive_GC_CONNECTING(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_CONNECTING); }
bool NetworkCoordinatorSocketHandler::Receive_SERCLI_CONNECT_FAILED(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERCLI_CONNECT_FAILED); }
bool NetworkCoordinatorSocketHandler::Receive_GC_CONNECT_FAILED(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_CONNECT_FAILED); }
bool NetworkCoordinatorSocketHandler::Receive_CLIENT_CONNECTED(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_CLIENT_CONNECTED); }
bool NetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_DIRECT_CONNECT); }
bool NetworkCoordinatorSocketHandler::Receive_GC_STUN_REQUEST(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_STUN_REQUEST); }
bool NetworkCoordinatorSocketHandler::Receive_SERCLI_STUN_RESULT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERCLI_STUN_RESULT); }
bool NetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_STUN_CONNECT); }

@ -0,0 +1,277 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file tcp_coordinator.h Basic functions to receive and send TCP packets to/from the Game Coordinator server.
*/
#ifndef NETWORK_CORE_TCP_COORDINATOR_H
#define NETWORK_CORE_TCP_COORDINATOR_H
#include "os_abstraction.h"
#include "tcp.h"
#include "packet.h"
#include "game_info.h"
/**
* Enum with all types of TCP Game Coordinator packets. The order MUST not be changed.
*
* GC -> packets from Game Coordinator to either Client or Server.
* SERVER -> packets from Server to Game Coordinator.
* CLIENT -> packets from Client to Game Coordinator.
* SERCLI -> packets from either the Server or Client to Game Coordinator.
**/
enum PacketCoordinatorType {
PACKET_COORDINATOR_GC_ERROR, ///< Game Coordinator indicates there was an error.
PACKET_COORDINATOR_SERVER_REGISTER, ///< Server registration.
PACKET_COORDINATOR_GC_REGISTER_ACK, ///< Game Coordinator accepts the registration.
PACKET_COORDINATOR_SERVER_UPDATE, ///< Server sends an set intervals an update of the server.
PACKET_COORDINATOR_CLIENT_LISTING, ///< Client is requesting a listing of all public servers.
PACKET_COORDINATOR_GC_LISTING, ///< Game Coordinator returns a listing of all public servers.
PACKET_COORDINATOR_CLIENT_CONNECT, ///< Client wants to connect to a server based on an invite code.
PACKET_COORDINATOR_GC_CONNECTING, ///< Game Coordinator informs the client of the token assigned to the connection attempt.
PACKET_COORDINATOR_SERCLI_CONNECT_FAILED, ///< Client/server tells the Game Coordinator the current connection attempt failed.
PACKET_COORDINATOR_GC_CONNECT_FAILED, ///< Game Coordinator informs client/server it has given up on the connection attempt.
PACKET_COORDINATOR_CLIENT_CONNECTED, ///< Client informs the Game Coordinator the connection with the server is established.
PACKET_COORDINATOR_GC_DIRECT_CONNECT, ///< Game Coordinator tells client to directly connect to the hostname:port of the server.
PACKET_COORDINATOR_GC_STUN_REQUEST, ///< Game Coordinator tells client/server to initiate a STUN request.
PACKET_COORDINATOR_SERCLI_STUN_RESULT, ///< Client/server informs the Game Coordinator of the result of the STUN request.
PACKET_COORDINATOR_GC_STUN_CONNECT, ///< Game Coordinator tells client/server to connect() reusing the STUN local address.
PACKET_COORDINATOR_END, ///< Must ALWAYS be on the end of this list!! (period)
};
/**
* The type of connection the Game Coordinator can detect we have.
*/
enum ConnectionType {
CONNECTION_TYPE_UNKNOWN, ///< The Game Coordinator hasn't informed us yet what type of connection we have.
CONNECTION_TYPE_ISOLATED, ///< The Game Coordinator failed to find a way to connect to your server. Nobody will be able to join.
CONNECTION_TYPE_DIRECT, ///< The Game Coordinator can directly connect to your server.
CONNECTION_TYPE_STUN, ///< The Game Coordinator can connect to your server via a STUN request.
};
/**
* The type of error from the Game Coordinator.
*/
enum NetworkCoordinatorErrorType {
NETWORK_COORDINATOR_ERROR_UNKNOWN, ///< There was an unknown error.
NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED, ///< Your request for registration failed.
NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE, ///< The invite code given is invalid.
};
/** Base socket handler for all Game Coordinator TCP sockets. */
class NetworkCoordinatorSocketHandler : public NetworkTCPSocketHandler {
protected:
bool ReceiveInvalidPacket(PacketCoordinatorType type);
/**
* Game Coordinator indicates there was an error. This can either be a
* permanent error causing the connection to be dropped, or in response
* to a request that is invalid.
*
* uint8 Type of error (see NetworkCoordinatorErrorType).
* string Details of the error.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_GC_ERROR(Packet *p);
/**
* Server is starting a multiplayer game and wants to let the
* Game Coordinator know.
*
* uint8 Game Coordinator protocol version.
* uint8 Type of game (see ServerGameType).
* uint16 Local port of the server.
* string Invite code the server wants to use (can be empty; coordinator will assign a new invite code).
* string Secret that belongs to the invite code (empty if invite code is empty).
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_SERVER_REGISTER(Packet *p);
/**
* Game Coordinator acknowledges the registration.
*
* string Invite code that can be used to join this server.
* string Secret that belongs to the invite code (only needed if reusing the invite code on next SERVER_REGISTER).
* uint8 Type of connection was detected (see ConnectionType).
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_GC_REGISTER_ACK(Packet *p);
/**
* Send an update of the current state of the server to the Game Coordinator.
*
* uint8 Game Coordinator protocol version.
* Serialized NetworkGameInfo. See game_info.hpp for details.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_SERVER_UPDATE(Packet *p);
/**
* Client requests a list of all public servers.
*
* uint8 Game Coordinator protocol version.
* uint8 Game-info version used by this client.
* string Revision of the client.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_CLIENT_LISTING(Packet *p);
/**
* Game Coordinator replies with a list of all public servers. Multiple
* of these packets are received after a request till all servers are
* sent over. Last packet will have server count of 0.
*
* uint16 Amount of public servers in this packet.
* For each server:
* string Connection string for this server.
* Serialized NetworkGameInfo. See game_info.hpp for details.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_GC_LISTING(Packet *p);
/**
* Client wants to connect to a Server.
*
* uint8 Game Coordinator protocol version.
* string Invite code of the Server to join.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_CLIENT_CONNECT(Packet *p);
/**
* Game Coordinator informs the Client under what token it will start the
* attempt to connect the Server and Client together.
*
* string Token to track the current connect request.
* string Invite code of the Server to join.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_GC_CONNECTING(Packet *p);
/**
* Client or Server failed to connect to the remote side.
*
* uint8 Game Coordinator protocol version.
* string Token to track the current connect request.
* uint8 Tracking number to track current connect request.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_SERCLI_CONNECT_FAILED(Packet *p);
/**
* Game Coordinator informs the Client that it failed to find a way to
* connect the Client to the Server. Any open connections for this token
* should be closed now.
*
* string Token to track the current connect request.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_GC_CONNECT_FAILED(Packet *p);
/**
* Client informs the Game Coordinator the connection with the Server is
* established. The Client will disconnect from the Game Coordinator next.
*
* uint8 Game Coordinator protocol version.
* string Token to track the current connect request.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_CLIENT_CONNECTED(Packet *p);
/**
* Game Coordinator requests that the Client makes a direct connection to
* the indicated peer, which is a Server.
*
* string Token to track the current connect request.
* uint8 Tracking number to track current connect request.
* string Hostname of the peer.
* uint16 Port of the peer.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_GC_DIRECT_CONNECT(Packet *p);
/**
* Game Coordinator requests the client/server to do a STUN request to the
* STUN server. Important is to remember the local port these STUN requests
* are sent from, as this will be needed for later conenctions too.
* The client/server should do multiple STUN requests for every available
* interface that connects to the Internet (e.g., once for IPv4 and once
* for IPv6).
*
* string Token to track the current connect request.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_GC_STUN_REQUEST(Packet *p);
/**
* Client/server informs the Game Coordinator the result of a STUN request.
*
* uint8 Game Coordinator protocol version.
* string Token to track the current connect request.
* uint8 Interface number, as given during STUN request.
* bool Whether the STUN connection was successful.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_SERCLI_STUN_RESULT(Packet *p);
/**
* Game Coordinator informs the client/server of its STUN peer (the host:ip
* of the other side). It should start a connect() to this peer ASAP with
* the local address as used with the STUN request.
*
* string Token to track the current connect request.
* uint8 Tracking number to track current connect request.
* uint8 Interface number, as given during STUN request.
* string Host of the peer.
* uint16 Port of the peer.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_GC_STUN_CONNECT(Packet *p);
bool HandlePacket(Packet *p);
public:
/**
* Create a new cs socket handler for a given cs.
* @param s The socket we are connected with.
*/
NetworkCoordinatorSocketHandler(SOCKET s = INVALID_SOCKET) : NetworkTCPSocketHandler(s) {}
bool ReceivePackets();
};
#endif /* NETWORK_CORE_TCP_COORDINATOR_H */

@ -30,6 +30,42 @@ class TCPListenHandler {
static SocketList sockets;
public:
static bool ValidateClient(SOCKET s, NetworkAddress &address)
{
/* Check if the client is banned. */
for (const auto &entry : _network_ban_list) {
if (address.IsInNetmask(entry.c_str())) {
Packet p(Tban_packet);
p.PrepareToSend();
DEBUG(net, 2, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), entry.c_str());
if (p.TransferOut<int>(send, s, 0) < 0) {
DEBUG(net, 0, "[%s] send failed: %s", Tsocket::GetName(), NetworkError::GetLast().AsString());
}
closesocket(s);
return false;
}
}
/* Can we handle a new client? */
if (!Tsocket::AllowConnection()) {
/* No more clients allowed?
* Send to the client that we are full! */
Packet p(Tfull_packet);
p.PrepareToSend();
if (p.TransferOut<int>(send, s, 0) < 0) {
DEBUG(net, 0, "[%s] send failed: %s", Tsocket::GetName(), NetworkError::GetLast().AsString());
}
closesocket(s);
return false;
}
return true;
}
/**
* Accepts clients from the sockets.
* @param ls Socket to accept clients from.
@ -53,41 +89,7 @@ public:
SetNoDelay(s); // XXX error handling?
/* Check if the client is banned */
bool banned = false;
for (const auto &entry : _network_ban_list) {
banned = address.IsInNetmask(entry.c_str());
if (banned) {
Packet p(Tban_packet);
p.PrepareToSend();
DEBUG(net, 2, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), entry.c_str());
if (p.TransferOut<int>(send, s, 0) < 0) {
DEBUG(net, 0, "[%s] send failed: %s", Tsocket::GetName(), NetworkError::GetLast().AsString());
}
closesocket(s);
break;
}
}
/* If this client is banned, continue with next client */
if (banned) continue;
/* Can we handle a new client? */
if (!Tsocket::AllowConnection()) {
/* no more clients allowed?
* Send to the client that we are full! */
Packet p(Tfull_packet);
p.PrepareToSend();
if (p.TransferOut<int>(send, s, 0) < 0) {
DEBUG(net, 0, "[%s] send failed: %s", Tsocket::GetName(), NetworkError::GetLast().AsString());
}
closesocket(s);
continue;
}
if (!Tsocket::ValidateClient(s, address)) continue;
Tsocket::AcceptConnection(s, address);
}
}

@ -0,0 +1,29 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file tcp_stun.cpp Basic functions to receive and send STUN packets.
*/
#include "../../stdafx.h"
#include "../../debug.h"
#include "tcp_stun.h"
#include "../../safeguards.h"
/**
* Helper for logging receiving invalid packets.
* @param type The received packet type.
* @return Always false, as it's an error.
*/
bool NetworkStunSocketHandler::ReceiveInvalidPacket(PacketStunType type)
{
DEBUG(net, 0, "[tcp/stun] Received illegal packet type %u", type);
return false;
}
bool NetworkStunSocketHandler::Receive_SERCLI_STUN(Packet *p) { return this->ReceiveInvalidPacket(PACKET_STUN_SERCLI_STUN); }

@ -0,0 +1,53 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file tcp_stun.h Basic functions to receive and send TCP packets to/from the STUN server.
*/
#ifndef NETWORK_CORE_TCP_STUN_H
#define NETWORK_CORE_TCP_STUN_H
#include "os_abstraction.h"
#include "tcp.h"
#include "packet.h"
/** Enum with all types of TCP STUN packets. The order MUST not be changed. **/
enum PacketStunType {
PACKET_STUN_SERCLI_STUN, ///< Send a STUN request to the STUN server.
PACKET_STUN_END, ///< Must ALWAYS be on the end of this list!! (period)
};
/** Base socket handler for all STUN TCP sockets. */
class NetworkStunSocketHandler : public NetworkTCPSocketHandler {
protected:
bool ReceiveInvalidPacket(PacketStunType type);
/**
* Send a STUN request to the STUN server letting the Game Coordinator know
* what our actually public IP:port is.
*
* uint8 Game Coordinator protocol version.
* string Token to track the current STUN request.
* uint8 Which interface number this is (for example, IPv4 or IPv6).
* The Game Coordinator relays this number back in later packets.
*
* @param p The packet that was just received.
* @return True upon success, otherwise false.
*/
virtual bool Receive_SERCLI_STUN(Packet *p);
public:
/**
* Create a new cs socket handler for a given cs.
* @param s the socket we are connected with.
* @param address IP etc. of the client.
*/
NetworkStunSocketHandler(SOCKET s = INVALID_SOCKET) : NetworkTCPSocketHandler(s) {}
};
#endif /* NETWORK_CORE_TCP_STUN_H */

@ -194,16 +194,6 @@ void NetworkUDPSocketHandler::HandleUDPPacket(Packet *p, NetworkAddress *client_
switch (this->HasClientQuit() ? PACKET_UDP_END : type) {
case PACKET_UDP_CLIENT_FIND_SERVER: this->Receive_CLIENT_FIND_SERVER(p, client_addr); break;
case PACKET_UDP_SERVER_RESPONSE: this->Receive_SERVER_RESPONSE(p, client_addr); break;
case PACKET_UDP_CLIENT_DETAIL_INFO: this->Receive_CLIENT_DETAIL_INFO(p, client_addr); break;
case PACKET_UDP_SERVER_DETAIL_INFO: this->Receive_SERVER_DETAIL_INFO(p, client_addr); break;
case PACKET_UDP_SERVER_REGISTER: this->Receive_SERVER_REGISTER(p, client_addr); break;
case PACKET_UDP_MASTER_ACK_REGISTER: this->Receive_MASTER_ACK_REGISTER(p, client_addr); break;
case PACKET_UDP_CLIENT_GET_LIST: this->Receive_CLIENT_GET_LIST(p, client_addr); break;
case PACKET_UDP_MASTER_RESPONSE_LIST: this->Receive_MASTER_RESPONSE_LIST(p, client_addr); break;
case PACKET_UDP_SERVER_UNREGISTER: this->Receive_SERVER_UNREGISTER(p, client_addr); break;
case PACKET_UDP_CLIENT_GET_NEWGRFS: this->Receive_CLIENT_GET_NEWGRFS(p, client_addr); break;
case PACKET_UDP_SERVER_NEWGRFS: this->Receive_SERVER_NEWGRFS(p, client_addr); break;
case PACKET_UDP_MASTER_SESSION_KEY: this->Receive_MASTER_SESSION_KEY(p, client_addr); break;
case PACKET_UDP_EX_MULTI: this->Receive_EX_MULTI(p, client_addr); break;
case PACKET_UDP_EX_SERVER_RESPONSE: this->Receive_EX_SERVER_RESPONSE(p, client_addr); break;
@ -301,13 +291,3 @@ void NetworkUDPSocketHandler::ReceiveInvalidPacket(PacketUDPType type, NetworkAd
void NetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_FIND_SERVER, client_addr); }
void NetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_RESPONSE, client_addr); }
void NetworkUDPSocketHandler::Receive_EX_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_EX_SERVER_RESPONSE, client_addr); }
void NetworkUDPSocketHandler::Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_DETAIL_INFO, client_addr); }
void NetworkUDPSocketHandler::Receive_SERVER_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_DETAIL_INFO, client_addr); }
void NetworkUDPSocketHandler::Receive_SERVER_REGISTER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_REGISTER, client_addr); }
void NetworkUDPSocketHandler::Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_MASTER_ACK_REGISTER, client_addr); }
void NetworkUDPSocketHandler::Receive_CLIENT_GET_LIST(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_GET_LIST, client_addr); }
void NetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_MASTER_RESPONSE_LIST, client_addr); }
void NetworkUDPSocketHandler::Receive_SERVER_UNREGISTER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_UNREGISTER, client_addr); }
void NetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_GET_NEWGRFS, client_addr); }
void NetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_NEWGRFS, client_addr); }
void NetworkUDPSocketHandler::Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_MASTER_SESSION_KEY, client_addr); }

@ -23,31 +23,12 @@
enum PacketUDPType {
PACKET_UDP_CLIENT_FIND_SERVER, ///< Queries a game server for game information
PACKET_UDP_SERVER_RESPONSE, ///< Reply of the game server with game information
PACKET_UDP_CLIENT_DETAIL_INFO, ///< Queries a game server about details of the game, such as companies
PACKET_UDP_SERVER_DETAIL_INFO, ///< Reply of the game server about details of the game, such as companies
PACKET_UDP_SERVER_REGISTER, ///< Packet to register itself to the master server
PACKET_UDP_MASTER_ACK_REGISTER, ///< Packet indicating registration has succeeded
PACKET_UDP_CLIENT_GET_LIST, ///< Request for serverlist from master server
PACKET_UDP_MASTER_RESPONSE_LIST, ///< Response from master server with server ip's + port's
PACKET_UDP_SERVER_UNREGISTER, ///< Request to be removed from the server-list
PACKET_UDP_CLIENT_GET_NEWGRFS, ///< Requests the name for a list of GRFs (GRF_ID and MD5)
PACKET_UDP_SERVER_NEWGRFS, ///< Sends the list of NewGRF's requested.
PACKET_UDP_MASTER_SESSION_KEY, ///< Sends a fresh session key to the client
PACKET_UDP_END, ///< Must ALWAYS be the last non-extended item in the list!! (period)
PACKET_UDP_EX_MULTI = 128, ///< Extended/multi packet type
PACKET_UDP_EX_SERVER_RESPONSE, ///< Reply of the game server with extended game information
};
/** The types of server lists we can get */
enum ServerListType {
SLT_IPv4 = 0, ///< Get the IPv4 addresses
SLT_IPv6 = 1, ///< Get the IPv6 addresses
SLT_AUTODETECT, ///< Autodetect the type based on the connection
SLT_END = SLT_AUTODETECT, ///< End of 'arrays' marker
};
/** Base socket handler for all UDP sockets */
class NetworkUDPSocketHandler : public NetworkSocketHandler {
protected:
@ -76,8 +57,7 @@ protected:
virtual void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr);
/**
* Return of server information to the client.
* Serialized NetworkGameInfo. See game_info.h for details.
* Response to a query letting the client know we are here.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
@ -85,120 +65,6 @@ protected:
virtual void Receive_EX_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr);
/**
* Query for detailed information about companies.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr);
/**
* Reply with detailed company information.
* uint8 Version of the packet.
* uint8 Number of companies.
* For each company:
* uint8 ID of the company.
* string Name of the company.
* uint32 Year the company was inaugurated.
* uint64 Value.
* uint64 Money.
* uint64 Income.
* uint16 Performance (last quarter).
* bool Company is password protected.
* uint16 Number of trains.
* uint16 Number of lorries.
* uint16 Number of busses.
* uint16 Number of planes.
* uint16 Number of ships.
* uint16 Number of train stations.
* uint16 Number of lorry stations.
* uint16 Number of bus stops.
* uint16 Number of airports and heliports.
* uint16 Number of harbours.
* bool Company is an AI.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_SERVER_DETAIL_INFO(Packet *p, NetworkAddress *client_addr);
/**
* Registers the server to the master server.
* string The "welcome" message to root out other binary packets.
* uint8 Version of the protocol.
* uint16 The port to unregister.
* uint64 The session key.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_SERVER_REGISTER(Packet *p, NetworkAddress *client_addr);
/**
* The master server acknowledges the registration.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr);
/**
* The client requests a list of servers.
* uint8 The protocol version.
* uint8 The type of server to look for: IPv4, IPv6 or based on the received packet.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_CLIENT_GET_LIST(Packet *p, NetworkAddress *client_addr);
/**
* The server sends a list of servers.
* uint8 The protocol version.
* For each server:
* 4 or 16 bytes of IPv4 or IPv6 address.
* uint8 The port.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr);
/**
* A server unregisters itself at the master server.
* uint8 Version of the protocol.
* uint16 The port to unregister.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_SERVER_UNREGISTER(Packet *p, NetworkAddress *client_addr);
/**
* The client requests information about some NewGRFs.
* uint8 The number of NewGRFs information is requested about.
* For each NewGRF:
* uint32 The GRFID.
* 16 * uint8 MD5 checksum of the GRF.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr);
/**
* The server returns information about some NewGRFs.
* uint8 The number of NewGRFs information is requested about.
* For each NewGRF:
* uint32 The GRFID.
* 16 * uint8 MD5 checksum of the GRF.
* string The name of the NewGRF.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr);
/**
* The master server sends us a session key.
* uint64 The session key.
* @param p The received packet.
* @param client_addr The origin of the packet.
*/
virtual void Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr);
void HandleUDPPacket(Packet *p, NetworkAddress *client_addr);
virtual void Receive_EX_MULTI(Packet *p, NetworkAddress *client_addr);

@ -19,6 +19,7 @@
#include "network_udp.h"
#include "network_gamelist.h"
#include "network_base.h"
#include "network_coordinator.h"
#include "core/udp.h"
#include "core/host.h"
#include "network_gui.h"
@ -62,7 +63,6 @@ bool _network_settings_access; ///< Can this client change server settings?
NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies.
ClientID _network_own_client_id; ///< Our client identifier.
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
bool _network_need_advertise; ///< Whether we need to advertise.
uint8 _network_reconnect; ///< Reconnect timeout
StringList _network_bind_list; ///< The addresses to bind on.
StringList _network_host_list; ///< The servers we know.
@ -478,6 +478,41 @@ static void CheckPauseOnJoin()
CheckPauseHelper(NetworkHasJoiningClient(), PM_PAUSED_JOIN);
}
/**
* Parse the company part ("#company" postfix) of a connecting string.
* @param connection_string The string with the connection data.
* @param company_id The company ID to set, if available.
* @return A std::string_view into the connection string without the company part.
*/
std::string_view ParseCompanyFromConnectionString(const std::string &connection_string, CompanyID *company_id)
{
std::string_view ip = connection_string;
if (company_id == nullptr) return ip;
size_t offset = ip.find_last_of('#');
if (offset != std::string::npos) {
std::string_view company_string = ip.substr(offset + 1);
ip = ip.substr(0, offset);
uint8 company_value;
auto [_, err] = std::from_chars(company_string.data(), company_string.data() + company_string.size(), company_value);
if (err == std::errc()) {
if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) {
if (company_value > MAX_COMPANIES || company_value == 0) {
*company_id = COMPANY_SPECTATOR;
} else {
/* "#1" means the first company, which has index 0. */
*company_id = (CompanyID)(company_value - 1);
}
} else {
*company_id = (CompanyID)company_value;
}
}
}
return ip;
}
/**
* Converts a string to ip/port/company
* Format: IP:port#company
@ -495,29 +530,7 @@ static void CheckPauseOnJoin()
*/
std::string_view ParseFullConnectionString(const std::string &connection_string, uint16 &port, CompanyID *company_id)
{
std::string_view ip = connection_string;
if (company_id != nullptr) {
size_t offset = ip.find_last_of('#');
if (offset != std::string::npos) {
std::string_view company_string = ip.substr(offset + 1);
ip = ip.substr(0, offset);
uint8 company_value;
auto [_, err] = std::from_chars(company_string.data(), company_string.data() + company_string.size(), company_value);
if (err == std::errc()) {
if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) {
if (company_value > MAX_COMPANIES || company_value == 0) {
*company_id = COMPANY_SPECTATOR;
} else {
/* "#1" means the first company, which has index 0. */
*company_id = (CompanyID)(company_value - 1);
}
} else {
*company_id = (CompanyID)company_value;
}
}
}
}
std::string_view ip = ParseCompanyFromConnectionString(connection_string, company_id);
size_t port_offset = ip.find_last_of(':');
size_t ipv6_close = ip.find_last_of(']');
@ -557,23 +570,6 @@ NetworkAddress ParseConnectionString(const std::string &connection_string, uint1
return NetworkAddress(ip, port);
}
/**
* Convert a string containing either "hostname" or "hostname:ip" to a
* NetworkAddress, where the string can be postfixed with "#company" to
* indicate the requested company.
*
* @param connection_string The string to parse.
* @param default_port The default port to set port to if not in connection_string.
* @param company Pointer to the company variable to set iff indicted.
* @return A valid NetworkAddress of the parsed information.
*/
static NetworkAddress ParseGameConnectionString(const std::string &connection_string, uint16 default_port, CompanyID *company)
{
uint16 port = default_port;
std::string_view ip = ParseFullConnectionString(connection_string, port, company);
return NetworkAddress(ip, port);
}
/**
* Handle the accepting of a connection to the server.
* @param s The socket of the new connection.
@ -617,9 +613,15 @@ void NetworkClose(bool close_admins)
}
ServerNetworkGameSocketHandler::CloseListeners();
ServerNetworkAdminSocketHandler::CloseListeners();
} else if (MyClient::my_client != nullptr) {
MyClient::SendQuit();
MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
_network_coordinator_client.CloseConnection();
} else {
if (MyClient::my_client != nullptr) {
MyClient::SendQuit();
MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
}
_network_coordinator_client.CloseAllTokens();
}
TCPConnecter::KillAll();
@ -639,7 +641,6 @@ void NetworkClose(bool close_admins)
static void NetworkInitialize(bool close_admins = true)
{
InitializeNetworkPools(close_admins);
NetworkUDPInitialize();
_sync_frame = 0;
_network_first_time = true;
@ -652,12 +653,12 @@ static void NetworkInitialize(bool close_admins = true)
}
/** Non blocking connection to query servers for their game info. */
class TCPQueryConnecter : TCPConnecter {
class TCPQueryConnecter : TCPServerConnecter {
private:
std::string connection_string;
public:
TCPQueryConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
TCPQueryConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
void OnFailure() override
{
@ -689,12 +690,12 @@ void NetworkQueryServer(const std::string &connection_string)
}
/** Non blocking connection to query servers for their game and company info. */
class TCPLobbyQueryConnecter : TCPConnecter {
class TCPLobbyQueryConnecter : TCPServerConnecter {
private:
std::string connection_string;
public:
TCPLobbyQueryConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
TCPLobbyQueryConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
void OnFailure() override
{
@ -729,9 +730,11 @@ void NetworkQueryLobbyServer(const std::string &connection_string)
* the list. If you use this function, the games will be marked
* as manually added.
* @param connection_string The IP:port of the server to add.
* @param manually Whether the enter should be marked as manual added.
* @param never_expire Whether the entry can expire (removed when no longer found in the public listing).
* @return The entry on the game list.
*/
NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually)
NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually, bool never_expire)
{
if (connection_string.empty()) return nullptr;
@ -747,6 +750,7 @@ NetworkGameList *NetworkAddServer(const std::string &connection_string, bool man
}
if (manually) item->manually = true;
if (never_expire) item->version = INT32_MAX;
return item;
}
@ -781,12 +785,12 @@ void NetworkRebuildHostList()
}
/** Non blocking connection create to actually connect to servers */
class TCPClientConnecter : TCPConnecter {
class TCPClientConnecter : TCPServerConnecter {
private:
std::string connection_string;
public:
TCPClientConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
TCPClientConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
void OnFailure() override
{
@ -822,7 +826,7 @@ public:
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password, const std::string &join_company_password)
{
CompanyID join_as = default_company;
std::string resolved_connection_string = ParseGameConnectionString(connection_string, NETWORK_DEFAULT_PORT, &join_as).GetAddressAsString(false);
std::string resolved_connection_string = ServerAddress::Parse(connection_string, NETWORK_DEFAULT_PORT, &join_as).connection_string;
if (!_network_available) return false;
if (!NetworkValidateOurClientName()) return false;
@ -932,6 +936,7 @@ bool NetworkServerStart()
NetworkDisconnect(false, false);
NetworkInitialize(false);
NetworkUDPInitialize();
DEBUG(net, 5, "Starting listeners for clients");
if (!ServerNetworkGameSocketHandler::Listen(_settings_client.network.server_port)) return false;
@ -959,15 +964,15 @@ bool NetworkServerStart()
NetworkInitGameInfo();
if (_settings_client.network.server_game_type != SERVER_GAME_TYPE_LOCAL) {
_network_coordinator_client.Register();
}
/* execute server initialization script */
IConsoleCmdExec("exec scripts/on_server.scr 0");
/* if the server is dedicated ... add some other script */
if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
/* Try to register us to the master server */
_network_need_advertise = true;
NetworkUDPAdvertise();
/* welcome possibly still connected admins - this can only happen on a dedicated server. */
if (_network_dedicated) ServerNetworkAdminSocketHandler::WelcomeAll();
@ -1016,8 +1021,6 @@ void NetworkDisconnect(bool blocking, bool close_admins)
}
}
if (_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise(blocking);
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
NetworkClose(close_admins);
@ -1026,6 +1029,29 @@ void NetworkDisconnect(bool blocking, bool close_admins)
NetworkUDPInitialize();
}
/**
* The setting server_game_type was updated; possibly we need to take some
* action.
*/
void NetworkUpdateServerGameType()
{
if (!_networking) return;
switch (_settings_client.network.server_game_type) {
case SERVER_GAME_TYPE_LOCAL:
_network_coordinator_client.CloseConnection();
break;
case SERVER_GAME_TYPE_INVITE_ONLY:
case SERVER_GAME_TYPE_PUBLIC:
_network_coordinator_client.Register();
break;
default:
NOT_REACHED();
}
}
/**
* Receives something from the network.
* @return true if everything went fine, false when the connection got closed.
@ -1059,6 +1085,7 @@ static void NetworkSend()
void NetworkBackgroundLoop()
{
_network_content_client.SendReceive();
_network_coordinator_client.SendReceive();
TCPConnecter::CheckCallbacks();
NetworkHTTPSocketHandler::HTTPReceive();
@ -1297,7 +1324,6 @@ void NetworkStartUp()
/* Network is available */
_network_available = NetworkCoreInitialize();
_network_dedicated = false;
_network_need_advertise = true;
/* Generate an server id when there is none yet */
if (_settings_client.network.network_id.empty()) NetworkGenerateServerId();
@ -1305,6 +1331,7 @@ void NetworkStartUp()
_network_game_info = {};
NetworkInitialize();
NetworkUDPInitialize();
DEBUG(net, 3, "Network online, multiplayer available");
NetworkFindBroadcastIPs(&_broadcast_list);
}
@ -1327,7 +1354,7 @@ extern "C" {
void CDECL em_openttd_add_server(const char *connection_string)
{
NetworkAddServer(connection_string, false);
NetworkAddServer(connection_string, false, true);
}
}

@ -140,9 +140,8 @@ void ClientNetworkEmergencySave()
if (!_networking) return;
if (!ClientNetworkGameSocketHandler::EmergencySavePossible()) return;
const char *filename = "netsave.sav";
DEBUG(net, 0, "Client: Performing emergency save (%s)", filename);
SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false, SMF_ZSTD_OK);
static int _netsave_ctr = 0;
DoAutoOrNetsave(_netsave_ctr, true);
}
@ -715,7 +714,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packe
item->online = true;
/* It could be either window, but only one is open, so redraw both. */
SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME);
UpdateNetworkGameWindow();
SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY);
/* We will receive company info next, so keep connection open. */

@ -367,7 +367,7 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const Conten
this->http_response_index = -1;
new NetworkHTTPContentConnecter(NETWORK_CONTENT_MIRROR_HOST, this, NETWORK_CONTENT_MIRROR_URL, content_request);
new NetworkHTTPContentConnecter(NetworkContentMirrorConnectionString(), this, NETWORK_CONTENT_MIRROR_URL, content_request);
/* NetworkHTTPContentConnecter takes over freeing of content_request! */
}
@ -799,7 +799,7 @@ void ClientNetworkContentSocketHandler::Connect()
{
if (this->sock != INVALID_SOCKET || this->isConnecting) return;
this->isConnecting = true;
new NetworkContentConnecter(NETWORK_CONTENT_SERVER_HOST);
new NetworkContentConnecter(NetworkContentServerConnectionString());
}
/**

@ -0,0 +1,687 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file network_coordinator.cpp Game Coordinator sending/receiving part of the network protocol. */
#include "../stdafx.h"
#include "../debug.h"
#include "../error.h"
#include "../rev.h"
#include "../settings_type.h"
#include "../strings_func.h"
#include "../window_func.h"
#include "../window_type.h"
#include "network.h"
#include "network_coordinator.h"
#include "network_gamelist.h"
#include "network_internal.h"
#include "network_server.h"
#include "network_stun.h"
#include "table/strings.h"
#include "../safeguards.h"
static const auto NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES = std::chrono::seconds(30); ///< How many time between updates the server sends to the Game Coordinator.
ClientNetworkCoordinatorSocketHandler _network_coordinator_client; ///< The connection to the Game Coordinator.
ConnectionType _network_server_connection_type = CONNECTION_TYPE_UNKNOWN; ///< What type of connection the Game Coordinator detected we are on.
std::string _network_server_invite_code = ""; ///< Our invite code as indicated by the Game Coordinator.
/** Connect to a game server by IP:port. */
class NetworkDirectConnecter : public TCPConnecter {
private:
std::string token; ///< Token of this connection.
uint8 tracking_number; ///< Tracking number of this connection.
public:
/**
* Try to establish a direct (hostname:port based) connection.
* @param hostname The hostname of the server.
* @param port The port of the server.
* @param token The token as given by the Game Coordinator to track this connection attempt.
* @param tracking_number The tracking number as given by the Game Coordinator to track this connection attempt.
*/
NetworkDirectConnecter(const std::string &hostname, uint16 port, const std::string &token, uint8 tracking_number) : TCPConnecter(hostname, port), token(token), tracking_number(tracking_number) {}
void OnFailure() override
{
_network_coordinator_client.ConnectFailure(this->token, this->tracking_number);
}
void OnConnect(SOCKET s) override
{
NetworkAddress address = NetworkAddress::GetPeerAddress(s);
_network_coordinator_client.ConnectSuccess(this->token, s, address);
}
};
/** Connecter used after STUN exchange to connect from both sides to each other. */
class NetworkReuseStunConnecter : public TCPConnecter {
private:
std::string token; ///< Token of this connection.
uint8 tracking_number; ///< Tracking number of this connection.
uint8 family; ///< Family of this connection.
public:
/**
* Try to establish a STUN-based connection.
* @param hostname The hostname of the peer.
* @param port The port of the peer.
* @param bind_address The local bind address used for this connection.
* @param token The connection token.
* @param tracking_number The tracking number of the connection.
* @param family The family this connection is using.
*/
NetworkReuseStunConnecter(const std::string &hostname, uint16 port, const NetworkAddress &bind_address, std::string token, uint8 tracking_number, uint8 family) :
TCPConnecter(hostname, port, bind_address),
token(token),
tracking_number(tracking_number),
family(family)
{
}
void OnFailure() override
{
/* Close the STUN connection too, as it is no longer of use. */
_network_coordinator_client.CloseStunHandler(this->token, this->family);
_network_coordinator_client.ConnectFailure(this->token, this->tracking_number);
}
void OnConnect(SOCKET s) override
{
NetworkAddress address = NetworkAddress::GetPeerAddress(s);
_network_coordinator_client.ConnectSuccess(this->token, s, address);
}
};
/** Connect to the Game Coordinator server. */
class NetworkCoordinatorConnecter : TCPConnecter {
public:
/**
* Initiate the connecting.
* @param connection_string The address of the Game Coordinator server.
*/
NetworkCoordinatorConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_COORDINATOR_SERVER_PORT) {}
void OnFailure() override
{
_network_coordinator_client.connecting = false;
_network_coordinator_client.CloseConnection(true);
}
void OnConnect(SOCKET s) override
{
assert(_network_coordinator_client.sock == INVALID_SOCKET);
_network_coordinator_client.sock = s;
_network_coordinator_client.last_activity = std::chrono::steady_clock::now();
_network_coordinator_client.connecting = false;
}
};
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p)
{
NetworkCoordinatorErrorType error = (NetworkCoordinatorErrorType)p->Recv_uint8();
std::string detail = p->Recv_string(NETWORK_ERROR_DETAIL_LENGTH);
switch (error) {
case NETWORK_COORDINATOR_ERROR_UNKNOWN:
this->CloseConnection();
return false;
case NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED:
SetDParamStr(0, detail);
ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED, STR_JUST_RAW_STRING, WL_ERROR);
/* To prevent that we constantly try to reconnect, switch to local game. */
_settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
this->CloseConnection();
return false;
case NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE: {
this->CloseToken(detail);
/* Mark the server as offline. */
NetworkGameList *item = NetworkGameListAddItem(detail);
item->online = false;
UpdateNetworkGameWindow();
return true;
}
default:
DEBUG(net, 0, "Invalid error type %u received from Game Coordinator", error);
this->CloseConnection();
return false;
}
}
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK(Packet *p)
{
/* Schedule sending an update. */
this->next_update = std::chrono::steady_clock::now();
_settings_client.network.server_invite_code = p->Recv_string(NETWORK_INVITE_CODE_LENGTH);
_settings_client.network.server_invite_code_secret = p->Recv_string(NETWORK_INVITE_CODE_SECRET_LENGTH);
_network_server_connection_type = (ConnectionType)p->Recv_uint8();
if (_network_server_connection_type == CONNECTION_TYPE_ISOLATED) {
ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_ISOLATED, STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL, WL_ERROR);
}
/* Users can change the invite code in the settings, but this has no effect
* on the invite code as assigned by the server. So
* _network_server_invite_code contains the current invite code,
* and _settings_client.network.server_invite_code contains the one we will
* attempt to re-use when registering again. */
_network_server_invite_code = _settings_client.network.server_invite_code;
SetWindowDirty(WC_CLIENT_LIST, 0);
if (_network_dedicated) {
std::string connection_type;
switch (_network_server_connection_type) {
case CONNECTION_TYPE_ISOLATED: connection_type = "Remote players can't connect"; break;
case CONNECTION_TYPE_DIRECT: connection_type = "Public"; break;
case CONNECTION_TYPE_STUN: connection_type = "Behind NAT"; break;
case CONNECTION_TYPE_UNKNOWN: // Never returned from Game Coordinator.
default: connection_type = "Unknown"; break; // Should never happen, but don't fail if it does.
}
std::string game_type;
switch (_settings_client.network.server_game_type) {
case SERVER_GAME_TYPE_INVITE_ONLY: game_type = "Invite only"; break;
case SERVER_GAME_TYPE_PUBLIC: game_type = "Public"; break;
case SERVER_GAME_TYPE_LOCAL: // Impossible to register local servers.
default: game_type = "Unknown"; break; // Should never happen, but don't fail if it does.
}
DEBUG(net, 3, "----------------------------------------");
DEBUG(net, 3, "Your server is now registered with the Game Coordinator:");
DEBUG(net, 3, " Game type: %s", game_type.c_str());
DEBUG(net, 3, " Connection type: %s", connection_type.c_str());
DEBUG(net, 3, " Invite code: %s", _network_server_invite_code.c_str());
DEBUG(net, 3, "----------------------------------------");
} else {
DEBUG(net, 3, "Game Coordinator registered our server with invite code '%s'", _network_server_invite_code.c_str());
}
return true;
}
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_LISTING(Packet *p)
{
uint8 servers = p->Recv_uint16();
/* End of list; we can now remove all expired items from the list. */
if (servers == 0) {
NetworkGameListRemoveExpired();
return true;
}
for (; servers > 0; servers--) {
std::string connection_string = p->Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
/* Read the NetworkGameInfo from the packet. */
NetworkGameInfo ngi = {};
DeserializeNetworkGameInfo(p, &ngi);
/* Now we know the connection string, we can add it to our list. */
NetworkGameList *item = NetworkGameListAddItem(connection_string);
/* Clear any existing GRFConfig chain. */
ClearGRFConfigList(&item->info.grfconfig);
/* Copy the new NetworkGameInfo info. */
item->info = ngi;
/* Check for compatability with the client. */
CheckGameCompatibility(item->info);
/* Mark server as online. */
item->online = true;
/* Mark the item as up-to-date. */
item->version = _network_game_list_version;
}
UpdateNetworkGameWindow();
return true;
}
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECTING(Packet *p)
{
std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
std::string invite_code = p->Recv_string(NETWORK_INVITE_CODE_LENGTH);
/* Find the connecter based on the invite code. */
auto connecter_it = this->connecter_pre.find(invite_code);
if (connecter_it == this->connecter_pre.end()) {
this->CloseConnection();
return false;
}
/* Now store it based on the token. */
this->connecter[token] = connecter_it->second;
this->connecter_pre.erase(connecter_it);
return true;
}
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECT_FAILED(Packet *p)
{
std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
auto connecter_it = this->connecter.find(token);
if (connecter_it != this->connecter.end()) {
connecter_it->second->SetFailure();
this->connecter.erase(connecter_it);
}
/* Close all remaining connections. */
this->CloseToken(token);
return true;
}
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT(Packet *p)
{
std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
uint8 tracking_number = p->Recv_uint8();
std::string hostname = p->Recv_string(NETWORK_HOSTNAME_LENGTH);
uint16 port = p->Recv_uint16();
/* Ensure all other pending connection attempts are killed. */
if (this->game_connecter != nullptr) {
this->game_connecter->Kill();
this->game_connecter = nullptr;
}
this->game_connecter = new NetworkDirectConnecter(hostname, port, token, tracking_number);
return true;
}
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_REQUEST(Packet *p)
{
std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
this->stun_handlers[token][AF_INET6] = ClientNetworkStunSocketHandler::Stun(token, AF_INET6);
this->stun_handlers[token][AF_INET] = ClientNetworkStunSocketHandler::Stun(token, AF_INET);
return true;
}
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT(Packet *p)
{
std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
uint8 tracking_number = p->Recv_uint8();
uint8 family = p->Recv_uint8();
std::string host = p->Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
uint16 port = p->Recv_uint16();
/* Check if we know this token. */
auto stun_it = this->stun_handlers.find(token);
if (stun_it == this->stun_handlers.end()) return true;
auto family_it = stun_it->second.find(family);
if (family_it == stun_it->second.end()) return true;
/* Ensure all other pending connection attempts are killed. */
if (this->game_connecter != nullptr) {
this->game_connecter->Kill();
this->game_connecter = nullptr;
}
/* We now mark the connection as closed, but we do not really close the
* socket yet. We do this when the NetworkReuseStunConnecter is connected.
* This prevents any NAT to already remove the route while we create the
* second connection on top of the first. */
family_it->second->CloseConnection(false);
/* Connect to our peer from the same local address as we use for the
* STUN server. This means that if there is any NAT in the local network,
* the public ip:port is still pointing to the local address, and as such
* a connection can be established. */
this->game_connecter = new NetworkReuseStunConnecter(host, port, family_it->second->local_addr, token, tracking_number, family);
return true;
}
void ClientNetworkCoordinatorSocketHandler::Connect()
{
/* We are either already connected or are trying to connect. */
if (this->sock != INVALID_SOCKET || this->connecting) return;
this->Reopen();
this->connecting = true;
this->last_activity = std::chrono::steady_clock::now();
new NetworkCoordinatorConnecter(NetworkCoordinatorConnectionString());
}
NetworkRecvStatus ClientNetworkCoordinatorSocketHandler::CloseConnection(bool error)
{
NetworkCoordinatorSocketHandler::CloseConnection(error);
this->CloseSocket();
this->connecting = false;
_network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
this->next_update = {};
this->CloseAllTokens();
SetWindowDirty(WC_CLIENT_LIST, 0);
return NETWORK_RECV_STATUS_OKAY;
}
/**
* Register our server to receive our invite code.
*/
void ClientNetworkCoordinatorSocketHandler::Register()
{
_network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
this->next_update = {};
SetWindowDirty(WC_CLIENT_LIST, 0);
this->Connect();
Packet *p = new Packet(PACKET_COORDINATOR_SERVER_REGISTER);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
p->Send_uint8(_settings_client.network.server_game_type);
p->Send_uint16(_settings_client.network.server_port);
if (_settings_client.network.server_invite_code.empty() || _settings_client.network.server_invite_code_secret.empty()) {
p->Send_string("");
p->Send_string("");
} else {
p->Send_string(_settings_client.network.server_invite_code);
p->Send_string(_settings_client.network.server_invite_code_secret);
}
this->SendPacket(p);
}
/**
* Send an update of our server status to the Game Coordinator.
*/
void ClientNetworkCoordinatorSocketHandler::SendServerUpdate()
{
DEBUG(net, 6, "Sending server update to Game Coordinator");
this->next_update = std::chrono::steady_clock::now() + NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES;
Packet *p = new Packet(PACKET_COORDINATOR_SERVER_UPDATE, TCP_MTU);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
SerializeNetworkGameInfo(p, GetCurrentNetworkServerGameInfo());
this->SendPacket(p);
}
/**
* Request a listing of all public servers.
*/
void ClientNetworkCoordinatorSocketHandler::GetListing()
{
this->Connect();
_network_game_list_version++;
Packet *p = new Packet(PACKET_COORDINATOR_CLIENT_LISTING);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
p->Send_uint8(NETWORK_GAME_INFO_VERSION);
p->Send_string(_openttd_revision);
this->SendPacket(p);
}
/**
* Join a server based on an invite code.
* @param invite_code The invite code of the server to connect to.
* @param connecter The connecter of the request.
*/
void ClientNetworkCoordinatorSocketHandler::ConnectToServer(const std::string &invite_code, TCPServerConnecter *connecter)
{
assert(StrStartsWith(invite_code, "+"));
if (this->connecter_pre.find(invite_code) != this->connecter_pre.end()) {
/* If someone is hammering the refresh key, one can sent out two
* requests for the same invite code. There isn't really a great way
* of handling this, so just ignore this request. */
connecter->SetFailure();
return;
}
/* Initially we store based on invite code; on first reply we know the
* token, and will start using that key instead. */
this->connecter_pre[invite_code] = connecter;
this->Connect();
Packet *p = new Packet(PACKET_COORDINATOR_CLIENT_CONNECT);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
p->Send_string(invite_code);
this->SendPacket(p);
}
/**
* Callback from a Connecter to let the Game Coordinator know the connection failed.
* @param token Token of the connecter that failed.
* @param tracking_number Tracking number of the connecter that failed.
*/
void ClientNetworkCoordinatorSocketHandler::ConnectFailure(const std::string &token, uint8 tracking_number)
{
/* Connecter will destroy itself. */
this->game_connecter = nullptr;
Packet *p = new Packet(PACKET_COORDINATOR_SERCLI_CONNECT_FAILED);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
p->Send_string(token);
p->Send_uint8(tracking_number);
this->SendPacket(p);
/* We do not close the associated connecter here yet, as the
* Game Coordinator might have other methods of connecting available. */
}
/**
* Callback from a Connecter to let the Game Coordinator know the connection
* to the game server is established.
* @param token Token of the connecter that succeeded.
* @param sock The socket that the connecter can now use.
*/
void ClientNetworkCoordinatorSocketHandler::ConnectSuccess(const std::string &token, SOCKET sock, NetworkAddress &address)
{
/* Connecter will destroy itself. */
this->game_connecter = nullptr;
if (_network_server) {
if (!ServerNetworkGameSocketHandler::ValidateClient(sock, address)) return;
DEBUG(net, 3, "[%s] Client connected from %s on frame %u", ServerNetworkGameSocketHandler::GetName(), address.GetHostname(), _frame_counter);
ServerNetworkGameSocketHandler::AcceptConnection(sock, address);
} else {
/* The client informs the Game Coordinator about the success. The server
* doesn't have to, as it is implied by the client telling. */
Packet *p = new Packet(PACKET_COORDINATOR_CLIENT_CONNECTED);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
p->Send_string(token);
this->SendPacket(p);
auto connecter_it = this->connecter.find(token);
assert(connecter_it != this->connecter.end());
connecter_it->second->SetConnected(sock);
this->connecter.erase(connecter_it);
}
/* Close all remaining connections. */
this->CloseToken(token);
}
/**
* Callback from the STUN connecter to inform the Game Coordinator about the
* result of the STUN.
*
* This helps the Game Coordinator not to wait for a timeout on its end, but
* rather react as soon as the client/server knows the result.
*/
void ClientNetworkCoordinatorSocketHandler::StunResult(const std::string &token, uint8 family, bool result)
{
Packet *p = new Packet(PACKET_COORDINATOR_SERCLI_STUN_RESULT);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
p->Send_string(token);
p->Send_uint8(family);
p->Send_bool(result);
this->SendPacket(p);
}
void ClientNetworkCoordinatorSocketHandler::CloseStunHandler(const std::string &token, uint8 family)
{
auto stun_it = this->stun_handlers.find(token);
if (stun_it == this->stun_handlers.end()) return;
if (family == AF_UNSPEC) {
for (auto &[family, stun_handler] : stun_it->second) {
stun_handler->CloseConnection();
stun_handler->CloseSocket();
}
this->stun_handlers.erase(stun_it);
} else {
auto family_it = stun_it->second.find(family);
if (family_it == stun_it->second.end()) return;
family_it->second->CloseConnection();
family_it->second->CloseSocket();
stun_it->second.erase(family_it);
}
}
/**
* Close everything related to this connection token.
* @param token The connection token to close.
*/
void ClientNetworkCoordinatorSocketHandler::CloseToken(const std::string &token)
{
/* Ensure all other pending connection attempts are also killed. */
if (this->game_connecter != nullptr) {
this->game_connecter->Kill();
this->game_connecter = nullptr;
}
/* Close all remaining STUN connections. */
this->CloseStunHandler(token);
/* Close the caller of the connection attempt. */
auto connecter_it = this->connecter.find(token);
if (connecter_it != this->connecter.end()) {
connecter_it->second->SetFailure();
this->connecter.erase(connecter_it);
}
auto connecter_pre_it = this->connecter_pre.find(token);
if (connecter_pre_it != this->connecter_pre.end()) {
connecter_pre_it->second->SetFailure();
this->connecter_pre.erase(connecter_pre_it);
}
}
/**
* Close all pending connection tokens.
*/
void ClientNetworkCoordinatorSocketHandler::CloseAllTokens()
{
/* Ensure all other pending connection attempts are also killed. */
if (this->game_connecter != nullptr) {
this->game_connecter->Kill();
this->game_connecter = nullptr;
}
/* Mark any pending connecters as failed. */
for (auto &[token, it] : this->connecter) {
this->CloseStunHandler(token);
it->SetFailure();
}
for (auto &[invite_code, it] : this->connecter_pre) {
it->SetFailure();
}
this->connecter.clear();
this->connecter_pre.clear();
}
/**
* Check whether we received/can send some data from/to the Game Coordinator server and
* when that's the case handle it appropriately.
*/
void ClientNetworkCoordinatorSocketHandler::SendReceive()
{
/* Private games are not listed via the Game Coordinator. */
if (_network_server && _settings_client.network.server_game_type == SERVER_GAME_TYPE_LOCAL) {
if (this->sock != INVALID_SOCKET) {
this->CloseConnection();
}
return;
}
static int last_attempt_backoff = 1;
static bool first_reconnect = true;
if (this->sock == INVALID_SOCKET) {
static std::chrono::steady_clock::time_point last_attempt = {};
/* Don't auto-reconnect when we are not a server. */
if (!_network_server) return;
/* Don't reconnect if we are connecting. */
if (this->connecting) return;
/* Throttle how often we try to reconnect. */
if (std::chrono::steady_clock::now() < last_attempt + std::chrono::seconds(1) * last_attempt_backoff) return;
last_attempt = std::chrono::steady_clock::now();
/* Delay reconnecting with up to 32 seconds. */
if (last_attempt_backoff < 32) {
last_attempt_backoff *= 2;
}
/* Do not reconnect on the first attempt, but only initialize the
* last_attempt variables. Otherwise after an outage all servers
* reconnect at the same time, potentially overwhelming the
* Game Coordinator. */
if (first_reconnect) {
first_reconnect = false;
return;
}
DEBUG(net, 1, "Connection with Game Coordinator lost; reconnecting...");
this->Register();
return;
}
last_attempt_backoff = 1;
first_reconnect = true;
if (_network_server && _network_server_connection_type != CONNECTION_TYPE_UNKNOWN && std::chrono::steady_clock::now() > this->next_update) {
this->SendServerUpdate();
}
if (!_network_server && std::chrono::steady_clock::now() > this->last_activity + IDLE_TIMEOUT) {
this->CloseConnection();
return;
}
if (this->CanSendReceive()) {
if (this->ReceivePackets()) {
this->last_activity = std::chrono::steady_clock::now();
}
}
this->SendPackets();
for (const auto &[token, families] : this->stun_handlers) {
for (const auto &[family, stun_handler] : families) {
stun_handler->SendReceive();
}
}
}

@ -0,0 +1,97 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file network_coordinator.h Part of the network protocol handling Game Coordinator requests. */
#ifndef NETWORK_COORDINATOR_H
#define NETWORK_COORDINATOR_H
#include "core/tcp_coordinator.h"
#include "network_stun.h"
#include <map>
/**
* Game Coordinator communication.
* For more detail about what the Game Coordinator does, please see
* docs/game_coordinator.md.
*
* For servers:
* - Server sends SERVER_REGISTER.
* - Game Coordinator probes server to check if it can directly connect.
* - Game Coordinator sends GC_REGISTER_ACK with type of connection.
* - Server sends every 30 seconds SERVER_UPDATE.
*
* For clients (listing):
* - Client sends CLIENT_LISTING.
* - Game Coordinator returns the full list of public servers via GC_LISTING (multiple packets).
*
* For clients (connecting):
* - Client sends CLIENT_CONNECT.
* - Game Coordinator checks what type of connections the servers supports:
* 1) Direct connect?
* - Send the client a GC_CONNECT with the peer address.
* - a) Client connects, client sends CLIENT_CONNECTED to Game Coordinator.
* - b) Client connect fails, client sends CLIENT_CONNECT_FAILED to Game Coordinator.
* 2) STUN?
* - Game Coordinator sends GC_STUN_REQUEST to server/client (asking for both IPv4 and IPv6 STUN requests).
* - Game Coordinator collects what combination works and sends GC_STUN_CONNECT to server/client.
* - a) Server/client connect, client sends CLIENT_CONNECTED to Game Coordinator.
* - b) Server/client connect fails, both send SERCLI_CONNECT_FAILED to Game Coordinator.
* - Game Coordinator tries other combination if available.
* - If all fails, Game Coordinator sends GC_CONNECT_FAILED to indicate no connection is possible.
*/
/** Class for handling the client side of the Game Coordinator connection. */
class ClientNetworkCoordinatorSocketHandler : public NetworkCoordinatorSocketHandler {
private:
std::chrono::steady_clock::time_point next_update; ///< When to send the next update (if server and public).
std::map<std::string, TCPServerConnecter *> connecter; ///< Based on tokens, the current connecters that are pending.
std::map<std::string, TCPServerConnecter *> connecter_pre; ///< Based on invite codes, the current connecters that are pending.
std::map<std::string, std::map<int, std::unique_ptr<ClientNetworkStunSocketHandler>>> stun_handlers; ///< All pending STUN handlers, stored by token:family.
TCPConnecter *game_connecter = nullptr; ///< Pending connecter to the game server.
protected:
bool Receive_GC_ERROR(Packet *p) override;
bool Receive_GC_REGISTER_ACK(Packet *p) override;
bool Receive_GC_LISTING(Packet *p) override;
bool Receive_GC_CONNECTING(Packet *p) override;
bool Receive_GC_CONNECT_FAILED(Packet *p) override;
bool Receive_GC_DIRECT_CONNECT(Packet *p) override;
bool Receive_GC_STUN_REQUEST(Packet *p) override;
bool Receive_GC_STUN_CONNECT(Packet *p) override;
public:
/** The idle timeout; when to close the connection because it's idle. */
static constexpr std::chrono::seconds IDLE_TIMEOUT = std::chrono::seconds(60);
std::chrono::steady_clock::time_point last_activity; ///< The last time there was network activity.
bool connecting; ///< Are we connecting to the Game Coordinator?
ClientNetworkCoordinatorSocketHandler() : connecting(false) {}
NetworkRecvStatus CloseConnection(bool error = true) override;
void SendReceive();
void ConnectFailure(const std::string &token, uint8 tracking_number);
void ConnectSuccess(const std::string &token, SOCKET sock, NetworkAddress &address);
void StunResult(const std::string &token, uint8 family, bool result);
void Connect();
void CloseToken(const std::string &token);
void CloseAllTokens();
void CloseStunHandler(const std::string &token, uint8 family = AF_UNSPEC);
void Register();
void SendServerUpdate();
void GetListing();
void ConnectToServer(const std::string &invite_code, TCPServerConnecter *connecter);
};
extern ClientNetworkCoordinatorSocketHandler _network_coordinator_client;
#endif /* NETWORK_COORDINATOR_H */

@ -28,7 +28,6 @@ extern NetworkCompanyState *_network_company_states;
extern ClientID _network_own_client_id;
extern ClientID _redirect_console_to_client;
extern bool _network_need_advertise;
extern uint8 _network_reconnect;
extern StringList _network_bind_list;
extern StringList _network_host_list;
@ -40,6 +39,7 @@ bool NetworkValidateOurClientName();
bool NetworkValidateClientName(std::string &client_name);
bool NetworkValidateServerName(std::string &server_name);
void NetworkUpdateClientName(const std::string &client_name);
void NetworkUpdateServerGameType();
bool NetworkCompanyHasClients(CompanyID company);
std::string NetworkChangeCompanyPassword(CompanyID company_id, std::string password);
void NetworkReboot();

@ -20,51 +20,13 @@
#include "../safeguards.h"
NetworkGameList *_network_game_list = nullptr;
/** The games to insert when the GUI thread has time for us. */
static std::atomic<NetworkGameList *> _network_game_delayed_insertion_list(nullptr);
/**
* Add a new item to the linked gamelist, but do it delayed in the next tick
* or so to prevent race conditions.
* @param item the item to add. Will be freed once added.
*/
void NetworkGameListAddItemDelayed(NetworkGameList *item)
{
item->next = _network_game_delayed_insertion_list.load(std::memory_order_relaxed);
while (!_network_game_delayed_insertion_list.compare_exchange_weak(item->next, item, std::memory_order_acq_rel)) {}
}
/** Perform the delayed (thread safe) insertion into the game list */
static void NetworkGameListHandleDelayedInsert()
{
while (true) {
NetworkGameList *ins_item = _network_game_delayed_insertion_list.load(std::memory_order_acquire);
while (ins_item != nullptr && !_network_game_delayed_insertion_list.compare_exchange_weak(ins_item, ins_item->next, std::memory_order_acq_rel)) {}
if (ins_item == nullptr) break; // No item left.
NetworkGameList *item = NetworkGameListAddItem(ins_item->connection_string);
if (item != nullptr) {
if (item->info.server_name.empty()) {
ClearGRFConfigList(&item->info.grfconfig);
item->info = {};
item->info.server_name = ins_item->info.server_name;
item->online = false;
}
item->manually |= ins_item->manually;
if (item->manually) NetworkRebuildHostList();
UpdateNetworkGameWindow();
}
delete ins_item;
}
}
NetworkGameList *_network_game_list = nullptr; ///< Game list of this client.
int _network_game_list_version = 0; ///< Current version of all items in the list.
/**
* Add a new item to the linked gamelist. If the IP and Port match
* return the existing item instead of adding it again
* @param address the address of the to-be added item
* @param connection_string the address of the to-be added item
* @return a point to the newly added or already existing item
*/
NetworkGameList *NetworkGameListAddItem(const std::string &connection_string)
@ -72,7 +34,7 @@ NetworkGameList *NetworkGameListAddItem(const std::string &connection_string)
NetworkGameList *item, *prev_item;
/* Parse the connection string to ensure the default port is there. */
const std::string resolved_connection_string = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT).GetAddressAsString(false);
const std::string resolved_connection_string = ServerAddress::Parse(connection_string, NETWORK_DEFAULT_PORT).connection_string;
prev_item = nullptr;
for (item = _network_game_list; item != nullptr; item = item->next) {
@ -81,6 +43,7 @@ NetworkGameList *NetworkGameListAddItem(const std::string &connection_string)
}
item = new NetworkGameList(resolved_connection_string);
item->version = _network_game_list_version;
if (prev_item == nullptr) {
_network_game_list = item;
@ -120,29 +83,31 @@ void NetworkGameListRemoveItem(NetworkGameList *remove)
}
}
static const uint MAX_GAME_LIST_REQUERY_COUNT = 10; ///< How often do we requery in number of times per server?
static const uint REQUERY_EVERY_X_GAMELOOPS = 60; ///< How often do we requery in time?
static const uint REFRESH_GAMEINFO_X_REQUERIES = 50; ///< Refresh the game info itself after REFRESH_GAMEINFO_X_REQUERIES * REQUERY_EVERY_X_GAMELOOPS game loops
/** Requeries the (game) servers we have not gotten a reply from */
void NetworkGameListRequery()
/**
* Remove all servers that have not recently been updated.
* Call this after you received all the servers from the Game Coordinator, so
* the ones that are no longer listed are removed.
*/
void NetworkGameListRemoveExpired()
{
NetworkGameListHandleDelayedInsert();
NetworkGameList **prev_item = &_network_game_list;
static uint8 requery_cnt = 0;
if (++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return;
requery_cnt = 0;
for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
item->retries++;
if (item->retries < REFRESH_GAMEINFO_X_REQUERIES && (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT)) continue;
for (NetworkGameList *item = _network_game_list; item != nullptr;) {
if (!item->manually && item->version < _network_game_list_version) {
NetworkGameList *remove = item;
item = item->next;
*prev_item = item;
/* item gets mostly zeroed by NetworkUDPQueryServer */
uint8 retries = item->retries;
NetworkUDPQueryServer(item->connection_string);
item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries;
/* Remove GRFConfig information */
ClearGRFConfigList(&remove->info.grfconfig);
delete remove;
} else {
prev_item = &item->next;
item = item->next;
}
}
UpdateNetworkGameWindow();
}
/**

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save