From d3ee045c2d492388b10518ddca5f8246dc8bab8c Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 10 Jan 2024 22:38:58 +0100 Subject: [PATCH 1/7] Codechange: refactor the Windows-only DllLoader in a cross-platform LibraryLoader (#11751) --- CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + src/library_loader.h | 112 ++++++++++++++++++++++++++ src/os/unix/CMakeLists.txt | 1 + src/os/unix/library_loader_unix.cpp | 64 +++++++++++++++ src/os/windows/CMakeLists.txt | 1 + src/os/windows/crashlog_win.cpp | 23 +++--- src/os/windows/font_win32.cpp | 7 +- src/os/windows/font_win32.h | 2 + src/os/windows/library_loader_win.cpp | 58 +++++++++++++ src/os/windows/win32.cpp | 9 ++- src/os/windows/win32.h | 43 ---------- src/video/win32_v.cpp | 11 +-- src/video/win32_v.h | 1 + 14 files changed, 268 insertions(+), 66 deletions(-) create mode 100644 src/library_loader.h create mode 100644 src/os/unix/library_loader_unix.cpp create mode 100644 src/os/windows/library_loader_win.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 59ae78d043..d1da5bad10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,6 +311,7 @@ link_package(LZO) if(NOT WIN32 AND NOT EMSCRIPTEN) link_package(CURL ENCOURAGED) + target_link_libraries(openttd_lib ${CMAKE_DL_LIBS}) endif() if(NOT EMSCRIPTEN) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 05689fe5c5..2a6275cd35 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,6 +232,7 @@ add_files( league_gui.h league_gui.cpp league_type.h + library_loader.h livery.h main_gui.cpp map.cpp diff --git a/src/library_loader.h b/src/library_loader.h new file mode 100644 index 0000000000..a6cc8285cf --- /dev/null +++ b/src/library_loader.h @@ -0,0 +1,112 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file library_loader.h Functions/types related to loading libraries dynamically. */ + +#ifndef LIBRARY_LOADER_H +#define LIBRARY_LOADER_H + +class LibraryLoader { +public: + /** + * A function loaded from a library. + * + * Will automatically cast to the correct function pointer type on retrieval. + */ + class Function { + public: + explicit Function(void *p) : p(p) {} + + template >> + operator T *() const + { + return reinterpret_cast(this->p); + } + + private: + void *p; + }; + + /** + * Load a library with the given filename. + */ + explicit LibraryLoader(const std::string &filename) + { + this->handle = this->OpenLibrary(filename); + } + + /** + * Close the library. + */ + ~LibraryLoader() + { + if (this->handle != nullptr) { + this->CloseLibrary(); + } + } + + /** + * Check whether an error occurred while loading the library or a function. + * + * @return Whether an error occurred. + */ + bool HasError() + { + return this->error.has_value(); + } + + /** + * Get the last error that occurred while loading the library or a function. + * + * @return The error message. + */ + std::string GetLastError() + { + return this->error.value_or("No error"); + } + + /** + * Get a function from a loaded library. + * + * @param symbol_name The name of the function to get. + * @return The function. Check HasError() before using. + */ + Function GetFunction(const std::string &symbol_name) + { + if (this->error.has_value()) return Function(nullptr); + return Function(this->GetSymbol(symbol_name)); + } + +private: + /** + * Open the library with the given filename. + * + * Should set error if any error occurred. + * + * @param filename The filename of the library to open. + */ + void *OpenLibrary(const std::string &filename); + + /** + * Close the library. + */ + void CloseLibrary(); + + /** + * Get a symbol from the library. + * + * Should set error if any error occurred. + * + * @param symbol_name The name of the symbol to get. + */ + void *GetSymbol(const std::string &symbol_name); + + std::optional error = {}; ///< The last error that occurred, if set. + void *handle = nullptr; ///< Handle to the library. +}; + +#endif /* LIBRARY_LOADER_H */ diff --git a/src/os/unix/CMakeLists.txt b/src/os/unix/CMakeLists.txt index 1e8bb5d63d..f6c40d015f 100644 --- a/src/os/unix/CMakeLists.txt +++ b/src/os/unix/CMakeLists.txt @@ -5,6 +5,7 @@ add_files( ) add_files( + library_loader_unix.cpp unix.cpp CONDITION UNIX ) diff --git a/src/os/unix/library_loader_unix.cpp b/src/os/unix/library_loader_unix.cpp new file mode 100644 index 0000000000..471f1faa2a --- /dev/null +++ b/src/os/unix/library_loader_unix.cpp @@ -0,0 +1,64 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file library_loader_unix.cpp Implementation of the LibraryLoader for Linux / MacOS */ + +#include "../../stdafx.h" + +#include + +#include "../../library_loader.h" + +#include "../../safeguards.h" + +/* Emscripten cannot dynamically load other files. */ +#if defined(__EMSCRIPTEN__) + +void *LibraryLoader::OpenLibrary(const std::string &) +{ + this->error = "Dynamic loading is not supported on this platform."; + return nullptr; +} + +void LibraryLoader::CloseLibrary() +{ +} + +void *LibraryLoader::GetSymbol(const std::string &) +{ + this->error = "Dynamic loading is not supported on this platform."; + return nullptr; +} + +#else + +void *LibraryLoader::OpenLibrary(const std::string &filename) +{ + void *h = dlopen(filename.c_str(), RTLD_NOW | RTLD_LOCAL); + if (h == nullptr) { + this->error = dlerror(); + } + + return h; +} + +void LibraryLoader::CloseLibrary() +{ + dlclose(this->handle); +} + +void *LibraryLoader::GetSymbol(const std::string &symbol_name) +{ + void *p = dlsym(this->handle, symbol_name.c_str()); + if (p == nullptr) { + this->error = dlerror(); + } + + return p; +} + +#endif /* __EMSCRIPTEN__ */ diff --git a/src/os/windows/CMakeLists.txt b/src/os/windows/CMakeLists.txt index 9215514fa2..dd446f7ac6 100644 --- a/src/os/windows/CMakeLists.txt +++ b/src/os/windows/CMakeLists.txt @@ -2,6 +2,7 @@ add_files( crashlog_win.cpp font_win32.cpp font_win32.h + library_loader_win.cpp string_uniscribe.cpp string_uniscribe.h survey_win.cpp diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index 7c05e81429..e74fc5ed0b 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -17,6 +17,7 @@ #include "../../gamelog.h" #include "../../saveload/saveload.h" #include "../../video/video_driver.hpp" +#include "../../library_loader.h" #include #include @@ -177,7 +178,7 @@ static const uint MAX_FRAMES = 64; /* virtual */ void CrashLogWindows::SurveyStacktrace(nlohmann::json &survey) const { - DllLoader dbghelp(L"dbghelp.dll"); + LibraryLoader dbghelp("dbghelp.dll"); struct ProcPtrs { BOOL (WINAPI * pSymInitialize)(HANDLE, PCSTR, BOOL); BOOL (WINAPI * pSymSetOptions)(DWORD); @@ -189,21 +190,21 @@ static const uint MAX_FRAMES = 64; BOOL (WINAPI * pSymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64); BOOL (WINAPI * pSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64); } proc = { - dbghelp.GetProcAddress("SymInitialize"), - dbghelp.GetProcAddress("SymSetOptions"), - dbghelp.GetProcAddress("SymCleanup"), - dbghelp.GetProcAddress("StackWalk64"), - dbghelp.GetProcAddress("SymFunctionTableAccess64"), - dbghelp.GetProcAddress("SymGetModuleBase64"), - dbghelp.GetProcAddress("SymGetModuleInfo64"), - dbghelp.GetProcAddress("SymGetSymFromAddr64"), - dbghelp.GetProcAddress("SymGetLineFromAddr64"), + dbghelp.GetFunction("SymInitialize"), + dbghelp.GetFunction("SymSetOptions"), + dbghelp.GetFunction("SymCleanup"), + dbghelp.GetFunction("StackWalk64"), + dbghelp.GetFunction("SymFunctionTableAccess64"), + dbghelp.GetFunction("SymGetModuleBase64"), + dbghelp.GetFunction("SymGetModuleInfo64"), + dbghelp.GetFunction("SymGetSymFromAddr64"), + dbghelp.GetFunction("SymGetLineFromAddr64"), }; survey = nlohmann::json::array(); /* Try to load the functions from the DLL, if that fails because of a too old dbghelp.dll, just skip it. */ - if (dbghelp.Success()) { + if (!dbghelp.HasError()) { /* Initialize symbol handler. */ HANDLE hCur = GetCurrentProcess(); proc.pSymInitialize(hCur, nullptr, TRUE); diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index 3d863b4dc0..a05b2211a6 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -15,9 +15,10 @@ #include "../../core/mem_func.hpp" #include "../../error_func.h" #include "../../fileio_func.h" -#include "../../fontdetection.h" #include "../../fontcache.h" #include "../../fontcache/truetypefontcache.h" +#include "../../fontdetection.h" +#include "../../library_loader.h" #include "../../string_func.h" #include "../../strings_func.h" #include "../../zoom_func.h" @@ -361,9 +362,9 @@ void LoadWin32Font(FontSize fs) if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) { /* Try a nice little undocumented function first for getting the internal font name. * Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */ - static DllLoader _gdi32(L"gdi32.dll"); + static LibraryLoader _gdi32("gdi32.dll"); typedef BOOL(WINAPI *PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD); - static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetProcAddress("GetFontResourceInfoW"); + static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetFunction("GetFontResourceInfoW"); if (GetFontResourceInfo != nullptr) { /* Try to query an array of LOGFONTs that describe the file. */ diff --git a/src/os/windows/font_win32.h b/src/os/windows/font_win32.h index 7ef5568601..02a84b63fc 100644 --- a/src/os/windows/font_win32.h +++ b/src/os/windows/font_win32.h @@ -13,6 +13,8 @@ #include "../../fontcache/truetypefontcache.h" #include "win32.h" +#include + /** Font cache for fonts that are based on a Win32 font. */ class Win32FontCache : public TrueTypeFontCache { private: diff --git a/src/os/windows/library_loader_win.cpp b/src/os/windows/library_loader_win.cpp new file mode 100644 index 0000000000..a682f2e7f1 --- /dev/null +++ b/src/os/windows/library_loader_win.cpp @@ -0,0 +1,58 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file library_loader_win.cpp Implementation of the LibraryLoader for Windows */ + +#include "../../stdafx.h" + +#include + +#include "../../library_loader.h" + +#include "../../safeguards.h" + +static std::string GetLoadError() +{ + auto error_code = GetLastError(); + + char buffer[512]; + if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error_code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), nullptr) == 0) { + return fmt::format("Unknown error {}", error_code); + } + + return buffer; +} + +void *LibraryLoader::OpenLibrary(const std::string &filename) +{ + void *h = ::LoadLibraryW(OTTD2FS(filename).c_str()); + if (h == nullptr) { + this->error = GetLoadError(); + } + + return h; +} + +void LibraryLoader::CloseLibrary() +{ + HMODULE handle = static_cast(this->handle); + + ::FreeLibrary(handle); +} + +void *LibraryLoader::GetSymbol(const std::string &symbol_name) +{ + HMODULE handle = static_cast(this->handle); + + void *p = reinterpret_cast(::GetProcAddress(handle, symbol_name.c_str())); + if (p == nullptr) { + this->error = GetLoadError(); + } + + return p; +} diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 1d4e747378..b198ed92c4 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -27,6 +27,7 @@ #include #include "../../language.h" #include "../../thread.h" +#include "../../library_loader.h" #include "../../safeguards.h" @@ -573,8 +574,8 @@ int OTTDStringCompare(std::string_view s1, std::string_view s2) #endif if (first_time) { - static DllLoader _kernel32(L"Kernel32.dll"); - _CompareStringEx = _kernel32.GetProcAddress("CompareStringEx"); + static LibraryLoader _kernel32("Kernel32.dll"); + _CompareStringEx = _kernel32.GetFunction("CompareStringEx"); first_time = false; } @@ -617,8 +618,8 @@ int Win32StringContains(const std::string_view str, const std::string_view value static bool first_time = true; if (first_time) { - static DllLoader _kernel32(L"Kernel32.dll"); - _FindNLSStringEx = _kernel32.GetProcAddress("FindNLSStringEx"); + static LibraryLoader _kernel32("Kernel32.dll"); + _FindNLSStringEx = _kernel32.GetFunction("FindNLSStringEx"); first_time = false; } diff --git a/src/os/windows/win32.h b/src/os/windows/win32.h index 561d471bac..4e35241721 100644 --- a/src/os/windows/win32.h +++ b/src/os/windows/win32.h @@ -10,51 +10,8 @@ #ifndef WIN32_H #define WIN32_H -#include bool MyShowCursor(bool show, bool toggle = false); -class DllLoader { -public: - explicit DllLoader(LPCTSTR filename) - { - this->hmodule = ::LoadLibrary(filename); - if (this->hmodule == nullptr) this->success = false; - } - - - ~DllLoader() - { - ::FreeLibrary(this->hmodule); - } - - bool Success() { return this->success; } - - class ProcAddress { - public: - explicit ProcAddress(void *p) : p(p) {} - - template >> - operator T *() const - { - return reinterpret_cast(this->p); - } - - private: - void *p; - }; - - ProcAddress GetProcAddress(const char *proc_name) - { - void *p = reinterpret_cast(::GetProcAddress(this->hmodule, proc_name)); - if (p == nullptr) this->success = false; - return ProcAddress(p); - } - -private: - HMODULE hmodule = nullptr; - bool success = true; -}; - char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen); wchar_t *convert_to_fs(const std::string_view name, wchar_t *utf16_buf, size_t buflen); diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 833f4bf72d..a2710186a2 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -22,6 +22,7 @@ #include "../window_gui.h" #include "../window_func.h" #include "../framerate_type.h" +#include "../library_loader.h" #include "win32_v.h" #include #include @@ -976,11 +977,11 @@ float VideoDriver_Win32Base::GetDPIScale() static bool init_done = false; if (!init_done) { init_done = true; - static DllLoader _user32(L"user32.dll"); - static DllLoader _shcore(L"shcore.dll"); - _GetDpiForWindow = _user32.GetProcAddress("GetDpiForWindow"); - _GetDpiForSystem = _user32.GetProcAddress("GetDpiForSystem"); - _GetDpiForMonitor = _shcore.GetProcAddress("GetDpiForMonitor"); + static LibraryLoader _user32("user32.dll"); + static LibraryLoader _shcore("shcore.dll"); + _GetDpiForWindow = _user32.GetFunction("GetDpiForWindow"); + _GetDpiForSystem = _user32.GetFunction("GetDpiForSystem"); + _GetDpiForMonitor = _shcore.GetFunction("GetDpiForMonitor"); } UINT cur_dpi = 0; diff --git a/src/video/win32_v.h b/src/video/win32_v.h index 8e9493df8f..272ee607a9 100644 --- a/src/video/win32_v.h +++ b/src/video/win32_v.h @@ -13,6 +13,7 @@ #include "video_driver.hpp" #include #include +#include /** Base class for Windows video drivers. */ class VideoDriver_Win32Base : public VideoDriver { From 94d31864b3c2bd432c7fd6e9a4722926678b722a Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 11 Jan 2024 18:39:13 +0000 Subject: [PATCH 2/7] Update: Translations from eints chinese (simplified): 16 changes by WenSimEHRP arabic (egypt): 23 changes by AviationGamerX korean: 1 change by telk5093 portuguese (brazilian): 10 changes by pasantoro polish: 4 changes by pAter-exe --- src/lang/arabic_egypt.txt | 27 ++++++++++++++++++++++---- src/lang/brazilian_portuguese.txt | 16 ++++++++++------ src/lang/korean.txt | 1 + src/lang/polish.txt | 8 ++++---- src/lang/simplified_chinese.txt | 32 +++++++++++++++---------------- 5 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 3563bca280..bb95b67a74 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -202,6 +202,7 @@ STR_UNITS_POWER_IMPERIAL :{DECIMAL}{NBSP} STR_UNITS_POWER_METRIC :{DECIMAL}{NBSP}حصان STR_UNITS_POWER_SI :{DECIMAL}{NBSP}ك واط +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg STR_UNITS_WEIGHT_SHORT_IMPERIAL :{DECIMAL}{NBSP} طن @@ -390,6 +391,7 @@ STR_SCENEDIT_FILE_MENU_QUIT :انهاء ###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :إعدادات اللعبه STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :الإعدادات +STR_SETTINGS_MENU_AI_SETTINGS :اعدادات االذكاء الاصطناعي STR_SETTINGS_MENU_NEWGRF_SETTINGS :إعدادات اﻹضافات STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :خيارات الشفافية STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :عرض اسماء المدن @@ -752,6 +754,7 @@ STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT :{BLACK}بدل STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES :{BLACK}عدم عرض ممتلكات اي شركة على الخارطة STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES :{BLACK}عرض جميع املاك الشركة على الخريطة STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS :{BLACK}عدم عرض أي بضائع على الخريطة +STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS :{BLACK}عرض جميع البضائع على الخريطة # Status bar messages STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS :{BLACK}اظهر اخر رسالة / تقرير @@ -948,6 +951,7 @@ STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}حدد هذا المربع لمزامنة الشاشة (v-sync). سيتم تطبيق الإعداد الذي تم تغييره فقط عند إعادة تشغيل اللعبة. يعمل فقط مع تمكين تسريع الأجهزة (hardware acceleration) +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}اسحب شريط التمرير لتعيين حجم الواجهة. اضغط مع الاستمرار على Ctrl للتعديل المستمر STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}الكشف التلقائي عن الحجم STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}اختر هذا المربع لكشف حجم الواجهة تلقائيا @@ -1252,6 +1256,7 @@ STR_CONFIG_SETTING_ORDER_REVIEW_EXDEPOT :نعم, بست STR_CONFIG_SETTING_ORDER_REVIEW_ON :لكل العربات STR_CONFIG_SETTING_WARN_INCOME_LESS :حذر عندما يكون الدخل سالبا :{STRING} +STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT :عند التمكين ، يتم إرسال رسالة إخبارية عندما لا تحقق السيارة أي ربح خلال سنة تقويمية واحدة STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :المركبات لا تنتهي صلاحيتها ابدا : {STRING} @@ -1406,6 +1411,7 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :استخدام STR_CONFIG_SETTING_LOADING_INDICATORS :تفعيل مؤشر التحميل: {STRING} STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :حدد ما إذا كانت مؤشرات التحميل معروضة فوق تحميل المركبات أو تفريغها +STR_CONFIG_SETTING_TIMETABLE_MODE_HELPTEXT :حدد الوحدات الزمنية المستخدمة في جداول مواعيد المركبات ###length 3 STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :عرض الوصول و المغادرة في جدولة الاعمال: {STRING} @@ -1469,6 +1475,7 @@ STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :حظر الطا STR_CONFIG_SETTING_AI_BUILDS_SHIPS :حظر السفن على الحاسوب: {STRING} +STR_CONFIG_SETTING_AI_PROFILE :الملف الشخصي للإعدادات الافتراضية: {STRING} ###length 3 STR_CONFIG_SETTING_AI_PROFILE_EASY :سهل @@ -1480,8 +1487,10 @@ STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :فترات الصيانة بالنسبة المئوية : {STRING} -STR_CONFIG_SETTING_SERVINT_AIRCRAFT ::مدة فحص الطائرة الإفتراضي{STRING} +STR_CONFIG_SETTING_SERVINT_AIRCRAFT :مدة فحص الإفتراضي للطائرة: {STRING} +STR_CONFIG_SETTING_SERVINT_SHIPS :مدة فحص الإفتراضي للسفن: {STRING} ###setting-zero-is-special +STR_CONFIG_SETTING_SERVINT_DISABLED :غير مفعل STR_CONFIG_SETTING_NOSERVICE :الغاء الصيانة عندما يكون التعطيل للمركبات غير مفعل: {STRING} @@ -1624,6 +1633,7 @@ STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 في {COMMA} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :مضاعف المدن المبدئي: {STRING} +STR_CONFIG_SETTING_DISTRIBUTION_PAX :وضع التوزيع للركاب: {STRING} ###length 3 STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :كلما قمت بتعليت هذا بشكل اكثر، كلما ازداد وقت الCPU في حساب الرسم البياني الرابط. إذا استغرق الأمر وقتًا طويلاً فقد تلاحظ تأخير في الاستجبة. إذا قمت بتغيره إلى قيمة منخفضة، فسيكون التوزيع غير دقيق، وقد تلاحظ عدم إرسال البضائع إلى الأماكن التي تتوقع أن تذهب إليها. @@ -1648,6 +1658,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_METRIC :متري (طن) STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE ::وحدات جهد الجر {STRING} ###length 3 +STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_IMPERIAL :إمبراطوري (lbf) STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_METRIC :متري (كغ - قوة) ###length 3 @@ -1979,6 +1990,7 @@ STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :منع STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}هل أنت متأكد أنك تريد طرد اللاعب '{STRING}'؟ STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}هل أنت متأكد أنك تريد حظر اللاعب '{STRING}'؟ STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}هل أنت متأكد أنك تريد حذف شركة '{COMPANY}'؟ +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}هل أنت متأكد أنك تريد محو كلمة السر الخاصة بالشركة '{COMPANY}'? STR_NETWORK_ASK_RELAY_NO :{BLACK}لا @@ -2600,6 +2612,7 @@ STR_ABOUT_VERSION :{BLACK}النس STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}النسخة المفتوحة {COPYRIGHT}2002-{STRING} فريق النسخة المفتوحة # Framerate display window +STR_FRAMERATE_CURRENT :{WHITE}الحالي STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} صورة في الثانية @@ -2845,6 +2858,7 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED} تحذير: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED} خطأ: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED} خطأ قاتل: {SILVER}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}ال NewGRF "{STRING}" قام باعادة خطء فادح:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} لن يعمل مع اصدار الباتش المسجل في النسخة المفتوحة STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} يعمل مع {STRING} اصدار من TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} مصمم ليستخدم مع {STRING} @@ -3114,6 +3128,7 @@ STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}السيولة المتاحة STR_FINANCES_LOAN_TITLE :{WHITE}القرض +STR_FINANCES_INTEREST_RATE :{WHITE}فائدة القرض: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}اقصى حد للقرض: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}اقتراض{CURRENCY_LONG} @@ -3333,6 +3348,7 @@ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}شراء STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}شراء طائرة ###length VEHICLE_TYPES +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}شراء العربة وتجديد بضائعها STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}شراء العربة وتجديد بضائعها STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}شراء وإعادة تجهيز السفينة @@ -3496,6 +3512,7 @@ STR_REPLACE_HELP_LEFT_ARRAY :{BLACK} اخت STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK} اختر نوع المحرك المراد إحلاله محل المحرك المختار في القائمة اليسرى STR_REPLACE_VEHICLES_START :{BLACK} بدأ تبديل العربات +STR_REPLACE_VEHICLES_NOW :استبدل جميع المركبات الآن STR_REPLACE_HELP_START_BUTTON :{BLACK}اضغط لبدأ عملية تبديل المحركات المختارة في القائمة اليسرى بالمحركات المختارة في القائمة اليمنى STR_REPLACE_NOT_REPLACING :{BLACK}لم يتم التبديل STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}لم يتم اختيار اي عربة @@ -3865,13 +3882,13 @@ STR_TIMETABLE_STAY_FOR_ESTIMATED :(البقاء STR_TIMETABLE_STAY_FOR :ويبقى لـ {STRING} STR_TIMETABLE_AND_TRAVEL_FOR :ويسافر لـ {STRING} -STR_TIMETABLE_TOTAL_TIME :{BLACK}جدولة الاوامر هذه ستأخذ {STRING} لنهاية -STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}جدولة الاوامر هذه ستأخذ على الاقل {STRING} لتكتمل (لايشمل كل الجدولة) +STR_TIMETABLE_TOTAL_TIME :{BLACK}جدول الاوامر هذه ستأخذ {STRING} للانتهاء +STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}جدول الاوامر هذا سيأخذ على الاقل {STRING} للانتهاء (ليست جميعها مجدولة) STR_TIMETABLE_STATUS_ON_TIME :{BLACK}هذه العربة تعمل حسب الجدولة في الوقت المُحَدَد STR_TIMETABLE_STATUS_LATE :{BLACK}هذه العربه {STRING} مُتاخِرة حاليا عن الجدوله STR_TIMETABLE_STATUS_EARLY :{BLACK}هذه العربه {STRING} مُتَقَدِمه عن الجدوله -STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}جدولة الاعمال لم تبدأ بعد +STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}جدول الاعمال لم تبدأ بعد @@ -4070,6 +4087,7 @@ STR_ERROR_OWNED_BY :{WHITE}مملو STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... المنطقة مملوكة لشركة منافسة STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}... تم الوصول لاقصى حدود للتضاريس STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}... تم الوصول لاقصى عدد ازالة +STR_ERROR_TREE_PLANT_LIMIT_REACHED :{WHITE}... تم الوصول للحد الاقصى لزرع الاشجار STR_ERROR_NAME_MUST_BE_UNIQUE :{WHITE}السم يجب ان يكون فريدا - غير مستخدم STR_ERROR_GENERIC_OBJECT_IN_THE_WAY :{WHITE}{1:STRING} على الطريق STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}غير مسموح في حين توقفت @@ -4405,6 +4423,7 @@ STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... ال STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}لا يمكن جدولة العربة ... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}يمكن للعربات الانتظار في المحطات فقط. STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}هذه العربة لا تتوقف في هذه المحطة. +STR_ERROR_TIMETABLE_NOT_STARTED :{WHITE}... جدول الاعمال لم تبدأ بعد # Sign related errors STR_ERROR_TOO_MANY_SIGNS :{WHITE}... العلامات كثيرة جدا diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 2e5d23a496..ece32ddb64 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -772,7 +772,7 @@ STR_SMALLMAP_LEGENDA_AIRCRAFT :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLACK}Rotas de Transporte STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Floresta STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Estação Ferroviária -STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Compartimento de Carga de Caminhões +STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Estação de caminhões STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Estação de Ônibus STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Aeroporto/Heliporto STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLACK}Doca @@ -1003,6 +1003,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :Dólar de Hong STR_GAME_OPTIONS_CURRENCY_INR :Rúpia Indiana STR_GAME_OPTIONS_CURRENCY_IDR :Rupia Indonésia STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaio +STR_GAME_OPTIONS_CURRENCY_LVL :Lats da Letônia STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Salvar automaticamente STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecionar o intervalo entre jogos salvos automaticos @@ -2056,14 +2057,17 @@ STR_CONFIG_SETTING_ACCOUNTING :Contabilidade STR_CONFIG_SETTING_VEHICLES :Veículos STR_CONFIG_SETTING_VEHICLES_PHYSICS :Física STR_CONFIG_SETTING_VEHICLES_ROUTING :Rota +STR_CONFIG_SETTING_VEHICLES_ORDERS :Ordens STR_CONFIG_SETTING_LIMITATIONS :Limitações STR_CONFIG_SETTING_ACCIDENTS :Desastres / Acidentes STR_CONFIG_SETTING_GENWORLD :Geração de Mundo STR_CONFIG_SETTING_ENVIRONMENT :Meio-Ambiente +STR_CONFIG_SETTING_ENVIRONMENT_TIME :Tempo STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :Autoridades STR_CONFIG_SETTING_ENVIRONMENT_TOWNS : Cidades STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :Indústrias STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :Distribuição de Carga +STR_CONFIG_SETTING_ENVIRONMENT_TREES :Árvores STR_CONFIG_SETTING_AI :Oponentes STR_CONFIG_SETTING_AI_NPC :Computadores STR_CONFIG_SETTING_NETWORK :Rede @@ -2721,9 +2725,9 @@ STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Construir ferro STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construir ferrovias. Ctrl alterna entre construção/remoção de trilhos. Shift altera construção/preço estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Construir ferrovias usando o modo Autotrilho. Ctrl alterna entre construção/remoçao de trilhos. Shift altera construção/preço estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construir depósito (para compra e manutenção de trens). Shift altera construção/preço estimado -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Converter linha em ponto de controle. Ctrl permite a união de pontos de controle. Shift altera construção/preço estimado +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Construir ponto de controle na rodovia. Ctrl permite unir pontos de controle. Shift alterna construir/mostrar custo estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Construir estação ferroviária. Ctrl permite a união de estações. Shift altera construção/preço estimado -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construir sinais ferroviários. Ctrl alterna a construção de semáforos/sinais{}Clicar e arrastar constroi sinais até a próxima junção ou sinal{}Ctrl+Clique alterna a janela de seleção de sinais. Shift alterna construção/preço estimado +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construir sinais na ferrovia. Ctrl alterna entre a construção de semáforos/sinais{}Clicar e arrastar constrói sinais ao longo de uma linha de trilhos. Ctrl constrói sinais até a próxima junção ou sinal{}Ctrl+Clique abre a janela de seleção de sinais. Shift alterna construir/mostrar custo estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Construir ponte ferroviária. Shift altera construção/preço estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Construir túnel ferroviário. Shift altera construção/preço estimado STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Alternar construir/remover ferrovias, sinais, pontos de controle e estações. Segure ctrl para remover os trilhos de estações e pontos de controle. @@ -2811,7 +2815,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construi STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Construir depósito de bonde (para compra e manutenção de bondes). Shift altera construção/preço estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Construir estação de ônibus. Ctrl permite a união de estações. Shift altera construção/preço estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Constuir estação de bonde para passageiros. Ctrl permite a união de estações. Shift altera construção/preço estimado -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construir área de carga. Ctrl permite a união de estações. Shift altera construção/preço estimado +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construir estação de caminhões. Ctrl permite unir estações. Shift alterna construir/mostrar custo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Constuir estação de bonde para carga. Ctrl permite a união de estações. Shift altera construção/preço estimado STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Ativar/Desativar vias de mão única STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Construir ponte rodoviária. Shift altera construção/preço estimado @@ -2836,7 +2840,7 @@ STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Selecion STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Orientação do estação de ônibus STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Selecionar orientação do estação de ônibus STR_STATION_BUILD_TRUCK_ORIENTATION :{WHITE}Orientação da área de carga -STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Selecionar orientação da área de carga +STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Selecionar a orientação da estação de caminhões STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Orientação da Estação de Bonde Passageiros STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Selecionar orientação da estação de bonde STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Orientação da Estação de Bonde de Carga @@ -3080,7 +3084,7 @@ STR_LAI_TREE_NAME_CACTUS_PLANTS :Cactos STR_LAI_STATION_DESCRIPTION_RAILROAD_STATION :Estação ferroviária STR_LAI_STATION_DESCRIPTION_AIRCRAFT_HANGAR :Hangar STR_LAI_STATION_DESCRIPTION_AIRPORT :Aeroporto -STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Área de carga +STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Estação de caminhões STR_LAI_STATION_DESCRIPTION_BUS_STATION :Estação de ônibus STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Doca STR_LAI_STATION_DESCRIPTION_BUOY :Bóia diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 1c2fc2d839..15ea9fc14f 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -1003,6 +1003,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :홍콩 달러 STR_GAME_OPTIONS_CURRENCY_INR :인도 루피 STR_GAME_OPTIONS_CURRENCY_IDR :인도네시아 루피아 STR_GAME_OPTIONS_CURRENCY_MYR :말레이시아 링깃 +STR_GAME_OPTIONS_CURRENCY_LVL :라트비아 라츠 STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}자동 저장 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}게임 자동 저장 간격을 선택 diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 7308ec4b87..e118cc27ba 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -1884,7 +1884,7 @@ STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Wysokość gran STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Wybierz, na jakiej wysokości zaczyna zalegać śnieg w krajobrazie arktycznym. Poziom pokrywy śnieżnej wpływa na rozmieszczenie przedsiębiorstw i na warunki rozwoju miast. Może być zmodyfikowana poprzez Edytor Scenariuszy, w innym przypadku jest obliczana za pomocą ustawienia „pokrycie śniegiem” STR_CONFIG_SETTING_SNOW_COVERAGE :Pokrycie śniegiem: {STRING} -STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Wybierz przybliżoną ilość śniegu w krajobrazie arktycznym. Śnieg wpływa również wpływa na rozmieszczenie przedsiębiorstw i na warunki rozwoju miast. Używane tylko podczas generowania mapy. Teren tuż ponad poziomem wody jest zawsze bez śniegu +STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Wybierz przybliżoną ilość śniegu w krajobrazie arktycznym. Śnieg wpływa również wpływa na rozmieszczenie przedsiębiorstw i na warunki rozwoju miast. Używane tylko podczas generowania mapy. Teren tuż ponad poziomem morza jest zawsze bez śniegu STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_DESERT_COVERAGE :Pokrycie pustynią: {STRING} @@ -3612,7 +3612,7 @@ STR_MAPGEN_DATE_TOOLTIP :{BLACK}Wybierz STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Liczba przedsiębiorstw: STR_MAPGEN_NUMBER_OF_INDUSTRIES_TOOLTIP :{BLACK}Wybierz gęstość rozmieszczenia przedsiębiorstw lub podaj ich określoną liczbę STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Najwyższy szczyt: -STR_MAPGEN_HEIGHTMAP_HEIGHT_TOOLTIP :{BLACK}Wybierz najwyższy szczyt, który gra spróbuje utworzyć, mierzony wysokością nad poziomem wody +STR_MAPGEN_HEIGHTMAP_HEIGHT_TOOLTIP :{BLACK}Wybierz najwyższy szczyt, który gra spróbuje utworzyć, mierzony wysokością nad poziomem morza STR_MAPGEN_HEIGHTMAP_HEIGHT_UP :{BLACK}Zwiększ wysokość najwyższego szczytu na mapie o jeden poziom STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN :{BLACK}Zmniejsz wysokość najwyższego szczytu na mapie o jeden poziom STR_MAPGEN_SNOW_COVERAGE :{BLACK}Pokrycie śniegiem: @@ -3624,8 +3624,8 @@ STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Zwiększ STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Zmniejsz pokrycie pustynią o 10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% STR_MAPGEN_TERRAIN_TYPE :{BLACK}Typ terenu: -STR_MAPGEN_SEA_LEVEL :{BLACK}Poziom wody: -STR_MAPGEN_SEA_LEVEL_TOOLTIP :{BLACK}Określ wysokość poziomu wody +STR_MAPGEN_SEA_LEVEL :{BLACK}Poziom morza: +STR_MAPGEN_SEA_LEVEL_TOOLTIP :{BLACK}Określ wysokość poziomu morza STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Liczba rzek: STR_MAPGEN_SMOOTHNESS :{BLACK}Gładkość: STR_MAPGEN_VARIETY :{BLACK}Różnorodność: diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index de399c5706..80d99e0d3d 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -1356,12 +1356,12 @@ STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :设置工厂周 STR_CONFIG_SETTING_MULTIPINDTOWN :允许在一个城镇中建设多个同类工业设施:{STRING} STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :通常,城市不希望有多个相同类型工业,本设置“打开”时允许多个同类型工厂在同一个城市 -STR_CONFIG_SETTING_SIGNALSIDE :显示信号灯:{STRING} -STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :选择在铁路哪一边放置信号灯 +STR_CONFIG_SETTING_SIGNALSIDE :铁路信号位置:{STRING} +STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :选择在铁路的哪一侧放置信号。 ###length 3 -STR_CONFIG_SETTING_SIGNALSIDE_LEFT :在左边 +STR_CONFIG_SETTING_SIGNALSIDE_LEFT :左侧 STR_CONFIG_SETTING_SIGNALSIDE_DRIVING_SIDE :道路通行方向 -STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :在右侧 +STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :右侧 STR_CONFIG_SETTING_SHOWFINANCES :在年终显示财务报表:{STRING} STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :“打开”时,在年底显示财务报表窗口,方便查看公司财务状况 @@ -1369,7 +1369,7 @@ STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :“打开”时 STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :新的调度命令默认为“不停车”: {STRING} STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :通常,车辆在它经过的每一个车站都会停车。“打开”本选项时,车辆会不停车的通过所有中间车站前往最终目的地。注意:这只是为每一条新调度命令设置一个默认信息,仍然可以为每条调度命令设置明确的信息 -STR_CONFIG_SETTING_STOP_LOCATION :新列车调度计划中默认命令为停靠在站台{STRING} 位置 +STR_CONFIG_SETTING_STOP_LOCATION :新列车调度计划中默认命令为停靠在站台 {STRING} 位置 STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :设置车辆在站台的默认停靠位置,“近端”是靠近车辆进入的那一端,“中间”是站台中间位置,“远端”是远离车辆进入的那一端。注意:本设定只改变新指令的默认设定。玩家仍可通过点击指令文字改变列车在某车站的停车位置。 ###length 3 STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :近端 @@ -1675,11 +1675,11 @@ STR_CONFIG_SETTING_QUICKGOTO :快速创建车 STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :启用时,打开调度计划窗口时预先选定“前往”命令 STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :默认铁路类型 (新建/读取游戏后): {STRING} -STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :设置开启或者载入游戏时的默认铁路类型,“第一可用的”是最老的铁路类型,“最后一个可用”的是最新的铁路类型,“最常用的”是当前用的最多的铁路类型 +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :设置开启或者载入游戏时的默认铁路类型,“最先可用的类型”是最老的铁路类型,“最新可用的类型”的是最新的铁路类型,“最常用的类型”是当前用的最多的铁路类型 ###length 3 -STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :第一个可用的 -STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_LAST :第后一个可用的 -STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_MOST_USED :最常用的 +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :最先可用的类型 +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_LAST :最新可用的类型 +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_MOST_USED :最常用的类型 STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION :显示预留的轨道: {STRING} STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :让预留的铁路轨道显示不同的颜色,以帮助查找列车拒绝进入路径轨道的原因 @@ -1754,10 +1754,10 @@ STR_CONFIG_SETTING_AI_PROFILE_HARD :困难 STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :联机游戏时允许电脑玩家(AI): {STRING} STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :“打开”时联机游戏允许电脑玩家 -STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :可允许的最大的代码量(如超过则会令脚本被禁用):{STRING} -STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :脚本在一个回合中可进行计算步数的最大值 +STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :不令脚本停运的最大代码数量:{STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :设定在每个计算循环中,脚本(AI与游戏脚本)的每一句代码最多可进行多少个计算步骤。 STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :每个脚本的内存上限: {STRING} -STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :单个脚本强制终止前可占用的最大内存量。对于大地图可能需要增加。 +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :单个脚本(AI与游戏脚本)可使用的最大内存量,在游玩大型地图时可能需要增加。 STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :维护间隔以百分比(%)计算: {STRING} @@ -1914,7 +1914,7 @@ STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :树木自动生 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :控制游戏中数目的随机生长,这将影响依赖树木的工业,比如木材厂 ###length 4 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :生长但不扩散 {RED}(损坏伐木场) -STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :只生长在雨林 +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :仅在雨林扩散 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_ALL :生长并四处扩散 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_GROWTH_NO_SPREAD :不生长,不扩散 {RED}(损坏伐木场) @@ -3239,7 +3239,7 @@ STR_MAPGEN_SNOW_COVERAGE :{BLACK}雪地 STR_MAPGEN_SNOW_COVERAGE_UP :{BLACK}将雪地比率增加10% STR_MAPGEN_SNOW_COVERAGE_DOWN :{BLACK}将雪地比率减少10% STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_DESERT_COVERAGE :{BLACK}沙漠覆盖率: +STR_MAPGEN_DESERT_COVERAGE :{BLACK}沙漠比率: STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}将沙漠比率增加10% STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}将沙漠比率减少10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% @@ -3304,7 +3304,7 @@ STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} STR_MAPGEN_TERRAIN_TYPE_QUERY_CAPT :{WHITE}最高峰目标高度 STR_MAPGEN_HEIGHTMAP_HEIGHT_QUERY_CAPT :{WHITE}最高峰 STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT :{WHITE}积雪覆盖率 (百分比) -STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}沙漠覆盖率 (百分比) +STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}沙漠比率 (百分比) STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}改变游戏开始的日期 # SE Map generation @@ -3375,7 +3375,7 @@ STR_NEWGRF_SETTINGS_FILENAME :{BLACK}文件 STR_NEWGRF_SETTINGS_GRF_ID :{BLACK}GRF ID:{SILVER}{STRING} STR_NEWGRF_SETTINGS_VERSION :{BLACK}版本: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}最低兼容版本: {SILVER}{NUM} -STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5 码:{SILVER}{STRING} +STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5码:{SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}调色板: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :默认 (DOS) STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :默认 (DOS) / 32 bpp From b1812751e098d81571d7dd2ee98192c9ec6ec615 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Fri, 12 Jan 2024 11:25:50 +0100 Subject: [PATCH 3/7] Fix: [CI] unbreak Linux releases by using a slightly older rust-cache action (#11758) The maintainer bumped node16 -> node20 in a patch version, which is a bit awkward for us, as we can't run node20 in this workflow (yet). Most other actions used a major version for that, and for similar reasons we cannot upgrade "download-artifact" to v4. This is a temporary solution, while we start looking into how to support node20 in this workflow. --- .github/workflows/release-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index e7151347dc..3205a50d7a 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -50,7 +50,7 @@ jobs: uses: dtolnay/rust-toolchain@stable - name: Enable Rust cache - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@v2.7.0 - name: Setup vcpkg caching uses: actions/github-script@v6 From 32ab7657924f88b9bd141d0955467a7a3214d48f Mon Sep 17 00:00:00 2001 From: Rubidium Date: Thu, 11 Jan 2024 21:39:47 +0100 Subject: [PATCH 4/7] Fix #11485: new run on same line must not use last_space of previous run as cut-off point Use the start of the next run instead as the location of the last space. --- src/gfx_layout_fallback.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gfx_layout_fallback.cpp b/src/gfx_layout_fallback.cpp index 1d3c4e1f99..fe4156deb5 100644 --- a/src/gfx_layout_fallback.cpp +++ b/src/gfx_layout_fallback.cpp @@ -256,6 +256,11 @@ std::unique_ptr FallbackParagraphLayout::NextLine next_run = this->buffer_begin + iter->first; begin = this->buffer; + /* Since a next run is started, there is already some text that + * will be shown for this line. However, we do not want to break + * this line at the previous space, so pretend we passed a space + * just before this next run. */ + last_space = begin - 1; } if (IsWhitespace(c)) last_space = this->buffer; From 1101b04371c4db16a5fc8b0ffded760dea4c81a3 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Thu, 11 Jan 2024 23:00:07 +0000 Subject: [PATCH 5/7] Fix: Build button text when train purchase window using "Engines" filter --- src/build_vehicle_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index aacd9f1c05..0427125399 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1142,7 +1142,7 @@ struct BuildVehicleWindow : Window { { NWidgetCore *widget = this->GetWidget(WID_BV_BUILD); - bool refit = this->sel_engine != INVALID_ENGINE && this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY && this->cargo_filter_criteria != CargoFilterCriteria::CF_NONE; + bool refit = this->sel_engine != INVALID_ENGINE && this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY && this->cargo_filter_criteria != CargoFilterCriteria::CF_NONE && this->cargo_filter_criteria != CargoFilterCriteria::CF_ENGINES; if (refit) refit = Engine::Get(this->sel_engine)->GetDefaultCargoType() != this->cargo_filter_criteria; if (refit) { From 28efa65e0c1b50c16554d0de4ada17c749de28d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Fri, 12 Jan 2024 17:04:43 +0100 Subject: [PATCH 6/7] Revert a2edf52: SQOpsLimiter does a more precise job (#11754) --- cmake/scripts/Regression.cmake | 4 ++++ regression/regression/main.nut | 7 +++++++ regression/regression/result.txt | 19 +++++++++++++++++++ src/script/api/script_list.cpp | 11 ----------- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/cmake/scripts/Regression.cmake b/cmake/scripts/Regression.cmake index 19fece83f5..c719b90406 100644 --- a/cmake/scripts/Regression.cmake +++ b/cmake/scripts/Regression.cmake @@ -54,6 +54,9 @@ string(REPLACE "0x(nil)" "0x00000000" REGRESSION_RESULT "${REGRESSION_RESULT}") string(REPLACE "0x0000000000000000" "0x00000000" REGRESSION_RESULT "${REGRESSION_RESULT}") string(REPLACE "0x0x0" "0x00000000" REGRESSION_RESULT "${REGRESSION_RESULT}") +# Convert path separators +string(REPLACE "\\" "/" REGRESSION_RESULT "${REGRESSION_RESULT}") + # Remove timestamps if any string(REGEX REPLACE "\[[0-9-]+ [0-9:]+\] " "" REGRESSION_RESULT "${REGRESSION_RESULT}") @@ -62,6 +65,7 @@ string(REPLACE "\ndbg: [script]" "\n" REGRESSION_RESULT "${REGRESSION_RESULT}") string(REPLACE "\n " "\nERROR: " REGRESSION_RESULT "${REGRESSION_RESULT}") string(REPLACE "\nERROR: [1] " "\n" REGRESSION_RESULT "${REGRESSION_RESULT}") string(REPLACE "\n[P] " "\n" REGRESSION_RESULT "${REGRESSION_RESULT}") +string(REPLACE "\n[S] " "\n" REGRESSION_RESULT "${REGRESSION_RESULT}") string(REGEX REPLACE "dbg: ([^\n]*)\n?" "" REGRESSION_RESULT "${REGRESSION_RESULT}") # Read the expected result diff --git a/regression/regression/main.nut b/regression/regression/main.nut index 100a47f3c9..b2daa5b687 100644 --- a/regression/regression/main.nut +++ b/regression/regression/main.nut @@ -2026,5 +2026,12 @@ function Regression::Start() print(" IsEventWaiting: false"); this.Math(); + + /* Check Valuate() is actually limited, MUST BE THE LAST TEST. */ + print("--Valuate() with excessive CPU usage--") + local list = AIList(); + list.AddItem(0, 0); + local Infinite = function(id) { while(true); } + list.Valuate(Infinite); } diff --git a/regression/regression/result.txt b/regression/regression/result.txt index 578f15e623..f1d20754b0 100644 --- a/regression/regression/result.txt +++ b/regression/regression/result.txt @@ -9587,4 +9587,23 @@ ERROR: IsEnd() is invalid as Begin() is never called -1 > 2147483647: false -2147483648 > 2147483647: false 13725 > -2147483648: true +--Valuate() with excessive CPU usage-- +Your script made an error: excessive CPU usage in valuator function + +*FUNCTION [unknown()] regression/main.nut line [2034] +*FUNCTION [Valuate()] NATIVE line [-1] +*FUNCTION [Start()] regression/main.nut line [2035] + +[id] 0 +[this] TABLE +[Infinite] CLOSURE +[list] INSTANCE +[this] INSTANCE +Your script made an error: excessive CPU usage in valuator function + +*FUNCTION [Start()] regression/main.nut line [2035] + +[Infinite] CLOSURE +[list] INSTANCE +[this] INSTANCE ERROR: The script died unexpectedly. diff --git a/src/script/api/script_list.cpp b/src/script/api/script_list.cpp index fc727cc934..f774b2a004 100644 --- a/src/script/api/script_list.cpp +++ b/src/script/api/script_list.cpp @@ -9,7 +9,6 @@ #include "../../stdafx.h" #include "script_list.hpp" -#include "script_controller.hpp" #include "../../debug.h" #include "../../script/squirrel.hpp" @@ -914,16 +913,6 @@ SQInteger ScriptList::Valuate(HSQUIRRELVM vm) } } - /* Kill the script when the valuator call takes way too long. - * Triggered by nesting valuators, which then take billions of iterations. */ - if (ScriptController::GetOpsTillSuspend() < -1000000) { - /* See below for explanation. The extra pop is the return value. */ - sq_pop(vm, nparam + 4); - - ScriptObject::SetAllowDoCommand(backup_allow); - return sq_throwerror(vm, "excessive CPU usage in valuator function"); - } - /* Was something changed? */ if (previous_modification_count != this->modifications) { /* See below for explanation. The extra pop is the return value. */ From 03df70ce8af258f25eaff49725676fad4bb849d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Fri, 12 Jan 2024 19:40:08 +0100 Subject: [PATCH 7/7] Fix #11752: [Win32] Wrong multi-line text layout due to incorrect partial run handling (#11761) --- src/os/windows/string_uniscribe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os/windows/string_uniscribe.cpp b/src/os/windows/string_uniscribe.cpp index dfb8ffd0c4..040101ec36 100644 --- a/src/os/windows/string_uniscribe.cpp +++ b/src/os/windows/string_uniscribe.cpp @@ -415,7 +415,7 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF UniscribeRun run = *i_run; /* Partial run after line break (either start or end)? Reshape run to get the first/last glyphs right. */ - if (i_run == last_run - 1 && remaining_offset < (last_run - 1)->len) { + if (i_run == last_run - 1 && remaining_offset <= (last_run - 1)->len) { run.len = remaining_offset - 1; if (!UniscribeShapeRun(this->text_buffer, run)) return nullptr;