mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
Merge commit 'f1dfa661a1898cde06a38ab4cb230c95912b245b' into jgrpp-beta
# Conflicts: # src/lang/estonian.txt # src/lang/hungarian.txt # src/network/core/game_info.cpp # src/network/core/game_info.h # src/network/core/packet.h # src/network/network.cpp # src/network/network_client.cpp # src/network/network_server.cpp # src/network/network_udp.cpp # src/openttd.cpp # src/string_func.h
This commit is contained in:
commit
da1ac73c02
@ -392,7 +392,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c
|
||||
fios->mtime = 0;
|
||||
strecpy(fios->name, d_name, lastof(fios->name));
|
||||
std::string dirname = std::string(d_name) + PATHSEP;
|
||||
SetDParamStr(0, dirname.c_str());
|
||||
SetDParamStr(0, dirname);
|
||||
GetString(fios->title, STR_SAVELOAD_DIRECTORY, lastof(fios->title));
|
||||
str_validate(fios->title, lastof(fios->title));
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ public:
|
||||
const CompanyProperties &c = *pair.second;
|
||||
if (!c.name.empty()) {
|
||||
SetDParam(1, STR_JUST_RAW_STRING);
|
||||
SetDParamStr(2, c.name.c_str());
|
||||
SetDParamStr(2, c.name);
|
||||
} else {
|
||||
SetDParam(1, c.name_1);
|
||||
SetDParam(2, c.name_2);
|
||||
|
44
src/gfx.cpp
44
src/gfx.cpp
@ -675,6 +675,28 @@ int DrawString(int left, int right, int top, const char *str, TextColour colour,
|
||||
return DrawLayoutLine(*layout.front(), top, left, right, align, underline, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw string, possibly truncated to make it fit in its allocated space
|
||||
*
|
||||
* @param left The left most position to draw on.
|
||||
* @param right The right most position to draw on.
|
||||
* @param top The top most position to draw on.
|
||||
* @param str String to draw.
|
||||
* @param colour Colour used for drawing the string, for details see _string_colourmap in
|
||||
* table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h
|
||||
* @param align The alignment of the string when drawing left-to-right. In the
|
||||
* case a right-to-left language is chosen this is inverted so it
|
||||
* will be drawn in the right direction.
|
||||
* @param underline Whether to underline what has been drawn or not.
|
||||
* @param fontsize The size of the initial characters.
|
||||
* @return In case of left or center alignment the right most pixel we have drawn to.
|
||||
* In case of right alignment the left most pixel we have drawn to.
|
||||
*/
|
||||
int DrawString(int left, int right, int top, const std::string &str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
|
||||
{
|
||||
return DrawString(left, right, top, str.c_str(), colour, align, underline, fontsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw string, possibly truncated to make it fit in its allocated space
|
||||
*
|
||||
@ -825,6 +847,28 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, const char *st
|
||||
return ((align & SA_VERT_MASK) == SA_BOTTOM) ? first_line : last_line;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw string, possibly over multiple lines.
|
||||
*
|
||||
* @param left The left most position to draw on.
|
||||
* @param right The right most position to draw on.
|
||||
* @param top The top most position to draw on.
|
||||
* @param bottom The bottom most position to draw on.
|
||||
* @param str String to draw.
|
||||
* @param colour Colour used for drawing the string, for details see _string_colourmap in
|
||||
* table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h
|
||||
* @param align The horizontal and vertical alignment of the string.
|
||||
* @param underline Whether to underline all strings
|
||||
* @param fontsize The size of the initial characters.
|
||||
*
|
||||
* @return If \a align is #SA_BOTTOM, the top to where we have written, else the bottom to where we have written.
|
||||
*/
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, const std::string &str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
|
||||
{
|
||||
return DrawStringMultiLine(left, right, top, bottom, str.c_str(), colour, align, underline, fontsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw string, possibly over multiple lines.
|
||||
*
|
||||
|
@ -93,8 +93,10 @@ void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSpri
|
||||
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI);
|
||||
|
||||
int DrawString(int left, int right, int top, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawString(int left, int right, int top, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawString(int left, int right, int top, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
|
||||
void DrawCharCentered(WChar c, const Rect &r, TextColour colour);
|
||||
|
@ -572,12 +572,12 @@ public:
|
||||
/* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */
|
||||
GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, nullptr, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix);
|
||||
std::string cargostring = this->MakeCargoListString(indsp->accepts_cargo, cargo_suffix, lengthof(indsp->accepts_cargo), STR_INDUSTRY_VIEW_REQUIRES_N_CARGO);
|
||||
y = DrawStringMultiLine(left, right, y, bottom, cargostring.c_str());
|
||||
y = DrawStringMultiLine(left, right, y, bottom, cargostring);
|
||||
|
||||
/* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */
|
||||
GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, nullptr, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix);
|
||||
cargostring = this->MakeCargoListString(indsp->produced_cargo, cargo_suffix, lengthof(indsp->produced_cargo), STR_INDUSTRY_VIEW_PRODUCES_N_CARGO);
|
||||
y = DrawStringMultiLine(left, right, y, bottom, cargostring.c_str());
|
||||
y = DrawStringMultiLine(left, right, y, bottom, cargostring);
|
||||
|
||||
/* Get the additional purchase info text, if it has not already been queried. */
|
||||
if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) {
|
||||
@ -972,7 +972,7 @@ public:
|
||||
}
|
||||
|
||||
if (!i->text.empty()) {
|
||||
SetDParamStr(0, i->text.c_str());
|
||||
SetDParamStr(0, i->text);
|
||||
y += WD_PAR_VSEP_WIDE;
|
||||
y = DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
|
||||
}
|
||||
|
@ -2248,6 +2248,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Your com
|
||||
STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Your computer took too long to download the map
|
||||
STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Your computer took too long to join the server
|
||||
STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Your player name is not valid
|
||||
STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}The queried server is too old for this client
|
||||
|
||||
############ Leave those lines in this order!!
|
||||
STR_NETWORK_ERROR_CLIENT_GENERAL :general error
|
||||
@ -2299,7 +2300,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} ha
|
||||
STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} has joined spectators
|
||||
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} has started a new company (#{2:NUM})
|
||||
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} has left the game ({2:STRING})
|
||||
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} has changed his/her name to {STRING}
|
||||
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} has changed their name to {STRING}
|
||||
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} gave {2:CURRENCY_LONG} to {1:STRING}
|
||||
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session
|
||||
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait...
|
||||
|
@ -1056,6 +1056,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :12 kuud
|
||||
|
||||
STR_GAME_OPTIONS_LANGUAGE :{BLACK}Keel
|
||||
STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Valib kasutajaliideses kasutatava keele
|
||||
STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% valmis)
|
||||
|
||||
STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Täisekraan
|
||||
STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Märgi see kast, et OpenTTD täisekraanirežiimis mängida
|
||||
@ -1069,6 +1070,8 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}Riistvar
|
||||
STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}Märkides selle ruudu, lubad OpenTTD-l üritada kasutada riistvarakiirendust. Muudetud seade omab mõju pärast mängu taaskäivitust
|
||||
STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Seade omab mõju alles pärast mängu taaskäivitust
|
||||
|
||||
STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync
|
||||
STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Märgi, et ekraani v-sync sisse lülitada. Seade kohaldub alles pärast mängu taaskäivitust. Töötab vaid, kui riistvarakiirendus on peal
|
||||
|
||||
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Liidese suurus
|
||||
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Vali kasutatav liideseelementide suurus
|
||||
@ -1202,6 +1205,7 @@ STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Seaded
|
||||
STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Märksõna:
|
||||
STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Ava kõik
|
||||
STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Sulge kõik
|
||||
STR_CONFIG_SETTING_RESET_ALL :{BLACK}Nulli kõik väärtused
|
||||
STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(seletus puudub)
|
||||
STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}Vaikeväärtus: {ORANGE}{STRING}
|
||||
STR_CONFIG_SETTING_TYPE :{LTBLUE}Seade liik: {ORANGE}{STRING}
|
||||
@ -1210,6 +1214,8 @@ STR_CONFIG_SETTING_TYPE_GAME_MENU :Mängu seade (s
|
||||
STR_CONFIG_SETTING_TYPE_GAME_INGAME :Mängu seaded (hoitakse salvestuses; mõjutab ainult praegust mängu)
|
||||
STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Ettevõtte seaded (hoitakse salvestuses; mõjutab ainult uusi mänge)
|
||||
STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Ettevõtte seaded (hoitakse salvestuses; mõjutab ainult praegust ettevõtet)
|
||||
STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION :{WHITE}Ettevaatust!
|
||||
STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}See toiming nullib kõik mänguseaded.{}Oled sa kindel, et jätkata?
|
||||
|
||||
STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Jagu:
|
||||
STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Liik:
|
||||
@ -2048,6 +2054,8 @@ 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
|
||||
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Avalik
|
||||
|
||||
# Network server list
|
||||
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Mitmikmäng
|
||||
@ -2111,6 +2119,8 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Serveril
|
||||
STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Määra salasõna
|
||||
STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Et server ei oleks avalik, kaitse oma mäng salasõnaga
|
||||
|
||||
STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Nähtavus
|
||||
STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Kas sinu server on kõikidele teistele avalikult nähtav
|
||||
STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} klient{P "" i}
|
||||
STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Kliente kuni:
|
||||
STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS.in :sees
|
||||
@ -2175,12 +2185,45 @@ STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server o
|
||||
STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Ettevõte on kaitstud. Sisesta salasõna
|
||||
|
||||
# Network company list added strings
|
||||
STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Klientide nimekiri
|
||||
STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Ühendatud mängijad
|
||||
STR_NETWORK_COMPANY_LIST_SPECTATE :Jälgi
|
||||
|
||||
# Network client list
|
||||
STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Mitmikmäng
|
||||
STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}Server
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Nimi
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Serveri nimi, kus sa mängid
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Muuda oma serveri nime
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Serveri nimi
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Nähtavus
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Kas sinu server on kõikidele teistele avalikult nähtav
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Mängija
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Nimi
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Sinu mängija nimi
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}Muuda oma mängija nime
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Sinu mängija nimi
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Haldustegevused, mida teha selle ettevõtte peal
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Haldustegevused, mida teha selle ettevõtte peal
|
||||
STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Liitu selle ettevõttega
|
||||
STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Saada sellele mängijale sõnum
|
||||
STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Saada sõnum igale selle ettevõtte mängijale
|
||||
STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Saada sõnum igale vaatlejale
|
||||
STR_NETWORK_CLIENT_LIST_SPECTATORS :Vaatlejad
|
||||
STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Uus ettevõte)
|
||||
STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Loo uus ettevõte ja liitu sellega
|
||||
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
|
||||
|
||||
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
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Salasõnaga avamine
|
||||
|
||||
STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Haldustoiming
|
||||
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Kas oled kindel, et välja visata mängija '{STRING}'?
|
||||
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Kas oled kindel, et sa tahad keelata mängija '{STRING}'?
|
||||
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Kas oled kindel, et tahad kustutada ettevõtte '{COMPANY}'?
|
||||
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Kas oled kindel, et soovid nullida ettevõtte '{COMPANY}' salasõna?
|
||||
|
||||
STR_NETWORK_SERVER :Server
|
||||
STR_NETWORK_CLIENT :Klient
|
||||
@ -2225,6 +2268,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}Ei saa u
|
||||
STR_NETWORK_ERROR_CLIENT_START :{WHITE}Ei õnnestu ühendada
|
||||
STR_NETWORK_ERROR_TIMEOUT :{WHITE}Ühendus nr {NUM} aegus
|
||||
STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Tekkis protokolliviga ja ühendus katkes
|
||||
STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Sinu mängijale ei ole nime määratud. Nime saab määrata mitmikmägu akna ülaosas
|
||||
STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Kliendi osa ei vasta serveri osaga
|
||||
STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Vale salasõna
|
||||
STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Server on täis
|
||||
@ -2237,6 +2281,8 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Sisestas
|
||||
STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Arvutil võttis liitumisega liiga kaua aega
|
||||
STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Kaardi allalaadimine võttis liiga kaua aega
|
||||
STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Serveriga liitumine võttis liiga kaua aega
|
||||
STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Sinu mängija nimi ei vasta nõuetele
|
||||
STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}Päritud server kasutab liiga vana versiooni
|
||||
|
||||
############ Leave those lines in this order!!
|
||||
STR_NETWORK_ERROR_CLIENT_GENERAL :üldine viga
|
||||
@ -2259,6 +2305,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :ei saanud õige
|
||||
STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :üldine aegumine
|
||||
STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :kaardi laadimine võttis liiga kaua aega
|
||||
STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :kaardi töötlemine võttis liiga kaua aega
|
||||
STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :kliendinimi ei vasta nõuetele
|
||||
############ End of leave-in-this-order
|
||||
|
||||
STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Võimalik ühenduse katkemine
|
||||
@ -3102,6 +3149,7 @@ STR_NEWGRF_ERROR_MSG_WARNING :{RED}Hoiatus: {
|
||||
STR_NEWGRF_ERROR_MSG_ERROR :{RED}Viga: {SILVER}{STRING}
|
||||
STR_NEWGRF_ERROR_MSG_FATAL :{RED}Saatuslik viga: {SILVER}{STRING}
|
||||
STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Esines raske NewGRF-i tõrge:{}{STRING}
|
||||
STR_NEWGRF_ERROR_POPUP :{WHITE}Esines viga NewGRF-iga:{}{STRING}
|
||||
STR_NEWGRF_ERROR_VERSION_NUMBER :OpenTTD väitel {1:STRING} ei tööta selle TTDPatch versiooniga.
|
||||
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} on {STRING} TTD osa jaoks.
|
||||
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} on mõeldud kasutamiseks {STRING}
|
||||
|
@ -1176,9 +1176,9 @@ STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Pelin asetukset
|
||||
STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Pelin asetukset (tallennetaan pelitallenteeseen; vaikuttavat vain nykyiseen peliin)
|
||||
STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Yhtiön asetukset (tallennetaan pelitallenteisiin; vaikuttavat vain uusiin peleihin)
|
||||
STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Yhtiön asetukset (tallennetaan pelitallenteeseen; vaikuttavat ainoastaan nykyiseen yhtiöön)
|
||||
STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}Näytä kaikki tulokset muuttamalla{}{SILVER}Kategoriaksi {WHITE}{STRING}
|
||||
STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}Näytä kaikki tulokset muuttamalla{}{SILVER}kategoriaksi {WHITE}{STRING}
|
||||
STR_CONFIG_SETTING_TYPE_HIDES :{BLACK}Näytä kaikki hakutulokset muuttamalla{}{SILVER}Tyypiksi {WHITE}Kaikki asetustyypit
|
||||
STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Näytä kaikki tulokset muuttamalla{}{SILVER}Kategoriaksi {WHITE}{STRING} {BLACK}ja {SILVER}Tyypiksi {WHITE}Kaikki asetustyypit
|
||||
STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Näytä kaikki tulokset muuttamalla{}{SILVER}kategoriaksi {WHITE}{STRING} {BLACK}ja {SILVER}tyypiksi {WHITE}kaikki asetustyypit
|
||||
STR_CONFIG_SETTINGS_NONE :{WHITE}- Ei mitään -
|
||||
|
||||
STR_CONFIG_SETTING_OFF :pois
|
||||
@ -1340,7 +1340,7 @@ STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :Suhteellinen ik
|
||||
STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_BEFORE :{COMMA} kuukau{P 0 si tta} ennen kulkuneuvon käyttöiän loppua
|
||||
STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_AFTER :{COMMA} kuukau{P 0 si tta} jälkeen kulkuneuvon käyttöiän lopun
|
||||
STR_CONFIG_SETTING_AUTORENEW_MONEY :Vähimmäisrahamäärä kulkuneuvon automaattiseen uudistukseen: {STRING}
|
||||
STR_CONFIG_SETTING_AUTORENEW_MONEY_HELPTEXT :Pienin rahamäärä, joka on oltava pankissa ennen kulkuneuvojen automaattista uudistamista
|
||||
STR_CONFIG_SETTING_AUTORENEW_MONEY_HELPTEXT :Vähimmäisrahamäärä, jonka on jäätävä pankkiin kulkuneuvoja automaattisesti uudistettaessa
|
||||
STR_CONFIG_SETTING_ERRMSG_DURATION :Virheilmoitusten näyttöaika: {STRING}
|
||||
STR_CONFIG_SETTING_ERRMSG_DURATION_HELPTEXT :Aika virheilmoitusten näyttämiseen punaisessa ikkunassa. Huomaa, että jotkut (kriittiset) virheilmoitukset eivät sulkeudu automaattisesti tämän ajan jälkeen, vaan ne on suljettava käsin
|
||||
STR_CONFIG_SETTING_ERRMSG_DURATION_VALUE :{COMMA} sekunti{P 0 "" a}
|
||||
@ -1464,7 +1464,7 @@ STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Mikäli käytö
|
||||
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Salli pelin ollessa pysäytettynä: {STRING}
|
||||
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Valitse käytössä olevat toiminnot pelin ollessa pysäytettynä
|
||||
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS :Ei mitään toimintoja
|
||||
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_CONSTRUCTION :Kaikki ei-rakennustoiminnot
|
||||
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_CONSTRUCTION :Kaikki paitsi rakennustoiminnot
|
||||
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_LANDSCAPING :Kaikki paitsi maastonmuokkaustoiminnot
|
||||
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_ACTIONS :Kaikki toiminnot
|
||||
STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :Käytä ryhmiä kulkuneuvolistassa: {STRING}
|
||||
@ -1601,7 +1601,7 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_SUMMARY :Tiivistelmä
|
||||
STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Täysi
|
||||
|
||||
STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Värilliset uutiset ilmestyvät: {STRING}
|
||||
STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Vuosi, jonka jälkeen sanomalehdet ovat värillisiä. Ennen tätä vuotta sanomalehdet käyttävät mustavalkoisia kuvia
|
||||
STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Vuosi, josta alkaen sanomalehdet painetaan värillisinä. Ennen tätä vuotta lehdet ovat mustavalkoiset.
|
||||
STR_CONFIG_SETTING_STARTING_YEAR :Aloitusvuosi: {STRING}
|
||||
STR_CONFIG_SETTING_ENDING_YEAR :Pistelaskun päättymisvuosi: {STRING}
|
||||
STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Pelin päättymisvuosi pisteiden laskemista varten. Tämän vuoden lopussa talletetaan yhtiön pistemäärä ja näytetään ennätysluettelo; pelaajat voivat jatkaa pelaamista tämän jälkeenkin.{}Jos päättymisvuosi on ennen alkamisvuotta, ennätyksiä ei näytetä koskaan.
|
||||
@ -1717,13 +1717,13 @@ STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuaalinen
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :epäsymmetrinen
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :symmetrinen
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_PAX :Matkustajien jakautuminen: {STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetrinen" tarkoittaa, että suunnilleen sama määrä matkustajia kulkee asemalta A asemalle B kuin asemalta B asemalle A. "epäsymmetrinen" tarkoittaa, että eri suuntiin voi kulkea eriävä määrä matkustajia. "manuaalinen" tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä matkustajilla.
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä matkustajia kulkee asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voi kulkea eriävä määrä matkustajia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä matkustajilla.
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Postin jakautuminen: {STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetrinen" tarkoittaa, että suunnilleen sama määrä postia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. "epäsymmetrinen" tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä postia. "manuaalinen" tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä postilla.
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä postia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä postia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä postilla.
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Arvokuljetusten jakautuminen: {STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Arvokuljetuksiin kuuluvat arvotavarat lauhkeassa ilmastossa, timantit subtrooppisessa ilmastossa ja kulta pohjoisessa ilmastossa. NewGRF:t voivat kuitenkin muuttaa näitä rahteja. "symmetrinen" tarkoittaa, että suunnilleen sama määrä rahtia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. "epäsymmetrinen" tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä rahtia. "manuaalinen" tarkoittaa, että automaattinen rahdin jakautuminen on poistettu käytöstä rahdilta. Suositeltavia asetuksia ovat "epäsymmetrinen" tai "manuaalinen" pelattaessa pohjoisessa ilmastossa, sillä pankit eivät lähetä kultaa takaisin kaivoksille. Lauhkeassa ja subtrooppisessa ilmastossa pelatessa voidaan myös valita "symmetrinen", sillä pankit lähettävät arvotavaroita takaisin alkuperäiselle pankille.
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Arvokuljetuksiin kuuluvat arvotavarat lauhkeassa ilmastossa, timantit subtrooppisessa ilmastossa ja kulta pohjoisessa ilmastossa. NewGRF:t voivat kuitenkin muuttaa näitä rahteja. ”Symmetrinen” tarkoittaa, että suunnilleen sama määrä rahtia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä rahtia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on poistettu käytöstä rahdilta. Suositeltavia asetuksia ovat ”epäsymmetrinen” tai ”manuaalinen” pelattaessa pohjoisessa ilmastossa, sillä pankit eivät lähetä kultaa takaisin kaivoksille. Lauhkeassa ja subtrooppisessa ilmastossa pelatessa voidaan myös valita ”symmetrinen”, sillä pankit lähettävät arvotavaroita takaisin alkuperäiselle pankille.
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Muiden rahtityyppien jakautuminen: {STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"epäsymmetrinen" tarkoittaa, että eri suuntiin voidaan lähettää eriäviä määriä rahtia. "manuaalinen" tarkoittaa, että automaattinen jakautuminen ei ole käytössä rahdille.
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriäviä määriä rahtia. ”Manuaalinen” tarkoittaa, että automaattinen jakautuminen ei ole käytössä rahdille.
|
||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Jakautumisen tarkkuus: {STRING}
|
||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Mitä suuremmaksi tämä asetus on määritetty, sitä enemmän prosessoriaikaa yhteyskuvaajan laskemiseen kuluu. Mikäli tähän kuluu liian paljon aikaa, saatat havaita pelin nykimistä. Jos arvo on määritetty liian pieneksi, jakauman laskeminen ei ole tarkka ja rahtia ei välttämättä lähetetä odotetuille asemille.
|
||||
STR_CONFIG_SETTING_DEMAND_DISTANCE :Välimatkan vaikutus kysyntään: {STRING}
|
||||
@ -1777,7 +1777,7 @@ STR_CONFIG_SETTING_INTERFACE :{ORANGE}Käytt
|
||||
STR_CONFIG_SETTING_INTERFACE_GENERAL :{ORANGE}Yleinen
|
||||
STR_CONFIG_SETTING_INTERFACE_VIEWPORTS :{ORANGE}Näkymät
|
||||
STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :{ORANGE}Rakentaminen
|
||||
STR_CONFIG_SETTING_ADVISORS :{ORANGE}Uutiset / Neuvonantajat
|
||||
STR_CONFIG_SETTING_ADVISORS :{ORANGE}Uutiset ja neuvonantajat
|
||||
STR_CONFIG_SETTING_COMPANY :{ORANGE}Yhtiö
|
||||
STR_CONFIG_SETTING_ACCOUNTING :{ORANGE}Talous
|
||||
STR_CONFIG_SETTING_VEHICLES :{ORANGE}Kulkuneuvot
|
||||
@ -1882,7 +1882,7 @@ STR_QUIT_NO :{BLACK}Ei
|
||||
# Abandon game
|
||||
STR_ABANDON_GAME_CAPTION :{WHITE}Pelin lopetus
|
||||
STR_ABANDON_GAME_QUERY :{YELLOW}Lopetetaanko peli?
|
||||
STR_ABANDON_SCENARIO_QUERY :{YELLOW}Lopetetaanko skenaario?
|
||||
STR_ABANDON_SCENARIO_QUERY :{YELLOW}Haluatko varmasti hylätä tämän skenaarion?
|
||||
|
||||
# Cheat window
|
||||
STR_CHEATS :{WHITE}Huijaukset
|
||||
@ -2214,7 +2214,7 @@ STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Et ole a
|
||||
STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Tämän asiakkaan versio ei vastaa palvelimen versiota
|
||||
STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Väärä salasana
|
||||
STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Palvelin on täynnä
|
||||
STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Sinut on kielletty palvelimelta
|
||||
STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Sinut on estetty palvelimelta
|
||||
STR_NETWORK_ERROR_KICKED :{WHITE}Sinut potkittiin pihalle palvelimelta
|
||||
STR_NETWORK_ERROR_KICK_MESSAGE :{WHITE}Syy: {STRING}
|
||||
STR_NETWORK_ERROR_CHEATER :{WHITE}Huijaaminen ei ole sallittua tällä palvelimella
|
||||
@ -2224,6 +2224,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Tietokon
|
||||
STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Kartan lataus kesti liian kauan
|
||||
STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Palvelimelle liittyminen kesti liian kauan
|
||||
STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Pelaajanimesi ei kelpaa
|
||||
STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}Kysytty palvelin on liian vanha tälle asiakkaalle
|
||||
|
||||
############ Leave those lines in this order!!
|
||||
STR_NETWORK_ERROR_CLIENT_GENERAL :yleinen virhe
|
||||
@ -2807,7 +2808,7 @@ STR_LAI_OBJECT_DESCRIPTION_COMPANY_OWNED_LAND :Yhtiön omistam
|
||||
STR_ABOUT_OPENTTD :{WHITE}Tietoja OpenTTD:stä
|
||||
STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Alkuperäiset oikeudet {COPYRIGHT} 1995 Chris Sawyer, kaikki oikeudet pidätetään
|
||||
STR_ABOUT_VERSION :{BLACK}OpenTTD-versio {REV}
|
||||
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-{STRING} The OpenTTD team
|
||||
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002–{STRING} The OpenTTD team
|
||||
|
||||
# Framerate display window
|
||||
STR_FRAMERATE_CAPTION :{WHITE}Kuvataajuus
|
||||
@ -3513,8 +3514,8 @@ STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Tarvitse
|
||||
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING}
|
||||
STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} odottamassa{STRING}
|
||||
|
||||
STR_CONFIG_GAME_PRODUCTION :{WHITE}Muokkaa tuotantoa (8:n kerroin, 2040 asti)
|
||||
STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Muuta tuotantotasoa (prosentteina, 800{NBSP}% asti)
|
||||
STR_CONFIG_GAME_PRODUCTION :{WHITE}Muokkaa tuotantoa (8:n kerroin, 2040:een asti)
|
||||
STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Muuta tuotantotasoa (prosentteina, 800{NBSP}%:iin asti)
|
||||
|
||||
# Vehicle lists
|
||||
STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING} – {COMMA} juna{P "" a}
|
||||
|
@ -1023,7 +1023,7 @@ STR_GAME_OPTIONS_CURRENCY_MYR :Maláj ringgit
|
||||
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Balra hajtás
|
||||
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Jobbra hajtás
|
||||
|
||||
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Városnevek
|
||||
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Városnevek:
|
||||
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}A városnevek stílusának kiválasztása
|
||||
|
||||
############ start of townname region
|
||||
@ -1063,6 +1063,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :12 havonta
|
||||
|
||||
STR_GAME_OPTIONS_LANGUAGE :{BLACK}Nyelv
|
||||
STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Válassz nyelvet
|
||||
STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% teljesítve)
|
||||
|
||||
STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Teljes képernyő
|
||||
STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Jelöld be ezt, ha teljes képernyős módban szeretnél játszani az OpenTTD-vel
|
||||
@ -2060,6 +2061,8 @@ 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
|
||||
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Nyilvános
|
||||
|
||||
# Network server list
|
||||
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Hálózati játék
|
||||
@ -2123,6 +2126,8 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}A játé
|
||||
STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Jelszó beállítása
|
||||
STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Védd le a játékodat jelszóval, ha nem akarod hogy illetéktelenek csatlakozzanak
|
||||
|
||||
STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Láthatóság
|
||||
STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Mások láthassák-e a szerveredet a publikus listában
|
||||
STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} kliens
|
||||
STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Játékosok max. száma:
|
||||
STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}A maximálisan felcsatlakozható kliensek számának kiválasztása. Nem szükséges pont ennyi embernek éppen kapcsolódva lennie
|
||||
@ -2186,12 +2191,45 @@ STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}A szerve
|
||||
STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}A vállalat jelszóval van védve. Írd be
|
||||
|
||||
# Network company list added strings
|
||||
STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Kliens lista
|
||||
STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Online játékosok
|
||||
STR_NETWORK_COMPANY_LIST_SPECTATE :Megfigyelés
|
||||
|
||||
# Network client list
|
||||
STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Többjátékos
|
||||
STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}Szerver
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Név
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}A szerver neve amin játszol
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}A szervered nevének szerkesztése
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Szerver neve
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Láthatóság
|
||||
STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Mások láthassák-e a szerveredet a publikus listában
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Játékos
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Név
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}A játékos neved
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}A játékos neved szerkesztése
|
||||
STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Játékos neve
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Adminisztrátori műveletek ehhez a vállalathoz
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Adminisztrátori műveletek ehhez a vállalathoz
|
||||
STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :Csatlakozz ehhez a vállalathoz
|
||||
STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Üzenet küldése ennek a játékosnak
|
||||
STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Üzenet küldése az összes játékosnak ebben a vállalatban
|
||||
STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Üzenet küldése az összes megfigyelőnek
|
||||
STR_NETWORK_CLIENT_LIST_SPECTATORS :Megfigyelők
|
||||
STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Új vállalat)
|
||||
STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Hozz létre egy új vállalatot és csatlakozz
|
||||
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
|
||||
|
||||
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
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Jelszó feloldása
|
||||
|
||||
STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Adminisztrátori művelet
|
||||
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Biztos ki akarod rúgni ezt a játékost: '{STRING}'?
|
||||
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Biztos ki akarod tiltani ezt a játékost: '{STRING}'?
|
||||
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Biztos ki akarod törölni a '{COMPANY}' vállalatot?
|
||||
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Biztos vissza akarod állítani a '{COMPANY}' vállalat jelszavát?
|
||||
|
||||
STR_NETWORK_SERVER :Szerver
|
||||
STR_NETWORK_CLIENT :Kliens
|
||||
@ -2236,6 +2274,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}Nem tudt
|
||||
STR_NETWORK_ERROR_CLIENT_START :{WHITE}Nem tudtam kapcsolódni
|
||||
STR_NETWORK_ERROR_TIMEOUT :{WHITE}A(z) {NUM}. játékos kapcsolata elveszett
|
||||
STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Protokoll-hiba keletkezett és megszakadt a kapcsolat
|
||||
STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}A játékos neved nem lett megadva. A nevet a többjátékos ablak tetején tudod beállítani.
|
||||
STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}A gépeden és a szerveren lévő programnak nem egyezik meg a verziója
|
||||
STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Rossz jelszó
|
||||
STR_NETWORK_ERROR_SERVER_FULL :{WHITE}A szerver tele van
|
||||
@ -2248,6 +2287,8 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Túl sok
|
||||
STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}A számítógéped túl lassú, hogy tartsa a szerver sebességét
|
||||
STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Túl sokáig tartott a térkép letöltése a számítógépednek
|
||||
STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Túl sokáig tartott a szerverhez való csatlakozása a számítógépednek
|
||||
STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}A játékos neved nem megfelelő
|
||||
STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}A lekérdezett szerver túl régi ehhez a klienshez
|
||||
|
||||
############ Leave those lines in this order!!
|
||||
STR_NETWORK_ERROR_CLIENT_GENERAL :általános hiba
|
||||
@ -2270,6 +2311,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :nem érkezett j
|
||||
STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :általános időtúllépés
|
||||
STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :térkép letöltés túl sokáig tartott
|
||||
STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :térkép feldolgozás túl sokáig tartott
|
||||
STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :Érvénytelen kliens név
|
||||
############ End of leave-in-this-order
|
||||
|
||||
STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Lehetséges, hogy elveszett a kapcsolat
|
||||
@ -3113,6 +3155,7 @@ STR_NEWGRF_ERROR_MSG_WARNING :{RED}Figyelmezt
|
||||
STR_NEWGRF_ERROR_MSG_ERROR :{RED}Hiba: {SILVER}{STRING}
|
||||
STR_NEWGRF_ERROR_MSG_FATAL :{RED}Végzetes hiba: {SILVER}{STRING}
|
||||
STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Egy végzetes NewGRF hiba történt:{}{STRING}
|
||||
STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF hiba történt:{}{STRING}
|
||||
STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} nem fog működni az OpenTTD által jelentett TTDPatch verzióval
|
||||
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} a TTD {STRING} verziójához van
|
||||
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} úgy lett tervezve, hogy együtt lesz használva ezzel: {STRING}
|
||||
|
@ -409,7 +409,7 @@ STR_SETTINGS_MENU_SIGNS_DISPLAYED :팻말을 표
|
||||
STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :경쟁사의 팻말과 역 이름을 표시
|
||||
STR_SETTINGS_MENU_FULL_ANIMATION :완전한 애니메이션
|
||||
STR_SETTINGS_MENU_FULL_DETAIL :그래픽을 아주 상세하게
|
||||
STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS :건물 숨기기
|
||||
STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS :건물 감추기
|
||||
STR_SETTINGS_MENU_TRANSPARENT_SIGNS :역명판 감추기
|
||||
STR_SETTINGS_MENU_MONEY_TEXT_EFFECTS :수입/지출 표시
|
||||
############ range ends here
|
||||
|
@ -2277,7 +2277,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} en
|
||||
STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} entrou como espectador
|
||||
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} iniciou uma nova empresa (#{2:NUM})
|
||||
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} deixou o jogo ({2:STRING})
|
||||
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} mudou o seu nome para {STRING}
|
||||
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} mudou o nome para {STRING}
|
||||
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} deu {2:CURRENCY_LONG} a {1:STRING}
|
||||
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servidor fechou a sessão
|
||||
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor está a reiniciar...{}Por favor espere...
|
||||
|
@ -2430,7 +2430,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} п
|
||||
STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} подключился в качестве зрителя
|
||||
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} основал новую компанию (#{2:NUM})
|
||||
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} покинул игру ({2:STRING})
|
||||
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} изменил имя на {STRING}
|
||||
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} сменил(а) имя на {STRING}
|
||||
STR_NETWORK_MESSAGE_GIVE_MONEY :*** Компания «{STRING}» передала «{STRING}» {CURRENCY_LONG}
|
||||
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Сервер закрыл сессию
|
||||
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Сервер перезапускается...{}Пожалуйста, подождите...
|
||||
|
@ -2225,6 +2225,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Su orden
|
||||
STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Su ordenador necesitó demasiado tiempo para descargar el mapa
|
||||
STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Su ordenador necesitó demasiado tiempo para conectar al servidor
|
||||
STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Tu nombre de jugador no es válido
|
||||
STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}El servidor es demasiado antiguo para este cliente.
|
||||
|
||||
############ Leave those lines in this order!!
|
||||
STR_NETWORK_ERROR_CLIENT_GENERAL :error general
|
||||
|
@ -462,7 +462,7 @@ struct MusicTrackSelectionWindow : public Window {
|
||||
SetDParam(0, STR_MUSIC_PLAYLIST_ALL + _settings_client.music.playlist);
|
||||
break;
|
||||
case WID_MTS_CAPTION:
|
||||
SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str());
|
||||
SetDParamStr(0, BaseMusic::GetUsedSet()->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -23,11 +23,13 @@ static const int DEFAULT_CONNECT_TIMEOUT_SECONDS = 3; ///< Allow connect() three
|
||||
*/
|
||||
const char *NetworkAddress::GetHostname()
|
||||
{
|
||||
if (StrEmpty(this->hostname) && this->address.ss_family != AF_UNSPEC) {
|
||||
if (this->hostname.empty() && this->address.ss_family != AF_UNSPEC) {
|
||||
assert(this->address_length != 0);
|
||||
getnameinfo((struct sockaddr *)&this->address, this->address_length, this->hostname, sizeof(this->hostname), nullptr, 0, NI_NUMERICHOST);
|
||||
char buffer[NETWORK_HOSTNAME_LENGTH];
|
||||
getnameinfo((struct sockaddr *)&this->address, this->address_length, buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);
|
||||
this->hostname = buffer;
|
||||
}
|
||||
return this->hostname;
|
||||
return this->hostname.c_str();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,32 +246,32 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList *
|
||||
/* Setting both hostname to nullptr and port to 0 is not allowed.
|
||||
* As port 0 means bind to any port, the other must mean that
|
||||
* we want to bind to 'all' IPs. */
|
||||
if (StrEmpty(this->hostname) && this->address_length == 0 && this->GetPort() == 0) {
|
||||
if (this->hostname.empty() && this->address_length == 0 && this->GetPort() == 0) {
|
||||
reset_hostname = true;
|
||||
int fam = this->address.ss_family;
|
||||
if (fam == AF_UNSPEC) fam = family;
|
||||
strecpy(this->hostname, fam == AF_INET ? "0.0.0.0" : "::", lastof(this->hostname));
|
||||
this->hostname = fam == AF_INET ? "0.0.0.0" : "::";
|
||||
}
|
||||
|
||||
static bool _resolve_timeout_error_message_shown = false;
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
int e = getaddrinfo(StrEmpty(this->hostname) ? nullptr : this->hostname, port_name, &hints, &ai);
|
||||
int e = getaddrinfo(this->hostname.empty() ? nullptr : this->hostname.c_str(), port_name, &hints, &ai);
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
std::chrono::seconds duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
|
||||
if (!_resolve_timeout_error_message_shown && duration >= std::chrono::seconds(5)) {
|
||||
DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s took %i seconds",
|
||||
this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), (int)duration.count());
|
||||
this->hostname.c_str(), port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), (int)duration.count());
|
||||
DEBUG(net, 0, " this is likely an issue in the DNS name resolver's configuration causing it to time out");
|
||||
_resolve_timeout_error_message_shown = true;
|
||||
}
|
||||
|
||||
|
||||
if (reset_hostname) strecpy(this->hostname, "", lastof(this->hostname));
|
||||
if (reset_hostname) this->hostname.clear();
|
||||
|
||||
if (e != 0) {
|
||||
if (func != ResolveLoopProc) {
|
||||
DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s failed: %s",
|
||||
this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)).c_str());
|
||||
this->hostname.c_str(), port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)).c_str());
|
||||
}
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@ -452,11 +454,11 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets)
|
||||
{
|
||||
assert(sockets != nullptr);
|
||||
|
||||
/* Setting both hostname to nullptr and port to 0 is not allowed.
|
||||
/* Setting both hostname to "" and port to 0 is not allowed.
|
||||
* As port 0 means bind to any port, the other must mean that
|
||||
* we want to bind to 'all' IPs. */
|
||||
if (this->address_length == 0 && this->address.ss_family == AF_UNSPEC &&
|
||||
StrEmpty(this->hostname) && this->GetPort() == 0) {
|
||||
this->hostname.empty() && this->GetPort() == 0) {
|
||||
this->Resolve(AF_INET, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc);
|
||||
this->Resolve(AF_INET6, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc);
|
||||
} else {
|
||||
|
@ -28,10 +28,10 @@ typedef SmallMap<NetworkAddress, SOCKET> SocketList; ///< Type for a mapping
|
||||
*/
|
||||
class NetworkAddress {
|
||||
private:
|
||||
char hostname[NETWORK_HOSTNAME_LENGTH]; ///< The hostname
|
||||
int address_length; ///< The length of the resolved address
|
||||
sockaddr_storage address; ///< The resolved address
|
||||
bool resolved; ///< Whether the address has been (tried to be) resolved
|
||||
std::string hostname; ///< The hostname
|
||||
int address_length; ///< The length of the resolved address
|
||||
sockaddr_storage address; ///< The resolved address
|
||||
bool resolved; ///< Whether the address has been (tried to be) resolved
|
||||
|
||||
/**
|
||||
* Helper function to resolve something to a socket.
|
||||
@ -52,7 +52,6 @@ public:
|
||||
address(address),
|
||||
resolved(address_length != 0)
|
||||
{
|
||||
*this->hostname = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +63,6 @@ public:
|
||||
address_length(address_length),
|
||||
resolved(address_length != 0)
|
||||
{
|
||||
*this->hostname = '\0';
|
||||
memset(&this->address, 0, sizeof(this->address));
|
||||
memcpy(&this->address, address, address_length);
|
||||
}
|
||||
@ -75,16 +73,15 @@ public:
|
||||
* @param port the port
|
||||
* @param family the address family
|
||||
*/
|
||||
NetworkAddress(const char *hostname = "", uint16 port = 0, int family = AF_UNSPEC) :
|
||||
NetworkAddress(std::string_view hostname = "", uint16 port = 0, int family = AF_UNSPEC) :
|
||||
address_length(0),
|
||||
resolved(false)
|
||||
{
|
||||
/* Also handle IPv6 bracket enclosed hostnames */
|
||||
if (StrEmpty(hostname)) hostname = "";
|
||||
if (*hostname == '[') hostname++;
|
||||
strecpy(this->hostname, StrEmpty(hostname) ? "" : hostname, lastof(this->hostname));
|
||||
char *tmp = strrchr(this->hostname, ']');
|
||||
if (tmp != nullptr) *tmp = '\0';
|
||||
if (!hostname.empty() && hostname.front() == '[' && hostname.back() == ']') {
|
||||
hostname.remove_prefix(1);
|
||||
hostname.remove_suffix(1);
|
||||
}
|
||||
this->hostname = hostname;
|
||||
|
||||
memset(&this->address, 0, sizeof(this->address));
|
||||
this->address.ss_family = family;
|
||||
|
@ -113,7 +113,7 @@ bool IsNetworkCompatibleVersion(const char *other, bool extended)
|
||||
void CheckGameCompatibility(NetworkGameInfo &ngi, bool extended)
|
||||
{
|
||||
/* Check if we are allowed on this server based on the revision-check. */
|
||||
ngi.version_compatible = IsNetworkCompatibleVersion(ngi.server_revision, extended);
|
||||
ngi.version_compatible = IsNetworkCompatibleVersion(ngi.server_revision.c_str(), extended);
|
||||
ngi.compatible = ngi.version_compatible;
|
||||
|
||||
/* Check if we have all the GRFs on the client-system too. */
|
||||
@ -123,31 +123,37 @@ void CheckGameCompatibility(NetworkGameInfo &ngi, bool extended)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill a NetworkGameInfo structure with the latest information of the server.
|
||||
* @param ngi the NetworkGameInfo struct to fill with data.
|
||||
* Fill a NetworkServerGameInfo structure with the static content, or things
|
||||
* that are so static they can be updated on request from a settings change.
|
||||
*/
|
||||
void FillNetworkGameInfo(NetworkGameInfo &ngi)
|
||||
void FillStaticNetworkServerGameInfo()
|
||||
{
|
||||
/* Update some game_info */
|
||||
ngi.clients_on = _network_game_info.clients_on;
|
||||
ngi.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
|
||||
_network_game_info.use_password = !StrEmpty(_settings_client.network.server_password);
|
||||
_network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
|
||||
_network_game_info.clients_max = _settings_client.network.max_clients;
|
||||
_network_game_info.companies_max = _settings_client.network.max_companies;
|
||||
_network_game_info.spectators_max = _settings_client.network.max_spectators;
|
||||
_network_game_info.map_width = MapSizeX();
|
||||
_network_game_info.map_height = MapSizeY();
|
||||
_network_game_info.landscape = _settings_game.game_creation.landscape;
|
||||
_network_game_info.dedicated = _network_dedicated;
|
||||
_network_game_info.grfconfig = _grfconfig;
|
||||
|
||||
ngi.use_password = !StrEmpty(_settings_client.network.server_password);
|
||||
ngi.clients_max = _settings_client.network.max_clients;
|
||||
ngi.companies_on = (byte)Company::GetNumItems();
|
||||
ngi.companies_max = _settings_client.network.max_companies;
|
||||
ngi.spectators_on = NetworkSpectatorCount();
|
||||
ngi.spectators_max = _settings_client.network.max_spectators;
|
||||
ngi.game_date = _date;
|
||||
ngi.map_width = MapSizeX();
|
||||
ngi.map_height = MapSizeY();
|
||||
ngi.map_set = _settings_game.game_creation.landscape;
|
||||
ngi.dedicated = _network_dedicated;
|
||||
ngi.grfconfig = _grfconfig;
|
||||
_network_game_info.server_name = _settings_client.network.server_name;
|
||||
_network_game_info.server_revision = GetNetworkRevisionString();
|
||||
}
|
||||
|
||||
strecpy(ngi.server_name, _settings_client.network.server_name, lastof(ngi.server_name));
|
||||
strecpy(ngi.server_revision, GetNetworkRevisionString(), lastof(ngi.server_revision));
|
||||
strecpy(ngi.short_server_revision, _openttd_revision, lastof(ngi.short_server_revision));
|
||||
/**
|
||||
* Get the NetworkServerGameInfo structure with the latest information of the server.
|
||||
* @return The current NetworkServerGameInfo.
|
||||
*/
|
||||
const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo()
|
||||
{
|
||||
/* Client_on is used as global variable to keep track on the number of clients. */
|
||||
_network_game_info.companies_on = (byte)Company::GetNumItems();
|
||||
_network_game_info.spectators_on = NetworkSpectatorCount();
|
||||
_network_game_info.game_date = _date;
|
||||
return &_network_game_info;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,7 +187,7 @@ static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
|
||||
* @param p the packet to write the data to.
|
||||
* @param info the NetworkGameInfo struct to serialize from.
|
||||
*/
|
||||
void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info)
|
||||
void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info)
|
||||
{
|
||||
p->Send_uint8 (NETWORK_GAME_INFO_VERSION);
|
||||
|
||||
@ -247,7 +253,7 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info)
|
||||
p->Send_string(""); // Used to be map-name.
|
||||
p->Send_uint16(info->map_width);
|
||||
p->Send_uint16(info->map_height);
|
||||
p->Send_uint8 (info->map_set);
|
||||
p->Send_uint8 (info->landscape);
|
||||
p->Send_bool (info->dedicated);
|
||||
}
|
||||
|
||||
@ -256,7 +262,7 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info)
|
||||
* @param p the packet to write the data to
|
||||
* @param info the NetworkGameInfo struct to serialize
|
||||
*/
|
||||
void SerializeNetworkGameInfoExtended(Packet *p, const NetworkGameInfo *info, uint16 flags, uint16 version)
|
||||
void SerializeNetworkGameInfoExtended(Packet *p, const NetworkServerGameInfo *info, uint16 flags, uint16 version)
|
||||
{
|
||||
p->Send_uint8(0); // version num
|
||||
|
||||
@ -275,7 +281,7 @@ void SerializeNetworkGameInfoExtended(Packet *p, const NetworkGameInfo *info, ui
|
||||
p->Send_string(""); // Used to be map-name.
|
||||
p->Send_uint32(info->map_width);
|
||||
p->Send_uint32(info->map_height);
|
||||
p->Send_uint8 (info->map_set);
|
||||
p->Send_uint8 (info->landscape);
|
||||
p->Send_bool (info->dedicated);
|
||||
|
||||
{
|
||||
@ -310,7 +316,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
|
||||
{
|
||||
static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
|
||||
|
||||
info->game_info_version = p->Recv_uint8();
|
||||
byte game_info_version = p->Recv_uint8();
|
||||
|
||||
/*
|
||||
* Please observe the order.
|
||||
@ -320,7 +326,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
|
||||
/* Update the documentation in game_info.h on changes
|
||||
* to the NetworkGameInfo wire-protocol! */
|
||||
|
||||
switch (info->game_info_version) {
|
||||
switch (game_info_version) {
|
||||
case 4: {
|
||||
GRFConfig **dst = &info->grfconfig;
|
||||
uint i;
|
||||
@ -353,24 +359,24 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
|
||||
FALLTHROUGH;
|
||||
|
||||
case 1:
|
||||
p->Recv_string(info->server_name, sizeof(info->server_name));
|
||||
p->Recv_string(info->server_revision, sizeof(info->server_revision));
|
||||
info->server_name = p->Recv_string(NETWORK_NAME_LENGTH);
|
||||
info->server_revision = p->Recv_string(NETWORK_REVISION_LENGTH);
|
||||
p->Recv_uint8 (); // Used to contain server-lang.
|
||||
info->use_password = p->Recv_bool ();
|
||||
info->clients_max = p->Recv_uint8 ();
|
||||
info->clients_on = p->Recv_uint8 ();
|
||||
info->spectators_on = p->Recv_uint8 ();
|
||||
if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
|
||||
if (game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
|
||||
info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
|
||||
info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
|
||||
}
|
||||
while (p->Recv_uint8() != 0) {} // Used to contain the map-name.
|
||||
info->map_width = p->Recv_uint16();
|
||||
info->map_height = p->Recv_uint16();
|
||||
info->map_set = p->Recv_uint8 ();
|
||||
info->landscape = p->Recv_uint8 ();
|
||||
info->dedicated = p->Recv_bool ();
|
||||
|
||||
if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
|
||||
if (info->landscape >= NETWORK_NUM_LANDSCAPES) info->landscape = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,15 +392,13 @@ void DeserializeNetworkGameInfoExtended(Packet *p, NetworkGameInfo *info)
|
||||
const uint8 version = p->Recv_uint8();
|
||||
if (version > 0) return; // Unknown version
|
||||
|
||||
info->game_info_version = 255;
|
||||
|
||||
info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
|
||||
info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
|
||||
info->companies_max = p->Recv_uint8 ();
|
||||
info->companies_on = p->Recv_uint8 ();
|
||||
info->spectators_max = p->Recv_uint8 ();
|
||||
p->Recv_string(info->server_name, sizeof(info->server_name));
|
||||
p->Recv_string(info->server_revision, sizeof(info->server_revision));
|
||||
info->server_name = p->Recv_string(NETWORK_NAME_LENGTH);
|
||||
info->server_revision = p->Recv_string(NETWORK_LONG_REVISION_LENGTH);
|
||||
p->Recv_uint8 (); // Used to contain server-lang.
|
||||
info->use_password = p->Recv_bool ();
|
||||
info->clients_max = p->Recv_uint8 ();
|
||||
@ -403,7 +407,7 @@ void DeserializeNetworkGameInfoExtended(Packet *p, NetworkGameInfo *info)
|
||||
while (p->Recv_uint8() != 0) {} // Used to contain the map-name.
|
||||
info->map_width = p->Recv_uint32();
|
||||
info->map_height = p->Recv_uint32();
|
||||
info->map_set = p->Recv_uint8 ();
|
||||
info->landscape = p->Recv_uint8 ();
|
||||
info->dedicated = p->Recv_bool ();
|
||||
|
||||
{
|
||||
@ -425,7 +429,7 @@ void DeserializeNetworkGameInfoExtended(Packet *p, NetworkGameInfo *info)
|
||||
}
|
||||
}
|
||||
|
||||
if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
|
||||
if (info->landscape >= NETWORK_NUM_LANDSCAPES) info->landscape = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,36 +57,34 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* The game information that is not generated on-the-fly and has to
|
||||
* be sent to the clients.
|
||||
* The game information that is sent from the server to the client.
|
||||
*/
|
||||
struct NetworkServerGameInfo {
|
||||
byte clients_on; ///< Current count of clients on server
|
||||
GRFConfig *grfconfig; ///< List of NewGRF files used
|
||||
Date start_date; ///< When the game started
|
||||
Date game_date; ///< Current date
|
||||
uint32 map_width; ///< Map width
|
||||
uint32 map_height; ///< Map height
|
||||
std::string server_name; ///< Server name
|
||||
std::string server_revision; ///< The version number the server is using (e.g.: 'r304' or 0.5.0)
|
||||
bool dedicated; ///< Is this a dedicated server?
|
||||
bool use_password; ///< Is this server passworded?
|
||||
byte clients_on; ///< Current count of clients on server
|
||||
byte clients_max; ///< Max clients allowed on server
|
||||
byte companies_on; ///< How many started companies do we have
|
||||
byte companies_max; ///< Max companies allowed on server
|
||||
byte spectators_on; ///< How many spectators do we have?
|
||||
byte spectators_max; ///< Max spectators allowed on server
|
||||
byte landscape; ///< The used landscape
|
||||
};
|
||||
|
||||
/**
|
||||
* The game information that is sent from the server to the clients.
|
||||
* The game information that is sent from the server to the clients
|
||||
* with extra information only required at the client side.
|
||||
*/
|
||||
struct NetworkGameInfo : NetworkServerGameInfo {
|
||||
GRFConfig *grfconfig; ///< List of NewGRF files used
|
||||
Date start_date; ///< When the game started
|
||||
Date game_date; ///< Current date
|
||||
uint32 map_width; ///< Map width
|
||||
uint32 map_height; ///< Map height
|
||||
char server_name[NETWORK_NAME_LENGTH]; ///< Server name
|
||||
char short_server_revision[NETWORK_REVISION_LENGTH]; ///< The version number the server is using (e.g.: 'r304' or 0.5.0) (truncated)
|
||||
char server_revision[NETWORK_LONG_REVISION_LENGTH]; ///< The version number the server is using (e.g.: 'r304' or 0.5.0)
|
||||
bool dedicated; ///< Is this a dedicated server?
|
||||
bool version_compatible; ///< Can we connect to this server or not? (based on server_revision)
|
||||
bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match
|
||||
bool use_password; ///< Is this server passworded?
|
||||
byte game_info_version; ///< Version of the game info
|
||||
byte clients_max; ///< Max clients allowed on server
|
||||
byte companies_on; ///< How many started companies do we have
|
||||
byte companies_max; ///< Max companies allowed on server
|
||||
byte spectators_on; ///< How many spectators do we have?
|
||||
byte spectators_max; ///< Max spectators allowed on server
|
||||
byte map_set; ///< Graphical set
|
||||
};
|
||||
|
||||
extern NetworkServerGameInfo _network_game_info;
|
||||
@ -95,14 +93,15 @@ const char *GetNetworkRevisionString();
|
||||
bool IsNetworkCompatibleVersion(const char *other, bool extended = false);
|
||||
void CheckGameCompatibility(NetworkGameInfo &ngi, bool extended = false);
|
||||
|
||||
void FillNetworkGameInfo(NetworkGameInfo &ngi);
|
||||
void FillStaticNetworkServerGameInfo();
|
||||
const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo();
|
||||
|
||||
void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf);
|
||||
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf);
|
||||
|
||||
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info);
|
||||
void DeserializeNetworkGameInfoExtended(Packet *p, NetworkGameInfo *info);
|
||||
void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info);
|
||||
void SerializeNetworkGameInfoExtended(Packet *p, const NetworkGameInfo *info, uint16 flags, uint16 version);
|
||||
void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info);
|
||||
void SerializeNetworkGameInfoExtended(Packet *p, const NetworkServerGameInfo *info, uint16 flags, uint16 version);
|
||||
|
||||
#endif /* NETWORK_CORE_GAME_INFO_H */
|
||||
|
@ -168,12 +168,11 @@ void Packet::Send_uint64(uint64 data)
|
||||
* the string + '\0'. No size-byte or something.
|
||||
* @param data The string to send
|
||||
*/
|
||||
void Packet::Send_string(const char *data)
|
||||
void Packet::Send_string(const std::string_view data)
|
||||
{
|
||||
assert(data != nullptr);
|
||||
/* Length of the string + 1 for the '\0' termination. */
|
||||
assert(this->CanWriteToPacket(strlen(data) + 1));
|
||||
while (this->buffer.emplace_back(*data++) != '\0') {}
|
||||
assert(this->CanWriteToPacket(data.size() + 1));
|
||||
this->buffer.insert(this->buffer.end(), data.begin(), data.end());
|
||||
this->buffer.emplace_back('\0');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -404,6 +403,35 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set
|
||||
str_validate(bufp, last, settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads characters (bytes) from the packet until it finds a '\0', or reaches a
|
||||
* maximum of \c length characters.
|
||||
* When the '\0' has not been reached in the first \c length read characters,
|
||||
* more characters are read from the packet until '\0' has been reached. However,
|
||||
* these characters will not end up in the returned string.
|
||||
* The length of the returned string will be at most \c length - 1 characters.
|
||||
* @param length The maximum length of the string including '\0'.
|
||||
* @param settings The string validation settings.
|
||||
* @return The validated string.
|
||||
*/
|
||||
std::string Packet::Recv_string(size_t length, StringValidationSettings settings)
|
||||
{
|
||||
assert(length > 1);
|
||||
|
||||
/* Both loops with Recv_uint8 terminate when reading past the end of the
|
||||
* packet as Recv_uint8 then closes the connection and returns 0. */
|
||||
std::string str;
|
||||
char character;
|
||||
while (--length > 0 && (character = this->Recv_uint8()) != '\0') str.push_back(character);
|
||||
|
||||
if (length == 0) {
|
||||
/* The string in the packet was longer. Read until the termination. */
|
||||
while (this->Recv_uint8() != '\0') {}
|
||||
}
|
||||
|
||||
return str_validate(str, settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of bytes that are still available for the Transfer functions.
|
||||
* @return The number of bytes that still have to be transfered.
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
void Send_uint16(uint16 data);
|
||||
void Send_uint32(uint32 data);
|
||||
void Send_uint64(uint64 data);
|
||||
void Send_string(const char *data);
|
||||
void Send_string(const std::string_view data);
|
||||
size_t Send_bytes (const byte *begin, const byte *end);
|
||||
void Send_binary(const char *data, const size_t size);
|
||||
|
||||
@ -88,6 +88,7 @@ public:
|
||||
uint32 Recv_uint32();
|
||||
uint64 Recv_uint64();
|
||||
void Recv_string(char *buffer, size_t size, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
|
||||
std::string Recv_string(size_t length, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
|
||||
void Recv_string(std::string &buffer, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
|
||||
void Recv_binary(char *buffer, size_t size);
|
||||
void Recv_binary(std::string &buffer, size_t size);
|
||||
|
@ -87,7 +87,7 @@ protected:
|
||||
NetworkAddress address;
|
||||
|
||||
public:
|
||||
TCPConnecter(const NetworkAddress &address);
|
||||
TCPConnecter(const std::string &connection_string, uint16 default_port);
|
||||
/** Silence the warnings */
|
||||
virtual ~TCPConnecter() {}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "../../thread.h"
|
||||
|
||||
#include "tcp.h"
|
||||
#include "../network_internal.h"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
@ -21,15 +22,16 @@ static std::vector<TCPConnecter *> _tcp_connecters;
|
||||
|
||||
/**
|
||||
* Create a new connecter for the given address
|
||||
* @param address the (un)resolved address to connect to
|
||||
* @param connection_string the address to connect to
|
||||
*/
|
||||
TCPConnecter::TCPConnecter(const NetworkAddress &address) :
|
||||
TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port) :
|
||||
connected(false),
|
||||
aborted(false),
|
||||
killed(false),
|
||||
sock(INVALID_SOCKET),
|
||||
address(address)
|
||||
sock(INVALID_SOCKET)
|
||||
{
|
||||
this->address = ParseConnectionString(connection_string, default_port);
|
||||
|
||||
_tcp_connecters.push_back(this);
|
||||
if (!StartNewThread(nullptr, "ottd:tcp", &TCPConnecter::ThreadEntry, this)) {
|
||||
this->Connect();
|
||||
|
@ -203,11 +203,9 @@ int NetworkHTTPSocketHandler::HandleHeader()
|
||||
|
||||
*url = '\0';
|
||||
|
||||
NetworkAddress address = ParseConnectionString(hname, 80);
|
||||
|
||||
/* Restore the URL. */
|
||||
*url = '/';
|
||||
new NetworkHTTPContentConnecter(address, callback, url, data, depth);
|
||||
new NetworkHTTPContentConnecter(hname, callback, url, data, depth);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -81,16 +81,14 @@ class NetworkHTTPContentConnecter : TCPConnecter {
|
||||
public:
|
||||
/**
|
||||
* Start the connecting.
|
||||
* @param address the address to connect to
|
||||
* @param callback the callback for HTTP retrieval
|
||||
* @param url the url at the server
|
||||
* @param data the data to send
|
||||
* @param depth the depth (redirect recursion) of the queries
|
||||
* @param connection_string The address to connect to.
|
||||
* @param callback The callback for HTTP retrieval.
|
||||
* @param url The url at the server.
|
||||
* @param data The data to send.
|
||||
* @param depth The depth (redirect recursion) of the queries.
|
||||
*/
|
||||
NetworkHTTPContentConnecter(const NetworkAddress &address,
|
||||
HTTPCallback *callback, const char *url,
|
||||
const char *data = nullptr, int depth = 0) :
|
||||
TCPConnecter(address),
|
||||
NetworkHTTPContentConnecter(const std::string &connection_string, HTTPCallback *callback, const char *url, const char *data = nullptr, int depth = 0) :
|
||||
TCPConnecter(connection_string, 80),
|
||||
callback(callback),
|
||||
url(stredup(url)),
|
||||
data(data),
|
||||
|
@ -28,11 +28,11 @@ NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind)
|
||||
this->bind.push_back(addr);
|
||||
}
|
||||
} else {
|
||||
/* As hostname nullptr and port 0/nullptr don't go well when
|
||||
/* As an empty hostname and port 0 don't go well when
|
||||
* resolving it we need to add an address for each of
|
||||
* the address families we support. */
|
||||
this->bind.emplace_back(nullptr, 0, AF_INET);
|
||||
this->bind.emplace_back(nullptr, 0, AF_INET6);
|
||||
this->bind.emplace_back("", 0, AF_INET);
|
||||
this->bind.emplace_back("", 0, AF_INET6);
|
||||
}
|
||||
|
||||
this->fragment_token = ((uint64) InteractiveRandom()) | (((uint64) InteractiveRandom()) << 32);
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "../gfx_func.h"
|
||||
#include "../error.h"
|
||||
#include "../core/checksum_func.hpp"
|
||||
#include <charconv>
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
@ -479,36 +480,51 @@ static void CheckPauseOnJoin()
|
||||
* Converts a string to ip/port/company
|
||||
* Format: IP:port#company
|
||||
*
|
||||
* connection_string will be re-terminated to separate out the hostname, port will
|
||||
* be set to the port strings given by the user, inside the memory area originally
|
||||
* occupied by connection_string. Similar for company, if set.
|
||||
* Returns the IP part as a string view into the passed string. This view is
|
||||
* valid as long the passed connection string is valid. If there is no port
|
||||
* present in the connection string, the port reference will not be touched.
|
||||
* When there is no company ID present in the connection string or company_id
|
||||
* is nullptr, then company ID will not be touched.
|
||||
*
|
||||
* @param connection_string The string with the connection data.
|
||||
* @param port The port reference to set.
|
||||
* @param company_id The company ID to set, if available.
|
||||
* @return A std::string_view into the connection string with the (IP) address part.
|
||||
*/
|
||||
void ParseFullConnectionString(const char **company, const char **port, char *connection_string)
|
||||
std::string_view ParseFullConnectionString(const std::string &connection_string, uint16 &port, CompanyID *company_id)
|
||||
{
|
||||
bool ipv6 = (strchr(connection_string, ':') != strrchr(connection_string, ':'));
|
||||
for (char *p = connection_string; *p != '\0'; p++) {
|
||||
switch (*p) {
|
||||
case '[':
|
||||
ipv6 = true;
|
||||
break;
|
||||
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);
|
||||
|
||||
case ']':
|
||||
ipv6 = false;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
if (company == nullptr) continue;
|
||||
*company = p + 1;
|
||||
*p = '\0';
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if (ipv6) break;
|
||||
*port = p + 1;
|
||||
*p = '\0';
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t port_offset = ip.find_last_of(':');
|
||||
size_t ipv6_close = ip.find_last_of(']');
|
||||
if (port_offset != std::string::npos && (ipv6_close == std::string::npos || ipv6_close < port_offset)) {
|
||||
std::string_view port_string = ip.substr(port_offset + 1);
|
||||
ip = ip.substr(0, port_offset);
|
||||
std::from_chars(port_string.data(), port_string.data() + port_string.size(), port);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -519,16 +535,11 @@ void ParseFullConnectionString(const char **company, const char **port, char *co
|
||||
* @param default_port The default port to set port to if not in connection_string.
|
||||
* @return A valid NetworkAddress of the parsed information.
|
||||
*/
|
||||
NetworkAddress ParseConnectionString(const std::string &connection_string, int default_port)
|
||||
NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port)
|
||||
{
|
||||
char internal_connection_string[NETWORK_HOSTNAME_PORT_LENGTH];
|
||||
strecpy(internal_connection_string, connection_string.c_str(), lastof(internal_connection_string));
|
||||
|
||||
const char *port = nullptr;
|
||||
ParseFullConnectionString(nullptr, &port, internal_connection_string);
|
||||
|
||||
int rport = port != nullptr ? atoi(port) : default_port;
|
||||
return NetworkAddress(internal_connection_string, rport);
|
||||
uint16 port = default_port;
|
||||
std::string_view ip = ParseFullConnectionString(connection_string, port);
|
||||
return NetworkAddress(ip, port);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -536,24 +547,16 @@ NetworkAddress ParseConnectionString(const std::string &connection_string, int d
|
||||
* NetworkAddress, where the string can be postfixed with "#company" to
|
||||
* indicate the requested company.
|
||||
*
|
||||
* @param company Pointer to the company variable to set iff indicted.
|
||||
* @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.
|
||||
*/
|
||||
NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &connection_string, int default_port)
|
||||
static NetworkAddress ParseGameConnectionString(const std::string &connection_string, uint16 default_port, CompanyID *company)
|
||||
{
|
||||
char internal_connection_string[NETWORK_HOSTNAME_PORT_LENGTH + 4]; // 4 extra for the "#" and company
|
||||
strecpy(internal_connection_string, connection_string.c_str(), lastof(internal_connection_string));
|
||||
|
||||
const char *port_s = nullptr;
|
||||
const char *company_s = nullptr;
|
||||
ParseFullConnectionString(&company_s, &port_s, internal_connection_string);
|
||||
|
||||
if (company_s != nullptr) *company = (CompanyID)atoi(company_s);
|
||||
|
||||
int port = port_s != nullptr ? atoi(port_s) : default_port;
|
||||
return NetworkAddress(internal_connection_string, port);
|
||||
uint16 port = default_port;
|
||||
std::string_view ip = ParseFullConnectionString(connection_string, port, company);
|
||||
return NetworkAddress(ip, port);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -637,9 +640,10 @@ static void NetworkInitialize(bool close_admins = true)
|
||||
class TCPQueryConnecter : TCPConnecter {
|
||||
private:
|
||||
bool request_company_info;
|
||||
std::string connection_string;
|
||||
|
||||
public:
|
||||
TCPQueryConnecter(const NetworkAddress &address, bool request_company_info) : TCPConnecter(address), request_company_info(request_company_info) {}
|
||||
TCPQueryConnecter(const std::string &connection_string, bool request_company_info) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), request_company_info(request_company_info), connection_string(connection_string) {}
|
||||
|
||||
void OnFailure() override
|
||||
{
|
||||
@ -649,24 +653,24 @@ public:
|
||||
void OnConnect(SOCKET s) override
|
||||
{
|
||||
_networking = true;
|
||||
new ClientNetworkGameSocketHandler(s, address);
|
||||
new ClientNetworkGameSocketHandler(s, this->connection_string);
|
||||
MyClient::SendInformationQuery(request_company_info);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Query a server to fetch his game-info.
|
||||
* @param address the address to query.
|
||||
* @param connection_string the address to query.
|
||||
* @param request_company_info Whether to request company info too.
|
||||
*/
|
||||
void NetworkTCPQueryServer(NetworkAddress address, bool request_company_info)
|
||||
void NetworkTCPQueryServer(const std::string &connection_string, bool request_company_info)
|
||||
{
|
||||
if (!_network_available) return;
|
||||
|
||||
NetworkDisconnect();
|
||||
NetworkInitialize();
|
||||
|
||||
new TCPQueryConnecter(address, request_company_info);
|
||||
new TCPQueryConnecter(connection_string, request_company_info);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -680,20 +684,18 @@ NetworkGameList *NetworkAddServer(const std::string &connection_string)
|
||||
{
|
||||
if (connection_string.empty()) return nullptr;
|
||||
|
||||
NetworkAddress address = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT);
|
||||
|
||||
/* Ensure the item already exists in the list */
|
||||
NetworkGameList *item = NetworkGameListAddItem(address);
|
||||
if (StrEmpty(item->info.server_name)) {
|
||||
NetworkGameList *item = NetworkGameListAddItem(connection_string);
|
||||
if (item->info.server_name.empty()) {
|
||||
ClearGRFConfigList(&item->info.grfconfig);
|
||||
address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
|
||||
item->info.server_name = connection_string;
|
||||
item->manually = true;
|
||||
|
||||
NetworkRebuildHostList();
|
||||
UpdateNetworkGameWindow();
|
||||
}
|
||||
|
||||
NetworkTCPQueryServer(address);
|
||||
NetworkTCPQueryServer(connection_string);
|
||||
|
||||
return item;
|
||||
}
|
||||
@ -723,14 +725,17 @@ void NetworkRebuildHostList()
|
||||
_network_host_list.clear();
|
||||
|
||||
for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
|
||||
if (item->manually) _network_host_list.emplace_back(NetworkAddressDumper().GetAddressAsString(&(item->address), false));
|
||||
if (item->manually) _network_host_list.emplace_back(item->connection_string);
|
||||
}
|
||||
}
|
||||
|
||||
/** Non blocking connection create to actually connect to servers */
|
||||
class TCPClientConnecter : TCPConnecter {
|
||||
private:
|
||||
std::string connection_string;
|
||||
|
||||
public:
|
||||
TCPClientConnecter(const NetworkAddress &address) : TCPConnecter(address) {}
|
||||
TCPClientConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
|
||||
|
||||
void OnFailure() override
|
||||
{
|
||||
@ -740,7 +745,7 @@ public:
|
||||
void OnConnect(SOCKET s) override
|
||||
{
|
||||
_networking = true;
|
||||
new ClientNetworkGameSocketHandler(s, this->address);
|
||||
new ClientNetworkGameSocketHandler(s, this->connection_string);
|
||||
IConsoleCmdExec("exec scripts/on_client.scr 0");
|
||||
NetworkClient_Connected();
|
||||
}
|
||||
@ -766,34 +771,12 @@ public:
|
||||
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const char *join_server_password, const char *join_company_password)
|
||||
{
|
||||
CompanyID join_as = default_company;
|
||||
NetworkAddress address = ParseGameConnectionString(&join_as, connection_string, NETWORK_DEFAULT_PORT);
|
||||
std::string resolved_connection_string = ParseGameConnectionString(connection_string, NETWORK_DEFAULT_PORT, &join_as).GetAddressAsString(false);
|
||||
|
||||
if (join_as != COMPANY_NEW_COMPANY && join_as != COMPANY_SPECTATOR) {
|
||||
join_as--;
|
||||
if (join_as >= MAX_COMPANIES) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return NetworkClientConnectGame(address, join_as, join_server_password, join_company_password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a client to the server at the given address.
|
||||
* See the overloaded NetworkClientConnectGame for more details.
|
||||
*
|
||||
* @param address The network address of the server to join to.
|
||||
* @param join_as The company number to join as.
|
||||
* @param join_server_password The password for the server.
|
||||
* @param join_company_password The password for the company.
|
||||
* @return Whether the join has started.
|
||||
*/
|
||||
bool NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const char *join_server_password, const char *join_company_password)
|
||||
{
|
||||
if (!_network_available) return false;
|
||||
if (!NetworkValidateClientName()) return false;
|
||||
|
||||
_network_join.address = address;
|
||||
_network_join.connection_string = resolved_connection_string;
|
||||
_network_join.company = join_as;
|
||||
_network_join.server_password = join_server_password;
|
||||
_network_join.company_password = join_company_password;
|
||||
@ -822,11 +805,11 @@ void NetworkClientJoinGame()
|
||||
NetworkDisconnect();
|
||||
NetworkInitialize();
|
||||
|
||||
strecpy(_settings_client.network.last_joined, _network_join.address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined));
|
||||
strecpy(_settings_client.network.last_joined, _network_join.connection_string.c_str(), lastof(_settings_client.network.last_joined));
|
||||
_network_join_status = NETWORK_JOIN_STATUS_CONNECTING;
|
||||
ShowJoinStatusWindow();
|
||||
|
||||
new TCPClientConnecter(_network_join.address);
|
||||
new TCPClientConnecter(_network_join.connection_string);
|
||||
}
|
||||
|
||||
static void NetworkInitGameInfo()
|
||||
@ -835,6 +818,7 @@ static void NetworkInitGameInfo()
|
||||
strecpy(_settings_client.network.server_name, "Unnamed Server", lastof(_settings_client.network.server_name));
|
||||
}
|
||||
|
||||
FillStaticNetworkServerGameInfo();
|
||||
/* The server is a client too */
|
||||
_network_game_info.clients_on = _network_dedicated ? 0 : 1;
|
||||
|
||||
@ -1243,7 +1227,7 @@ void NetworkStartUp()
|
||||
/* Generate an server id when there is none yet */
|
||||
if (StrEmpty(_settings_client.network.network_id)) NetworkGenerateServerId();
|
||||
|
||||
memset(&_network_game_info, 0, sizeof(_network_game_info));
|
||||
_network_game_info = {};
|
||||
|
||||
NetworkInitialize();
|
||||
DEBUG(net, 3, "[core] network online, multiplayer available");
|
||||
|
@ -150,9 +150,9 @@ void ClientNetworkEmergencySave()
|
||||
* Create a new socket for the client side of the game connection.
|
||||
* @param s The socket to connect with.
|
||||
*/
|
||||
ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler (SOCKET s, NetworkAddress address)
|
||||
ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler (SOCKET s, std::string connection_string)
|
||||
: NetworkGameSocketHandler(s),
|
||||
address(address), savegame(nullptr), token(0), status(STATUS_INACTIVE)
|
||||
connection_string(std::move(connection_string)), savegame(nullptr), token(0), status(STATUS_INACTIVE)
|
||||
{
|
||||
assert(ClientNetworkGameSocketHandler::my_client == nullptr);
|
||||
ClientNetworkGameSocketHandler::my_client = this;
|
||||
@ -702,7 +702,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packe
|
||||
NetworkGameList *item = GetLobbyGameInfo();
|
||||
if (item == nullptr) {
|
||||
/* This is not the lobby, so add it to the game list. */
|
||||
item = NetworkGameListAddItem(this->address);
|
||||
item = NetworkGameListAddItem(this->connection_string);
|
||||
}
|
||||
|
||||
/* Clear any existing GRFConfig chain. */
|
||||
|
@ -15,7 +15,7 @@
|
||||
/** Class for handling the client side of the game connection. */
|
||||
class ClientNetworkGameSocketHandler : public NetworkGameSocketHandler {
|
||||
private:
|
||||
NetworkAddress address; ///< Address we are connected to.
|
||||
std::string connection_string; ///< Address we are connected to.
|
||||
struct PacketReader *savegame; ///< Packet reader for reading the savegame.
|
||||
byte token; ///< The token we need to send back to the server to prove we're the right client.
|
||||
|
||||
@ -86,7 +86,7 @@ protected:
|
||||
static NetworkRecvStatus SendMapOk();
|
||||
void CheckConnection();
|
||||
public:
|
||||
ClientNetworkGameSocketHandler(SOCKET s, NetworkAddress address);
|
||||
ClientNetworkGameSocketHandler(SOCKET s, std::string connection_string);
|
||||
~ClientNetworkGameSocketHandler();
|
||||
|
||||
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override;
|
||||
@ -132,10 +132,10 @@ void NetworkClientSetCompanyPassword(const char *password);
|
||||
/** Information required to join a server. */
|
||||
struct NetworkJoinInfo {
|
||||
NetworkJoinInfo() : company(COMPANY_SPECTATOR), server_password(nullptr), company_password(nullptr) {}
|
||||
NetworkAddress address; ///< The address of the server to join.
|
||||
CompanyID company; ///< The company to join.
|
||||
const char *server_password; ///< The password of the server to join.
|
||||
const char *company_password; ///< The password of the company to join.
|
||||
std::string connection_string; ///< The address of the server to join.
|
||||
CompanyID company; ///< The company to join.
|
||||
const char *server_password; ///< The password of the server to join.
|
||||
const char *company_password; ///< The password of the company to join.
|
||||
};
|
||||
|
||||
extern NetworkJoinInfo _network_join;
|
||||
|
@ -367,8 +367,7 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const Conten
|
||||
|
||||
this->http_response_index = -1;
|
||||
|
||||
NetworkAddress address(NETWORK_CONTENT_MIRROR_HOST, NETWORK_CONTENT_MIRROR_PORT);
|
||||
new NetworkHTTPContentConnecter(address, this, NETWORK_CONTENT_MIRROR_URL, content_request);
|
||||
new NetworkHTTPContentConnecter(NETWORK_CONTENT_MIRROR_HOST, this, NETWORK_CONTENT_MIRROR_URL, content_request);
|
||||
/* NetworkHTTPContentConnecter takes over freeing of content_request! */
|
||||
}
|
||||
|
||||
@ -774,7 +773,7 @@ public:
|
||||
* Initiate the connecting.
|
||||
* @param address The address of the server.
|
||||
*/
|
||||
NetworkContentConnecter(const NetworkAddress &address) : TCPConnecter(address) {}
|
||||
NetworkContentConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_CONTENT_SERVER_PORT) {}
|
||||
|
||||
void OnFailure() override
|
||||
{
|
||||
@ -800,7 +799,7 @@ void ClientNetworkContentSocketHandler::Connect()
|
||||
{
|
||||
if (this->sock != INVALID_SOCKET || this->isConnecting) return;
|
||||
this->isConnecting = true;
|
||||
new NetworkContentConnecter(NetworkAddress(NETWORK_CONTENT_SERVER_HOST, NETWORK_CONTENT_SERVER_PORT, AF_UNSPEC));
|
||||
new NetworkContentConnecter(NETWORK_CONTENT_SERVER_HOST);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ void NetworkReboot();
|
||||
void NetworkDisconnect(bool blocking = false, bool close_admins = true);
|
||||
void NetworkGameLoop();
|
||||
void NetworkBackgroundLoop();
|
||||
void ParseFullConnectionString(const char **company, const char **port, char *connection_string);
|
||||
std::string_view ParseFullConnectionString(const std::string &connection_string, uint16 &port, CompanyID *company_id = nullptr);
|
||||
void NetworkStartDebugLog(const std::string &connection_string);
|
||||
void NetworkPopulateCompanyStats(NetworkCompanyStats *stats);
|
||||
|
||||
@ -70,6 +70,7 @@ void NetworkServerDailyLoop();
|
||||
void NetworkServerMonthlyLoop();
|
||||
void NetworkServerYearlyLoop();
|
||||
void NetworkServerSendConfigUpdate();
|
||||
void NetworkServerUpdateGameInfo();
|
||||
void NetworkServerShowStatusToConsole();
|
||||
bool NetworkServerStart();
|
||||
void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci);
|
||||
|
@ -44,20 +44,20 @@ static void NetworkGameListHandleDelayedInsert()
|
||||
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->address);
|
||||
NetworkGameList *item = NetworkGameListAddItem(ins_item->connection_string);
|
||||
|
||||
if (item != nullptr) {
|
||||
if (StrEmpty(item->info.server_name)) {
|
||||
if (item->info.server_name.empty()) {
|
||||
ClearGRFConfigList(&item->info.grfconfig);
|
||||
memset(&item->info, 0, sizeof(item->info));
|
||||
strecpy(item->info.server_name, ins_item->info.server_name, lastof(item->info.server_name));
|
||||
item->info = {};
|
||||
item->info.server_name = ins_item->info.server_name;
|
||||
item->online = false;
|
||||
}
|
||||
item->manually |= ins_item->manually;
|
||||
if (item->manually) NetworkRebuildHostList();
|
||||
UpdateNetworkGameWindow();
|
||||
}
|
||||
free(ins_item);
|
||||
delete ins_item;
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,19 +67,20 @@ static void NetworkGameListHandleDelayedInsert()
|
||||
* @param address the address of the to-be added item
|
||||
* @return a point to the newly added or already existing item
|
||||
*/
|
||||
NetworkGameList *NetworkGameListAddItem(NetworkAddress address)
|
||||
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);
|
||||
|
||||
prev_item = nullptr;
|
||||
for (item = _network_game_list; item != nullptr; item = item->next) {
|
||||
if (item->address == address) return item;
|
||||
if (item->connection_string == resolved_connection_string) return item;
|
||||
prev_item = item;
|
||||
}
|
||||
|
||||
item = CallocT<NetworkGameList>(1);
|
||||
item->next = nullptr;
|
||||
item->address = address;
|
||||
item = new NetworkGameList(resolved_connection_string);
|
||||
|
||||
if (prev_item == nullptr) {
|
||||
_network_game_list = item;
|
||||
@ -109,8 +110,7 @@ void NetworkGameListRemoveItem(NetworkGameList *remove)
|
||||
|
||||
/* Remove GRFConfig information */
|
||||
ClearGRFConfigList(&remove->info.grfconfig);
|
||||
free(remove);
|
||||
remove = nullptr;
|
||||
delete remove;
|
||||
|
||||
DEBUG(net, 4, "[gamelist] removed server from list");
|
||||
NetworkRebuildHostList();
|
||||
@ -141,7 +141,7 @@ void NetworkGameListRequery()
|
||||
|
||||
/* item gets mostly zeroed by NetworkUDPQueryServer */
|
||||
uint8 retries = item->retries;
|
||||
NetworkUDPQueryServer(item->address);
|
||||
NetworkUDPQueryServer(item->connection_string);
|
||||
item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries;
|
||||
}
|
||||
}
|
||||
|
@ -16,19 +16,24 @@
|
||||
|
||||
/** Structure with information shown in the game list (GUI) */
|
||||
struct NetworkGameList {
|
||||
NetworkGameInfo info; ///< The game information of this server
|
||||
NetworkAddress address; ///< The connection info of the game server
|
||||
bool online; ///< False if the server did not respond (default status)
|
||||
bool manually; ///< True if the server was added manually
|
||||
uint8 retries; ///< Number of retries (to stop requerying)
|
||||
NetworkGameList *next; ///< Next pointer to make a linked game list
|
||||
NetworkGameList(const std::string &connection_string, bool manually = false) :
|
||||
connection_string(connection_string), manually(manually)
|
||||
{
|
||||
}
|
||||
|
||||
NetworkGameInfo info = {}; ///< The game information of this server
|
||||
std::string connection_string; ///< Address of the server
|
||||
bool online = false; ///< False if the server did not respond (default status)
|
||||
bool manually = false; ///< True if the server was added manually
|
||||
uint8 retries = 0; ///< Number of retries (to stop requerying)
|
||||
NetworkGameList *next = nullptr; ///< Next pointer to make a linked game list
|
||||
};
|
||||
|
||||
/** Game list of this client */
|
||||
extern NetworkGameList *_network_game_list;
|
||||
|
||||
void NetworkGameListAddItemDelayed(NetworkGameList *item);
|
||||
NetworkGameList *NetworkGameListAddItem(NetworkAddress address);
|
||||
NetworkGameList *NetworkGameListAddItem(const std::string &connection_string);
|
||||
void NetworkGameListRemoveItem(NetworkGameList *remove);
|
||||
void NetworkGameListRequery();
|
||||
|
||||
|
@ -286,8 +286,10 @@ protected:
|
||||
/** Sort servers by name. */
|
||||
static bool NGameNameSorter(NetworkGameList * const &a, NetworkGameList * const &b)
|
||||
{
|
||||
int r = strnatcmp(a->info.server_name, b->info.server_name, true); // Sort by name (natural sorting).
|
||||
return r == 0 ? a->address.CompareTo(b->address) < 0: r < 0;
|
||||
int r = strnatcmp(a->info.server_name.c_str(), b->info.server_name.c_str(), true); // Sort by name (natural sorting).
|
||||
if (r == 0) r = a->connection_string.compare(b->connection_string);
|
||||
|
||||
return r < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -337,7 +339,7 @@ protected:
|
||||
static bool NGameAllowedSorter(NetworkGameList * const &a, NetworkGameList * const &b)
|
||||
{
|
||||
/* The servers we do not know anything about (the ones that did not reply) should be at the bottom) */
|
||||
int r = StrEmpty(a->info.server_revision) - StrEmpty(b->info.server_revision);
|
||||
int r = a->info.server_revision.empty() - b->info.server_revision.empty();
|
||||
|
||||
/* Reverse default as we are interested in version-compatible clients first */
|
||||
if (r == 0) r = b->info.version_compatible - a->info.version_compatible;
|
||||
@ -374,7 +376,7 @@ protected:
|
||||
assert((*item) != nullptr);
|
||||
|
||||
sf.ResetState();
|
||||
sf.AddLine((*item)->info.server_name);
|
||||
sf.AddLine((*item)->info.server_name.c_str());
|
||||
return sf.GetState();
|
||||
}
|
||||
|
||||
@ -648,7 +650,7 @@ public:
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CLIENTS);
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
|
||||
SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + sel->info.map_set);
|
||||
SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + sel->info.landscape);
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE); // landscape
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
|
||||
@ -661,8 +663,7 @@ public:
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
|
||||
std::string address = sel->address.GetAddressAsString();
|
||||
SetDParamStr(0, address.c_str());
|
||||
SetDParamStr(0, sel->connection_string.c_str());
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_ADDRESS); // server address
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
|
||||
@ -766,7 +767,7 @@ public:
|
||||
break;
|
||||
|
||||
case WID_NG_REFRESH: // Refresh
|
||||
if (this->server != nullptr) NetworkTCPQueryServer(this->server->address);
|
||||
if (this->server != nullptr) NetworkTCPQueryServer(this->server->connection_string);
|
||||
break;
|
||||
|
||||
case WID_NG_NEWGRF: // NewGRF Settings
|
||||
@ -1486,22 +1487,22 @@ struct NetworkLobbyWindow : public Window {
|
||||
|
||||
case WID_NL_JOIN: // Join company
|
||||
/* Button can be clicked only when it is enabled. */
|
||||
NetworkClientConnectGame(this->server->address, this->company);
|
||||
NetworkClientConnectGame(this->server->connection_string, this->company);
|
||||
break;
|
||||
|
||||
case WID_NL_NEW: // New company
|
||||
NetworkClientConnectGame(this->server->address, COMPANY_NEW_COMPANY);
|
||||
NetworkClientConnectGame(this->server->connection_string, COMPANY_NEW_COMPANY);
|
||||
break;
|
||||
|
||||
case WID_NL_SPECTATE: // Spectate game
|
||||
NetworkClientConnectGame(this->server->address, COMPANY_SPECTATOR);
|
||||
NetworkClientConnectGame(this->server->connection_string, COMPANY_SPECTATOR);
|
||||
break;
|
||||
|
||||
case WID_NL_REFRESH: // Refresh
|
||||
/* Clear the information so removed companies don't remain */
|
||||
for (auto &company : this->company_info) company = {};
|
||||
|
||||
NetworkTCPQueryServer(this->server->address, true);
|
||||
NetworkTCPQueryServer(this->server->connection_string, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1569,9 +1570,9 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
|
||||
DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START);
|
||||
DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME);
|
||||
|
||||
strecpy(_settings_client.network.last_joined, ngl->address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined));
|
||||
strecpy(_settings_client.network.last_joined, ngl->connection_string.c_str(), lastof(_settings_client.network.last_joined));
|
||||
|
||||
NetworkTCPQueryServer(ngl->address, true);
|
||||
NetworkTCPQueryServer(ngl->connection_string, true);
|
||||
|
||||
new NetworkLobbyWindow(&_network_lobby_window_desc, ngl);
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ extern uint8 _network_reconnect;
|
||||
|
||||
extern CompanyMask _network_company_passworded;
|
||||
|
||||
void NetworkTCPQueryServer(NetworkAddress address, bool request_company_info = false);
|
||||
void NetworkTCPQueryServer(const std::string &connection_string, bool request_company_info = false);
|
||||
|
||||
void GetBindAddresses(NetworkAddressList *addresses, uint16 port);
|
||||
struct NetworkGameList *NetworkAddServer(const std::string &connection_string);
|
||||
@ -126,8 +126,6 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err);
|
||||
bool NetworkFindName(char *new_name, const char *last);
|
||||
const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed);
|
||||
|
||||
bool NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const char *join_server_password = nullptr, const char *join_company_password = nullptr);
|
||||
NetworkAddress ParseConnectionString(const std::string &connection_string, int default_port);
|
||||
NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &connection_string, int default_port);
|
||||
NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port);
|
||||
|
||||
#endif /* NETWORK_INTERNAL_H */
|
||||
|
@ -360,11 +360,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendClientInfo(NetworkClientIn
|
||||
/** Send the client information about the server. */
|
||||
NetworkRecvStatus ServerNetworkGameSocketHandler::SendGameInfo()
|
||||
{
|
||||
NetworkGameInfo ngi;
|
||||
FillNetworkGameInfo(ngi);
|
||||
|
||||
Packet *p = new Packet(PACKET_SERVER_GAME_INFO, SHRT_MAX);
|
||||
SerializeNetworkGameInfo(p, &ngi);
|
||||
SerializeNetworkGameInfo(p, GetCurrentNetworkServerGameInfo());
|
||||
|
||||
this->SendPacket(p);
|
||||
|
||||
@ -373,11 +370,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendGameInfo()
|
||||
|
||||
NetworkRecvStatus ServerNetworkGameSocketHandler::SendGameInfoExtended(PacketGameType reply_type, uint16 flags, uint16 version)
|
||||
{
|
||||
NetworkGameInfo ngi;
|
||||
FillNetworkGameInfo(ngi);
|
||||
|
||||
Packet *p = new Packet(reply_type, SHRT_MAX);
|
||||
SerializeNetworkGameInfoExtended(p, &ngi, flags, version);
|
||||
SerializeNetworkGameInfoExtended(p, GetCurrentNetworkServerGameInfo(), flags, version);
|
||||
|
||||
this->SendPacket(p);
|
||||
|
||||
@ -2166,6 +2160,12 @@ void NetworkServerSendConfigUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the server's NetworkServerGameInfo due to changes in settings. */
|
||||
void NetworkServerUpdateGameInfo()
|
||||
{
|
||||
if (_network_server) FillStaticNetworkServerGameInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell that a particular company is (not) passworded.
|
||||
* @param company_id The company that got/removed the password.
|
||||
|
@ -102,35 +102,34 @@ static Packet PrepareUdpClientFindServerPacket()
|
||||
|
||||
/**
|
||||
* Helper function doing the actual work for querying the server.
|
||||
* @param address The address of the server.
|
||||
* @param connection_string The address of the server.
|
||||
* @param needs_mutex Whether we need to acquire locks when sending the packet or not.
|
||||
* @param manually Whether the address was entered manually.
|
||||
*/
|
||||
static void DoNetworkUDPQueryServer(NetworkAddress &address, bool needs_mutex, bool manually)
|
||||
static void DoNetworkUDPQueryServer(const std::string &connection_string, bool needs_mutex, bool manually)
|
||||
{
|
||||
/* Clear item in gamelist */
|
||||
NetworkGameList *item = CallocT<NetworkGameList>(1);
|
||||
address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
|
||||
item->address = address;
|
||||
item->manually = manually;
|
||||
NetworkGameList *item = new NetworkGameList(connection_string, manually);
|
||||
item->info.server_name = connection_string;
|
||||
NetworkGameListAddItemDelayed(item);
|
||||
|
||||
std::unique_lock<std::mutex> lock(_udp_client.mutex, std::defer_lock);
|
||||
if (needs_mutex) lock.lock();
|
||||
/* Init the packet */
|
||||
NetworkAddress address = NetworkAddress(ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT));
|
||||
Packet p = PrepareUdpClientFindServerPacket();
|
||||
if (_udp_client.socket != nullptr) _udp_client.socket->SendPacket(&p, &address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query a specific server.
|
||||
* @param address The address of the server.
|
||||
* @param connection_string The address of the server.
|
||||
* @param manually Whether the address was entered manually.
|
||||
*/
|
||||
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
||||
void NetworkUDPQueryServer(const std::string &connection_string, bool manually)
|
||||
{
|
||||
if (address.IsResolved() || !StartNewThread(nullptr, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(address), true, std::move(manually))) {
|
||||
DoNetworkUDPQueryServer(address, true, manually);
|
||||
if (!StartNewThread(nullptr, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(connection_string), true, std::move(manually))) {
|
||||
DoNetworkUDPQueryServer(connection_string, true, manually);
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +172,7 @@ protected:
|
||||
void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) override;
|
||||
void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) override;
|
||||
void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr) override;
|
||||
void Reply_CLIENT_FIND_SERVER_extended(Packet *p, NetworkAddress *client_addr, NetworkGameInfo *ngi);
|
||||
void Reply_CLIENT_FIND_SERVER_extended(Packet *p, NetworkAddress *client_addr, const NetworkServerGameInfo *ngi);
|
||||
public:
|
||||
/**
|
||||
* Create the socket.
|
||||
@ -190,16 +189,13 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *p, Networ
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkGameInfo ngi;
|
||||
FillNetworkGameInfo(ngi);
|
||||
|
||||
if (p->CanReadFromPacket(8) && p->Recv_uint32() == FIND_SERVER_EXTENDED_TOKEN) {
|
||||
this->Reply_CLIENT_FIND_SERVER_extended(p, client_addr, &ngi);
|
||||
this->Reply_CLIENT_FIND_SERVER_extended(p, client_addr, GetCurrentNetworkServerGameInfo());
|
||||
return;
|
||||
}
|
||||
|
||||
Packet packet(PACKET_UDP_SERVER_RESPONSE);
|
||||
SerializeNetworkGameInfo(&packet, &ngi);
|
||||
SerializeNetworkGameInfo(&packet, GetCurrentNetworkServerGameInfo());
|
||||
|
||||
/* Let the client know that we are here */
|
||||
this->SendPacket(&packet, client_addr);
|
||||
@ -207,7 +203,7 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *p, Networ
|
||||
DEBUG(net, 2, "[udp] queried from %s", client_addr->GetHostname());
|
||||
}
|
||||
|
||||
void ServerNetworkUDPSocketHandler::Reply_CLIENT_FIND_SERVER_extended(Packet *p, NetworkAddress *client_addr, NetworkGameInfo *ngi)
|
||||
void ServerNetworkUDPSocketHandler::Reply_CLIENT_FIND_SERVER_extended(Packet *p, NetworkAddress *client_addr, const NetworkServerGameInfo *ngi)
|
||||
{
|
||||
uint16 flags = p->Recv_uint16();
|
||||
uint16 version = p->Recv_uint16();
|
||||
@ -396,7 +392,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE_Common(Packet *p, Ne
|
||||
DEBUG(net, 4, "[udp]%s server response from %s", extended ? " extended" : "", NetworkAddressDumper().GetAddressAsString(client_addr));
|
||||
|
||||
/* Find next item */
|
||||
item = NetworkGameListAddItem(*client_addr);
|
||||
item = NetworkGameListAddItem(client_addr->GetAddressAsString(false));
|
||||
|
||||
/* Clear any existing GRFConfig chain. */
|
||||
ClearGRFConfigList(&item->info.grfconfig);
|
||||
@ -434,7 +430,8 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE_Common(Packet *p, Ne
|
||||
SerializeGRFIdentifier(&packet, &in_request[i]->ident);
|
||||
}
|
||||
|
||||
this->SendPacket(&packet, &item->address);
|
||||
NetworkAddress address = NetworkAddress(ParseConnectionString(item->connection_string, NETWORK_DEFAULT_PORT));
|
||||
this->SendPacket(&packet, &address);
|
||||
|
||||
DEBUG(net, 4, "[udp] sent newgrf data request (%u) to %s", in_request_count, NetworkAddressDumper().GetAddressAsString(client_addr));
|
||||
|
||||
@ -453,7 +450,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE_Common(Packet *p, Ne
|
||||
}
|
||||
|
||||
if (client_addr->GetAddress()->ss_family == AF_INET6) {
|
||||
strecat(item->info.server_name, " (IPv6)", lastof(item->info.server_name));
|
||||
item->info.server_name.append(" (IPv6)");
|
||||
}
|
||||
|
||||
UpdateNetworkGameWindow();
|
||||
@ -489,7 +486,7 @@ void ClientNetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, Netw
|
||||
/* Somehow we reached the end of the packet */
|
||||
if (this->HasClientQuit()) return;
|
||||
|
||||
DoNetworkUDPQueryServer(addr, false, false);
|
||||
DoNetworkUDPQueryServer(addr.GetAddressAsString(false), false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
void NetworkUDPInitialize();
|
||||
void NetworkUDPSearchGame();
|
||||
void NetworkUDPQueryMasterServer();
|
||||
void NetworkUDPQueryServer(NetworkAddress address, bool manually = false);
|
||||
void NetworkUDPQueryServer(const std::string &connection_string, bool manually = false);
|
||||
void NetworkUDPAdvertise();
|
||||
void NetworkUDPRemoveAdvertise(bool blocking);
|
||||
void NetworkUDPClose();
|
||||
|
@ -51,9 +51,9 @@ void ShowNewGRFError()
|
||||
if (c->error == nullptr || (c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL && c->error->severity != STR_NEWGRF_ERROR_MSG_ERROR)) continue;
|
||||
|
||||
SetDParam (0, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING);
|
||||
SetDParamStr(1, c->error->custom_message.c_str());
|
||||
SetDParamStr(1, c->error->custom_message);
|
||||
SetDParamStr(2, c->filename);
|
||||
SetDParamStr(3, c->error->data.c_str());
|
||||
SetDParamStr(3, c->error->data);
|
||||
for (uint i = 0; i < lengthof(c->error->param_value); i++) {
|
||||
SetDParam(4 + i, c->error->param_value[i]);
|
||||
}
|
||||
@ -70,9 +70,9 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint
|
||||
{
|
||||
if (c->error != nullptr) {
|
||||
char message[512];
|
||||
SetDParamStr(0, c->error->custom_message.c_str()); // is skipped by built-in messages
|
||||
SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages
|
||||
SetDParamStr(1, c->filename);
|
||||
SetDParamStr(2, c->error->data.c_str());
|
||||
SetDParamStr(2, c->error->data);
|
||||
for (uint i = 0; i < lengthof(c->error->param_value); i++) {
|
||||
SetDParam(3 + i, c->error->param_value[i]);
|
||||
}
|
||||
@ -752,7 +752,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
case WID_NS_PRESET_LIST: {
|
||||
Dimension d = GetStringBoundingBox(STR_NUM_CUSTOM);
|
||||
for (const auto &i : this->grf_presets) {
|
||||
SetDParamStr(0, i.c_str());
|
||||
SetDParamStr(0, i);
|
||||
d = maxdim(d, GetStringBoundingBox(STR_JUST_RAW_STRING));
|
||||
}
|
||||
d.width += padding.width;
|
||||
@ -785,7 +785,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
SetDParam(0, STR_NUM_CUSTOM);
|
||||
} else {
|
||||
SetDParam(0, STR_JUST_RAW_STRING);
|
||||
SetDParamStr(1, this->grf_presets[this->preset].c_str());
|
||||
SetDParamStr(1, this->grf_presets[this->preset]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -555,7 +555,7 @@ void OpenBrowser(const char *url)
|
||||
struct AfterNewGRFScan : NewGRFScanCallback {
|
||||
Year startyear; ///< The start year.
|
||||
uint32 generation_seed; ///< Seed for the new game.
|
||||
char *dedicated_host; ///< Hostname for the dedicated server.
|
||||
std::string dedicated_host; ///< Hostname for the dedicated server.
|
||||
uint16 dedicated_port; ///< Port for the dedicated server.
|
||||
char *network_conn; ///< Information about the server to connect to, or nullptr.
|
||||
const char *join_server_password; ///< The password to join the server with.
|
||||
@ -567,7 +567,7 @@ struct AfterNewGRFScan : NewGRFScanCallback {
|
||||
*/
|
||||
AfterNewGRFScan() :
|
||||
startyear(INVALID_YEAR), generation_seed(GENERATE_NEW_SEED),
|
||||
dedicated_host(nullptr), dedicated_port(0), network_conn(nullptr),
|
||||
dedicated_port(0), network_conn(nullptr),
|
||||
join_server_password(nullptr), join_company_password(nullptr),
|
||||
save_config(true)
|
||||
{
|
||||
@ -608,7 +608,7 @@ struct AfterNewGRFScan : NewGRFScanCallback {
|
||||
if (startyear != INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", startyear);
|
||||
if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed;
|
||||
|
||||
if (dedicated_host != nullptr) {
|
||||
if (!dedicated_host.empty()) {
|
||||
_network_bind_list.clear();
|
||||
_network_bind_list.emplace_back(dedicated_host);
|
||||
}
|
||||
@ -720,10 +720,7 @@ int openttd_main(int argc, char *argv[])
|
||||
dedicated = true;
|
||||
SetDebugString("net=3");
|
||||
if (mgo.opt != nullptr) {
|
||||
const char *port = nullptr;
|
||||
ParseFullConnectionString(nullptr, &port, mgo.opt);
|
||||
if (!StrEmpty(mgo.opt)) scanner->dedicated_host = mgo.opt;
|
||||
if (port != nullptr) scanner->dedicated_port = atoi(port);
|
||||
scanner->dedicated_host = ParseFullConnectionString(mgo.opt, scanner->dedicated_port);
|
||||
}
|
||||
break;
|
||||
case 'f': _dedicated_forks = true; break;
|
||||
@ -1000,6 +997,28 @@ void HandleExitGameRequest()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers everything that should be triggered when starting a game.
|
||||
* @param dedicated_server Whether this is a dedicated server or not.
|
||||
*/
|
||||
static void OnStartGame(bool dedicated_server)
|
||||
{
|
||||
/* Update the local company for a loaded game. It is either always
|
||||
* a company or in the case of a dedicated server a spectator */
|
||||
if (_network_server && !dedicated_server) {
|
||||
NetworkServerDoMove(CLIENT_ID_SERVER, GetDefaultLocalCompany());
|
||||
} else {
|
||||
SetLocalCompany(dedicated_server ? COMPANY_SPECTATOR : GetDefaultLocalCompany());
|
||||
}
|
||||
if (_ctrl_pressed && !dedicated_server) {
|
||||
DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
|
||||
}
|
||||
/* Update the static game info to set the values from the new game. */
|
||||
NetworkServerUpdateGameInfo();
|
||||
/* Execute the game-start script */
|
||||
IConsoleCmdExec("exec scripts/game_start.scr 0");
|
||||
}
|
||||
|
||||
static void MakeNewGameDone()
|
||||
{
|
||||
SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
|
||||
@ -1009,9 +1028,8 @@ static void MakeNewGameDone()
|
||||
|
||||
/* In a dedicated server, the server does not play */
|
||||
if (!VideoDriver::GetInstance()->HasGUI()) {
|
||||
SetLocalCompany(COMPANY_SPECTATOR);
|
||||
OnStartGame(true);
|
||||
if (_settings_client.gui.pause_on_newgame) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
|
||||
IConsoleCmdExec("exec scripts/game_start.scr 0");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1030,9 +1048,7 @@ static void MakeNewGameDone()
|
||||
BuildOwnerLegend();
|
||||
}
|
||||
|
||||
IConsoleCmdExec("exec scripts/game_start.scr 0");
|
||||
|
||||
SetLocalCompany(COMPANY_FIRST);
|
||||
OnStartGame(false);
|
||||
|
||||
InitializeRailGUI();
|
||||
InitializeRoadGUI();
|
||||
@ -1227,18 +1243,7 @@ void SwitchToMode(SwitchMode new_mode)
|
||||
/* Reset engine pool to simplify changing engine NewGRFs in scenario editor. */
|
||||
EngineOverrideManager::ResetToCurrentNewGRFConfig();
|
||||
}
|
||||
/* Update the local company for a loaded game. It is either always
|
||||
* a company or in the case of a dedicated server a spectator */
|
||||
if (_network_server && !_network_dedicated) {
|
||||
NetworkServerDoMove(CLIENT_ID_SERVER, GetDefaultLocalCompany());
|
||||
} else {
|
||||
SetLocalCompany(_network_dedicated ? COMPANY_SPECTATOR : GetDefaultLocalCompany());
|
||||
}
|
||||
if (_ctrl_pressed && !_network_dedicated) {
|
||||
DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
|
||||
}
|
||||
/* Execute the game-start script */
|
||||
IConsoleCmdExec("exec scripts/game_start.scr 0");
|
||||
OnStartGame(_network_dedicated);
|
||||
/* Decrease pause counter (was increased from opening load dialog) */
|
||||
DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
|
||||
}
|
||||
|
@ -1825,6 +1825,7 @@ static bool UpdateServerPassword(int32 p1)
|
||||
_settings_client.network.server_password[0] = '\0';
|
||||
}
|
||||
|
||||
NetworkServerUpdateGameInfo();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1848,6 +1849,7 @@ static bool UpdateSettingsPassword(int32 p1)
|
||||
|
||||
static bool UpdateClientConfigValues(int32 p1)
|
||||
{
|
||||
NetworkServerUpdateGameInfo();
|
||||
if (_network_server) NetworkServerSendConfigUpdate();
|
||||
|
||||
return true;
|
||||
@ -2071,7 +2073,7 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati
|
||||
SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN);
|
||||
}
|
||||
|
||||
SetDParamStr(0, StrEmpty(filename) ? item->name.c_str() : filename);
|
||||
SetDParamStr(0, StrEmpty(filename) ? item->name : filename);
|
||||
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_GRF, WL_CRITICAL);
|
||||
delete c;
|
||||
continue;
|
||||
|
@ -127,7 +127,7 @@ struct BaseSetTextfileWindow : public TextfileWindow {
|
||||
{
|
||||
if (widget == WID_TF_CAPTION) {
|
||||
SetDParam(0, content_type);
|
||||
SetDParamStr(1, this->baseset->name.c_str());
|
||||
SetDParamStr(1, this->baseset->name);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -308,10 +308,10 @@ struct GameOptionsWindow : Window {
|
||||
case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break;
|
||||
case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[_gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom_cfg + 1 : 0]); break;
|
||||
case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[_font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom_cfg + 1 : 0]); break;
|
||||
case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name.c_str()); break;
|
||||
case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name); break;
|
||||
case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break;
|
||||
case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name.c_str()); break;
|
||||
case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str()); break;
|
||||
case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name); break;
|
||||
case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->name); break;
|
||||
case WID_GO_BASE_MUSIC_STATUS: SetDParam(0, BaseMusic::GetUsedSet()->GetNumInvalid()); break;
|
||||
case WID_GO_REFRESH_RATE_DROPDOWN: SetDParam(0, _settings_client.gui.refresh_rate); break;
|
||||
case WID_GO_RESOLUTION_DROPDOWN: {
|
||||
|
@ -43,7 +43,7 @@ std::string CDECL stdstr_fmt(const char *str, ...) WARN_FORMAT(1, 2);
|
||||
std::string stdstr_vfmt(const char *str, va_list va) WARN_FORMAT(1, 0);
|
||||
|
||||
char *str_validate(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2);
|
||||
std::string str_validate(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
|
||||
[[nodiscard]] std::string str_validate(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
|
||||
void ValidateString(const char *str);
|
||||
|
||||
const char *str_fix_scc_encoded(char *str, const char *last) NOACCESS(2);
|
||||
|
@ -300,6 +300,17 @@ void SetDParamStr(uint n, const char *str)
|
||||
SetDParam(n, (uint64)(size_t)str);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used to "bind" the C string of a std::string to a OpenTTD dparam slot.
|
||||
* The caller has to ensure that the std::string reference remains valid while the string is shown.
|
||||
* @param n slot of the string
|
||||
* @param str string to bind
|
||||
*/
|
||||
void SetDParamStr(uint n, const std::string &str)
|
||||
{
|
||||
SetDParamStr(n, str.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift the string parameters in the global string parameter array by \a amount positions, making room at the beginning.
|
||||
* @param amount Number of positions to shift.
|
||||
|
@ -208,6 +208,7 @@ void SetDParamMaxValue(uint n, uint64 max_value, uint min_count = 0, FontSize si
|
||||
void SetDParamMaxDigits(uint n, uint count, FontSize size = FS_NORMAL);
|
||||
|
||||
void SetDParamStr(uint n, const char *str);
|
||||
void SetDParamStr(uint n, const std::string &str);
|
||||
|
||||
void CopyInDParam(int offs, const uint64 *src, int num);
|
||||
void CopyOutDParam(uint64 *dst, int offs, int num);
|
||||
|
@ -6233,6 +6233,7 @@ type = SLE_STRB
|
||||
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
|
||||
guiflags = SGF_NETWORK_ONLY
|
||||
def = nullptr
|
||||
proc = UpdateClientConfigValues
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDTC_STR]
|
||||
@ -6300,6 +6301,7 @@ guiflags = SGF_NETWORK_ONLY
|
||||
def = 25
|
||||
min = 2
|
||||
max = MAX_CLIENTS
|
||||
proc = UpdateClientConfigValues
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDTC_VAR]
|
||||
|
@ -442,7 +442,7 @@ public:
|
||||
}
|
||||
|
||||
if (!this->town->text.empty()) {
|
||||
SetDParamStr(0, this->town->text.c_str());
|
||||
SetDParamStr(0, this->town->text);
|
||||
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y += FONT_HEIGHT_NORMAL, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
|
||||
}
|
||||
}
|
||||
@ -524,7 +524,7 @@ public:
|
||||
if (_settings_game.economy.station_noise_level) aimed_height += FONT_HEIGHT_NORMAL;
|
||||
|
||||
if (!this->town->text.empty()) {
|
||||
SetDParamStr(0, this->town->text.c_str());
|
||||
SetDParamStr(0, this->town->text);
|
||||
aimed_height += GetStringHeight(STR_JUST_RAW_STRING, width - WD_FRAMERECT_LEFT - WD_FRAMERECT_RIGHT);
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ StringID DropDownListParamStringItem::String() const
|
||||
|
||||
StringID DropDownListCharStringItem::String() const
|
||||
{
|
||||
SetDParamStr(0, this->raw_string.c_str());
|
||||
SetDParamStr(0, this->raw_string);
|
||||
return this->string;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user